Re: MQTT Support
Posted: Thursday 02 January 2014 23:37
again some code example for domoticz.js, continuing where you left
it will support different types of messages (json or normal, and using idx or dtype and dsubtype), once you see the source I think it makes sense. Feedback appreciated.
I can definately see the flexibility that JSON provides.
I'm trying to make it even more userfriendly by adding some option to the json for passing SensorType:
{
"data":[{
"SensorType":"Temperature",
"svalue":"21.1"
}]
}
this hasn't finished yet because it's quite a lot of work and also Domoticz isn't always consistently behaving here. Support here would be welcome.
it will support different types of messages (json or normal, and using idx or dtype and dsubtype), once you see the source I think it makes sense. Feedback appreciated.
I can definately see the flexibility that JSON provides.
I'm trying to make it even more userfriendly by adding some option to the json for passing SensorType:
{
"data":[{
"SensorType":"Temperature",
"svalue":"21.1"
}]
}
this hasn't finished yet because it's quite a lot of work and also Domoticz isn't always consistently behaving here. Support here would be welcome.
Code: Select all
var Domoticz_HID = '3'; //Hardware ID of dummy in Domoticz
Domoticz_IP = '127.0.0.1'; //IP address of Domoticz (127.0.0.1 for same machine)
Domoticz_Port = '8080'; //Port of Domoticz
var mqtt = require('mqtt');
var url = require('url');
var http = require('http');
var request = require('request');
client = mqtt.createClient(1883, 'localhost');
// the lua-script in domoticz pushes all events to port 5001. This function will republish them on the mqtt bus
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Response from Node.js \n');
console.log('publish: '+'/events/domoticz'+url.parse(req.url).pathname, url.parse(req.url).query);
client.publish('/events/domoticz'+url.parse(req.url).pathname, url.parse(req.url).query);
}).listen(5001, 'localhost');
/* here we subscribe to topic /actions/domoticz in mqtt. Parsable messages which are published here will be sent to domoticz
Example data 1 (JSON, idx-value):
mosquitto_pub -t /actions/domoticz/xyz -m '
{
"data":[{
"idx":247,
"svalue":"21.1;70%"
}]
}'
Example data 2 (JSON, did/dunit/dtype/dsubtype):
{
"data":[{
"dunit":1,
"dtype":80,
"dsubtype":9,
"svalue":"21.1"
}]
}
(for dtype and dsubtype please refer to http://sourceforge.net/p/domoticz/code/HEAD/tree/domoticz/main/RFXtrx.h
e.g. 80,9 = temperature, 82,10 = temperature+humidity, 32, 1 = shuttercontact)
Example data 3 (Normal, idx-value):
mosquitto_pub -t /actions/domoticz/247 -m 21.1
Example data 4 (JSON, SensorType):
{
"data":[{
"SensorType":"Temperature",
"svalue":"21.1"
}]
}
*/
client.subscribe('/actions/domoticz/#');
client.on('message', function (topic, message) {
console.log('Received: '+ topic + ' ' + message);
var url = 'http://'+Domoticz_IP+':'+Domoticz_Port;
var svalue = 0;
var idx = 0;
var nvalue = 0;
var dunit = 1; // default
var dtype = 80; // default = temperature device
var dsubtype = 9;
try {
var payload = JSON.parse(message);
if (payload.data != null) {
console.log('JSON Payload');
for (var i = payload.data.length - 1; i >= 0; i--) {
var data = payload.data[i];
if(data.nvalue) {
nvalue = data.nvalue;
}
if(data.svalue) {
svalue = data.svalue;
}
if(data.dunit) {
dunit = data.dunit;
}
if(data.dsubtype) {
dsubtype = data.dsubtype;
}
//use idx if found, otherwise use hid/did/dunit/dtype/dsubtype style of interfacing with domoticz.
if(data.idx) {
idx = data.idx;
url = url + "/json.htm?type=command¶m=udevice&idx="+idx+
"&nvalue="+nvalue+"&svalue="+svalue;
}
else {
if (data.SensorType) {
switch (data.SensorType.toLowerCase()) {
case "temperature":
dtype = 80;
dsubtype = 1;
break;
case "humidity":
dtype = 81;
dsubtype = 1;
break;
case "temp+hum":
dtype = 82;
dsubtype = 1;
svalue = svalue + ';0'; // don't know why this is needed
// also for no apparent reason the &did cannot be a random string so it will end up like 0000
break;
case "temp+hum+baro":
dtype = 84;
dsubtype = 1;
// unclear what the svalue should look like ???
break;
case "rain":
dtype = 85;
dsubtype = 3;
break;
case "wind":
dtype = 86;
dsubtype = 1;
// 0;N;0;0;0;0 ???
break;
case "uv":
dtype = 87;
dsubtype = 1;
// 0.0 UVI
break;
case "uv":
case "electricity":
dtype = 248;
dsubtype = 1;
// 0.0 UVI
case "gas":
dtype = 113;
dsubtype = 0;
break;
case "shuttercontact":
dtype = 32;
dsubtype = 1;
break;
default:
console.log('Warning: no matching SensorType. Default used');
break;
};
};
url = url + "/json.htm?type=command¶m=udevice&hid="+Domoticz_HID+"&did="+topic+"&dunit="+dunit+"&dtype="+dtype+"&dsubtype="+dsubtype+
"&nvalue="+nvalue+"&svalue="+svalue;
};
request(url, function(error, response, body){
console.log("Sending request");
console.log(url);
console.log(error);
// console.log(response);
console.log(body);
});
}
}
else {
console.log('Normal Payload');
var parts = topic.split("/");
idx = parts.pop();
svalue = message;
url = url + "/json.htm?type=command¶m=udevice&idx="+idx+"&nvalue=0&svalue="+svalue;
request(url, function(error, response, body){
console.log("Sending request");
console.log(url);
console.log(error);
// console.log(response);
console.log(body);
});
};
}
catch(e) {
console.log("Could not parse payload");
console.log(e);
}
});