Skip to content

Commit f3b9e98

Browse files
committed
Add writer
1 parent e109e22 commit f3b9e98

File tree

6 files changed

+50
-11
lines changed

6 files changed

+50
-11
lines changed

iot-devices/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ ENV NODE_ENV=production
129129
# Ports used by application
130130
EXPOSE ${DUMMY_DEVICES_PORT:-3001}
131131
CMD ["./bin/devices"]
132+
VOLUME ["/data"]
132133
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \
133134
CMD ["/nodejs/bin/node", "./bin/healthcheck"]
134135

iot-devices/app.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const MyCache = require('./lib/cache');
1010
/* global MQTT_CLIENT */
1111
const DEVICE_TRANSPORT = process.env.DUMMY_DEVICES_TRANSPORT || 'HTTP';
1212
const DEVICE_PAYLOAD = process.env.DUMMY_DEVICES_PAYLOAD || 'ultralight';
13+
const HISTORY_LOG = process.env.HISTORY_LOG;
1314

1415
// The motion sensor offers no commands, hence it does not need an endpoint.
1516

@@ -35,6 +36,10 @@ global.MQTT_CLIENT = mqtt.connect(mqttBrokerUrl);
3536
const iotRouter = express.Router();
3637

3738
debug(`Devices use a ${DEVICE_PAYLOAD} payload`);
39+
40+
if (HISTORY_LOG) {
41+
debug(`Logging measures to ${HISTORY_LOG}`);
42+
}
3843
// If the Ultralight Dummy Devices are configured to use the HTTP transport, then
3944
// listen to the command endpoints using HTTP
4045
if (DEVICE_TRANSPORT === 'HTTP') {

iot-devices/lib/writer.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const debug = require('debug')('devices:writer');
2+
const JSONMeasure = require('../models/measure/json');
3+
const fs = require('fs');
4+
5+
const HISTORY_LOG = process.env.HISTORY_LOG;
6+
const json = new JSONMeasure({});
7+
const stream = HISTORY_LOG
8+
? fs.createWriteStream(HISTORY_LOG, { flags: 'a' })
9+
: null;
10+
11+
exports.write = function (deviceId, state, offset) {
12+
if (!stream) {
13+
console.log(HISTORY_LOG);
14+
return;
15+
}
16+
if (!deviceId.startsWith('cow')) {
17+
return;
18+
}
19+
const data = JSON.parse(json.format(state, false));
20+
const animal = `urn:ngsi-ld:Animal:${deviceId}`;
21+
const device = `urn:ngsi-ld:Device:${deviceId}`;
22+
const line = `${animal},Device,${data.bpm},Point,${data.gps},${device},${data.d},${data.o}`;
23+
24+
stream.write(line + '\n');
25+
};

iot-devices/models/devices.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const _ = require('lodash');
99
const debug = require('debug')('devices:devices');
1010
const Northbound = require('../controllers/iot/northbound');
1111
const Emitter = require('../lib/emitter');
12+
const Writer = require('../lib/writer');
1213

1314
// A series of constants used by our set of devices
1415

@@ -18,8 +19,8 @@ const WATER_ON = 's|ON';
1819
const HUMIDITY_WET = 'h|80';
1920
const TRACTOR_IDLE = 'd|IDLE';
2021

21-
const PIG_IDLE = 'd|AT_REST';
22-
const COW_IDLE = 'd|AT_REST';
22+
const PIG_IDLE = 'o|0|hide|o,x|d|AT_REST';
23+
const COW_IDLE = 'o|0|hide|o,x|d|AT_REST';
2324
const PIG_STATE = [
2425
'AT_REST',
2526
'FORAGING',
@@ -319,7 +320,6 @@ function fireAnimalCollars() {
319320

320321
function sendAnimalCollarReadings() {
321322
const deviceIds = myCache.keys();
322-
323323
_.forEach(deviceIds, (deviceId) => {
324324
getDeviceState(deviceId).then((state) => {
325325
const isSensor = true;
@@ -347,6 +347,9 @@ function sendAnimalCollarReadings() {
347347
}
348348
}
349349
state.s = getStatusCode(state.d);
350+
if (state.o) {
351+
state.o++;
352+
}
350353
setDeviceState(deviceId, toUltraLight(state), isSensor);
351354
break;
352355
case 'cow':
@@ -375,6 +378,9 @@ function sendAnimalCollarReadings() {
375378
}
376379
}
377380
state.s = getStatusCode(state.d);
381+
if (state.o) {
382+
state.o++;
383+
}
378384
setDeviceState(deviceId, toUltraLight(state), isSensor);
379385
break;
380386
default:
@@ -542,7 +548,7 @@ function setDeviceState(deviceId, state, isSensor = true, force = false) {
542548
if (isSensor && (state !== previousState || force)) {
543549
Northbound.sendMeasure(deviceId, payload);
544550
}
545-
551+
Writer.write(deviceId, state);
546552
Emitter.emit(deviceId, payload);
547553
}
548554

iot-devices/models/measure/json.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,19 @@ class JSONMeasure {
5959
this.headers['Content-Type'] = 'application/json';
6060
}
6161

62-
format(state) {
62+
format(state, hide = true) {
6363
const keyValuePairs = state.split('|');
6464
const obj = {};
6565
for (let i = 0; i < keyValuePairs.length; i = i + 2) {
6666
obj[keyValuePairs[i]] = keyValuePairs[i + 1];
6767
}
68-
const keys = (obj.hide || '').split(',');
69-
delete obj.hide;
70-
_.forEach(keys, function (key) {
71-
delete obj[key];
72-
});
68+
if (hide) {
69+
const keys = (obj.hide || '').split(',');
70+
delete obj.hide;
71+
_.forEach(keys, function (key) {
72+
delete obj[key];
73+
});
74+
}
7375
return JSON.stringify(obj);
7476
}
7577

iot-devices/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
},
1010
"scripts": {
1111
"start": "node ./bin/devices",
12-
"local": "PIG_COUNT=0 COW_COUNT=4 DEBUG=devices.* npm start",
12+
"local": "HISTORY_LOG=append.csv PIG_COUNT=0 COW_COUNT=4 DEBUG=devices.* npm start",
1313
"lint": "eslint . --cache --fix",
1414
"prettier": "prettier --parser flow --single-quote --write **/**/*.js **/*.js *.js"
1515
},

0 commit comments

Comments
 (0)