Okay as promised⊠this is how you get MQTT working within Home Assistant by way of Node Red. Yes, this does use the cloud and I understand the risks, blah blah blah⊠this is just to help those that want to make use of their sensors and not cobble something together or rely on IFTTT.
This first documentation will cover the initial (legacy?) API access. Iâll write up on a follow-up post on how to use the app-based API.
Be sure you have Node Red installed â you can do this in Home Assistant by going to Configuration â Add-ons, Backups & Supervisor â Add-ons tab â Add-on Store. Youâll find Node-Red under the Home Assistant Community Add-ons.
To make this easier, Iâve created a sample flow that you can import into Node-Red. To import this, open up Node-Red on the left. If this is your first time opening Node-Red, it will create a blank tab that you can work on. Click on the three dots in the upper right and select Import. Copy the text below and paste it into this window and click Import. A new tab will be added called Flow 1 with the nodes.
[{"id":"c731b68e7e93d637","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"cf49b4468439e5aa","type":"mqtt in","z":"c731b68e7e93d637","name":"YoLink MQTT","topic":"{CSName}/#","qos":"2","datatype":"auto","broker":"dcbbcf25a3deef7b","nl":false,"rap":true,"rh":0,"inputs":0,"x":170,"y":140,"wires":[["5a4bf1f398aa126f"]]},{"id":"ba3da4f3e73c8fa3","type":"comment","z":"c731b68e7e93d637","name":"Enabling API access for YoLink Device","info":"1. Open the App on your phone and go to the device you want to enable API access for. \n2. Click on the three dots in the upper right.\n3. Scroll down to SN and click on the QR code.\n4. Screenshot this and print it out.\n5. Go to https://www.the-qrcode-generator.com/scan and scan the QR code you printed. You will be presented with a number, save that serial number down.\n6. Next, open MQTT Explorer and create a new MQTT connection. Use the following connection parameters:\n\n Host: api.yosmart.com Port: 8003\n User: <Your CSID>\n Pass: <MD5 hash of your CSSecKey>\n \n Save and Connect.\n7. In the MQTT explorer window, locate the publish section on the right side. Expand it if necessary.\n8. In the Topic line, enter the following topic for the first device you'd like to add:\n <CSID>/<DEVICE_SN>/request\n9. Set the type to 'json'.\n10. In the text box, enter the following:\n\n { \"method\": \"Manage.addYoLinkDevice\",\n \"time\": <EPOCH_TIME>,\n \"params\": { \"sn\": \"<DEVICE_SN>\" }}\n \n Replace <DEVICE_SN> with the device serial number you're adding.\n \n Replace <EPOCH_TIME> with the time value from https://www.epochconverter.com/\n\n11. Click the Publish button.\n12. If all goes well, you should see a response in the topic <CSID>/<DEVICE_SN>/response that matches the serial number. It should explain the type of device and have a code of \"000000\".\n13. Grab the 'token' that is listed, you will need that for all future requests. You will continue to get information in <CSID>/<DEVICE_SN>/report for each sensor added.\n \n\n\n\n\n\n\n\n\nRequest: {username}/<DEVICE_SN>/request\nResponse: {username}/<DEVICE_SN>/response\n\nTemp Sensor Method: THSensor.getState\n\n\n","x":450,"y":60,"wires":[]},{"id":"5a4bf1f398aa126f","type":"json","z":"c731b68e7e93d637","name":"Parse JSON","property":"payload","action":"","pretty":false,"x":310,"y":240,"wires":[["734eec60711d5905","1abd5af51bdbba4b"]]},{"id":"734eec60711d5905","type":"switch","z":"c731b68e7e93d637","name":"Device Selector","property":"payload.deviceId","propertyType":"msg","rules":[{"t":"eq","v":"{device1}","vt":"str"},{"t":"eq","v":"{device2}","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":440,"y":360,"wires":[["bf54159158f2f41b","cebe5e6e6461c9c0","47990cde1f470a4f"],["66bd633936ed1ddb","ef09aeda9d7e752f","c787b835989fc2da","8aacaf2332bc5c11"]]},{"id":"bf54159158f2f41b","type":"ha-entity","z":"c731b68e7e93d637","name":"Garage Freezer Temp Sensor Status","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Garage Freezer Temp Sensor Status"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.state","stateType":"msg","attributes":[{"property":"version","value":"payload.data.version","valueType":"msg"},{"property":"tempCorrection","value":"payload.data.tempCorrection","valueType":"msg"},{"property":"loraSignal","value":"payload.data.loraInfo.signal","valueType":"msg"},{"property":"gatewayId","value":"payload.data.loraInfo.gatewayId","valueType":"msg"},{"property":"gateways","value":"payload.data.loraInfo.gateways","valueType":"msg"},{"property":"humidityCorrection","value":"payload.data.humidityCorrection","valueType":"msg"},{"property":"mode","value":"payload.data.mode","valueType":"msg"},{"property":"interval","value":"payload.data.interval","valueType":"msg"},{"property":"msgid","value":"payload.msgid","valueType":"msg"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":830,"y":100,"wires":[[]]},{"id":"1abd5af51bdbba4b","type":"debug","z":"c731b68e7e93d637","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":490,"y":140,"wires":[]},{"id":"38d5dbe64d88bb1b","type":"ha-entity","z":"c731b68e7e93d637","name":"Garage Freezer Temperature","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Garage Freezer Temperature"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"°F"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.temperature","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":940,"y":160,"wires":[[]]},{"id":"cebe5e6e6461c9c0","type":"change","z":"c731b68e7e93d637","name":"C to F","rules":[{"t":"set","p":"payload.data.temperature","pt":"msg","to":"payload.data.temperature * 1.8 + 32","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":160,"wires":[["38d5dbe64d88bb1b"]]},{"id":"47990cde1f470a4f","type":"ha-entity","z":"c731b68e7e93d637","name":"Garage Freezer Temp Sensor Battery Alarm","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Garage Freezer Temp Sensor Battery Alarm"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.alarm.lowBattery","stateType":"msg","attributes":[{"property":"battery","value":"payload.data.battery","valueType":"msg"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":850,"y":40,"wires":[[]]},{"id":"66bd633936ed1ddb","type":"ha-entity","z":"c731b68e7e93d637","name":"Master Bathroom TH Sensor Battery Alarm","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Master Bathroom TH Sensor Battery Alarm"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.alarm.lowBattery","stateType":"msg","attributes":[{"property":"battery","value":"payload.data.battery","valueType":"msg"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":850,"y":380,"wires":[[]]},{"id":"ef09aeda9d7e752f","type":"ha-entity","z":"c731b68e7e93d637","name":"Master Bathroom TH Sensor Status","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Master Bathroom TH Sensor Status"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.state","stateType":"msg","attributes":[{"property":"version","value":"payload.data.version","valueType":"msg"},{"property":"tempCorrection","value":"payload.data.tempCorrection","valueType":"msg"},{"property":"loraSignal","value":"payload.data.loraInfo.signal","valueType":"msg"},{"property":"gatewayId","value":"payload.data.loraInfo.gatewayId","valueType":"msg"},{"property":"gateways","value":"payload.data.loraInfo.gateways","valueType":"msg"},{"property":"humidityCorrection","value":"payload.data.humidityCorrection","valueType":"msg"},{"property":"mode","value":"payload.data.mode","valueType":"msg"},{"property":"interval","value":"payload.data.interval","valueType":"msg"},{"property":"msgid","value":"payload.msgid","valueType":"msg"}],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":820,"y":440,"wires":[[]]},{"id":"c787b835989fc2da","type":"change","z":"c731b68e7e93d637","name":"C to F","rules":[{"t":"set","p":"payload.data.temperature","pt":"msg","to":"payload.data.temperature * 1.8 + 32","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":500,"wires":[["3acb1d99cdd29169"]]},{"id":"3acb1d99cdd29169","type":"ha-entity","z":"c731b68e7e93d637","name":"Master Bathroom Temperature","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Master Bathroom Temperature"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"°F"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.temperature","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":950,"y":500,"wires":[[]]},{"id":"8aacaf2332bc5c11","type":"ha-entity","z":"c731b68e7e93d637","name":"Master Bathroom Humidity","server":"1a70fbd4.64fc74","version":2,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Master Bathroom Humidity"},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":"%"},{"property":"state_class","value":""},{"property":"last_reset","value":""}],"state":"payload.data.humidity","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":800,"y":560,"wires":[[]]},{"id":"dcbbcf25a3deef7b","type":"mqtt-broker","name":"yolink","broker":"api.yosmart.com","port":"8003","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":"","credentials":{"user":"{CSID}","password":"password"}},{"id":"1a70fbd4.64fc74","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]
Finishing the MQTT setup:
- Open the Yolink MQTT object by double-clicking on it. Click on the pencil icon next to the yolink server.
- In this window, click on the Security tab. On this tab, enter your CSID for the Username and then enter an MD5 hash of your CSSecKey for the password. For MD5 hashing, you can use https://www.md5hashgenerator.com/. Click Update on the upper right to close the server screen.
- Back on the MQTT page, change the Topic box to your CSName/# (for instance, johnnyqman/#). Click Update in the upper right.
When you deploy this, it will connect to MQTT and start listening to device statuses from your hub. I have two devices shown as examples there to help you configure your devices⊠a YS8003 and outdoor temp sensor with probe (I couldnât find the model number). I do have outdoor gate sensors but I donât have them added in here at the moment. Unfortunately none of your sensors have been configured to send data across the API. To do this, we will need to make some MQTT requests to the API for this to happen.
To enable API access, you can use MQTT Explorer (http://mqtt-explorer.com/) to send your MQTT commands.
-
Open the App on your phone and go to the device you want to enable API access for.
-
Click on the three dots in the upper right.
-
Scroll down to SN and click on the QR code.
-
Screenshot this and print it out.
-
Go to Scan QR Codes with your WebCam and use your webcam to scan the QR code you printed. You will be presented with a number, save that serial number down.
-
Next, open MQTT Explorer and create a new MQTT connection using the information below. Use the following connection parameters:
Host: api.yosmart.com Port: 8003
User: Your CSID
Pass: MD5 hash of your CSSecKey
Save and Connect.
-
In the MQTT explorer window, locate the publish section on the right side. Expand it if necessary.
-
In the Topic line, enter the following topic for the first device youâd like to add:
CSID/DEVICE_SN/request
-
Set the type to âjsonâ.
-
In the text box, enter the following:
{ âmethodâ: âManage.addYoLinkDeviceâ,
âtimeâ: EPOCH_TIME,
âparamsâ: { âsnâ: âDEVICE_SNâ }}
Replace DEVICE_SN with the device serial number youâre adding.
Replace EPOCH_TIME with the time value from https://www.epochconverter.com/
-
Click the Publish button.
-
If all goes well, you should see a response in the topic CSID/DEVICE_SN/response that matches the serial number. It should explain the type of device and have a code of â000000â.
-
Grab the âtokenâ that is listed, you will need that for all future requests. You will continue to get information in CSID/DEVICE_SN/report for each sensor added.
-
Create an MQTT request for every device that you need to enable API access for.
Now that weâve enabled API access for our sensors, we need to add them to Node-Red so it. can start sending data to HA. Go back to Node-Red and continue below.
- Double click on the Device Selector node.
- Change the {device1} and {device2} entries to match the tokens that you received from enabling the API access in MQTT Explorer. It should be a string of about 15-20 alphanumeric characters. There will be one for each device. If you have more than two, click the +add button at the bottom to add another item.
- Click Update when youâre done.
- When a message comes in with the specific token, it will be directed to the respective point on the switch node. From there you can tell HA what to do.
Hopefully this should give some a starting point. I wrote this in bit of a rush so it may be a little jumbled. I donât have any extra sensors that I can go through the actual process with. Once I figure out how to get my auth token from the app API access Iâll update.