Z2M. external_convertors. Add date-time data for last update of Motion/Presence detection sensors

Hi community!
I have several different presence and motion sensors, such as
_TZE204_ztqnh5cg - Human presence sensor 24G
but it only transmits the current state. I’m going to add the following to it so that it transmits additionally

  1. The date when the presence was detected
  2. And the time how long ago it was

For it:

  1. I took the converter from zigbee-herdsman-converters/src/devices/tuya.ts at ddb5c8da6c43f8a602ede8cdd96eb1a4ea4d73db · Koenkk/zigbee-herdsman-converters · GitHub as a basis
    for this sensor
    iHseno TY_24G_Sensor_V2 control via MQTT | Zigbee2MQTT
  2. Added additional fields
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

// Helper function to format the duration of time
function formatDuration(seconds) {
    if (seconds < 60) {
        return `${seconds}с. тому`; // Return time in seconds if it's less than 1 minute
    }

    const days = Math.floor(seconds / (24 * 3600));
    const hours = Math.floor((seconds % (24 * 3600)) / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);

    let result = '';
    if (days > 0) result += `${days}д. `;
    if (hours > 0) result += `${hours}г. `;
    result += `${minutes}хв. тому`;

    return result;
}

const definition = {
    fingerprint: tuya.fingerprint("TS0601", ["_TZE204_qasjif9e", "_TZE204_ztqnh5cg", "_TZE204_iadro9bf", "_TZE284_iadro9bf"]),
    model: "ZY-M100-S_2",
    vendor: "Tuya",
    description: "Mini human breathe sensor",
    fromZigbee: [
        (model, msg, publish, options, meta) => {
            const now = Math.floor(Date.now() / 1000); // Current time in seconds

            // Initialize lastPresenceTime if it doesn't exist
            if (!model.lastPresenceTime) {
                model.lastPresenceTime = now; // Set initial time if not set before
            }

            // If presence is true, update the last detection time
            if (msg.hasOwnProperty('presence') && msg.presence === true) {
                model.lastPresenceTime = now; // Update the last presence time
            }

            // Always update the last detection time and calculate the duration
            if (model.lastPresenceTime) {
                const duration = now - model.lastPresenceTime; // Calculate duration
                model.presenceDuration = formatDuration(duration); // Format the duration as "X days Y hours Z minutes ago"
            }

            // Return the data for Home Assistant
            return {
                presence: msg.presence,
                last_presence_time: model.lastPresenceTime,
                presence_duration: model.presenceDuration,
                ...msg, // Return all other incoming data
            };
        },
        tuya.fz.datapoints // Handle incoming data
    ],
    toZigbee: [tuya.tz.datapoints], // Handle outgoing data
    exposes: [
        e.illuminance(),
        e.presence(),
        e.numeric("target_distance", ea.STATE).withDescription("Distance to target").withUnit("m"),
        e.numeric("radar_sensitivity", ea.STATE_SET).withValueMin(0).withValueMax(9).withValueStep(1).withDescription("sensitivity of the radar"),
        e.numeric("minimum_range", ea.STATE_SET).withValueMin(0).withValueMax(9.5).withValueStep(0.15).withDescription("Minimum range").withUnit("m"),
        e.numeric("maximum_range", ea.STATE_SET).withValueMin(0).withValueMax(9.5).withValueStep(0.15).withDescription("Maximum range").withUnit("m"),
        e.numeric("detection_delay", ea.STATE_SET).withValueMin(0).withValueMax(10).withValueStep(0.1).withDescription("Detection delay").withUnit("s"),
        e.numeric("fading_time", ea.STATE_SET).withValueMin(0.5).withValueMax(1500).withValueStep(1).withDescription("Fading time").withUnit("s"),
        e.numeric("last_presence_time", ea.STATE).withDescription("Time of last presence detection").withUnit("s"),
        e.text("presence_duration", ea.STATE).withDescription("Time since last presence detection")
    ],
    meta: {
        tuyaDatapoints: [
            [1, "presence", tuya.valueConverter.trueFalse1],
            [9, "target_distance", tuya.valueConverter.divideBy100],
            [104, "illuminance", tuya.valueConverter.raw],
            [2, "radar_sensitivity", tuya.valueConverter.raw],
            [4, "maximum_range", tuya.valueConverter.divideBy100],
            [3, "minimum_range", tuya.valueConverter.divideBy100],
            [102, "fading_time", tuya.valueConverter.divideBy10],
            [101, "detection_delay", tuya.valueConverter.divideBy10],
        ],
    },
    whiteLabel: [tuya.whitelabel("iHseno", "TY_24G_Sensor_V2", "Human presence sensor 24G", ["_TZE204_ztqnh5cg"])],
};

module.exports = definition;
  1. But now both new fields are Null

Could you please help me with it?

I’m trying to solve this within the converter, I understand that this can be done in the HA itself, but I wanted it to be automatically created when adding sensors of a particular type.