forked from BrianHepler/MMM-WeasleyClock
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode_helper.js
More file actions
215 lines (178 loc) · 6.53 KB
/
node_helper.js
File metadata and controls
215 lines (178 loc) · 6.53 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/* eslint-disable no-trailing-spaces */
/* Magic Mirror
* Node Helper: MMM-WeasleyClock
*
* By {{AUTHOR_NAME}}
* {{LICENSE}} Licensed.
*/
var NodeHelper = require("node_helper");
const mqtt = require("mqtt");
const fs = require("fs");
const {Howl, Howler} = require("howler");
var client;
module.exports = NodeHelper.create({
// Initialize MQTT connection object
start: function() {
// var client = new Messaging.Client()
},
stop: function() {
this.client.end();
this.client = null;
},
/* socketNotificationReceived(notification, payload)
* This method is called when a socket notification arrives.
*
* argument notification string - The identifier of the noitication.
* argument payload mixed - The payload of the notification.
*/
socketNotificationReceived: function(notification, payload) {
console.log("Weasley clock node helper received notifications: " + notification);
if(notification === "MMM-WeasleyClock-CONFIG") {
this.establishConnection(payload);
}
if (notification === "MMM-WeasleyClock-START") {
if (payload.debug) { console.log("Starting Weasley Clock message client. Notification:", notification, "payload: ", payload); }
// Send notification
this.sendNotificationTest(this.anotherFunction());
}
// save this for later. Perhaps provide long/lat regions for push to phones.
if (notification === "MMM-WeasleyClock-UPDATECLIENTS") {
if (payload.debug) { console.log("Updating clients."); }
// this.updateClients(payload);
}
// possibly this will never be used
if (notification === "MMM-WeasleyClock-PLAYSOUND") {
if (payload.debug) { console.log("Playing sound effect."); }
this.playSound(payload);
}
},
establishConnection: function(config) {
var subTopic = "owntracks/" + config.uniqueId;
if (this.client == null) {
this.client = this.getMQTTClient(config);
// handle the events from the MQTT server
this.client.on("connect", ()=> {
console.debug("Subscribing to all content for uniqueID " + subTopic);
this.client.subscribe(subTopic + "/+");
this.client.subscribe(subTopic + "/+/event");
this.client.on("message", (topic, message) => {
console.log ("message received in topic " + topic);
var msgObj = JSON.parse(message.toString());
this.handleMessage(config, topic, msgObj);
});
});
this.client.on("error", function(error) {
console.error("Can't connect." + error);
process.exit(1);
});
}
},
/**
* Creates an MQTT client object configured for a connection.
* @param {Object} config The configuration object as modified by the user
*/
getMQTTClient: function(config) {
console.log("establishing mqtt connection using uniqueId: " + config.uniqueId);
var caFile = fs.readFileSync(this.path + "/weasley_mirror_ca.crt");
var options = {
clientId: "mirror-" + config.uniqueId,
username: config.uniqueId,
password: "Get_Out_Of_My_Code",
rejectUnauthorized: false,
host: config.host,
port: config.port,
clean: true,
ca: caFile
};
console.debug(options);
client = mqtt.connect("mqtts://" + config.host, options);
return client;
},
// Process the messages received by the client
handleMessage: function(config, topic, message) {
console.debug(message);
if (message == null) {
console.error("Null value from MQTT server.");
}
// extract person from path
var topicArray = topic.split("/");
var person = topicArray[topicArray.length - 1];
console.debug("Parsing message for '" + person + "'");
message.person = person;
// valid _type are: beacon, card, cmd, configuration, encrypted, location, lwt, steps, transition, waypoint, waypoints
console.debug("processing message type: " + message._type);
switch (message._type) {
case "waypoint": console.debug("New Waypoint detected");
this.sendSocketNotification("MMM-WeasleyClock-WAYPOINT", message);
break;
case "location": console.debug("location detected");
this.processLocation(config, message);
break;
case "transition": console.debug("transition event detected.");
this.processTransition(config, message);
break;
case "lwt": console.debug("LWT event detected.");
// var options = { key : message.tid, location: "lost"};
// sendSocketNotification("MMM-WeasleyMirror-LOST", options);
this.sendSocketNotification("MMM-WeasleyClock-LOST", message);
break;
default: console.debug("Event received but not processed.");
}
},
/**
* Processes the location messages. Looks for a high velocity and a location.
* Currently, location takes precedence over velocity, so if you're driving
* past a location, it will mark you as in that location instead of traveling.
* @param {*} config Configuration object passed in from the module.
* @param {*} message Message received from the MQTT server.
*/
processLocation: function(config, message) {
var vel = message.vel;
console.debug("Traveling at " + vel);
// check for region
if (message.inregions) {
console.log(message.person + " is in region '" + message.inregions + "'");
this.sendSocketNotification("MMM-WeasleyClock-UPDATE", message);
} else if (vel > 10) {
console.log("Mark " + message.person + " as traveling");
this.sendSocketNotification("MMM-WeasleyClock-TRAVELING", message);
}
},
// Looks for module location match with transition message.
// Note: transition messages put regions in the "desc" field.
processTransition: function(config, message) {
var event = message.event;
if (event == "enter") {
console.debug(message.person + " has entered region(s) '" + message.desc +"'");
message.inregions = new Array(message.desc);
this.sendSocketNotification("MMM-WeasleyClock-UPDATE", message);
} else {
console.debug(message.person + " has just left '" + message.inregions + "'");
this.sendSocketNotification("MMM-WeasleyClock-TRAVELING", message);
}
//TODO: add notification noise to signal change in state.
},
playSound: function (config) {
// are we gonna do this?
var filename = "/sounds/crank-n-chimes.mp3";
let soundfile = this.path + filename;
// Make sure file exists before playing
try {
fs.accessSync(soundfile, fs.F_OK);
console.debug("Playing " + soundfile);
// new Audic(soundfile.toString()).play();
// var howl = new Howl([this.path + "\sounds\crank-n-chimes.mp3",this.path + "\sounds\crank-n-chimes.wav"]);
var howl = new Howl(
{
src:[soundfile],
onend: function() {
console.log("Finished playback.");
}
});
} catch (e) {
// Custom sequence doesn't exist
console.debug("Sound does not exist: " + soundfile);
return;
}
},
});