From 52eb8072664a61ea61dbdbef7485d6c81dbbcfe9 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 18 Oct 2015 18:10:20 +0200 Subject: o Dropping the app concept. o Switching to pg-promise to not get overloaded by callbacks. --- src/Diller.js | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DillerDao.js | 47 ++++++++++++++++++++++++++ src/config.js | 12 +++++-- 3 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 src/Diller.js create mode 100644 src/DillerDao.js (limited to 'src') diff --git a/src/Diller.js b/src/Diller.js new file mode 100644 index 0000000..9a1de23 --- /dev/null +++ b/src/Diller.js @@ -0,0 +1,101 @@ +var DillerDao = require('./DillerDao'); +var pgp = require('pg-promise')(); + +function Diller(config, log) { + + function newValue(dao, device, property, value) { + log.info('new value for device ' + device.key + '/' + property.key + ' = ' + value, { + deviceId: device.id, + propertyId: property.id, + value: value + }); + + return dao.insertValue(property.id, value); + } + + function newName(dao, device, property, name) { + log.info('New name for property ', device.key + '/' + property.key + '.name = ' + name); + + return dao.updatePropertyName(property.id, name); + } + + function newDescription(dao, device, property, description) { + log.info('New description for property ', device.key + '/' + property.key + '.description = ' + description); + + return dao.updatePropertyDescription(property.id, description); + } + + function onMessage(topic, message, payload) { + var parts = topic.split(/\//); + + log.info('Processing message to ' + topic); + + // /diller/5c:cf:7f:06:59:a5/sensors/temp-0/value + + if (parts[3] == 'sensors') { + parts[3] = 'property'; + } + + if (parts.length != 6 || parts[1] != 'diller' || parts[3] != 'property') { + log.warn('no match: ', topic, parts); + return; + } + + var device_key = parts[2]; + var property_key = parts[4]; + var msg_type = parts[5]; + + var f; + if (msg_type == 'value') { + f = newValue + } else if (msg_type == 'name') { + f = newName + } else if (msg_type == 'description') { + f = newDescription + } + + if (!f) { + log.warn('Unknown message topic:', topic); + return; + } + + return pgp(config.postgresqlConfig) + .tx(function (pg) { + var dao = new DillerDao(pg); + + return dao.deviceByKey(device_key) + .then(function (device) { + return device || dao.insertDevice(device_key).then(function (device) { + log.info('New device created', {device_key: device_key, id: device.id}); + return device; + }); + }) + .then(function (device) { + return dao.devicePropertyByDeviceIdAndKey(device.id, property_key).then(function (property) { + var ret = {device: device, property: property}; + return (property && ret) || dao.insertDeviceProperty(device.id, property_key).then(function (p) { + log.info('Created new device property', {id: p.id, key: p.key}); + ret.property = p; + return ret; + }); + }); + }) + .then(function (data) { + return f(dao, data.device, data.property, message.toString()); + }); + }).then(function (res) { + log.warn('success', res); + }, function (res) { + log.warn('fail', res); + }); + } + + return { + onMessage: onMessage + } +} + +//noinspection JSUnresolvedVariable +module.exports = { + Diller: Diller +}; diff --git a/src/DillerDao.js b/src/DillerDao.js new file mode 100644 index 0000000..ed6fcf0 --- /dev/null +++ b/src/DillerDao.js @@ -0,0 +1,47 @@ +function DillerDao(client) { + + var deviceColumns = 'id, key, created_timestamp'; + var propertyColumns = 'id, device, key, created_timestamp'; + + function deviceByKey(key) { + return client.oneOrNone("SELECT " + deviceColumns + " FROM device WHERE key=$1", key); + } + + function insertDevice(key) { + return client.one("INSERT INTO device(id, key, created_timestamp) VALUES(DEFAULT, $1, CURRENT_TIMESTAMP) RETURNING " + deviceColumns, key); + } + + function devicePropertyByDeviceIdAndKey(deviceId, key) { + return client.oneOrNone('SELECT id FROM device_property WHERE device=$1 AND key=$2', [deviceId, key]); + } + + function insertDeviceProperty(deviceId, key) { + return client.oneOrNone('INSERT INTO device_property(id, device, key, created_timestamp) VALUES(DEFAULT, $1, $2, CURRENT_TIMESTAMP) RETURNING ' + propertyColumns, [deviceId, key]); + } + + function updatePropertyName(id, name) { + return client.none('UPDATE device_property SET name=$1 WHERE id=$2', name, id); + } + + function updatePropertyDescription(id, description) { + return client.none('UPDATE device_property SET description=$1 WHERE id=$2', description, id); + } + + function insertValue(propertyId, value) { + return client.none('INSERT INTO value(property, timestamp, value) VALUES($1, CURRENT_TIMESTAMP, $2)', [propertyId, value]); + } + + return { + deviceByKey: deviceByKey, + insertDevice: insertDevice, + + devicePropertyByDeviceIdAndKey: devicePropertyByDeviceIdAndKey, + insertDeviceProperty: insertDeviceProperty, + updatePropertyName: updatePropertyName, + updatePropertyDescription: updatePropertyDescription, + + insertValue: insertValue + } +} + +module.exports = DillerDao; diff --git a/src/config.js b/src/config.js index 949c284..a80fceb 100644 --- a/src/config.js +++ b/src/config.js @@ -3,10 +3,16 @@ function isProd() { } var mqttUrl = process.env.MQTT_URL || 'mqtt://trygvis.io'; -var postgresqlUrl = process.env.DATABASE_URL || 'postgres://diller:diller@localhost:5432/diller'; +//var postgresqlUrl = process.env.DATABASE_URL || 'postgres://diller:diller@localhost:5432/diller'; +var postgresqlConfig = { + host: process.env.DB_HOST || '/var/run/postgresql', + database: process.env.DB_DATABASE || 'diller', + user: process.env.DB_USER || 'diller', + password: process.env.DB_PASSWORD || 'diller' +}; module.exports = { isProd: isProd, mqttUrl: mqttUrl, - postgresqlUrl: postgresqlUrl -} + postgresqlConfig: postgresqlConfig +}; -- cgit v1.2.3