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);
}
});