Skip to content

Instantly share code, notes, and snippets.

@faust93
Last active February 20, 2024 20:35
Show Gist options
  • Save faust93/7c99b63768f3fb376ee129d155752b6d to your computer and use it in GitHub Desktop.
Save faust93/7c99b63768f3fb376ee129d155752b6d to your computer and use it in GitHub Desktop.
Z2M external converter for Woox R7051 Siren

Zigbee2Mqtt external converter for Woox R7051 Siren

Woox R7051 Z2M converter with siren volume,brightness,duration controls exposed

r7051.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 tuya = require('zigbee-herdsman-converters/lib/tuya');
const {} = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;

const woox = {
    fz: {
        siren_brightness: {
            cluster: 'ssIasWd',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                const result = {};
                if (msg.data.hasOwnProperty('1')) {
                    result['brightness'] = msg.data['1'];
                }
                return result;
            },
        },
        siren_duration_volume: {
            cluster: 'ssIasWd',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                const result = {};
                if (msg.data.hasOwnProperty('maxDuration')) result['duration'] = msg.data.maxDuration;
                if (msg.data.hasOwnProperty('2')) {
                    result['volume'] = msg.data['2'];
                }
                return result;
            },
        },
    },
    tz: {
        ts0219_brightness: {
            key: ['brightness'],
            convertSet: async (entity, key, value, meta) => {
                await entity.write('ssIasWd', {0x0001: {value: value, type: 0x20}});
            },
            convertGet: async (entity, key, meta) => {
                await entity.read('ssIasWd', [0x0001]);
            },
        },
    },
};

const definition = {
    fingerprint: [{ modelID: 'TS0219', manufacturerName: '_TYZB01_ynsiasng' }],
    zigbeeModel: ['TS0219'],
    model: 'R7051',
    vendor: 'Woox',
    description: 'Smart Indoor Siren',
    fromZigbee: [fz.battery, fz.power_source, fz.ias_alarm_only_alarm_1, woox.fz.siren_brightness, woox.fz.siren_duration_volume],
    toZigbee: [tz.ts0216_alarm, woox.tz.ts0219_brightness, tz.ts0216_duration, tz.ts0216_volume],
    exposes: [e.battery(), e.battery_voltage(), e.binary('alarm', ea.STATE, true, false),
             e.binary('ac_connected', ea.STATE, true, false).withDescription('Is the device plugged in'),
             e.binary('alarm', ea.STATE_SET, true, false).withDescription('Manual start of siren'),
             e.numeric('volume', ea.ALL).withValueMin(0).withValueMax(100).withDescription('Volume of siren'),
             e.numeric('duration', ea.ALL).withValueMin(0).withValueMax(3600).withDescription('Duration of siren'),
             e.numeric('brightness', ea.ALL).withValueMin(0).withValueMax(100).withDescription('Brightness of siren')],
    meta: { disableDefaultResponse: true },
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        const bindClusters = ['genPowerCfg'];
        await reporting.bind(endpoint, coordinatorEndpoint, bindClusters);
        await reporting.batteryVoltage(endpoint);
        await reporting.batteryPercentageRemaining(endpoint);
        if (device.powerSource == 'Mains (3 phase)') {
            device.powerSource = 'Mains (single phase)';
        } else if (device.powerSource == 'Emergency mains and transfer switch') {
            device.powerSource = 'Battery';
        }
    },
};

module.exports = definition;

How To

  1. Place r7051.js file inside the data folder (see external-converters for the details)
  2. Add the following lines to the configuration.yaml:
external_converters:
  - r7051.js
  1. Restart Z2M

Mqtt Payload

To trigger your siren send the following payload to the respective z2m mqtt topic, like zigbee2mqtt/woox_buzzer/set:

{"duration": 2, "brightness":50, "volume": 50, "alarm": true}
@Mecallie
Copy link

Mecallie commented Jan 7, 2024

Thank you!

Just tried this: all I can do is turn on the default alarm (long beep) and change the volume (setting it to 1 makes for a very annoying buzz ⏰ ). Changing any of the other settings seems to make no difference (duration is always 2 seconds, no strobe).

When I change something in the top part of the z2m gui and press "Apply" it does now give a red strobe and an intermittent beep (like a smoke detector). I cannot change any of the settings there however.

Well, at least I can use it as a 2 second beep now. Never know when that might come in handy 🤣

If there is anything I can help with/test let me know!

@faust93
Copy link
Author

faust93 commented Jan 8, 2024

Just tried this: all I can do is turn on the default alarm (long beep) and change the volume (setting it to 1 makes for a very annoying buzz ⏰ ). Changing any of the other settings seems to make no difference (duration is always 2 seconds, no strobe).

Hmm, that's interesting. What controls do you have in 'Exposes' tab of your Woox siren in Z2M? There should be battery/voltage/link stuff along with actual controls - Volume,Duration,Brightness and Alarm toggle. Changing Brightness slider alone (tap slider knob, change value, release) should effect in red led intensity (just red light will turn on, no sound). Changing Volume (tap,change,release) should effect in siren sound (no lights, just constant sound for a second or so). Changing Duration alone will produce no effect until you turn siren on with Alarm toggle. Setting toggle to True will result in siren beeping and flashing with respective volume & brightness for 'Duration' period of seconds. Well, for me it works such way at least.. :)

@Mecallie
Copy link

Mecallie commented Jan 9, 2024

afbeelding

This is what I have.

Strange thing: the duration of the "warning" part does not seem to do anything. The duration of the "alarm" part sets the time.
In fact nothing in the Warning section works. Just the controls below "Alarm" do anything. But if I press "Toepassen" (Apply) under the Warning part it uses the time/volume set under the Alarm part...

I added your converter after the siren was already available in Z2M. Should I try removing and re-adding it?

@faust93
Copy link
Author

faust93 commented Jan 10, 2024

This is what I have.
I added your converter after the siren was already available in Z2M. Should I try removing and re-adding it?

It should be like this:
image

According to the screen you still have default Woox converter in action. External ones have higher priority usually and should override defaults which did not happen in your case for some reason. What Z2M version do you have? I'm using latest dev branch running in docker but not sure if it matters. And mine works without removing/re-adding, just added external converter, restarted and that's it.
Have you looked at the logs?

@Mecallie
Copy link

I am using version 1.35.1-1 .
Should there be something in the config about an external converter? Or is it enough that I have added it to configuration.yaml?

@faust93
Copy link
Author

faust93 commented Jan 13, 2024

I am using version 1.35.1-1 . Should there be something in the config about an external converter? Or is it enough that I have added it to configuration.yaml?

Using the same version. Nothing special about config, mine looks as follows:

external_converters:
  - r7051.js
homeassistant:
  legacy_triggers: true
advanced:
  homeassistant_discovery_topic: homeassistant
  homeassistant_status_topic: homeassistant/status
  homeassistant_legacy_entity_attributes: false
  homeassistant_legacy_triggers: false
  log_level: info
  last_seen: ISO_8601
... etc

r7051.js is in the same folder as configuration.yaml file. Check r7051.js file permissions, may be that's the case. Anyway there should be something in Z2M logs.

@Mecallie
Copy link

Mecallie commented Jan 14, 2024

Ok, first one was my bad (typo). But now I get "Setup failed for 'external_converters': Integration not found." in the logs.
When I click on the log entry it further says "Logger: homeassistant.setup, Source: setup.py:221".

Any ideas?

EDIT: got it! Instead of in the normal config directory I had to place the file in the /share/zigbee2mqtt/ directory. I also added the converter name in the GUI, but I think that is the same as changing the configuration.yaml in THAT directory. WORKS! Thank you!

Now if we could get the different types of sounds that would be awesome 😃

@faust93
Copy link
Author

faust93 commented Jan 15, 2024

EDIT: got it! Instead of in the normal config directory I had to place the file in the /share/zigbee2mqtt/ directory. I also added the converter name in the GUI, but I think that is the same as changing the configuration.yaml in THAT directory. WORKS! Thank you!

Now if we could get the different types of sounds that would be awesome 😃

Yep, after reading the docs External converters just realized that converter locations might be different for dockerized and bare-metal Z2M installations. Regarding sounds/led colors etc - I'm still wondering if these features are supported initially by this siren? I just found brightness control point accidentally in the zigbee traffic dump posted here on the github by some guy for the same siren but branded differently and there was nothing about sounds & leds.

@Mecallie
Copy link

I was guessing it is supported. Since in the default config it has 7 sounds to choose from, that has to come from somewhere? Also the led has two colours, would be strange if you could only use one?

But this is just a guess. If someone has a Woox hub maybe he/she could tell?

@faust93
Copy link
Author

faust93 commented Jan 20, 2024

I was guessing it is supported. Since in the default config it has 7 sounds to choose from, that has to come from somewhere? Also the led has two colours, would be strange if you could only use one?

But this is just a guess. If someone has a Woox hub maybe he/she could tell?

Yes, for sure we need full zigbee traffic dump between hub and siren to figure out DPs responsible for sound and color configuration. This device appears to be Tuya under the hood and there are several variations of this siren just branded differently but having the same hw/fw actually. And tuya is known for zigbee protocol violations, making a kind of proprietary 'extensions' to it.

@miloumeeloo
Copy link

Can you please explain how do you use the payload in HA? I tried with both mqtt siren and switch without success.

@faust93
Copy link
Author

faust93 commented Feb 20, 2024

Can you please explain how do you use the payload in HA? I tried with both mqtt siren and switch without success.

HA script:

alias: siren_toggle
sequence:
  - service: mqtt.publish
    data:
      topic: zigbee2mqtt/woox_buzzer/set
      qos: "0"
      payload: >-
        {"duration": {{ duration }}, "brightness": {{ brightness }}, "volume":
        {{ volume }}, "alarm": {{ alarm }}}
mode: single
icon: mdi:alarm-light

To call the script:

action:
  - service: script.siren_toggle
    data:
      duration: 15
      brightness: 50
      volume: 90
      alarm: 1

@miloumeeloo
Copy link

Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment