-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode_helper.js
126 lines (122 loc) · 3.86 KB
/
node_helper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
var NodeHelper = require("node_helper");
// const AbortController = require("abort-controller");
module.exports = NodeHelper.create({
moduleName: "MMM-Luftdaten",
state: {
sensorApi: "https://data.sensor.community/airrohr/v1/sensor/",
sensorHost: null,
sensorData: {},
lastUpdate: null,
sensorTypeAssignments: {
P1: "pm10",
P2: "pm25",
temperature: "temperature",
pressure: "pressure",
humidity: "humidity"
},
sensors: {}
},
// Override start method.
start: function () {
this.fetchers = [];
console.log("Starting node helper for: " + this.name);
},
// Override socketNotificationReceived method.
socketNotificationReceived: function (notification, payload) {
if (notification === "ADD_SENSOR") {
var { sensorId, fetchInterval, sensorIsHost } = payload;
var instance = this;
if (sensorIsHost) this.state.sensorHost = sensorId;
if (payload && sensorId && fetchInterval) {
if (!this.state.sensors[sensorId]) {
instance.fetchApiData(sensorId);
this.state.sensors[sensorId] = setInterval(function () {
instance.fetchApiData(sensorId);
}, this.getUpdateInterval(fetchInterval));
} else {
//when sensor already exists, directly update data on all clients
this.sendDataToClient();
}
}
}
},
sendDataToClient: function () {
this.sendSocketNotification("SENSOR_DATA_RECEIVED", {
sensorData: this.state.sensorData,
lastUpdate: this.state.sensorData["lastUpdate"]
});
},
sendErrorToClient: function () {
this.sendSocketNotification("SENSOR_DATA_CONNECTION_ERROR", {
lastUpdate: this.state.sensorData["lastUpdate"]
});
},
// Update Sensor Data.
updateSensorData: function (sensors, timestamp) {
for (let index in sensors) {
const sensor = sensors[index];
let sensorType = sensor.value_type;
if (sensorType.includes("_")) {
sensorType = sensorType.split("_")[1];
}
if (sensor && this.isValidSensorType(sensorType)) {
let type = this.getSensorKeyFromType(sensorType);
this.state.sensorData[type] = sensor.value;
}
}
if (timestamp) {
this.state.sensorData["lastUpdate"] = timestamp;
}
this.sendDataToClient();
//console.log("SensorDataUpdated:", this.state.sensorData, timestamp);
},
getSensorKeyFromType(name) {
return this.state.sensorTypeAssignments[name];
},
isValidSensorType(name) {
return this.state.sensorTypeAssignments[name] || false;
},
async fetchApiData(sensorId) {
let url;
if (this.state.sensorHost) {
url = `http://${this.state.sensorHost}/data.json`;
} else if (sensorId) {
url = this.state.sensorApi + sensorId + "/";
}
console.log(`${this.moduleName}: fetchData from ${url}`);
if (!url) {
console.error(
`${this.moduleName}: missconfiguration sensorHost or sensorIds has to be set!`
);
this.sendErrorToClient();
return;
}
const instance = this;
try {
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
if (Array.isArray(data)) {
if (data.length) {
const { sensordatavalues, timestamp } = data[0];
instance.updateSensorData(sensordatavalues, timestamp);
} else {
throw `Empty response`;
}
} else if (Array.isArray(data.sensordatavalues)) {
instance.updateSensorData(data.sensordatavalues, new Date());
}
} else {
const error = response.text();
throw `No positive response ${error}`;
}
} catch (e) {
console.error(`${this.moduleName}: ${e}`);
this.sendErrorToClient();
}
},
getUpdateInterval(minutes) {
const min = !minutes || minutes < 5 ? 5 : minutes;
return min * 60 * 1000;
}
});