forked from stjohnjohnson/mqtt-dasher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
114 lines (99 loc) · 3.29 KB
/
server.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
/*jslint node: true */
'use strict';
var winston = require('winston'),
path = require('path'),
fs = require('fs'),
yaml = require('js-yaml'),
async = require('async'),
mqtt = require('mqtt'),
fs = require('fs'),
DashButton = require('node-dash-button');
var CONFIG_DIR = process.env.CONFIG_DIR || process.cwd(),
CONFIG_FILE = path.join(CONFIG_DIR, 'config.yml'),
SAMPLE_FILE = path.join(__dirname, '_config.yml'),
CURRENT_VERSION = require('./package').version;
var config,
buttons = {},
broker,
timeouts = {};
// Show Debug logs in console
winston.level = 'debug';
/**
* Load user configuration (or create it)
* @method loadConfiguration
* @return {Object} Configuration
*/
function loadConfiguration () {
if (!fs.existsSync(CONFIG_FILE)) {
fs.writeFileSync(CONFIG_FILE, fs.readFileSync(SAMPLE_FILE));
}
return yaml.safeLoad(fs.readFileSync(CONFIG_FILE));
}
/**
* Notify the broker that something triggered
* @method notifyMQTT
* @param {String} topic Topic to message
* @param {Boolean} value Value to set (ON, OFF)
*/
function notifyMQTT (topic, value) {
var state = value ? 'active': 'inactive';
winston.debug('Notifying MQTT %s with %s', topic, state);
broker.publish(topic, state, {
retain: true
}, function (err) {
if (err) {
winston.error('Error notifying MQTT', err);
}
});
}
/**
* Handle an events from the Amazon Dash
* @method buttonEvent
* @param {String} mac Mac Address (identifier)
* @param {String} topic MQTT topic to write to
*/
function buttonEvent (mac, topic) {
winston.info('Button press detected on %s for %s', mac, topic);
// Auto-clear action after 10 seconds
clearTimeout(timeouts[topic]);
timeouts[topic] = setTimeout(notifyMQTT.bind(null, topic, false), 10000);
// Notify MQTT
notifyMQTT(topic, true);
}
// Main flow
async.series([
function loadFromDisk (next) {
winston.info('Starting MQTT Amazon Dash - v%s', CURRENT_VERSION);
winston.info('Loading configuration');
config = loadConfiguration();
process.nextTick(next);
},
function connectToMQTT (next) {
winston.info('Connecting to MQTT at mqtt://%s', config.mqtt.host);
var mqtt_broker_options = config.mqtt;
broker = mqtt.connect(mqtt_broker_options);
broker.on('connect', function () {
next();
// @TODO Not call this twice if we get disconnected
next = function () {};
});
},
function setupButtons (next) {
winston.info('Listening for %d buttons', Object.keys(config.buttons).length);
Object.keys(config.buttons).forEach(function (macAddress) {
var button = config.buttons[macAddress];
var topic = button.name;
if (config.mqtt.preface) {
topic = config.mqtt.preface + '/' + topic;
}
buttons[macAddress] = DashButton(macAddress, button.interface, button.timeout, button.protocol);
buttons[macAddress].on('detected', buttonEvent.bind(null, macAddress, topic));
});
process.nextTick(next);
}
], function (error) {
if (error) {
return winston.error(error);
}
winston.info('Waiting for dash buttons to be pressed');
});