HDL Smartbus via NodeRed and MQTT

Thanks @Cregeland

Unfortunately the motor controller does not send current state.

Went down the rabbit hole and have done some changes.

Instead of the delay timer i now save the command value and use it again when the broadcast message reports stopped to know if it the state state is open or closed. Also added position of 0%(Closed) 100%(Open) or 50%(Stopped) You should now be able to stop the blinds midway and continue with open or close.

You will have to change the cover.yaml file to something like this:

#Test blind HDL curtain controller
#
# Bedroom blinds
- platform: mqtt
  name: "Blind Bedroom"
  device_class: shade
  command_topic: "hdl/cc/1.5/1/set"
  state_topic: "hdl/cc/1.5/1/state"
  optimistic: true
  position_topic: "hdl/cc/1.5/1/position"
#
# Living Room blinds
- platform: mqtt
  name: "Blind Living Room"
  device_class: shade
  command_topic: "hdl/cc/1.5/2/set"
  state_topic: "hdl/cc/1.5/2/state"
  optimistic: true
  position_topic: "hdl/cc/1.5/2/position"

Here is the new flow.

Can you report how it works for you now?

hi
I found a new device, code 5195, which is a fresh air system
The current node cannot find this device
Through the mobile phone, I found some control codes


01 01 00 03 A4 00 41 A8 00 00 00 00 00 00 42 38 00 00 00 00 00 00 43 5F 00 00 43 EE 00 00 AE 6C
01 01 00 <-(fan speed) 03 A4 00 41 A8 00 00 00 00 00 00 42 38 00 00 00 00 00 00 43 5F 00 00 43 EE 00 00 AE 6C
00 = auto , 01 min , 02 mid , 03 max

01 01 00 03<-(mode) A4 00 41 A8 00 00 00 00 00 00 42 38 00 00 00 00 00 00 43 5F 00 00 43 EE 00 00 AE 6C

00 is ai mode
01 is manual mode
02 Internal circulation mode
03 constant temperature mode

hope update command.js
new problem
looks contrid-hdlbus can’t support devicetype
default typeid is 00 00

    "payload": {
        "opCode": 0x002,
        "sender": {
            "deviceType": 0x00B,
            "subnetId": 1,
            "deviceId": 2,
            "wasSendToThisDevice": true/false

hdlbus can’t get typeid
i use hdl setup tools , get packet like this
1A 01 33 11 B6 FF 02 FF FF 01 04 0A 12 00 41 01 00 F0 00 00 00 E9 25 85 11 AA
01 33 >>> subnet 01 device 51
11 B6 is type id , but can’t show on node-red debug tab
FF 02 is code
FF FF boardcast
and sender ip show wrong , is show 1.X
{“sender”:“1.X”,“target”:“255.255”,“code”:55876,“payload”:{“date”:“2022-05-01T10:10:02.000Z”},“topic”:“command”,"_msgid":“3bdb6b0988422f31”}

need update bus.js for show typeid , and custom type in msg.payload.typeid better

Hi @ritech

I dont think any of those codes are control codes, they are all broadcasting from the device id 51. And none of the messages are adressed to device id 51. Think the code 144B is not sendt from the sensor but from the software? But the code FF02 apears to be a brodcast from the device

I did not know HDL had any fresh air systems.
Do you have a model nr or anything on the unit?
Do you have a datasheet?
Are you trying to change the modes or do you only want to know what status it is at now?
What all the data is after the Mode(If you want to control the unit you will most likely have to send all the fields)?
Do you have any way of controling or reading the status from the unit now?
How does the unit 51 apear from the HDL buspro tool?

I think this is due to the fact that you have selected 0 as the target device id in the test software(Top left corner). Do you have a device with ID 0?

I dont think this is the same message as above this is 55873(DA44) code witch is the “Broadcast System Date and Time” and apears to be decoded correctly. This will start sending if you clicked the Broadcast computer time button on the command test software?

If you run this flow can you see anything in you nodered debug window when operating the unit from your phone?

[{"id":"2028b4409a28faca","type":"tab","label":"Ritech","disabled":false,"info":"","env":[]},{"id":"99c349440d10726e","type":"hdl-raw-in","z":"2028b4409a28faca","controller":"","name":"","x":150,"y":220,"wires":[["85c09ce6ab7f25a3","bec07bf6e3510bc3"]]},{"id":"85c09ce6ab7f25a3","type":"switch","z":"2028b4409a28faca","name":"sender","property":"sender","propertyType":"msg","rules":[{"t":"eq","v":"1.51","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":390,"y":240,"wires":[["66a1f288d6695412"]]},{"id":"bec07bf6e3510bc3","type":"switch","z":"2028b4409a28faca","name":"target","property":"target","propertyType":"msg","rules":[{"t":"eq","v":"1.51","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":390,"y":140,"wires":[["6ac1dbc2c178b255"]]},{"id":"346d7a1441e18b88","type":"comment","z":"2028b4409a28faca","name":"Command to module","info":"","x":410,"y":100,"wires":[]},{"id":"4d01437c34be4341","type":"comment","z":"2028b4409a28faca","name":"Answers from Module","info":"","x":420,"y":200,"wires":[]},{"id":"6ac1dbc2c178b255","type":"debug","z":"2028b4409a28faca","name":"To Device 51","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":550,"y":140,"wires":[]},{"id":"66a1f288d6695412","type":"debug","z":"2028b4409a28faca","name":"From Device 51","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":560,"y":240,"wires":[]},{"id":"665659ea9e40cdaf","type":"comment","z":"2028b4409a28faca","name":"Debug","info":"","x":130,"y":60,"wires":[]}]

i am a chinese user


i have decode new type , code 5195

0x144B: {
parse: function(buffer) {
return {
acstatus: Boolean(buffer.readUInt8(1)), //Status. 1 on. 0 off.
acno: buffer.readUInt8(0), //AF No.
setupmode: buffer.readUInt8(3),//0 ai 1 manual 2 inside 3 constant temperature
setupspeed: buffer.readUInt8(2),//Fan Speed. 0 Auto. 1 High. 2 Medium. 3 Low.
temperature: {
insidetemp: buffer.readUInt32BE(26),//insidetemp
pm25: buffer.readUInt8(27),//pm25
tvoc: buffer.readUInt8(28),//tvoc
co2: buffer.readUInt8(29),//co2
humidity: buffer.readUInt8(25)//湿度
},
};
},
encode: function(data) {
var buffer = new Buffer(30);
var temperature = data.temperature;
buffer.writeUInt8(data.acstatus, 1);
buffer.writeUInt8(data.acno, 0);
buffer.writeUInt8(data.setupmode, 3);
buffer.writeUInt8(data.setupspeed, 2);
return buffer;
}
},

air fan sensor data is wrong , becos hdl decode this value

I just moved into this room. I’ll check the model of the new HDL device
Do you know what code 65282 stands for? I can see this message every few seconds in tools
1A 01 33 11 B6 FF 02 FF FF 01 04 0A 12 00 82 02 00 A0 00 00 00 DF 1A DA 38 2C

11 B6

this code have bug for few ac system
can’t resolve “acno”
if create two ac panel , when click no2 power , mqtt send acno = 1 to hdl
i dont’t know command.js how to check acno , topic?

I do not know the codes for the unit and they are not in any of the documentation i have available, but from other HDL devices i would expect up to 5 different codes.

  • Read Status message
  • Responce read status message
  • Control message
  • Responce control message
  • Status Broadcast message. That could be the code 65282 if it comes regulary.

If you import the flow attached on above message you should see all the messages going to the device id 51 and all the responces from the device. That way you can see what the control and responce messages are when changing the unit from the phone app.

Is this on the Fresh air module or are you trying to interface Air condition modules?

  • Read Status message
  • Responce read status message
  • Control message
  • Responce control message
  • Status Broadcast message. That could be the code 65282 if it comes regulary.

air fresh module read and write use same message
this message includes switch, speed, cycle mode and current PM2 5. TVOC, indoor temperature, etc
no responce message
you are right , 65282 is broadcast message from air fresh module
I plan to dismantle the weak current box recently and find out the specific model

To display the current temperature i recomend using the sensor that the AC module uses for each room. You should find the temperatures on the MQTT explorer under temp or you will have to use the one from the ac message i dont have access to my installation now but you should also see it in the mqtt explorer.

Are you not able to access the fresh air module from HDL buspro tool? It should show the model nr there.

If you use the flow above you should see all the traffic going in and out to the fresh air module?

6457 code is the “Response Read AC Status” So that means that when you open the phone app the app sends the code 6456 " Read AC Status" To get the value without the app you just need to send the same message from nodered.
I can see that the codes are not implemented but should be easy to implement if you send me some debug data.

If you could use the debug flow above and change the switch nodes with target and sender to the device id of the AC module and post what you get in the debug window. (I would like to get screenshots of the codes 6456, 6457, 6458 and 6459)

Thank you again @Linax, I really appreciate the effort you are putting in here :+1:

The curtain controller now seem to work correctly (up, stop, down). But the position indication is acting a bit weird:

  • Curtain is up. I click down. The motor runs in down direction
  • If I do not click stop - the relay will stop after 10 seconds (timer set in HDL config).
  • The status still shows the curtain is in down operation (arrow down).
  • If I click stop the curtain motor will not do anything (already stopped by timer) - but the status will then show «down» icon. If I click stop once more the curtain icon will show «open» icon.
  • The same thing happens on the way up. I run the curtain up - the motor stops by timer - but status stuck with up arrow icon. If i then click stop - the status icon will show up. If I click stop again it will stay in up status.

It seems that the status will not update unless I click stop - and somehow the down status will switch to up if pressing «stop» twice on the way down.

i slove ac problem , run ok now.

about air fresh , i found 5195 0x14 0x4b is response code , i try 5194 send command , not response , i try 5190 - 5200 all port , only 5195 work , control and response on same port . when i send control code, not response show , but few seconds , about 30 secs , air fresh boardcoast status , this status code same as control code. by observing , i think this boardcast time its random ,about 30 - 60 sec. this is a problem ,when i set air fresh to on , not response from hdl to mqtt save temp oldhdlstate , lovelace can’t get now status .
I don’t know if I missed the real control port number,
Does each controller of hdl have more than two ports? Separate read and write?

Temporarily solve the problem of air fresh sending status. I send the get flow send to hdl to hdl to switch to mtqq at the same time, which manually updated the value of mtqq. I’ll keep looking for the real control port.
I am now using the climate control panel to control the fresh air blower
It can display the temperature of the new fan, but cannot display the values ​​such as tvoc pm2.5, how can I display it?
In addition to the mode selection, I can’t add setupmode, there are fresh fan modes, automatic mode, manual mode, internal circulation mode, constant temperature mode, how can I add it to the options
My switch mode is fan_only and off of the air conditioner.
The limitation of mqtt cannot add some custom modes

#AF

  • platform: mqtt
    name: “air fresh”
    modes:
    • “off”
    • “fan_only”
      fan_modes:
    • “auto”
    • “low”
    • “medium”
    • “high”
      current_temperature_topic: “hdl/af/1.51.1”
      current_temperature_template: “{{value_json.temperature.insidetemp}}”
      mode_state_topic: “hdl/af/1.51.1”
      mode_command_topic: “hdl/af/1.51.1/mode/set”
      mode_state_template: “{{value_json.status}}”
      fan_mode_state_topic: “hdl/af/1.51.1”
      fan_mode_command_topic: “hdl/af/1.51.1/fan/set”
      fan_mode_state_template: “{{value_json.setupspeed}}”

QQ图片20220505195845

Must be a bug somewhere, will check when i have some more time :slight_smile:

Yes i belive so, thermostats, relays, dimmers and US switches at least have. If you run the flow above and report the codes you get to the debug window i can have a look at it, without it i am not realy able to help as i can not see what is going on.
It is also possible you can get the API documentation from HDL china tech support for the module, my local HDL distributor does not have the units and thus will not supply it to me.

Run the flow above and report what you get in the debug, i expect the sensor values to be present in one of the broadcast messages, could be that the value will need to be scaled as well(Will have to check what the value is in the phone app at the same time and post and i can try to decode it).

True but you can add custom modes as presets look in to the “preset_modes”, check the example for heatmodule above. Can give you example if you share your current flow and the mentioned debugs.

i use preset_mode_value_template
control air fresh setupmode ok

preset_mode_state_topic: "hdl/af/1.51.1"
preset_mode_command_topic: "hdl/af/1.51.1/textmode/set"
preset_mode_value_template: "{{value_json.setupmode}}"

but i setup 4 mode , lovelace show 5 mode , add a "none mode

hi linax
I have tried to use it. During the use, I found a small bug. When the system is in the initial stage, if I use the auto mode to start the air conditioner, it will jump to the cool mode, but it will be normal when I click it again. After careful analysis of the data packets, this problem should be caused by hdl. When I sent 0x03 (auto) to my gateway for the first time, the feedback was actually 0x00. I tried a lot, and the first boot after the system reset will appear. Now The solution is to send the packet twice when the setupmode is auto, and only send it once in other modes. I don’t know yet how to return msg twice through the function, I’m just using hdl buspro tools to send packet.

Is it possible to capture click of a button? I.e on a DLP or iTouch 4btn. I would like to turn on a Hue lamp or perform other actions when pressing a button on the iTouch.

The Universal switch could work - but it’s a bit more flexible to use the button directly in HA.

Is this something you have any experience with @Linax ? :slight_smile:

Not really in a good way, as the buttons does not broadcast current state.

I would not recomend US for lights as you do not get any dimming possibility. I would recomend programing the switch to turn on a light in your nodered instance. (Point the DLP to the device id that you have set nodered up to). You will have to send the answerback message to stop the switch from sending the message 3 times and flashing the status led 3 times.

I have control over some “ikea tradfri” cabinet lights from DLP and iTouch 4btn, also status updates to switch when light is turned on from HA or Ikea switches. It is done straight in nodered as HA would make it more complex and add more time delay.

Here is how i have it made for 2x ikea lights, you should be able to use the flow to make the same for Hue lamps with for example the pallet " node-red-contrib-huemagic".

[{"id":"476aa68f8e4864eb","type":"tab","label":"Ikea to HDL","disabled":false,"info":"","env":[]},{"id":"03fccca7aa2e5fa0","type":"comment","z":"476aa68f8e4864eb","name":"Send answerback msg to HDL","info":"","x":700,"y":120,"wires":[]},{"id":"e8447e63c013754d","type":"switch","z":"476aa68f8e4864eb","name":"code","property":"code","propertyType":"msg","rules":[{"t":"eq","v":"49","vt":"str"}],"checkall":"false","repair":false,"outputs":1,"x":490,"y":240,"wires":[["e18770fce674959d","dd79a7bb86381d9a"]]},{"id":"68706f16b9eb163a","type":"hdl-raw-in","z":"476aa68f8e4864eb","controller":"","name":"From HDL","x":220,"y":240,"wires":[["7123909ca623ed81"]]},{"id":"7123909ca623ed81","type":"switch","z":"476aa68f8e4864eb","name":"target","property":"target","propertyType":"msg","rules":[{"t":"eq","v":"1.98","vt":"str"},{"t":"eq","v":"1.63","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":350,"y":240,"wires":[["e8447e63c013754d"],[]]},{"id":"8ee1c84d2d65a743","type":"tradfri-light-control","z":"476aa68f8e4864eb","gateway":"","name":"","action":"{}","accessories":[],"groups":[],"logInputErrors":true,"x":1030,"y":280,"wires":[]},{"id":"e18770fce674959d","type":"function","z":"476aa68f8e4864eb","name":"Build and send Response","func":"//Save to var\nvar target = msg.target\nvar sender = msg.sender\n\n//Reverse msg.target and msg.sender to vars\nmsg.target = sender\nmsg.sender = target\n\n//Change code to responce single channel\nmsg.code = 50\n\n//Insert success\nmsg.payload.success = true\n\n//Return msg\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":160,"wires":[["a8e40829f3de5426","506e37ad5e6b5963"]]},{"id":"02a994e86f70d93c","type":"comment","z":"476aa68f8e4864eb","name":"Command from HDL to Ikea","info":"","x":260,"y":200,"wires":[]},{"id":"a2dbe32501bca54b","type":"comment","z":"476aa68f8e4864eb","name":"Reconfigure command for Ikea light","info":"","x":720,"y":240,"wires":[]},{"id":"a8e40829f3de5426","type":"hdl-raw-out","z":"476aa68f8e4864eb","controller":"","name":"","x":990,"y":160,"wires":[]},{"id":"dd79a7bb86381d9a","type":"switch","z":"476aa68f8e4864eb","name":"channel","property":"payload.channel","propertyType":"msg","rules":[{"t":"eq","v":"25","vt":"num"},{"t":"eq","v":"26","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":660,"y":300,"wires":[["8e6ddd87fb3c6597"],["44f39b504b89b85c"]]},{"id":"44396640c077d6c9","type":"tradfri-monitor","z":"476aa68f8e4864eb","gateway":"","name":"","x":230,"y":460,"wires":[["bf5162f2ec55b930","5a04ab1401b60719"]]},{"id":"bf5162f2ec55b930","type":"debug","z":"476aa68f8e4864eb","name":"tradfri monitor","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":400,"y":520,"wires":[]},{"id":"44f39b504b89b85c","type":"function","z":"476aa68f8e4864eb","name":"65539","func":"// Insert Ikea device id as msg.topic\nmsg.topic = 65539\n\n//Change light % to var\nvar dim_level = Number(msg.payload.level);\n\n//If off change to Off\nif (dim_level == 0) {\n    msg.payload =  {\n        onOff: false,\n        }\n    } \n\n//Of on change to on\nif (dim_level <= 1) {\n    msg.payload =  {\n        onOff: true,\n        }\n    }\n\n// Update dim level\nmsg.payload.brightness = dim_level\n\n//Return msg\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":810,"y":340,"wires":[["8ee1c84d2d65a743"]]},{"id":"8e6ddd87fb3c6597","type":"function","z":"476aa68f8e4864eb","name":"65537","func":"// Insert Ikea device id as msg.topic\nmsg.topic = 65537\n\n//Change light % to var\nvar dim_level = Number(msg.payload.level);\n\n//If off change to Off\nif (dim_level == 0) {\n    msg.payload =  {\n        onOff: false,\n        }\n    } \n\n//Of on change to on\nif (dim_level <= 1) {\n    msg.payload =  {\n        onOff: true,\n        }\n    }\n\n// Update dim level\nmsg.payload.brightness = dim_level\n\n//Return msg\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":810,"y":280,"wires":[["8ee1c84d2d65a743"]]},{"id":"94891ae6d0cd64c1","type":"comment","z":"476aa68f8e4864eb","name":"Feedback from Ikea to HDL","info":"","x":260,"y":400,"wires":[]},{"id":"e4e2b3eb5f75ae7c","type":"switch","z":"476aa68f8e4864eb","name":"topic","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"65537","vt":"num"},{"t":"eq","v":"65539","vt":"num"}],"checkall":"false","repair":false,"outputs":2,"x":630,"y":460,"wires":[["7894333b5f4b6075"],["bab4eeaa498c7e5b"]]},{"id":"5a04ab1401b60719","type":"switch","z":"476aa68f8e4864eb","name":"","property":"payload.event","propertyType":"msg","rules":[{"t":"eq","v":"device updated","vt":"str"}],"checkall":"false","repair":false,"outputs":1,"x":390,"y":460,"wires":[["435a4cf40fd44815"]]},{"id":"7894333b5f4b6075","type":"function","z":"476aa68f8e4864eb","name":"Change","func":"// Insert msg.code\nmsg.code = 50\n\n//Add target\nmsg.target = \"1.118\"\n\n//Add payload channel\nmsg.payload = {\n    channel: 25,\n    level: 29,\n    success: true,\n};\n\n//Add level\nif (msg.olddata.lightbulb.isOn == false) {\n    msg.payload.level = 0\n    }\nif (msg.olddata.lightbulb.isOn == true) {\n    msg.payload.level = msg.olddata.lightbulb.dimmer\n    }    \n\n//Insert success\nmsg.payload.success = true\n\n//Return msg\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":440,"wires":[["d57ede79754f77fd"]]},{"id":"d57ede79754f77fd","type":"hdl-raw-out","z":"476aa68f8e4864eb","controller":"","name":"","x":970,"y":460,"wires":[]},{"id":"435a4cf40fd44815","type":"change","z":"476aa68f8e4864eb","name":"Move","rules":[{"t":"set","p":"olddata","pt":"msg","to":"payload","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":460,"wires":[["e4e2b3eb5f75ae7c"]]},{"id":"bab4eeaa498c7e5b","type":"function","z":"476aa68f8e4864eb","name":"Change","func":"// Insert msg.code\nmsg.code = 50\n\n//Add target\nmsg.target = \"1.118\"\n\n//Add payload channel\nmsg.payload = {\n    channel: 25,\n    level: 29,\n    success: true,\n};\n\n//Add level\nif (msg.olddata.lightbulb.isOn == false) {\n    msg.payload.level = 0\n    }\nif (msg.olddata.lightbulb.isOn == true) {\n    msg.payload.level = msg.olddata.lightbulb.dimmer\n    }    \n\n//Insert success\nmsg.payload.success = true\n\n//Return msg\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":500,"wires":[["d57ede79754f77fd"]]},{"id":"506e37ad5e6b5963","type":"debug","z":"476aa68f8e4864eb","name":"answeerback to HDL","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":980,"y":100,"wires":[]}]

It is possible to make a flow check if the answerback message is the same as the command message and if not resend the command. You would have to share you current setup if you would like me to make an example.