Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
12.11k stars 1.68k forks source link

Yale YMC-420 D Support #8946

Closed MrNiero closed 2 years ago

MrNiero commented 3 years ago

Hi there, I just bought a new Yale YMC 420 D and looks like there's a little information regarding this model. As far as I could check, it was released about a month ago, so...I couldn't find anything "relatable". This lock supports:

yale.js { zigbeeModel: ['YMC 420 D'], model: 'YMC 420 D', vendor: 'Yale', description: 'YMC 420 D - Digital Lock', extend: lockExtend, meta: {timeout: 20000}, },

MQTT Info zigbee2mqtt/YMC420D 10 most recently received message(s) Received 16:05:26 QoS: 0 Payload: battery: 192 linkquality: 164 lock_state: locked state: LOCK

zigbee2mqtt Debug Log Debug Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":1}' from endpoint 1 with groupID 0 Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":190,"linkquality":148,"lock_state":"locked","state":"LOCK"}' Debug Received Zigbee message from 'YMC420D', type 'readResponse', cluster 'genPowerCfg', data '{"batteryPercentageRemaining":190}' from endpoint 1 with groupID 0 Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":190,"linkquality":180,"lock_state":"locked","state":"LOCK"}' Info MQTT publish: topic 'zigbee2mqtt/bridge/response/device/configure', payload '{"data":{"id":"YMC420D"},"status":"ok","transaction":"ncxl4-1"}' Debug No converter available for 'YMC 420 D' with cluster 'closuresDoorLock' and type 'raw' and data '{"data":[9,35,32,0,2,1,0,0,227,28,234,40],"type":"Buffer"}' Debug Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":190,"linkquality":172,"lock_state":"unlocked","state":"UNLOCK"}' Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":190,"linkquality":172,"lock_state":"unlocked","state":"UNLOCK"}' Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":190,"linkquality":152,"lock_state":"locked","state":"LOCK"}' Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":190,"linkquality":148,"lock_state":"locked","state":"LOCK"}' Debug No converter available for 'YMC 420 D' with cluster 'closuresDoorLock' and type 'raw' and data '{"data":[9,47,32,2,10,0,0,0,242,28,234,40],"type":"Buffer"}'

Information about the device + link

I've tried to find an international link, but also unable......

https://www.yalehome.com.br/pt-BR/produtos1/products/fechaduras-digitais-biometricas/fechadura-digital-ymc420d/

data/database.db entry of the device

{"id":5,"type":"EndDevice","ieeeAddr":"0x00158d0006dbf814","nwkAddr":30626,"manufId":4151,"manufName":"Yale","powerSource":"Battery","modelId":"YMC 420 D","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":2064,"inClusterList":[0,4,3,4111,257],"outClusterList":[0,4,3,4111,257],"clusters":{"genBasic":{"attributes":{"modelId":"YMC 420 D","manufacturerName":"Yale","powerSource":3,"zclVersion":2,"appVersion":1,"stackVersion":1,"hwVersion":1,"dateCode":"20160301","swBuildId":"02.01.03"}},"genPowerCfg":{"attributes":{"batteryPercentageRemaining":184}},"closuresDoorLock":{"attributes":{"lockState":1,"operatingMode":1}}},"binds":[{"cluster":257,"type":"endpoint","deviceIeeeAddress":"0x804b50fffe0ea2ed","endpointID":1},{"cluster":1,"type":"endpoint","deviceIeeeAddress":"0x804b50fffe0ea2ed","endpointID":1}],"configuredReportings":[{"cluster":257,"attrId":0,"minRepIntval":0,"maxRepIntval":3600,"repChange":0},{"cluster":1,"attrId":33,"minRepIntval":3600,"maxRepIntval":62000,"repChange":0}],"meta":{}}},"appVersion":1,"stackVersion":1,"hwVersion":1,"dateCode":"20160301","swBuildId":"02.01.03","zclVersion":2,"interviewCompleted":true,"meta":{"configured":923668394},"lastSeen":1633115328213}

MrNiero commented 3 years ago

This weekend I had some time to dig around. I changed the parameter battery: {dontDividePercentage: } from true to false, and now I have the battery value displaying correctly.

But yet, I still cannot find the action_user anywhere - json, log.....nowhere to be found...

Debug Received Zigbee message from 'YMC420D', type 'raw', cluster 'closuresDoorLock', data '{"data":[9,178,32,1,2,0,0,0,234,3,247,40],"type":"Buffer"}' from endpoint 1 with groupID 0 Debug Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"auto_relock_time":0,"battery":95,"linkquality":196,"lock_state":"unlocked","sound_volume":"silent_mode","state":"UNLOCK"}' Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"auto_relock_time":0,"battery":95,"linkquality":196,"lock_state":"unlocked","sound_volume":"silent_mode","state":"UNLOCK"}' Debug Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":1}' from endpoint 1 with groupID 0 Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"auto_relock_time":0,"battery":95,"linkquality":196,"lock_state":"locked","sound_volume":"silent_mode","state":"LOCK"}' Info MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"auto_relock_time":0,"battery":95,"linkquality":192,"lock_state":"locked","sound_volume":"silent_mode","state":"LOCK"}' Debug No converter available for 'YMC 420 D' with cluster 'closuresDoorLock' and type 'raw' and data '{"data":[9,192,32,2,10,0,0,0,249,3,247,40],"type":"Buffer"}'

image ] image

MrNiero commented 3 years ago

After some research (and broken things) I was able to get new stats from the Lock such as the unlock method. I've put together some info from another devices and was able to return the values.

1st discovery - Unlike the other locks, the 420D is returning its values as type RAW. 2nd discovery - For some reason commandOperationEventNotification, commandProgrammingEventNotification, commandGetPinCodeRsp, commandGetUserStatusRsp are not returning AT ALL from the lock.

Tweaking the js file as below, I was able to return a few more values than before. But yet, I cannot return anything related to the action_user...

**_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 constants = require('zigbee-herdsman-converters/lib/constants'); const reporting = require('zigbee-herdsman-converters/lib/reporting'); const extend = require('zigbee-herdsman-converters/lib/extend'); const e = exposes.presets; const ea = exposes.access;

const fzLocal = { action: { cluster: 'closuresDoorLock', type: 'raw', convert: (model, msg, publish, options, meta) => { const lookup = {
0: 'keypad_unlock', 1: 'zigbee_unlock', 2: 'manual_lock',
3: 'rfid_unlock', 4: 'finger_unlock',
10: 'auto_lock', 14: 'inside_unlock', }; }; const value = lookup[msg.data[4]]; if (value == 'lock' || value == 'inside_unlock') { return {action: value}; } else { return {action: lookup[msg.data[3]]}; } }, }, }

const lockExtend = (meta) => { return { fromZigbee: [fz.lock_operation_event, fz.lock_programming_event, fz.lock_pin_code_response, fz.lock_user_status_response, fz.lock, fz.battery,
fzLocal.action], toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus], meta: {pinCodeCount: 250, ...meta}, exposes: [e.lock(), e.battery(), e.pincode()], configure: async (device, coordinatorEndpoint, logger) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']); await reporting.lockState(endpoint); await reporting.batteryPercentageRemaining(endpoint); }, }; };

module.exports = [
{ zigbeeModel: ['YMC 420 D'], model: 'YMC 420 D', vendor: 'Yale', description: 'YMC 420 D - Digital Lock', extend: lockExtend({timeout: 20000}), }, ];_**

image

Zigbee2MQTT:debug 2021-11-08 18:25:44: Received Zigbee message from 'YMC420D', type 'raw', cluster 'closuresDoorLock', data '{"data":[9,205,32,4,2,1,0,0,88,82,28,41],"type":"Buffer"}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:25:44: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"finger_unlock","battery":86,"linkquality":160,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:25:44: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"","battery":86,"linkquality":160,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:25:44: MQTT publish: topic 'zigbee2mqtt/YMC420D/action', payload 'finger_unlock' Zigbee2MQTT:debug 2021-11-08 18:25:44: Received Zigbee message from 'YMC420D', type 'read', cluster 'genTime', data '["time","timeStatus"]' from endpoint 1 with groupID 0 Zigbee2MQTT:debug 2021-11-08 18:25:45: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:25:45: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":144,"lock_state":"unlocked","state":"UNLOCK"}' Zigbee2MQTT:debug 2021-11-08 18:25:45: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:25:45: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":140,"lock_state":"unlocked","state":"UNLOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:02: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":1}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:02: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":140,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:03: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":1}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:03: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":164,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:03: Received Zigbee message from 'YMC420D', type 'raw', cluster 'closuresDoorLock', data '{"data":[9,224,32,2,7,0,0,0,107,82,28,41],"type":"Buffer"}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:03: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"unlock","battery":86,"linkquality":156,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:26:03: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"","battery":86,"linkquality":156,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:26:03: MQTT publish: topic 'zigbee2mqtt/YMC420D/action', payload 'unlock' Zigbee2MQTT:debug 2021-11-08 18:26:16: Received Zigbee message from 'YMC420D', type 'raw', cluster 'closuresDoorLock', data '{"data":[9,231,32,3,2,1,0,0,121,82,28,41],"type":"Buffer"}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:16: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"rfid_unlock","battery":86,"linkquality":96,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:26:16: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"","battery":86,"linkquality":96,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:26:16: MQTT publish: topic 'zigbee2mqtt/YMC420D/action', payload 'rfid_unlock' Zigbee2MQTT:debug 2021-11-08 18:26:17: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:17: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":156,"lock_state":"unlocked","state":"UNLOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:17: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:17: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":160,"lock_state":"unlocked","state":"UNLOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:22: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":1}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:22: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":164,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:23: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":1}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:23: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":86,"linkquality":168,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:debug 2021-11-08 18:26:23: Received Zigbee message from 'YMC420D', type 'raw', cluster 'closuresDoorLock', data '{"data":[9,242,32,2,7,0,0,0,126,82,28,41],"type":"Buffer"}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-11-08 18:26:23: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"unlock","battery":86,"linkquality":172,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:26:23: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"","battery":86,"linkquality":172,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-11-08 18:26:23: MQTT publish: topic 'zigbee2mqtt/YMC420D/action', payload 'unlock' Zigbee2MQTT:debug 2021-11-08 18:26:32: Received Zigbee message from 'Sensor Porta da Sala', type 'commandStatusChangeNotification', cluster 'ssIasZone', data '{"extendedstatus":0,"zonestatus":0}' from endpoint 1 with groupID 0

MrNiero commented 2 years ago

hey @Koenkk I know you're probably swamped there, but....we could use a hand or two :)

oguime commented 2 years ago

I would be interested too. Seems like a nice update to the YRL226L with the addition of card and fingerprint authentication for an equivalent price, if you consider that the zigbee module comes standard...

dudu631 commented 2 years ago

I'm up for this as well!

Koenkk commented 2 years ago

@nieror where are you currently stuck? (what doesn't work yet?)

MrNiero commented 2 years ago

hello @Koenkk thank you for you reply. (sorry for the delay... I'm in a stressfull work related week so I wasn't able to reply).

Summing up, pretty much anything related to PIN operations. I am able to retrieve lock status, unlock type (e.g.: rfid, finger, etc) I just noticed that I can change an user's PIN via the "Exposes" page, but I don't get any info from there, like, if it was successful or not....I had to check the logs to make sure the SET operation completed and on the lock itself if really changed the PIN.

So pretty much I'm stuck with retrieving the PIN/User that unlocked the door in any way. As I've mentioned in my lastest post, I can't see on the debug anything related to the commandOperationEventNotification, commandProgrammingEventNotification, commandGetPinCodeRsp, commandGetUserStatusRsp events.

I think I forgot to mention, I'm using a Sonoff ZB Bridge, not sure if it would interfere....

Koenkk commented 2 years ago

I'm using a Sonoff ZB Bridge

This could be the issue, I expect this locks works with the same config as all other Yale locks. I'm not sure if the sonoff ZB bridge forwards all messages to z2m (the EZSP integration is very experimental). Could you try with a recommended adapter: https://www.zigbee2mqtt.io/guide/adapters/#recommended

rrlevy commented 2 years ago

I just purchased this lock, and I'll test with different adapters to confirm (I have a Conbee II now, and a zzh not being used)

But from what I've heard from other people that have this product, this lock is still not working with Zigbee2Mqtt, only directly with ZHA.

I'll post my results here as soon as I get it installed

rrlevy commented 2 years ago

I just installed mine here using Conbee II. It looks just like the Sonoff example above.

Here are my logs for a finger unlock:

image

Zigbee2MQTT:info 2021-12-04 16:44:40: MQTT publish: topic 'zigbee2mqtt/Yale YMC420D', payload '{"action":"finger_unlock","battery":0,"linkquality":255,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-12-04 16:44:40: MQTT publish: topic 'zigbee2mqtt/Yale YMC420D', payload '{"action":"","battery":0,"linkquality":255,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-12-04 16:44:40: MQTT publish: topic 'homeassistant/device_automation/0x00158d0006d6d31d/action_finger_unlock/config', payload '{"automation_type":"trigger","device":{"identifiers":["zigbee2mqtt_0x00158d0006d6d31d"],"manufacturer":"Yale","model":"YMC 420 D - Digital Lock (YMC 420 D)","name":"Yale YMC420D","sw_version":"02.01.03"},"payload":"finger_unlock","subtype":"finger_unlock","topic":"zigbee2mqtt/Yale YMC420D/action","type":"action"}' Zigbee2MQTT:info 2021-12-04 16:44:41: MQTT publish: topic 'zigbee2mqtt/Yale YMC420D/action', payload 'finger_unlock' Zigbee2MQTT:info 2021-12-04 16:44:42: MQTT publish: topic 'zigbee2mqtt/Yale YMC420D', payload '{"battery":0,"linkquality":255,"lock_state":"unlocked","state":"UNLOCK"}' Zigbee2MQTT:info 2021-12-04 16:44:42: MQTT publish: topic 'zigbee2mqtt/Yale YMC420D', payload '{"battery":0,"linkquality":255,"lock_state":"unlocked","state":"UNLOCK"}'

I used the external converter as posted above:

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 constants = require("zigbee-herdsman-converters/lib/constants");
const reporting = require("zigbee-herdsman-converters/lib/reporting");
const extend = require("zigbee-herdsman-converters/lib/extend");
const e = exposes.presets;
const ea = exposes.access;

const fzLocal = {
  action: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const lookup = {
        0: "keypad_unlock",
        1: "zigbee_unlock",
        2: "manual_lock",
        3: "rfid_unlock",
        4: "finger_unlock",
        10: "auto_lock",
        14: "inside_unlock",
      };
      const value = lookup[msg.data[4]];
      if (value == "lock" || value == "inside_unlock") {
        return { action: value };
      } else {
        return { action: lookup[msg.data[3]] };
      }
    },
  },
};

const lockExtend = (meta) => {
  return {
    fromZigbee: [
      fz.lock_operation_event,
      fz.lock_programming_event,
      fz.lock_pin_code_response,
      fz.lock_user_status_response,
      fz.lock,
      fz.battery,
      fzLocal.action,
    ],
    toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
    meta: { pinCodeCount: 250, ...meta },
    exposes: [e.lock(), e.battery(), e.pincode()],
    configure: async (device, coordinatorEndpoint, logger) => {
      const endpoint = device.getEndpoint(1);
      await reporting.bind(endpoint, coordinatorEndpoint, [
        "closuresDoorLock",
        "genPowerCfg",
      ]);
      await reporting.lockState(endpoint);
      await reporting.batteryPercentageRemaining(endpoint);
    },
  };
};

module.exports = [
  {
    zigbeeModel: ["YMC 420 D"],
    model: "YMC 420 D",
    vendor: "Yale",
    description: "YMC 420 D - Digital Lock",
    extend: lockExtend({ timeout: 20000 }),
  },
];
rrlevy commented 2 years ago

These are the logs for LOCKING and UNLOCKING via Zigbee2MQTT:

Info MQTT publish: topic 'zigbee2mqtt/Yale YMC 420D', payload '{"action":"zigbee_unlock","battery":null,"linkquality":255,"lock_state":"locked","state":"LOCK"}' Info MQTT publish: topic 'zigbee2mqtt/Yale YMC 420D', payload '{"action":"","battery":null,"linkquality":255,"lock_state":"locked","state":"LOCK"}' Info MQTT publish: topic 'zigbee2mqtt/Yale YMC 420D/action', payload 'zigbee_unlock' Info MQTT publish: topic 'zigbee2mqtt/Yale YMC 420D', payload '{"battery":null,"linkquality":255,"lock_state":"unlocked","state":"UNLOCK"}' Info MQTT publish: topic 'zigbee2mqtt/Yale YMC 420D', payload '{"battery":null,"linkquality":255,"lock_state":"locked","state":"LOCK"}'

Koenkk commented 2 years ago

@rrlevy looks all is working?

rrlevy commented 2 years ago

@Koenkk only the lock/unlock is working, but as @nieror mentioned, we can't get any information about the user unlocking the door.

Koenkk commented 2 years ago

@rrlevy can you check if the configuring goes OK? You can force it via the frontend -> press yellow button on the device page. Before doing this make sure to wake up the lock otherwise it might fail due to the lock being asleep.

rrlevy commented 2 years ago

I just tried pairing it again (I had uninstalled and removed it from my network).

Here is the log for the pairing process:

Info Device '0x00158d0006d6d31d' joined
Info MQTT publish: topic 'zigbee2mqtt/bridge/event', payload '{"data":{"friendly_name":"0x00158d0006d6d31d","ieee_address":"0x00158d0006d6d31d"},"type":"device_joined"}'
Info MQTT publish: topic 'zigbee2mqtt/bridge/log', payload '{"message":{"friendly_name":"0x00158d0006d6d31d"},"type":"device_connected"}'
Info Starting interview of '0x00158d0006d6d31d'
Info MQTT publish: topic 'zigbee2mqtt/bridge/event', payload '{"data":{"friendly_name":"0x00158d0006d6d31d","ieee_address":"0x00158d0006d6d31d","status":"started"},"type":"device_interview"}'
Info MQTT publish: topic 'zigbee2mqtt/bridge/log', payload '{"message":"interview_started","meta":{"friendly_name":"0x00158d0006d6d31d"},"type":"pairing"}'
Info Successfully interviewed '0x00158d0006d6d31d', device has successfully been paired
Info Device '0x00158d0006d6d31d' is supported, identified as: Yale YMC 420 D - Digital Lock (YMC 420 D)
Info MQTT publish: topic 'zigbee2mqtt/bridge/event', payload '{"data":{"definition":{"description":"YMC 420 D - Digital Lock","exposes":[{"features":[{"access":7,"description":"State of the lock","name":"state","property":"state","type":"binary","value_off":"UNLOCK","value_on":"LOCK"},{"access":1,"description":"Actual state of the lock","name":"lock_state","property":"lock_state","type":"enum","values":["not_fully_locked","locked","unlocked"]}],"type":"lock"},{"access":1,"description":"Remaining battery in %","name":"battery","property":"battery","type":"numeric","unit":"%","value_max":100,"value_min":0},{"features":[{"access":2,"description":"User ID to set or clear the pincode for","name":"user","property":"user","type":"numeric"},{"access":2,"description":"Type of user, unrestrictied: owner (default), (year|week)_day_schedule: user has ability to open lock based on specific time period, master: user has ability to both program and operate the door lock, non_access: user is recognized by the lock but does not have the ability to open the lock","name":"user_type","property":"user_type","type":"enum","values":["unrestricted","year_day_schedule","week_day_schedule","master","non_access"]},{"access":2,"description":"Whether the user is enabled/disabled","name":"user_enabled","property":"user_enabled","type":"binary","value_off":false,"value_on":true},{"access":2,"description":"Pincode to set, set pincode to null to clear","name":"pin_code","property":"pin_code","type":"numeric"}],"name":"pin_code","property":"pin_code","type":"composite"},{"access":1,"description":"Link quality (signal strength)","name":"linkquality","property":"linkquality","type":"numeric","unit":"lqi","value_max":255,"value_min":0}],"model":"YMC 420 D","options":[{"access":2,"description":"Expose pin of this lock in the published payload (default false).","name":"expose_pin","property":"expose_pin","type":"binary","value_off":false,"value_on":true}],"supports_ota":false,"vendor":"Yale"},"friendly_name":"0x00158d0006d6d31d","ieee_address":"0x00158d0006d6d31d","status":"successful","supported":true},"type":"device_interview"}'
Info Configuring '0x00158d0006d6d31d'
Info MQTT publish: topic 'zigbee2mqtt/bridge/log', payload '{"message":"interview_successful","meta":{"description":"YMC 420 D - Digital Lock","friendly_name":"0x00158d0006d6d31d","model":"YMC 420 D","supported":true,"vendor":"Yale"},"type":"pairing"}'
Info MQTT publish: topic 'homeassistant/lock/0x00158d0006d6d31d/lock/config', payload '{"availability":[{"topic":"zigbee2mqtt/bridge/state"}],"command_topic":"zigbee2mqtt/0x00158d0006d6d31d/set","device":{"identifiers":["zigbee2mqtt_0x00158d0006d6d31d"],"manufacturer":"Yale","model":"YMC 420 D - Digital Lock (YMC 420 D)","name":"0x00158d0006d6d31d","sw_version":"02.01.03"},"json_attributes_topic":"zigbee2mqtt/0x00158d0006d6d31d","name":"0x00158d0006d6d31d","state_locked":"LOCK","state_topic":"zigbee2mqtt/0x00158d0006d6d31d","state_unlocked":"UNLOCK","unique_id":"0x00158d0006d6d31d_lock_zigbee2mqtt","value_template":"{{ value_json.state }}"}'
Info MQTT publish: topic 'homeassistant/sensor/0x00158d0006d6d31d/battery/config', payload '{"availability":[{"topic":"zigbee2mqtt/bridge/state"}],"device":{"identifiers":["zigbee2mqtt_0x00158d0006d6d31d"],"manufacturer":"Yale","model":"YMC 420 D - Digital Lock (YMC 420 D)","name":"0x00158d0006d6d31d","sw_version":"02.01.03"},"device_class":"battery","enabled_by_default":true,"entity_category":"diagnostic","json_attributes_topic":"zigbee2mqtt/0x00158d0006d6d31d","name":"0x00158d0006d6d31d battery","state_class":"measurement","state_topic":"zigbee2mqtt/0x00158d0006d6d31d","unique_id":"0x00158d0006d6d31d_battery_zigbee2mqtt","unit_of_measurement":"%","value_template":"{{ value_json.battery }}"}'
Info MQTT publish: topic 'homeassistant/sensor/0x00158d0006d6d31d/linkquality/config', payload '{"availability":[{"topic":"zigbee2mqtt/bridge/state"}],"device":{"identifiers":["zigbee2mqtt_0x00158d0006d6d31d"],"manufacturer":"Yale","model":"YMC 420 D - Digital Lock (YMC 420 D)","name":"0x00158d0006d6d31d","sw_version":"02.01.03"},"enabled_by_default":false,"entity_category":"diagnostic","icon":"mdi:signal","json_attributes_topic":"zigbee2mqtt/0x00158d0006d6d31d","name":"0x00158d0006d6d31d linkquality","state_class":"measurement","state_topic":"zigbee2mqtt/0x00158d0006d6d31d","unique_id":"0x00158d0006d6d31d_linkquality_zigbee2mqtt","unit_of_measurement":"lqi","value_template":"{{ value_json.linkquality }}"}'
Info MQTT publish: topic 'zigbee2mqtt/0x00158d0006d6d31d', payload '{"battery":0,"linkquality":255,"state":null}'
Info Successfully configured '0x00158d0006d6d31d'

And here the log for the forced configuration after paired:

Info MQTT publish: topic 'zigbee2mqtt/bridge/response/device/configure', payload '{"data":{"id":"0x00158d0006d6d31d"},"status":"ok","transaction":"5h6sl-3"}'

I used the same external converter as posted above

MrNiero commented 2 years ago

Even tho I work with IT Infrastructure, I'm not a dev, but as far as I understand this codes, what really calls to return the PIN are these functions: commandOperationEventNotification, commandProgrammingEventNotification, commandGetPinCodeRsp, commandGetUserStatusRsp, and for some reason I cannot see them anywhere.... Not sure that since this lock has the ZB Module integrated, if for some reason they've changed some key elements of the communication... I think that the 1st indication of this "change" is that this lock does not report the regular commandOperationEventNotification. Instead is reports as 'RAW". Not sure if my "insight" helps, but....that's what I've found so far....

@Koenkk I've enabled the herdsman-converters log and this is what I get unlocking the door with my fingerprint. Can't see any indication that the PIN / user is showing up anywhere on the logs.

Zigbee2MQTT:debug 2021-12-06 14:59:02: Received Zigbee message from 'YMC420D', type 'raw', cluster 'closuresDoorLock', data '{"data":[9,225,32,4,2,1,0,0,228,11,65,41],"type":"Buffer"}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-12-06 14:59:02: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"fingerprint","battery":88,"linkquality":128,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-12-06 14:59:02: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"action":"","battery":88,"linkquality":128,"lock_state":"locked","state":"LOCK"}' Zigbee2MQTT:info 2021-12-06 14:59:02: MQTT publish: topic 'zigbee2mqtt/YMC420D/action', payload 'fingerprint' 2021-12-06T17:59:04.006Z zigbee-herdsman:adapter:ezsp:uart <-- [6035b1a97d312a15b658954b24ab5593499c9e5b104fb99874fade8683fc7d5e0fa5ed8e7e] [96,53,177,169,125,49,42,21,182,88,149,75,36,171,85,147,73,156,158,91,16,79,185,152,116,250,222,134,131,252,125,94,15,165,237,142,126] 2021-12-06T17:59:04.006Z zigbee-herdsman:adapter:ezsp:uart Recv DATA frame (6,0,0): 6035b1a9112a15b658954b24ab5593499c9e5b104fb99874fade8683fc7e0fa5ed8e7e0000 2021-12-06T17:59:04.006Z zigbee-herdsman:adapter:ezsp:uart Send ACK frame (7) 2021-12-06T17:59:04.006Z zigbee-herdsman:adapter:ezsp:uart --> [87009f7e] [135,0,159,126] 2021-12-06T17:59:04.007Z zigbee-herdsman:adapter:ezsp:log <=== Frame: 77900145000004010101010100010000d07cbba277ffff0718e50a000030020643 2021-12-06T17:59:04.007Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 69 (incomingMessageHandler) received: 0004010101010100010000d07cbba277ffff0718e50a000030020643 2021-12-06T17:59:04.008Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 69 (incomingMessageHandler) parsed: 0,EmberApsFrame: {"profileId":260,"clusterId":257,"sourceEndpoint":1,"destinationEndpoint":1,"options":256,"groupId":0,"sequence":208},124,-69,30626,255,255,� 0 2021-12-06T17:59:04.008Z zigbee-herdsman:adapter:ezsp processMessage: {"messageType":0,"apsFrame":{"profileId":260,"clusterId":257,"sourceEndpoint":1,"destinationEndpoint":1,"options":256,"groupId":0,"sequence":208},"lqi":124,"rssi":-69,"sender":30626,"bindingIndex":255,"addressIndex":255,"message":{"type":"Buffer","data":[24,229,10,0,0,48,2]}} 2021-12-06T17:59:04.014Z zigbee-herdsman:controller:log Received 'zcl' data '{"frame":{"Header":{"frameControl":{"frameType":0,"manufacturerSpecific":false,"direction":1,"disableDefaultResponse":true,"reservedBits":0},"transactionSequenceNumber":229,"manufacturerCode":null,"commandIdentifier":10},"Payload":[{"attrId":0,"dataType":48,"attrData":2}],"Command":{"ID":10,"name":"report","parameters":[{"name":"attrId","type":33},{"name":"dataType","type":32},{"name":"attrData","type":1000}]}},"address":30626,"endpoint":1,"linkquality":124,"groupID":0,"wasBroadcast":false,"destinationEndpoint":1}' Zigbee2MQTT:debug 2021-12-06 14:59:04: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 Zigbee2MQTT:info 2021-12-06 14:59:04: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":88,"linkquality":124,"lock_state":"unlocked","state":"UNLOCK"}' 2021-12-06T17:59:04.892Z zigbee-herdsman:adapter:ezsp:uart <-- [7035b1a97d312a15b658954b24ab5593499c9f7b7d384fb99874face8583fc7d5e0fa5e8b97e] [112,53,177,169,125,49,42,21,182,88,149,75,36,171,85,147,73,156,159,123,125,56,79,185,152,116,250,206,133,131,252,125,94,15,165,232,185,126] 2021-12-06T17:59:04.892Z zigbee-herdsman:adapter:ezsp:uart Recv DATA frame (7,0,0): 7035b1a9112a15b658954b24ab5593499c9f7b184fb99874face8583fc7e0fa5e8b97e000000 2021-12-06T17:59:04.892Z zigbee-herdsman:adapter:ezsp:uart Send ACK frame (0) 2021-12-06T17:59:04.893Z zigbee-herdsman:adapter:ezsp:uart --> [8070787e] [128,112,120,126] 2021-12-06T17:59:04.893Z zigbee-herdsman:adapter:ezsp:log <=== Frame: 77900145000004010101010100010000d15cb3a277ffff0708e60a000030020374a0 2021-12-06T17:59:04.893Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 69 (incomingMessageHandler) received: 0004010101010100010000d15cb3a277ffff0708e60a000030020374a0 2021-12-06T17:59:04.894Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 69 (incomingMessageHandler) parsed: 0,EmberApsFrame: {"profileId":260,"clusterId":257,"sourceEndpoint":1,"destinationEndpoint":1,"options":256,"groupId":0,"sequence":209},92,-77,30626,255,255,� 0 2021-12-06T17:59:04.894Z zigbee-herdsman:adapter:ezsp processMessage: {"messageType":0,"apsFrame":{"profileId":260,"clusterId":257,"sourceEndpoint":1,"destinationEndpoint":1,"options":256,"groupId":0,"sequence":209},"lqi":92,"rssi":-77,"sender":30626,"bindingIndex":255,"addressIndex":255,"message":{"type":"Buffer","data":[8,230,10,0,0,48,2]}} 2021-12-06T17:59:04.902Z zigbee-herdsman:controller:log Received 'zcl' data '{"frame":{"Header":{"frameControl":{"frameType":0,"manufacturerSpecific":false,"direction":1,"disableDefaultResponse":false,"reservedBits":0},"transactionSequenceNumber":230,"manufacturerCode":null,"commandIdentifier":10},"Payload":[{"attrId":0,"dataType":48,"attrData":2}],"Command":{"ID":10,"name":"report","parameters":[{"name":"attrId","type":33},{"name":"dataType","type":32},{"name":"attrData","type":1000}]}},"address":30626,"endpoint":1,"linkquality":92,"groupID":0,"wasBroadcast":false,"destinationEndpoint":1}' Zigbee2MQTT:debug 2021-12-06 14:59:04: Received Zigbee message from 'YMC420D', type 'attributeReport', cluster 'closuresDoorLock', data '{"lockState":2}' from endpoint 1 with groupID 0 2021-12-06T17:59:04.910Z zigbee-herdsman:controller:endpoint DefaultResponse 0x00158d0006dbf814/1 257(10, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":1,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) 2021-12-06T17:59:04.911Z zigbee-herdsman:adapter:ezsp sendZclFrameToEndpointInternal 0x00158d0006dbf814:30626/1 (0,0,1) Zigbee2MQTT:info 2021-12-06 14:59:04: MQTT publish: topic 'zigbee2mqtt/YMC420D', payload '{"battery":88,"linkquality":92,"lock_state":"unlocked","state":"UNLOCK"}' 2021-12-06T17:59:04.916Z zigbee-herdsman:adapter:ezsp:log ===> Send command setExtendedTimeout: (00158d0006dbf814,true) 2021-12-06T17:59:04.916Z zigbee-herdsman:adapter:ezsp:log ===> Send data setExtendedTimeout: (7800017e0014f8db06008d150001) 2021-12-06T17:59:04.916Z zigbee-herdsman:adapter:ezsp:uart Send DATA frame (0,0,0): 7800017e0014f8db06008d150001 2021-12-06T17:59:04.917Z zigbee-herdsman:adapter:ezsp:uart waiting (1) 2021-12-06T17:59:04.917Z zigbee-herdsman:adapter:ezsp:uart --> [003a21a92a2a014a82924aa8bf55937d33527e] [0,58,33,169,42,42,1,74,130,146,74,168,191,85,147,125,51,82,126] 2021-12-06T17:59:04.917Z zigbee-herdsman:adapter:ezsp:uart waiting (1) success 2021-12-06T17:59:04.937Z zigbee-herdsman:adapter:ezsp:uart <-- [013aa1a92a2ad23a7e] [1,58,161,169,42,42,210,58,126] 2021-12-06T17:59:04.937Z zigbee-herdsman:adapter:ezsp:uart Recv DATA frame (0,1,0): 013aa1a92a2ad23a7e 2021-12-06T17:59:04.938Z zigbee-herdsman:adapter:ezsp:uart Send ACK frame (1) 2021-12-06T17:59:04.938Z zigbee-herdsman:adapter:ezsp:uart --> [8160597e] [129,96,89,126] 2021-12-06T17:59:04.938Z zigbee-herdsman:adapter:ezsp:log <=== Frame: 7880017e00 2021-12-06T17:59:04.940Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 126 (setExtendedTimeout) received: 2021-12-06T17:59:04.941Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 126 (setExtendedTimeout) parsed: 2021-12-06T17:59:04.943Z zigbee-herdsman:adapter:ezsp:log ===> Send command sendUnicast: (0,30626,EmberApsFrame: {"clusterId":257,"profileId":260,"sequence":3,"sourceEndpoint":1,"destinationEndpoint":1,"groupId":0,"options":320},4,� ) 2021-12-06T17:59:04.944Z zigbee-herdsman:adapter:ezsp:log ===> Send data sendUnicast: (790001340000a2770401010101014001000003040518e60b0a00) 2021-12-06T17:59:04.944Z zigbee-herdsman:adapter:ezsp:uart Send DATA frame (1,1,0): 790001340000a2770401010101014001000003040518e60b0a00 2021-12-06T17:59:04.945Z zigbee-herdsman:adapter:ezsp:uart waiting (2) 2021-12-06T17:59:04.945Z zigbee-herdsman:adapter:ezsp:uart --> [7d313b21a9602a15102e904b24ab5493099d4e27a8e9cb7f6df6cc6359e47e] [125,49,59,33,169,96,42,21,16,46,144,75,36,171,84,147,9,157,78,39,168,233,203,127,109,246,204,99,89,228,126] 2021-12-06T17:59:04.945Z zigbee-herdsman:adapter:ezsp:uart waiting (2) success 2021-12-06T17:59:04.995Z zigbee-herdsman:adapter:ezsp:uart <-- [123ba1a9602a15b965bf7e] [18,59,161,169,96,42,21,185,101,191,126] 2021-12-06T17:59:04.998Z zigbee-herdsman:adapter:ezsp:uart Recv DATA frame (1,2,0): 123ba1a9602a15b965bf7e 2021-12-06T17:59:04.999Z zigbee-herdsman:adapter:ezsp:uart Send ACK frame (2) 2021-12-06T17:59:04.999Z zigbee-herdsman:adapter:ezsp:uart --> [82503a7e] [130,80,58,126] 2021-12-06T17:59:05.001Z zigbee-herdsman:adapter:ezsp:log <=== Frame: 7980013400000b 2021-12-06T17:59:05.001Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 52 (sendUnicast) received: 000b 2021-12-06T17:59:05.002Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 52 (sendUnicast) parsed: 0,11 2021-12-06T17:59:05.598Z zigbee-herdsman:adapter:ezsp:uart <-- [223bb1a96b2a15102e904b24ab5493099d4e27a0e9ce67fab67e] [34,59,177,169,107,42,21,16,46,144,75,36,171,84,147,9,157,78,39,160,233,206,103,250,182,126] 2021-12-06T17:59:05.599Z zigbee-herdsman:adapter:ezsp:uart Recv DATA frame (2,2,0): 223bb1a96b2a15102e904b24ab5493099d4e27a0e9ce67fab67e 2021-12-06T17:59:05.600Z zigbee-herdsman:adapter:ezsp:uart Send ACK frame (3) 2021-12-06T17:59:05.600Z zigbee-herdsman:adapter:ezsp:uart --> [83401b7e] [131,64,27,126] 2021-12-06T17:59:05.602Z zigbee-herdsman:adapter:ezsp:log <=== Frame: 7990013f0000a277040101010101400100000b040000 2021-12-06T17:59:05.602Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 63 (messageSentHandler) received: 00a277040101010101400100000b040000 2021-12-06T17:59:05.603Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 63 (messageSentHandler) parsed: 0,30626,EmberApsFrame: {"profileId":260,"clusterId":257,"sourceEndpoint":1,"destinationEndpoint":1,"options":320,"groupId":0,"sequence":11},4,0, 2021-12-06T17:59:05.605Z zigbee-herdsman:adapter:ezsp:uart <-- [323bb1a9d42a57102ea53b7e] [50,59,177,169,212,42,87,16,46,165,59,126] 2021-12-06T17:59:05.606Z zigbee-herdsman:adapter:ezsp:uart Recv DATA frame (3,2,0): 323bb1a9d42a57102ea53b7e 2021-12-06T17:59:05.606Z zigbee-herdsman:adapter:ezsp:uart Send ACK frame (4) 2021-12-06T17:59:05.607Z zigbee-herdsman:adapter:ezsp:uart --> [8430fc7e] [132,48,252,126] 2021-12-06T17:59:05.608Z zigbee-herdsman:adapter:ezsp:log <=== Frame: 799001800042a277 2021-12-06T17:59:05.609Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 128 (incomingRouteErrorHandler) received: 42a277 2021-12-06T17:59:05.609Z zigbee-herdsman:adapter:ezsp:log <=== Application frame 128 (incomingRouteErrorHandler) parsed: 66,30626 2021-12-06T17:59:05.610Z zigbee-herdsman:adapter:ezsp:driver handleRouteError: nwk=30626, status=66

rrlevy commented 2 years ago

One interesting thing that I also noticed is that after I pair the lock, it looses all the user configurations that were previously made. (fingerprints, codes, cards, etc). I have to add it all again.

I'm not sure if this is something being done by the lock itself or if it's related to the external converter code posted.

MrNiero commented 2 years ago

One interesting thing that I also noticed is that after I pair the lock, it looses all the user configurations that were previously made. (fingerprints, codes, cards, etc). I have to add it all again.

I'm not sure if this is something being done by the lock itself or if it's related to the external converter code posted.

Noticed that as well, but as far as I understand that would be a default behavior. Like, switching from local hardware management to a remote software management.

In which I just noticed that it's also something that is not reporting. I may be wrong, but shouldn't any changes made to the lock configuration also be logged? really...not sure...just asking :)

rrlevy commented 2 years ago

I got an answer for a comment from a Youtuber sponsored by Yale that this specific lock should receive a firmware update from Yale. Maybe we need that for it to send those information we are missing.

https://youtu.be/jd1HS4YryBs

Koenkk commented 2 years ago

@rrlevy that could be it indeed, if we have the firmware file we I can enable OTA updates from it from z2m.

MrNiero commented 2 years ago

@rrlevy that could be it indeed, if we have the firmware file we I can enable OTA updates from it from z2m.

"Problem" is that this lock is so new that its not even listed on Yale Access... so not sure where we could find it...

oguime commented 2 years ago

I'm buying one hopping integration comes soon, because prices are going up...

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days

dudu631 commented 2 years ago

Any news on this?

joaofelipes commented 2 years ago

I just bought one of those and it will be great if it worked with z2m!

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days

rrlevy commented 2 years ago

This should still be open since it's still not working

dudu631 commented 2 years ago

It seems that new models are coming with a firmware that works with zigbee2mqtt. Can anyone confirm this information?

cefranco76 commented 2 years ago

Hi guys, that's my solution.

I'm not an expert on that but I just realized that msg has on data[5] the action's User ID Then I've created an attribute called userid with the returning value of msg.data[5].

And as a plus, I transformed the ID in names....


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 constants = require("zigbee-herdsman-converters/lib/constants");
const reporting = require("zigbee-herdsman-converters/lib/reporting");
const extend = require("zigbee-herdsman-converters/lib/extend");
const e = exposes.presets;
const ea = exposes.access;

const fzLocal = {
  action: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const lookup = {
        0: "keypad_unlock",
        1: "zigbee_unlock",
        2: "manual_lock",
        3: "rfid_unlock",
        4: "finger_unlock",
        10: "auto_lock",
        14: "inside_unlock",
      };
      const value = lookup[msg.data[4]];
      if (value == "lock" || value == "inside_unlock") {
        return { action: value };
      } else {
        return { action: lookup[msg.data[3]] };
      }
    },
  },
  userid: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
    return { userid: msg.data[5] };
    },
  },

  username: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const userNames = {
        0: "",
        1: "Eduardo",
        2: "Ana Maria",
        94: "Teste UserID 94",
      };
    return { username: userNames[msg.data[5]] };
    },
  },
};

const lockExtend = (meta) => {
  return {
    fromZigbee: [
      fz.lock_operation_event,
      fz.lock_programming_event,
      fz.lock_pin_code_response,
      fz.lock_user_status_response,
      fz.lock,
      fz.battery,
      fzLocal.userid,
      fzLocal.username,
      fzLocal.action,
    ],
    toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
    meta: { pinCodeCount: 250, ...meta },
    exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action()],
    configure: async (device, coordinatorEndpoint, logger) => {
      const endpoint = device.getEndpoint(1);
      await reporting.bind(endpoint, coordinatorEndpoint, [
        "closuresDoorLock",
        "genPowerCfg",
      ]);
      await reporting.lockState(endpoint);
      await reporting.batteryPercentageRemaining(endpoint);
    },
  };
};

module.exports = [
  {
    zigbeeModel: ["YMC 420 D"],
    model: "YMC 420 D",
    vendor: "Yale",
    description: "YMC 420 D - Digital Lock",
    extend: lockExtend({ timeout: 20000 }), //
  },
];

image

MrNiero commented 2 years ago

booooooa! Way to go! Thanks for the addition. I'll be testing that as well.

dudu631 commented 2 years ago

It seems that new models are coming with a firmware that works with zigbee2mqtt. Can anyone confirm this information?

Nope. Received a new model and it doesn't recognize. Will try @cefranco76 solution!

gregolin commented 2 years ago

Hi guys, that's my solution.

I'm not an expert on that but I just realized that msg has on data[5] the action's User ID Then I've created an attribute called userid with the returning value of msg.data[5].

And as a plus, I transformed the ID in names....


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 constants = require("zigbee-herdsman-converters/lib/constants");
const reporting = require("zigbee-herdsman-converters/lib/reporting");
const extend = require("zigbee-herdsman-converters/lib/extend");
const e = exposes.presets;
const ea = exposes.access;

const fzLocal = {
  action: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const lookup = {
        0: "keypad_unlock",
        1: "zigbee_unlock",
        2: "manual_lock",
        3: "rfid_unlock",
        4: "finger_unlock",
        10: "auto_lock",
        14: "inside_unlock",
      };
      const value = lookup[msg.data[4]];
      if (value == "lock" || value == "inside_unlock") {
        return { action: value };
      } else {
        return { action: lookup[msg.data[3]] };
      }
    },
  },
  userid: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
    return { userid: msg.data[5] };
    },
  },

  username: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const userNames = {
        0: "",
        1: "Eduardo",
        2: "Ana Maria",
        94: "Teste UserID 94",
      };
    return { username: userNames[msg.data[5]] };
    },
  },
};

const lockExtend = (meta) => {
  return {
    fromZigbee: [
      fz.lock_operation_event,
      fz.lock_programming_event,
      fz.lock_pin_code_response,
      fz.lock_user_status_response,
      fz.lock,
      fz.battery,
    fzLocal.userid,
    fzLocal.username,
      fzLocal.action,
    ],
    toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
    meta: { pinCodeCount: 250, ...meta },
    exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action()],
    configure: async (device, coordinatorEndpoint, logger) => {
      const endpoint = device.getEndpoint(1);
      await reporting.bind(endpoint, coordinatorEndpoint, [
        "closuresDoorLock",
        "genPowerCfg",
      ]);
      await reporting.lockState(endpoint);
      await reporting.batteryPercentageRemaining(endpoint);
    },
  };
};

module.exports = [
  {
    zigbeeModel: ["YMC 420 D"],
    model: "YMC 420 D",
    vendor: "Yale",
    description: "YMC 420 D - Digital Lock",
    extend: lockExtend({ timeout: 20000 }), //
  },
];

image

This script worked well, thanks. But I have noticed that the Zigbee2MQTT receives 3 or 4 messages for each action (lock or unlock), and they seem don't have any pattern to be identified (understanding which of them is the valid). Have you seen this behavioral? Thanks.

cefranco76 commented 2 years ago

Hi guys, that's my solution. I'm not an expert on that but I just realized that msg has on data[5] the action's User ID Then I've created an attribute called userid with the returning value of msg.data[5]. And as a plus, I transformed the ID in names....


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 constants = require("zigbee-herdsman-converters/lib/constants");
const reporting = require("zigbee-herdsman-converters/lib/reporting");
const extend = require("zigbee-herdsman-converters/lib/extend");
const e = exposes.presets;
const ea = exposes.access;

const fzLocal = {
  action: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const lookup = {
        0: "keypad_unlock",
        1: "zigbee_unlock",
        2: "manual_lock",
        3: "rfid_unlock",
        4: "finger_unlock",
        10: "auto_lock",
        14: "inside_unlock",
      };
      const value = lookup[msg.data[4]];
      if (value == "lock" || value == "inside_unlock") {
        return { action: value };
      } else {
        return { action: lookup[msg.data[3]] };
      }
    },
  },
  userid: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
    return { userid: msg.data[5] };
    },
  },

  username: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const userNames = {
        0: "",
        1: "Eduardo",
        2: "Ana Maria",
        94: "Teste UserID 94",
      };
    return { username: userNames[msg.data[5]] };
    },
  },
};

const lockExtend = (meta) => {
  return {
    fromZigbee: [
      fz.lock_operation_event,
      fz.lock_programming_event,
      fz.lock_pin_code_response,
      fz.lock_user_status_response,
      fz.lock,
      fz.battery,
      fzLocal.userid,
      fzLocal.username,
      fzLocal.action,
    ],
    toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
    meta: { pinCodeCount: 250, ...meta },
    exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action()],
    configure: async (device, coordinatorEndpoint, logger) => {
      const endpoint = device.getEndpoint(1);
      await reporting.bind(endpoint, coordinatorEndpoint, [
        "closuresDoorLock",
        "genPowerCfg",
      ]);
      await reporting.lockState(endpoint);
      await reporting.batteryPercentageRemaining(endpoint);
    },
  };
};

module.exports = [
  {
    zigbeeModel: ["YMC 420 D"],
    model: "YMC 420 D",
    vendor: "Yale",
    description: "YMC 420 D - Digital Lock",
    extend: lockExtend({ timeout: 20000 }), //
  },
];

image

This script worked well, thanks. But I have noticed that the Zigbee2MQTT receives 3 or 4 messages for each action (lock or unlock), and they seem don't have any pattern to be identified (understanding which of them is the valid). Have you seen this behavioral? Thanks.

I presume that there's a sequence of messages like "Previous State", "Action Empty", "Action Command" and "Current State".

But nonetheless irrelevant to wellfunction. I would not worry about that. If the lock, hass, integration, all works fine, that's allright for me.

cefranco76 commented 2 years ago

Happy to help on something that I don't know. lol.

dudu631 commented 2 years ago

I added your converter and seems to be working great so far!

gregolin commented 2 years ago

This script worked well, thanks. But I have noticed that the Zigbee2MQTT receives 3 or 4 messages for each action (lock or unlock), and they seem don't have any pattern to be identified (understanding which of them is the valid). Have you seen this behavioral? Thanks.

I presume that there's a sequence of messages like "Previous State", "Action Empty", "Action Command" and "Current State".

But nonetheless irrelevant to wellfunction. I would not worry about that. If the lock, hass, integration, all works fine, that's allright for me.

In fact it is working well and I can capture lock or unlock on Zibbee2MQTT... I only would like to capture who is unlocking as well, in order to send a notification to my cellphone, and these 3-4 messages in sequence are making the task harder :-)

Where do you see the usernames? I couldn't find them anywhere. I'd like to know who is unlocking it (even out of Zigbee2MQTT). Thanks.

cefranco76 commented 2 years ago

This script worked well, thanks. But I have noticed that the Zigbee2MQTT receives 3 or 4 messages for each action (lock or unlock), and they seem don't have any pattern to be identified (understanding which of them is the valid). Have you seen this behavioral? Thanks.

I presume that there's a sequence of messages like "Previous State", "Action Empty", "Action Command" and "Current State". But nonetheless irrelevant to wellfunction. I would not worry about that. If the lock, hass, integration, all works fine, that's allright for me.

In fact it is working well and I can capture lock or unlock on Zibbee2MQTT... I only would like to capture who is unlocking as well, in order to send a notification to my cellphone, and these 3-4 messages in sequence are making the task harder :-)

Where do you see the usernames? I couldn't find them anywhere. I'd like to know who is unlocking it (even out of Zigbee2MQTT). Thanks.

This is already done. Look at this picture:

166815561-7eb6cee8-7400-48da-b9bc-a4068463fd8d

It's my LOCK ENTITY and has its attributes, with "userid" that I entered in the LOCK and "username" that the EXTERNAL CONVERTER filled. The "userid" is the same ID of user on LOCK. Look for it in the attributes of YOUR LOCK ENTITY.

To see it working, configure the user 001 on your LOCK, then, in the EXTERNAL CONVERTER replace your name where you see "Eduardo" and then, in "Developer Tools / Template", write it as it follows:

{{ state_attr('lock.REPLACE_BY_YOUR_LOCK_ENTITY','userid') }} {{ state_attr('lock.REPLACE_BY_YOUR_LOCK_ENTITY','username') }}

gregolin commented 2 years ago

meta: { pinCodeCount: 250, ...meta }, exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action()],

Hi @cefranco76 . The script shows me error on these two lines (83 and 84). Is this correct? Thanks.

cefranco76 commented 2 years ago

meta: { pinCodeCount: 250, ...meta }, exposes: [e.lock(), e.battery(), e.pincode()],

image

My lines are the same with no error messages. If you could share those errors...

gregolin commented 2 years ago

Two images below:

Screen Shot 2022-06-07 at 7 55 38 PM Screen Shot 2022-06-07 at 7 55 26 PM

Thanks.

cefranco76 commented 2 years ago

Two images below:

Screen Shot 2022-06-07 at 7 55 38 PM Screen Shot 2022-06-07 at 7 55 26 PM

Thanks.

@gregolin I didn't catch yet what you're doing, but as far as I know we don't need to compile this code outside zigbee2mqtt. The only thing I did was save this code in a JS file, place it at zigbee2mqtt folder, add an external converter in the configs and restart the addon.

Maybe there're some errors on code, as "...meta", but a really don't know why the addon ignores it.

gregolin commented 2 years ago

I'm not compiling it. This screen comes from HA file editor :-)

cefranco76 commented 2 years ago

I'm not compiling it. This screen comes from HA file editor :-)

ok, I misunderstood... But I really don't know why you see this errors, as I mentioned before, I placed the js file, restart the addon and everything worked well.

gregolin commented 2 years ago

Here everything is working with this model (YMC 420D), but I'm having problems with another Yale lock (YDF40), which is listed officially as supported but I'm having issues during the interview. I don't know if this script has been causing any issue or other problem... so I'm investigating everything, including these errors.

cefranco76 commented 2 years ago

If you remove this external converter the YDF40 works as expected?

Here everything is working with this model (YMC 420D), but I'm having problems with another Yale lock (YDF40), which is listed officially as supported but I'm having issues during the interview. I don't know if this script has been causing any issue or other problem... so I'm investigating everything, including these errors.

diogofm7 commented 2 years ago

besides the sensors, this converter allows me to lock and unlock it by zigbee2mqtt???

is it working fine, or do we still have some bug??

dsantos21 commented 2 years ago

Hi @Koenkk ! Could this code integrate the main Zigbee2mqtt base? :D It was tested by everyone here, but unfortunately it wasn't committed :D

I was able to test it too. I think that the username translation shouldn't make to the final code, as its not possible for end-user's to edit it later.

The working code is here: https://github.com/Koenkk/zigbee2mqtt/issues/8946#issuecomment-1117818080

Thanks again!!!

dsantos21 commented 2 years ago

I've made some more tests and the main differences I could gather from the converter 'Yale.js' to the code proposed here is that most of the message is now RAW, instead of, for example,:

lock_operation_event: {
    cluster: 'closuresDoorLock',
    type: 'commandOperationEventNotification',

With type = 'raw' it just works. And, of course, the mapping model is also different (as shown in the comment code block above).

I've tried my best to do this PR! Feel free to change everything :D. In the end, I believe that this PR will be worse to review than to do from scratch... :-D.

PS: Tested only as external converter (code below), but it is slightly different from fz and devices.js...

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 extend = require("zigbee-herdsman-converters/lib/extend");
const ota = require('zigbee-herdsman-converters/lib/ota');
const constants = require("zigbee-herdsman-converters/lib/constants");
const e = exposes.presets;
const ea = exposes.access;

const fzLocal = {
  username: {
    cluster: "closuresDoorLock",
    type: "raw",
    convert: (model, msg, publish, options, meta) => {
      const userNames = {
        0: "Yale YMC 420 D",
        1: "User 001",
        2: "User 002"
      };
    return { username: userNames[msg.data[5]] };
    },
  },
  lock_operation_event: {
    cluster: 'closuresDoorLock',
    type: 'raw',
    convert: (model, msg, publish, options, meta) => {
      const lookup = {
        0: 'keypad_unlock',
        1: 'zigbee_unlock',
        2: 'auto_lock',
        3: 'rfid_unlock',
        4: 'finger_unlock',
        5: 'Unlock_failure_invalid_pin_or_id',
        6: 'Unlock_failure_invalid_schedule',
        7: 'one_touch_lock',
        8: 'Key_lock',
        9: 'Key_unlock',
        10: 'auto_lock',
        11: 'Schedule_lock',
        12: 'Schedule_unlock',
        13: 'Manual_lock',
        14: 'manual_unlock',
        15: 'Non_access_user_operational_event',
      };

      return {
        action: lookup[msg.data['3']],
        action_user: msg.data['5'],
        action_source: msg.data['4'],
        action_source_name: constants.lockSourceName[msg.data['4']],
      };
    },
  },
};

const lockExtend = (meta) => {
  return {
    fromZigbee: [
        fzLocal.lock_operation_event,
        fz.lock_programming_event,
        fz.lock_pin_code_response,
        fz.lock_user_status_response,
        fz.lock,
        fz.battery,
        fzLocal.username,
    ],
    toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
    meta: { pinCodeCount: 250, dontDividePercentage: false },
    exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action(), e.lock_action_source_name(), e.lock_action_user()],
    configure: async (device, coordinatorEndpoint, logger) => {
      const endpoint = device.getEndpoint(1);
      await reporting.bind(endpoint, coordinatorEndpoint, [
        "closuresDoorLock", "genPowerCfg"
      ]);
      await reporting.lockState(endpoint);
      await reporting.batteryPercentageRemaining(endpoint);
    },
  };
};

module.exports = [
  {
    zigbeeModel: ["YMC 420 D"],
    model: "YMC 420 D",
    vendor: "Yale",
    description: "YMC 420 D - Digital Lock v1",
    extend: lockExtend({ timeout: 20000 }), //
  },
];
MrNiero commented 2 years ago

Hey everyone! I do agree that this code could be merged and integrated to the native app.

About the code above the main difference with mine is that I'm not "hardcoding" users. I'm using Home Assistant with Node Red to "convert" the userid. I thought it would be easier to manage and alter things if needed - I understand that for a residential use, there's not much to be altering, but for other uses, I think it would be better to do it so. Something like this:

userid: { cluster: "closuresDoorLock", type: "raw", convert: (model, msg, publish, options, meta) => { return { userid: msg.data[5] }; }, },

image

Anyway Ill try to merge this code with the one Im running to check the difference!

dsantos21 commented 2 years ago

Hi @nieror the proposed code doesn't include any hard code user mapping! The code block shown above was just my test as external converter, base to PR. The proposed code to merge is here: https://github.com/Koenkk/zigbee-herdsman-converters/pull/4581

Thanks for your help!