node-red-contrib-proficloud
Version:
Proficloud - IIoT-Platform of Phoenix Contact
261 lines (240 loc) • 9.19 kB
JavaScript
var proficloud_connector = require("pcv3cloudconnector-nodejs");
var fs = require("fs");
module.exports = function (RED) {
function ProficloudDevice(config) {
RED.nodes.createNode(this, config);
this.status({fill: "blue", shape: "dot", text: "initializing"});
var node = this;
// compatible code for versions below 1.0.54
if (config.proficloud_api == undefined) {
node.log("No URL set");
config.proficloud_api = "env.kaa.proficloud-production.io";
config.proficloud_mqtt = "mqtts://mqtt.proficloud-production.io:8883";
}
// if uuid has been set via payload, get it from config file
if (fs.existsSync("./config.json") && !config.uuid) {
node.log("uuid was set via payload, searching in config.json");
var jsonData = JSON.parse(fs.readFileSync("./config.json"));
for (key in jsonData) {
var found = false;
for (key1 in jsonData[key]) {
if (found) {
config.uuid = jsonData[key][key1];
break;
}
if (jsonData[key][key1] == node.id) {
found = true;
}
}
}
node.log("not uuid found for this node");
}
node.log("connecting to: " + config.proficloud_api + " " + config.proficloud_mqtt);
connectToCloud(config, node);
node.on("input", function (msg) {
if (!msg.payload) {
node.error("payload in wrong format; no msg.payload object found");
return;
}
if ("config" in msg.payload) {
config.uuid = msg.payload.config.uuid;
console.log("uuid set via payload");
connectToCloud(config, node);
// storing uuid in config file, so it doesn't need to be sent again when re-deploying NodeRED
// make new config file if it doens't exist yet
if (!fs.existsSync("./config.json")) {
var jsonArray = [];
jsonArray.push({
nodeId: node.id,
uuid: config.uuid
});
var data = JSON.stringify(jsonArray);
fs.writeFile("./config.json", data, function (err) {
if (err) {
console.log("There has been an error saving the uuid");
console.log(err.message);
return;
}
console.log("uuid successfully stored in new config.json");
});
} else {
fs.readFile("./config.json", (err, data) => {
if (err) {
console.log("Error reading file config.json from disk: " + err);
} else {
const jsonFile = JSON.parse(data);
// if there is already a uuid for this node, don't store it again
for (key in jsonFile) {
found = false;
for (key1 in jsonFile[key]) {
if (jsonFile[key][key1] == node.id) {
found = true;
}
}
}
if (!found) {
//add new data
jsonFile.push({
nodeId: node.id,
uuid: config.uuid
});
// write new data back to file
fs.writeFile("./config.json", JSON.stringify(jsonFile), (err) => {
if (err) {
console.log("Error writing uuid to file config.json: " + err);
return;
}
console.log("uuid succesfully written to config.json");
});
}
}
});
}
}
if ("data" in msg.payload) {
try {
if (config.tsd_interval_activated) {
node.connector.sendTSDToBuffer(msg.payload.data);
} else {
node.connector.sendTSD(msg.payload.data);
}
} catch (e) {
node.error(e);
}
}
if ("log" in msg.payload) {
try {
node.connector.sendLog(msg.payload.log);
} catch (e) {
node.error(e);
}
}
if ("trafficlight" in msg.payload) {
try {
node.connector.sendTrafficLight(msg.payload.trafficlight);
} catch (e) {
node.error(e);
}
}
if ("metadata" in msg.payload) {
try {
if (!config.metaByPayload) {
this.log("payload meta is set");
var meta_object = {};
if ("fw_version" in msg.payload.metadata) {
meta_object["con_FirmwareVersion"] = msg.payload.metadata.fw_version;
} else {
this.log("firmware version empty");
}
if ("hw_version" in msg.payload.metadata) {
meta_object["con_HardwareVersion"] = msg.payload.metadata.hw_version;
} else {
this.log("hardware version empty");
}
if ("device_type" in msg.payload.metadata) {
meta_object["con_DeviceType"] = msg.payload.metadata.device_type;
} else {
this.log("device type empty");
}
if ("serial_number" in msg.payload.metadata) {
meta_object["con_SerialNumber"] = msg.payload.metadata.serial_number;
} else {
this.log("serial number empty");
}
node.connector.sendMeta(meta_object);
this.log([
`sent payload meta: deviceType: ${meta_object["con_DeviceType"]}`,
` serialNumber: ${meta_object["con_SerialNumber"]}`,
` firmwareVersion: ${meta_object["con_FirmwareVersion"]}`,
` hardwareVersion: ${meta_object["con_HardwareVersion"]}`
]);
}
} catch (e) {
node.error(e);
}
}
if ("event" in msg.payload) {
try {
node.connector.sendEvent(msg.payload.event.id, msg.payload.event.payload);
} catch (e) {
node.error(e);
}
}
});
this.on("close", function () {
node.connector.disconnect();
});
function connectToCloud(config, node) {
node.connector = new proficloud_connector.Connector(
config.uuid,
(proficloud_api = config.proficloud_api),
(proficloud_mqtt_url = config.proficloud_mqtt),
(userDir = RED.settings.userDir)
);
// computing time interval for buffering in milliseconds
if (config.tsd_timeunit == "s") {
config.tsd_interval = config.tsd_interval * 1000;
} else if (config.tsd_timeunit == "m") {
config.tsd_interval = config.tsd_interval * 60000;
} else if (config.tsd_timeunit == "h") {
config.tsd_interval = config.tsd_interval * 3600000;
}
node.connector.setTSDBufferConfig(config.tsd_interval_activated, config.tsd_interval);
node.connector.registerCommandCallback((command, payload) => {
var msg = {payload: {command: {id: command, payload: payload}}};
node.send(msg);
});
node.connector.registerCommandCallback((command, payload) => {
var msg = {payload: {command: {id: command, payload: payload}}};
node.send(msg);
});
node.connector.registerEventCallback((event_id, event_payload) => {
var msg = {payload: {event: {id: event_id, payload: event_payload}}};
node.send(msg);
});
const connectCallback = () => {
node.log("connected callback");
try {
if (config.metaByPayload) {
node.log("custom meta is set");
var meta_object = {
con_DeviceType: config.deviceType,
con_SerialNumber: config.serialNumber,
con_FirmwareVersion: config.firmwareVersion,
con_HardwareVersion: config.hardwareVersion
};
node.connector.sendMeta(meta_object);
node.log([
`sent custom meta: deviceType: ${meta_object["con_DeviceType"]}`,
` serialNumber: ${meta_object["con_SerialNumber"]}`,
` firmwareVersion: ${meta_object["con_FirmwareVersion"]}`,
` hardwareVersion: ${meta_object["con_HardwareVersion"]}`
]);
}
node.status({fill: "green", shape: "dot", text: "connected"});
} catch (e) {
node.error(e);
node.status({fill: "red", shape: "ring", text: "not connected"});
}
};
const connectionLostCallback = () => {
node.log("connection lost callback");
node.status({fill: "red", shape: "ring", text: "not connected"});
setTimeout(reconnectCallback, 30 * 1000);
};
const reconnectCallback = () => {
node.status({fill: "blue", shape: "dot", text: "reconnecting"});
node.connector.connect(connectCallback, connectionLostCallback);
};
const startWithDelay = () => {
setTimeout(node.connector.connect, config.autodelay * 1000, connectCallback, connectionLostCallback);
};
if (config.autostart) {
startWithDelay();
} else {
node.status({fill: "gray", shape: "ring", text: "no autoconnect"});
}
}
}
RED.nodes.registerType("ProficloudDevice", ProficloudDevice);
};