Centralite 3400 keypad support

Has anyone got this working with zigbee2mqtt?

I’ve got a home assistant based alarm setup, but need the keypad for visitors and the all important wife approval factor.

The centralite looks like a good option if it works!

1 Like

wow yes it is
i am looking for somthing like that …

Yeah, same here. I will be following this post

Yes please. Good idea. Anybody knows other zibgee keypad with z2m ?
Thx

I had one arrive late last week. Will do my best to see if i can get it working!

Ive managed to get it to pair by adding a basic devices.js entry, but struggling to get any further than that!

1 Like

Ive since managed to get z3m to read the arm mode (ie arm stay, arm away, arm night) but nothing else further than that unfortunately!

i am looking for somthing like that too!

Still really struggling to get it to work!

Good discusion here: https://community.smartthings.com/t/centralite-keypads/25473 with code.
Seem not very easy to rewrite :frowning:

I stumbled across that thread before i got the keypad — I figured if someone can get it working with ST, id be able to get it working with z2m, but no such luck.

At the moment the thing is a paperweight.

Actually I got my keypad yesterday and I played a bit around. So far I can get the arm status and the 6 digit keycode from the pad. That Code is far from finished and very dirty but might lead others to the right direction.
The keypad also sends detected motion to the zigbee network (currently not handled by my code) and i.e. tamper alerts.
The most important missing stuff is sending the right replies to the keypad to set its status. I started with zigbee2mqtt coding yesteray - I currently do not know how to send that to the keypad… Perhaps someone might help.

in fromZigbee.js modify “command_arm” like this:

command_arm: {
    cluster: 'ssIasAce',
    type: 'commandArm',
    convert: (model, msg, publish, options, meta) => {
        const lookup = {
            0: 'disarm',
            1: 'arm_day_zones',
            2: 'arm_night_zones',
            3: 'arm_all_zones',
        };
        const keycode = String.fromCharCode(msg.data['u1'],msg.data['u2'],msg.data['u3'],msg.data['u4'],msg.data['u5'],msg.data['u6']);
        const payload = {action: getProperty(lookup[msg.data['armmode']], msg, model)};
        payload.keycode = keycode;
        if (msg.groupID) payload.action_group = msg.groupID;
        return payload;
    },
},

Then in devices.js add a device:

{
    zigbeeModel: ['3400-D'], // The model ID from: Device with modelID 'lumi.sens' is not supported.
    model: '3400-D', // Vendor model number, look on the device for a model number
    vendor: 'CentraLite', // Vendor of the device (only used for documentation and startup logging)
    description: 'CentraLite 3400-D Keypad', // Description of the device, copy from vendor site. (only used for documentation and startup logging)
    supports: 'keypad', // Actions this device supports (only used for documentation)
    meta: {configureKey: 1, disableDefaultResponse: true},
    fromZigbee: [ fz.command_arm, fz.command_panic, fz.command_emergency, fz.battery, fz.occupancy, fz.temperature, fz.st_button_state], // We will add this later
    toZigbee: [], // Should be empty, unless device can be controlled (e.g. lights, switches).
    configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg', 'ssIasZone', 'ssIasAce']);
            await configureReporting.temperature(endpoint);
//            await configureReporting.batteryPercentageRemaining(endpoint);
            await configureReporting.batteryVoltage(endpoint);
        },
    },

and cluster.js change ssIasAce like this:

ssIasAce: {
        ID: 1281,
        attributes: {},
        commands: {
            arm: {
                ID: 0,
                parameters: [
                    { name: 'armmode', type: dataType_1.default.uint8 },
                    { name: 'unknown1', type: dataType_1.default.uint8 },
                    { name: 'u1', type: dataType_1.default.uint8 },
                    { name: 'u2', type: dataType_1.default.uint8 },
                    { name: 'u3', type: dataType_1.default.uint8 },
                    { name: 'u4', type: dataType_1.default.uint8 },
                    { name: 'u5', type: dataType_1.default.uint8 },
                    { name: 'u6', type: dataType_1.default.uint8 },
                ],
            },

[…]

Wow – you certainly got a lot further than i did! Thats a great start.

I began work on getting this to work seperately last month and was not aware someone else had already done most of the hard work on this already, my devices.js looks almost the same, but I did not configure the batteryPercentageRemaining attribute as id 0x20 (ID: 32) appears to be the only genPowerCfg attribute to be supported using the mitchpond/centralite-keypad.src/centralite-keypad.groovy file as a resource, were you able to get reporting from id: 33 batteryPercentageRemaining?, I have yet to recieve mine yet (waiting for several months now due to shipment delays due to virus), but should be able to help get this up and running if a few people are able to help :slight_smile: Ill start working on the toZigbee.js and have an update soon.

I’ve got a centralite 3400-D too and im interested in integrating this device in z2m. I will buy a home base too. So i can temporary pair the device with a compatible basestation. Maybe we can sniff some important informations. I’ve only got limited experience with this but i help where i can.

   arm_mode: {
        key: ['arm_mode’],
        convertSet: async (entity, key, value, meta) => {
        	const lookup = {
            	'disarm': 0x00,
            	'arm_stay': 0x01,
            	'arm_arm_night': 0x02,
            	'armed_away': 0x03,
        	};

            await entity.write('ssIasZone', lookup[value.toLowercase()]);
            return {state: {arm_mode: value}};
        },
        convertGet: async (entity, key, meta) => {
            await entity.read('ssIasAce');
        },
    },

Can someone add this to their tozigbee.js and try to set it? Im probably off by a mile…

I’ve added it to my tozigbee.js and tried to disarm by keypad. This is the log output:

zigbee2mqtt:debug 2020-06-01 09:56:23: Received Zigbee message from '0x000d6f000d8a5f63', type 'commandArm', cluster 'ssIasAce', data '{"armmode":0,"unknown1":6,"u1":49,"u2":50,"u3":52,"u4":53,"u5":55,"u6":57}' from endpoint 1 with groupID 0
zigbee2mqtt:info  2020-06-01 09:56:23: MQTT publish: topic 'zigbee2mqtt/0x000d6f000d8a5f63', payload '{"linkquality":89,"temperature":23.27,"keycode":"124579","voltage":2800,"action":"disarm"}'
zigbee2mqtt:info  2020-06-01 09:56:23: MQTT publish: topic 'zigbee2mqtt/0x000d6f000d8a5f63', payload '{"linkquality":89,"temperature":23.27,"keycode":"124579","voltage":2800,"action":""}'
zigbee2mqtt:info  2020-06-01 09:56:23: MQTT publish: topic 'homeassistant/device_automation/0x000d6f000d8a5f63/action_disarm/config', payload '{"automation_type":"trigger","type":"action","subtype":"disarm","payload":"disarm","topic":"zigbee2mqtt/0x000d6f000d8a5f63/action","device":{"identifiers":["zigbee2mqtt_0x000d6f000d8a5f63"],"name":"0x000d6f000d8a5f63","sw_version":"Zigbee2mqtt 1.13.1","model":"CentraLite 3400-D Keypad (3400-D)","manufacturer":"CentraLite"}}'
zigbee2mqtt:info  2020-06-01 09:56:23: MQTT publish: topic 'zigbee2mqtt/0x000d6f000d8a5f63/action', payload 'disarm'
zigbee2mqtt:debug 2020-06-01 09:56:26: Device '0x000d6f000d8a5f63' announced itself
zigbee2mqtt:info  2020-06-01 09:56:26: MQTT publish: topic 'zigbee2mqtt/bridge/log', payload '{"type":"device_announced","message":"announce","meta":{"friendly_name":"0x000d6f000d8a5f63"}}'

You will also need to modify devices.js and include tz.arm_mode in toZigbee

Sorry, i allready edited my devices.js file. Here it is:

{
        zigbeeModel: ['3400-D'],
        model: '3400-D',
        vendor: 'CentraLite',
        description: 'CentraLite 3400-D Keypad',
        supports: 'keypad',
        meta: {configureKey: 1, disableDefaultResponse: true},
        fromZigbee: [ fz.command_arm, fz.temperature ],
        toZigbee: [ tz.arm_mode ],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg', 'ssIasZone', 'ssIasAce']);
            await configureReporting.temperature(endpoint);
            await configureReporting.batteryVoltage(endpoint);
    },
},

It doesnt appear to be using the correct payload, it should be:

zigbee2mqtt/0x000d6f000d8a5f63/set/arm_mode

{“arm_mode”: “disarm”}