Hello, I’m new here. Just migrated from philips hue bridge to Home assistant and to that point, it’s been a pleasure really.
What I’ve done
I bought a device after verifying it was compatible with Zigbee2MQTT. Just to realise it is not, even though the selling point also advertised it is…
Anyway, The device is an HS2IRC from Heiman. An integration exists in Zigbee2Mqtt here:
Though, it looks like HS2IRC is the model name used to sell, but actually names many similar devices.
Looking into the integration on github, I found that it has been written for device IRControl-EM
integration code
{
fingerprint: [{modelID: 'IRControl-EM', manufacturerName: 'HEIMAN'}],
model: 'HS2IRC',
vendor: 'HEIMAN',
description: 'Smart IR Control',
fromZigbee: [fz.battery, fz.heiman_ir_remote],
toZigbee: [tz.heiman_ir_remote],
exposes: [e.battery()],
configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'heimanSpecificInfraRedRemote']);
await reporting.batteryPercentageRemaining(endpoint);
},
},
My device reports itself as IRControl2-EF-3.0
on zigbee2mqtt and thus is not recognised.
So I copied the integration and made a file in homeassistant/zigbee2mqtt/external_converters
to add it manually. (I commented out the part about battery because the device has no battery. But I also tried with those not commented)
my_converter.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 e = exposes.presets;
const definition = {
zigbeeModel: ['IRControl2-EF-3.0', 'IRControl-EM'],
fingerprint: [
{modelID: 'IRControl-EM', manufacturerName: 'HEIMAN'},
{modelID: 'IRControl2-EF-3.0', manufacturerName: 'HEIMAN'},
],
model: 'HS2IRC',
vendor: 'HEIMAN',
description: 'Smart IR Control',
// fromZigbee: [fz.battery, fz.heiman_ir_remote],
fromZigbee: [fz.heiman_ir_remote],
toZigbee: [tz.heiman_ir_remote],
// exposes: [e.battery()],
exposes: [],
configure: async (device, coordinatorEndpoint) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'heimanSpecificInfraRedRemote']);
// await reporting.batteryPercentageRemaining(endpoint);
},
}
module.exports = definition;
Rebooting z2m, it picks the file, I even got the luxuary of having the picture of the device (taken from IRControl-EM
)
Back in home assistant have been trying to communicate with the device but it’s been a real hassle and I don’t manage to make it work…
I’ve created a script, inspired by what I could find on internet (most of it from this actually : HEIMAN HS2IRC control via MQTT | Zigbee2MQTT). It’s ugly cause I don’t know how to make it… not ugly : I activate only the action I want and run the script, and each time I try something, I deactivate all actions but the one I want to try.
The home assistant script
sequence:
- alias: MQTT "Publier" Create device
action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Salon - IR/set
payload: |-
{
"create": {
"model_type": 55
}
}
qos: "0"
enabled: false
- alias: MQTT "Publier" remove device (not working tho)
action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Salon - IR/set
payload: |-
{
"delete": {
"id": 16,
"key_code": 31
}
}
qos: "0"
enabled: false
- alias: MQTT "Publier" learn key code
action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Salon - IR/set
payload: |-
{
"learn": {
"id": 1,
"key_code": 31
}
}
qos: "1"
enabled: true
- alias: MQTT "Publier" list devices
action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Salon - IR/set
payload: |-
{
"get_list": ""
}
qos: "0"
retain: true
enabled: false
- alias: MQTT "Publier" send stored key
action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Salon - IR/set
payload: |
{
"send_key": {
"id": 1,
"key_code": 1
}
}
qos: "0"
enabled: false
alias: Talk with IR
description: ""
What works
-
I can remove devices with the action
delete
. (only works if I delete all key codes and devices at once though). I get no logs in z2m though (even the publish is not shown). -
I can add devices with the action
create
. I get no logs, but then the get_list shows the device -
I can get a status with
get_list
. Publishing the action returns something consistent but then I get an error. I don’t know why I get it tough as I got what I wanted…
get_list log
[2025-01-23 10:44:22] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Salon - IR', payload '{"devices":[{"id":1,"key_codes":[],"model_type":55}],"linkquality":255}'
[2025-01-23 10:44:32] error: z2m: Publish 'set' 'get_list' to 'Salon - IR' failed: 'Error: ZCL command 0xa49e69fffe4d810a/1 heimanSpecificInfraRedRemote.getIdAndKeyCodeList({}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":false,"direction":0,"reservedBits":0,"manufacturerCode":null,"writeUndiv":false}) failed ({"target":52324,"apsFrame":{"profileId":260,"clusterId":64642,"sourceEndpoint":1,"destinationEndpoint":1,"options":4416,"groupId":0,"sequence":248},"zclSequence":2,"commandIdentifier":11} timed out after 10000ms)'
What does NOT work
Well, anything else, the most important being, learning a new code with learn
, I get action_result: error
, see the log
learn log
1:09:45] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Salon - IR', payload '{"action":"learn","action_key_code":31,"action_result":"error","devices":[{"id":1,"key_codes":[],"model_type":55}],"linkquality":255}'
[2025-01-23 11:09:45] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Salon - IR', payload '{"action":"","devices":[{"id":1,"key_codes":[],"model_type":55}],"linkquality":255}'
[2025-01-23 11:09:45] info: z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Salon - IR/action', payload 'learn'
other log that I don’t know what to do with, it this at Z2M reboot:
boot log
info: z2m: Salon - IR (0xa49e69fffe4d810a): Not supported (Router)
Any help would be highly appreciated ! I am thinking of returning it. Might work with object : “not compatible with zigbee2mqtt as adverstised”. But I feel like it would also benefit others if I manage to make this work…