Skip to content

Instantly share code, notes, and snippets.

@mountaindude
Created September 1, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mountaindude/2e43be05e76a81ab8601 to your computer and use it in GitHub Desktop.
Save mountaindude/2e43be05e76a81ab8601 to your computer and use it in GitHub Desktop.
Using Node-RED for publishing Telldus Live data to MQTT

The code in this entry will retrieve sensor and device data from Telldus Live, and then output that same data in a structured way to MQTT topics of your choice. Devices are typically various kinds of actuators, for example radio controlled mains switches.

Other applications can then subscribe to the MQTT topics, and provide for example visualisations of the sensor data, send alerts when certain conditions occur, or store the data in some kind of database.

Please note that the code in this repo is intended to go inside a Node-RED function - it is not a Node-RED module in itself.

More related information, ideas and code can be found at https://www.ptarmiganlabs.com/2015/08/31/using-node-red-for-publishing-telldus-live-data-to-mqtt/

[{"id":"6df5285e.920ad8","type":"function","name":"Read all device and sensor data from Telldus Live","func":"// Node-RED function to\n// a) extract data from TelldusLive API, and\n// b) send that data to MQTT for later consumption by various MQTT clients\n//\n// The code below relies on the following modules to be installed in the Node-RED environment, including being set up\n// in the functionGlobalContext section of the Node-RED settings.js config file (see last section of http://nodered.org/docs/writing-functions.html page)\n//\n// a) MQTT module (https://www.npmjs.com/package/mqtt)\n// b) Telldus-Live module (https://github.com/TheThingSystem/node-telldus-live)\n//\n//\n// Code below borrows a lot from the test script at https://github.com/TheThingSystem/node-telldus-live, with main addition being the use of MQTT client to publish such messages.\n//\n\n// Define Telldus Live API credentials\nvar publicKey = '<enter your public key here>'\n , privateKey = '<enter your private key here>'\n , token = '<enter your token here>'\n , tokenSecret = '<enter your token secret here>'\n , cloud\n ;\n\nvar mqtt = context.global.mqttModule;\nvar mqttClient = mqtt.connect('mqtt://<IP of your mqtt broker>');\n\nvar batteryStatus;\n\n\n// Convenience function to format datetimes in nice human readable format\nfunction formatDate(d){\n if(typeof d === 'number') d = new Date(d);\n if(!(d instanceof Date)) return d;\n function pad(n){return n<10 ? '0'+n : n}\n return d.getFullYear()+'-'\n + pad(d.getMonth()+1)+'-'\n + pad(d.getDate())+' '\n + pad(d.getHours()) + \":\"\n + pad(d.getMinutes()) + \":\"\n + pad(d.getSeconds());\n}\n\n\n// Create and log into new TelldusAPI object\ncloud = new context.global.telldusLive.TelldusAPI({ publicKey : publicKey\n , privateKey : privateKey });\n\ncloud.login(token, tokenSecret, function(err, user) {\n\n if (!!err) return console.log('login error: ' + err.message);\n\n console.log('user: ');\n console.log(user);\n console.log('');\n console.log('');\n\n // \n cloud.getSensors(function(err, sensors) {\n var f, i;\n\n if (!!err) return console.log('getSensors: ' + err.message);\n\n f = function(offset, p, s) {\n\n return function(err, sensor) {\n var i, prop, props, type;\n\n if (!!err) return console.log(s + ' id=' + p.id + ': ' + err.message);\n\n console.log('sensor #' + offset + ' ' + s + ': '); console.log(sensor);\n props = { temp : [ 'temperature', 'celcius', 'meteo' ]\n , humidity : [ 'humidity', 'percentage', 'meteo' ]\n };\n\n type = null;\n for (i = 0; i < sensor.data.length; i++) {\n type = props[sensor.data[i].name];\n if (!!type) break;\n }\n if (!type) return;\n\n console.log('/device/climate/' + (sensor.protocol || 'telldus') + '/' + type[2]);\n console.log(' uuid=teldus:' + sensor.id);\n console.log(' name: ' + sensor.name);\n console.log(' status: ' + (p.online === '1' ? 'present' : 'absent'));\n console.log(' battery: ' + sensor.battery);\n console.log(' lastSample: ' + sensor.lastUpdated * 1000);\n console.log(' lastSample: ' + '' + formatDate(sensor.lastUpdated * 1000));\n console.log(' info:');\n\n\n batteryStatus = '-'\n if (sensor.battery === '253') {\n batteryStatus = 'ok';\n } else if (sensor.battery === '254') {\n batteryStatus = 'unknown';\n } else if (sensor.battery === '255') {\n batteryStatus = 'low battery';\n } else {\n batteryStatus = sensor.battery;\n }\n\n\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/telldus id', sensor.id);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/protocol', '' + sensor.protocol);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/last update', '' + sensor.lastUpdated * 1000);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/last update nice', '' + formatDate(sensor.lastUpdated * 1000));\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/ignored', '' + sensor.ignored);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/editable', '' + sensor.editable);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/status', (p.online === '1' ? 'present' : 'absent'));\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/sensor id', sensor.sensorId);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/timezone offset', '' + sensor.timezoneoffset);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/battery status', batteryStatus);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/mqtt last update', '' + Date.now());\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/mqtt last update nice', '' + formatDate(Date.now()));\n\n for (i = 0; i < sensor.data.length; i++) {\n prop = props[sensor.data[i].name];\n if (prop) console.log(' ' + prop[0] + ': \"' + prop[1] + '\"');\n }\n console.log(' values:');\n for (i = 0; i < sensor.data.length; i++) {\n prop = props[sensor.data[i].name];\n if (prop) console.log(' ' + prop[0] + ': ' + sensor.data[i].value);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/data/' + prop[0] + '/value', sensor.data[i].value);\n mqttClient.publish('common/telldus live/' + sensor.clientName + '/sensors/' + sensor.name + '/data/' + prop[0] + '/unit', prop[1]);\n }\n console.log('');\n };\n };\n\n for (i = 0; i < sensors.length; i++) cloud.getSensorInfo(sensors[i], f(i, sensors[i], 'getSensorInfo'));\n\n }).getDevices(function(err, devices) {\n var f, i;\n\n if (!!err) return console.log('getDevices: ' + err.message);\n\n f = function(offset, p, s) {\n return function(err, device) {\n var d, type, types;\n\n if (!!err) return console.log(s + ' id=' + p.id + ': ' + err.message);\n\n console.log('device #' + offset + ' ' + s + ': '); console.log(device);\n types = { 'selflearning-switch' : 'onoff'\n , 'selflearning-dimmer' : 'dimmer'\n , 'codeswitch' : 'onoff' };\n\n type = null;\n d = device.model.split(':');\n type = types[d[0]];\n if (!type) return;\n\n console.log('/device/switch' + '/' + (d[d.length - 1] || 'telldus') + '/' + type);\n console.log(' uuid=teldus:' + device.id);\n console.log(' perform: off, on');\n console.log(' name: ' + device.name);\n console.log('last update: ' + device.lastUpdated*1000);\n console.log(' status: ' + (device.online === '0' ? 'absent' : device.status));\n console.log(' info:');\n if (type === 'dimmer') console.log(' dimmer: percentage');\n console.log(' values:');\n if (type === 'dimmer') console.log(' dimmer: ' + Math.round((1-(255 - device.statevalue)/255)*100) + '%');\n console.log('');\n\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/telldus id', device.id);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/protocol', '' + device.protocol);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/model', '' + device.model);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/state', '' + device.state);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/state value', '' + device.statevalue);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/methods', '' + device.methods);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/type', '' + type);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/client', '' + device.client);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/online', '' + device.online);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/editable', '' + device.editable);\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/status', '' + (device.online === '0' ? 'absent' : device.status));\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/mqtt last update', '' + Date.now());\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/mqtt last update nice', '' + formatDate(Date.now()));\n\n for (j = 0; j < device.parameter.length; j++) {\n mqttClient.publish('common/telldus live/' + device.client + '/devices/' + device.name + '/data/' + device.parameter[j].name , '' + device.parameter[j].value);\n }\n };\n };\n\n for (i = 0; i < devices.length; i++) {\n if (devices[i].type === 'device') cloud.getDeviceInfo(devices[i], f(i, devices[i], 'getDeviceInfo'));\n }\n });\n}).on('error', function(err) {\n console.log('background error: ' + err.message);\n});\n\n\nreturn msg;","outputs":1,"noerr":0,"x":425,"y":400,"z":"6b400632.94bff8","wires":[[]]}]
@burner-
Copy link

burner- commented May 25, 2020

This function use hard coded mqtt connection and cause duplicated clients and other crap for mqtt server. Basically useless with those bugs. These days there is mqtt module support directly at telldus live unit so it is better to use it that try fix this.

@mountaindude
Copy link
Author

Fully agree - lots have happened in the 5 years since that gist was created

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