Hi,
Sorry, I didn’t seen your messages.
I created a configuration file in /etc/mosquitto/inc/
on the bridge, with the following content:
connection domotique
address <my-mqtt-server>:1883
topic cmd/clip/event/publish out 0 "" hue/bridge/
I’ve also created a Node-RED plugin. Development version is available here: GitHub - rclsilver/node-red-contrib-hue-mqtt at dev. I have to finish it with:
- documentation / examples
- translations
I’ve created it from GitHub - Foddy/node-red-contrib-huemagic: Philips Hue node to control bridges, lights, groups, motion sensors, temperature sensors and Lux sensors using Node-RED.
I wrote a local library to use in functions in node-red: GitHub - rclsilver/node-red-utils. You have to git pull this repository in /data in Node-RED container and add following settings in settings.js node-red configuration file:
functionGlobalContext: {
utils: require('./utils'),
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},
You can find bellow my implementation in Node-RED:
[
{
"id": "6912c440.c1421c",
"type": "mqtt in",
"z": "fd782201.29744",
"name": "Raw hue events",
"topic": "hue/bridge/cmd/clip/event/publish",
"qos": "2",
"datatype": "json",
"broker": "971e1087.5d6b5",
"nl": false,
"rap": true,
"rh": 0,
"x": 140,
"y": 120,
"wires": [["53f1b951.c88a28"]]
},
{
"id": "53f1b951.c88a28",
"type": "hue-mqtt-in",
"z": "fd782201.29744",
"name": "MQTT updates",
"bridge": "4a6301b0.fb715",
"x": 340,
"y": 120,
"wires": [[]]
},
{
"id": "33a1c624.b4176a",
"type": "hue-cache",
"z": "fd782201.29744",
"name": "Hue cache",
"bridge": "4a6301b0.fb715",
"x": 310,
"y": 220,
"wires": [["7ae4286.6d705d8"], []]
},
{
"id": "7ae4286.6d705d8",
"type": "function",
"z": "fd782201.29744",
"name": "Discovery",
"func": "const topicPrefix = 'homeassistant';\nconst { hue } = global.get('utils');\n\nif (msg.type === 'temperature') {\n return hue.temperatureToHomeassistant(msg, topicPrefix);\n} else if (msg.type === 'brightness') {\n return hue.brightnessToHomeassistant(msg, topicPrefix);\n} else if (msg.type === 'motion') {\n node.send(hue.motionBatteryToHomeassistant(msg, topicPrefix));\n node.send(hue.motionEnabledToHomeassistant(msg, topicPrefix));\n node.send(hue.motionToHomeassistant(msg, topicPrefix));\n} else if (msg.type === 'light') {\n return hue.lightToHomeassistant(msg, topicPrefix);\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 220,
"wires": [["341f0151.e0b2fe"]]
},
{
"id": "341f0151.e0b2fe",
"type": "mqtt out",
"z": "fd782201.29744",
"name": "",
"topic": "",
"qos": "2",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "971e1087.5d6b5",
"x": 630,
"y": 220,
"wires": []
},
{
"id": "af5c245c.a2e728",
"type": "inject",
"z": "fd782201.29744",
"name": "Manual refresh",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 130,
"y": 220,
"wires": [["33a1c624.b4176a"]]
},
{
"id": "3fd2690b.2ae9b6",
"type": "hue-temperature",
"z": "fd782201.29744",
"name": "Entrée",
"bridge": "4a6301b0.fb715",
"sensor": "4",
"x": 130,
"y": 300,
"wires": [["d36b0833.8c9a28"]]
},
{
"id": "2d53b396.109aec",
"type": "hue-temperature",
"z": "fd782201.29744",
"name": "Couloir",
"bridge": "4a6301b0.fb715",
"sensor": "8",
"x": 130,
"y": 380,
"wires": [["1013304c.64039"]]
},
{
"id": "d36b0833.8c9a28",
"type": "change",
"z": "fd782201.29744",
"name": "Set label",
"rules": [
{ "t": "set", "p": "label", "pt": "msg", "to": "Entrée", "tot": "str" }
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 260,
"y": 300,
"wires": [["a9dd1b6b.fc22c8"]]
},
{
"id": "1013304c.64039",
"type": "change",
"z": "fd782201.29744",
"name": "Set label",
"rules": [
{ "t": "set", "p": "label", "pt": "msg", "to": "Couloir", "tot": "str" }
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 260,
"y": 380,
"wires": [["a9dd1b6b.fc22c8"]]
},
{
"id": "a9dd1b6b.fc22c8",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { datetime, hue } = global.get('utils');\nconst { area } = hue.parseName(msg.info.name);\nconst timestamp = datetime.toTimestamp(msg.payload.updated);\n\nreturn {\n topic: `home/${area}/sensor/temperature`,\n payload: {\n value: msg.payload.celsius,\n battery: msg.info.battery,\n timestamp: timestamp,\n label: msg.label,\n }\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 460,
"y": 340,
"wires": [["37443c5c.b6e3b4"]]
},
{
"id": "37443c5c.b6e3b4",
"type": "mqtt out",
"z": "fd782201.29744",
"name": "",
"topic": "",
"qos": "1",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "971e1087.5d6b5",
"x": 630,
"y": 420,
"wires": []
},
{
"id": "96ada3bb.813fa",
"type": "hue-brightness",
"z": "fd782201.29744",
"name": "Entrée",
"bridge": "4a6301b0.fb715",
"sensor": "3",
"x": 130,
"y": 460,
"wires": [["d0f56618.ad0348"]]
},
{
"id": "88728839.f2a828",
"type": "hue-brightness",
"z": "fd782201.29744",
"name": "Couloir",
"bridge": "4a6301b0.fb715",
"sensor": "7",
"x": 130,
"y": 540,
"wires": [["3315e3b2.d48f7c"]]
},
{
"id": "d0f56618.ad0348",
"type": "change",
"z": "fd782201.29744",
"name": "Set label",
"rules": [
{ "t": "set", "p": "label", "pt": "msg", "to": "Entrée", "tot": "str" }
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 260,
"y": 460,
"wires": [["5fa4f379.28695c"]]
},
{
"id": "3315e3b2.d48f7c",
"type": "change",
"z": "fd782201.29744",
"name": "Set label",
"rules": [
{ "t": "set", "p": "label", "pt": "msg", "to": "Couloir", "tot": "str" }
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 260,
"y": 540,
"wires": [["5fa4f379.28695c"]]
},
{
"id": "5fa4f379.28695c",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { datetime, hue } = global.get('utils');\nconst { area } = hue.parseName(msg.info.name);\nconst timestamp = datetime.toTimestamp(msg.payload.updated);\n\nreturn {\n topic: `home/${area}/sensor/brightness`,\n payload: {\n value: msg.payload.lux,\n battery: msg.info.battery,\n timestamp: timestamp,\n label: msg.label,\n }\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 460,
"y": 500,
"wires": [["37443c5c.b6e3b4"]]
},
{
"id": "24267098.776ca",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { datetime, hue } = global.get('utils');\nconst { area, name } = hue.parseName(msg.info.name);\nconst timestamp = datetime.toTimestamp(msg.payload.updated);\n\nreturn {\n topic: `home/${area}/button/${name}`,\n payload: {\n button: msg.payload.name,\n action: msg.payload.action,\n battery: msg.info.battery,\n timestamp,\n },\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 460,
"y": 620,
"wires": [["4d8c7418.f4677c"]]
},
{
"id": "b04994ee.564598",
"type": "hue-switch",
"z": "fd782201.29744",
"name": "Switches",
"bridge": "4a6301b0.fb715",
"sensor": "",
"x": 140,
"y": 620,
"wires": [["24267098.776ca"]]
},
{
"id": "4d8c7418.f4677c",
"type": "mqtt out",
"z": "fd782201.29744",
"name": "",
"topic": "",
"qos": "1",
"retain": "false",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "971e1087.5d6b5",
"x": 630,
"y": 620,
"wires": []
},
{
"id": "5795579c.357888",
"type": "mqtt out",
"z": "fd782201.29744",
"name": "",
"topic": "",
"qos": "1",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "971e1087.5d6b5",
"x": 1090,
"y": 780,
"wires": []
},
{
"id": "75dee6be.de3d98",
"type": "hue-motion",
"z": "fd782201.29744",
"name": "Motions",
"bridge": "4a6301b0.fb715",
"sensor": "",
"x": 720,
"y": 740,
"wires": [["b395f324.09108"]]
},
{
"id": "b395f324.09108",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { datetime, hue } = global.get('utils');\nconst { area, name } = hue.parseName(msg.info.name);\nconst timestamp = datetime.toTimestamp(msg.payload.updated);\n\nreturn {\n topic: `home/${area}/sensor/${name}`,\n payload: {\n value: msg.payload.motion,\n enabled: msg.payload.active,\n battery: msg.info.battery,\n timestamp: timestamp,\n }\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 920,
"y": 740,
"wires": [["5795579c.357888"]]
},
{
"id": "97dbf0a3.89307",
"type": "hue-light",
"z": "fd782201.29744",
"name": "Lights",
"bridge": "4a6301b0.fb715",
"light": "",
"x": 730,
"y": 820,
"wires": [["2795da08.900126"]]
},
{
"id": "2795da08.900126",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { hue } = global.get('utils');\nconst { area, name } = hue.parseName(msg.info.name);\n\n// Availability topic\nif (msg.payload.reachable !== undefined) {\n node.send({\n topic: `home/${area}/light/${name}/availability`,\n payload: msg.payload.reachable ? 'online' : 'offline',\n });\n}\n\n// State topic\nlet message = {\n topic: `home/${area}/light/${name}/state`,\n payload: {\n state: msg.payload.on ? 'ON' : 'OFF',\n },\n};\n\nif (msg.payload.brightness !== undefined) {\n message.payload.brightness = msg.payload.brightness;\n}\n\nif (msg.payload.xy !== undefined) {\n message.payload.color = msg.payload.xy;\n}\n\nif (msg.payload.colorTemp !== undefined) {\n message.payload.color_temp = msg.payload.colorTemp;\n}\n\nnode.send(message);",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 920,
"y": 820,
"wires": [["5795579c.357888"]]
},
{
"id": "2b17af94.a22cb",
"type": "mqtt in",
"z": "fd782201.29744",
"name": "Motions commands",
"topic": "home/+/sensor/+/set",
"qos": "2",
"datatype": "json",
"broker": "971e1087.5d6b5",
"nl": false,
"rap": true,
"rh": 0,
"x": 150,
"y": 740,
"wires": [["c3bac75a.7d26b8"]]
},
{
"id": "458d2f58.b715",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { mqtt } = global.get('utils');\nconst { area, name } = mqtt.parseTopic(msg.topic);\n\nreturn {\n payload: {\n sensorName: `${area}_${name}`,\n enabled: msg.payload,\n }\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 550,
"y": 740,
"wires": [["75dee6be.de3d98"]]
},
{
"id": "c3bac75a.7d26b8",
"type": "switch",
"z": "fd782201.29744",
"name": "Filter motions",
"property": "topic",
"propertyType": "msg",
"rules": [
{
"t": "regex",
"v": "^home/[^/]+/sensor/motion[^/]*/set$",
"vt": "str",
"case": false
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 360,
"y": 740,
"wires": [["458d2f58.b715"]]
},
{
"id": "5f979bb3.e0c984",
"type": "mqtt in",
"z": "fd782201.29744",
"name": "Lights commands",
"topic": "home/+/light/+/set",
"qos": "2",
"datatype": "json",
"broker": "971e1087.5d6b5",
"nl": false,
"rap": true,
"rh": 0,
"x": 140,
"y": 820,
"wires": [["756a1bd3.18a854"]]
},
{
"id": "756a1bd3.18a854",
"type": "function",
"z": "fd782201.29744",
"name": "Build message",
"func": "const { mqtt } = global.get('utils');\nconst { area, name } = mqtt.parseTopic(msg.topic);\nconst payload = {\n lightName: `${area}_${name}`,\n};\n\nif (msg.payload.state !== undefined) {\n payload.on = msg.payload.state === 'ON';\n}\n\nif (msg.payload.brightness !== undefined) {\n payload.brightness = msg.payload.brightness;\n}\n\nif (msg.payload.color !== undefined) {\n payload.xy = msg.payload.color;\n}\n\nif (msg.payload.color_temp !== undefined) {\n payload.colorTemp = msg.payload.color_temp;\n}\n\nreturn {\n payload,\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 360,
"y": 820,
"wires": [["97dbf0a3.89307"]]
},
{
"id": "971e1087.5d6b5",
"type": "mqtt-broker",
"name": "Local MQTT",
"broker": "mosquitto.mosquitto.svc.cluster.local",
"port": "1883",
"clientid": "node-red",
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"sessionExpiry": ""
},
{
"id": "4a6301b0.fb715",
"type": "hue-bridge",
"name": "Hue Bridge",
"bridge": "192.168.1.42",
"key": "secret",
"interval": "60000"
}
]