homebridge-easy-mqtt 1.5.0-beta.0 → 1.5.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ /*jshint esversion: 6,node: true,-W041: false */
2
+ 'use strict';
3
+
4
+ const DEBUG = true;
5
+
6
+ var fs = require('fs');
7
+ var os = require('os');
8
+ var path = require('path');
9
+ var hostname = os.hostname().split(".")[0];
10
+
11
+ // Not needed for homebridge-easy-mqtt
12
+ // var googleDrive = require('./lib/googleDrive').drive;
13
+
14
+ var fileSuffix = '_persist.json';
15
+
16
+ var thisStorage;
17
+
18
+ class FakeGatoStorage {
19
+ constructor(params) {
20
+ if (!params)
21
+ params = {};
22
+
23
+ this.writers = [];
24
+
25
+ this.log = params.log || {};
26
+ if (!this.log.debug) {
27
+ this.log.debug = DEBUG ? console.log : function () { };
28
+ }
29
+ thisStorage = this;
30
+ this.addingWriter = false;
31
+ }
32
+
33
+ addWriter(service, params) {
34
+ if (!this.addingWriter) {
35
+ this.addingWriter = true;
36
+ if (!params)
37
+ params = {};
38
+
39
+ this.log.debug("** Fakegato-storage AddWriter :", service.accessoryName);
40
+
41
+ let newWriter = {
42
+ 'service': service,
43
+ 'callback': params.callback,
44
+ 'storage': params.storage || 'fs',
45
+ 'fileName': params.filename || hostname + "_" + service.accessoryName + fileSuffix // Unique filename per homebridge server. Allows test environments on other servers not to break prod.
46
+ };
47
+ var onReady = typeof (params.onReady) == 'function' ? params.onReady : function () { }.bind(this);
48
+
49
+ switch (newWriter.storage) {
50
+ case 'fs':
51
+ newWriter.storageHandler = fs;
52
+ newWriter.path = params.path || path.join(os.homedir(), '.homebridge');
53
+ this.writers.push(newWriter);
54
+ this.addingWriter = false;
55
+ onReady();
56
+ break;
57
+ // Not needed for homebridge-easy-mqtt
58
+ // case 'googleDrive':
59
+ // newWriter.path = params.path || 'fakegato';
60
+ // newWriter.keyPath = params.keyPath || path.join(os.homedir(), '.homebridge');
61
+ // newWriter.storageHandler = new googleDrive({
62
+ // keyPath: newWriter.keyPath, callback: function () {
63
+ // this.addingWriter = false;
64
+ // onReady(arguments);
65
+ // }.bind(this), folder: newWriter.path
66
+ // });
67
+ // this.writers.push(newWriter);
68
+ // break;
69
+ /*
70
+ case 'memcached' :
71
+
72
+ break;
73
+ */
74
+ }
75
+ } else {
76
+ setTimeout(function () {
77
+ this.addWriter(service, params);
78
+ }.bind(this), 100);
79
+ }
80
+ }
81
+ getWriter(service) {
82
+ let findServ = function (element) {
83
+ return element.service === service;
84
+ };
85
+ return this.writers.find(findServ);
86
+ }
87
+ _getWriterIndex(service) {
88
+ let findServ = function (element) {
89
+ return element.service === service;
90
+ };
91
+ return this.writers.findIndex(findServ);
92
+ }
93
+ getWriters() {
94
+ return this.writers;
95
+ }
96
+ delWriter(service) {
97
+ let index = this._getWriterIndex(service);
98
+ this.writers.splice(index, 1);
99
+ }
100
+
101
+ write(params) { // must be asynchronous
102
+ if (!this.writing) {
103
+ this.writing = true;
104
+ let writer = this.getWriter(params.service);
105
+ let callBack = typeof (params.callback) == 'function' ? params.callback : (typeof (writer.callback) == 'function' ? writer.callback : function () { }); // use parameter callback or writer callback or empty function
106
+ switch (writer.storage) {
107
+ case 'fs':
108
+ this.log.debug("** Fakegato-storage write FS file:", path.join(writer.path, writer.fileName), params.data.substr(1, 80));
109
+ writer.storageHandler.writeFile(path.join(writer.path, writer.fileName), params.data, 'utf8', function () {
110
+ this.writing = false;
111
+ callBack(arguments);
112
+ }.bind(this));
113
+ break;
114
+ // Not needed for homebridge-easy-mqtt
115
+ // case 'googleDrive':
116
+ // this.log.debug("** Fakegato-storage write googleDrive file:", writer.path, writer.fileName, params.data.substr(1, 80));
117
+ // writer.storageHandler.writeFile(writer.path, writer.fileName, params.data, function () {
118
+ // this.writing = false;
119
+ // callBack(arguments);
120
+ // }.bind(this));
121
+ // break;
122
+ /*
123
+ case 'memcached' :
124
+
125
+ break;
126
+ */
127
+ }
128
+ } else {
129
+ setTimeout(function () { // retry in 100ms
130
+ this.write(params);
131
+ }.bind(this), 100);
132
+ }
133
+ }
134
+ read(params) {
135
+ let writer = this.getWriter(params.service);
136
+ let callBack = typeof (params.callback) == 'function' ? params.callback : (typeof (writer.callback) == 'function' ? writer.callback : function () { }); // use parameter callback or writer callback or empty function
137
+ switch (writer.storage) {
138
+ case 'fs':
139
+ this.log.debug("** Fakegato-storage read FS file:", path.join(writer.path, writer.fileName));
140
+ writer.storageHandler.readFile(path.join(writer.path, writer.fileName), 'utf8', callBack);
141
+ break;
142
+ // Not needed for homebridge-easy-mqtt
143
+ // case 'googleDrive':
144
+ // this.log.debug("** Fakegato-storage read googleDrive file: %s/%s", writer.path, writer.fileName);
145
+ // writer.storageHandler.readFile(writer.path, writer.fileName, callBack);
146
+ // break;
147
+ /*
148
+ case 'memcached' :
149
+
150
+ break;
151
+ */
152
+ }
153
+ }
154
+ remove(params) {
155
+ let writer = this.getWriter(params.service);
156
+ let callBack = typeof (params.callback) == 'function' ? params.callback : (typeof (writer.callback) == 'function' ? writer.callback : function () { }); // use parameter callback or writer callback or empty function
157
+ switch (writer.storage) {
158
+ case 'fs':
159
+ this.log.debug("** Fakegato-storage delete FS file:", path.join(writer.path, writer.fileName));
160
+ writer.storageHandler.unlink(path.join(writer.path, writer.fileName), callBack);
161
+ break;
162
+ // Not needed for homebridge-easy-mqtt
163
+ // case 'googleDrive':
164
+ // this.log.debug("** Fakegato-storage delete googleDrive file:", writer.path, writer.fileName);
165
+ // writer.storageHandler.deleteFile(writer.path, writer.fileName, callBack);
166
+ // break;
167
+ /*
168
+ case 'memcached' :
169
+
170
+ break;
171
+ */
172
+ }
173
+ }
174
+ }
175
+
176
+ module.exports = {
177
+ FakeGatoStorage: FakeGatoStorage
178
+ };
@@ -0,0 +1,133 @@
1
+ /*jshint esversion: 6,node: true,-W041: false */
2
+ 'use strict';
3
+
4
+ const DEBUG = true;
5
+
6
+ class FakeGatoTimer {
7
+ constructor(params) {
8
+ if (!params)
9
+ params = {};
10
+ this.subscribedServices = [];
11
+ this.minutes = params.minutes || 10;
12
+
13
+ this.intervalID = null;
14
+ this.running = false;
15
+ this.log = params.log || {};
16
+ if (!this.log.debug) {
17
+ this.log.debug = DEBUG ? console.log : function () { };
18
+ }
19
+ }
20
+
21
+ // Subscription management
22
+ subscribe(service, callback) {
23
+ this.log.debug("** Fakegato-timer Subscription :", service.accessoryName);
24
+ let newService = {
25
+ 'service': service,
26
+ 'callback': callback,
27
+ 'backLog': [],
28
+ 'previousBackLog': [],
29
+ 'previousAvrg': {}
30
+ };
31
+
32
+ this.subscribedServices.push(newService);
33
+ }
34
+ getSubscriber(service) {
35
+ let findServ = function (element) {
36
+ return element.service === service;
37
+ };
38
+ return this.subscribedServices.find(findServ);
39
+ }
40
+ _getSubscriberIndex(service) {
41
+ let findServ = function (element) {
42
+ return element.service === service;
43
+ };
44
+ return this.subscribedServices.findIndex(findServ);
45
+ }
46
+ getSubscribers() {
47
+ return this.subscribedServices;
48
+ }
49
+ unsubscribe(service) {
50
+ let index = this._getSubscriberIndex(service);
51
+ this.subscribedServices.splice(index, 1);
52
+ if (this.subscribedServices.length === 0 && this.running)
53
+ this.stop();
54
+ }
55
+
56
+ // Timer management
57
+ start() {
58
+ this.log.debug("**Start Global Fakegato-Timer - " + this.minutes + "min**");
59
+ if (this.running)
60
+ this.stop();
61
+ this.running = true;
62
+ this.intervalID = setInterval(this.executeCallbacks.bind(this), this.minutes * 60 * 1000);
63
+ }
64
+ stop() {
65
+ this.log.debug("**Stop Global Fakegato-Timer****");
66
+ clearInterval(this.intervalID);
67
+ this.running = false;
68
+ this.intervalID = null;
69
+ }
70
+
71
+ // Data management
72
+ executeCallbacks() {
73
+ this.log.debug("**Fakegato-timer: executeCallbacks**");
74
+ if (this.subscribedServices.length !== 0) {
75
+ for (let s in this.subscribedServices) {
76
+ if (this.subscribedServices.hasOwnProperty(s)) {
77
+
78
+ let service = this.subscribedServices[s];
79
+ if (typeof (service.callback) == 'function') {
80
+ service.previousAvrg = service.callback({
81
+ 'backLog': service.backLog,
82
+ 'previousAvrg': service.previousAvrg,
83
+ 'timer': this,
84
+ 'immediate': false
85
+ });
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ executeImmediateCallback(service) {
92
+ this.log.debug("**Fakegato-timer: executeImmediateCallback**");
93
+
94
+ if (typeof (service.callback) == 'function' && service.backLog.length)
95
+ service.callback({
96
+ 'backLog': service.backLog,
97
+ 'timer': this,
98
+ 'immediate': true
99
+ });
100
+ }
101
+ addData(params) {
102
+ let data = params.entry;
103
+ let service = params.service;
104
+ let immediateCallback = params.immediateCallback || false;
105
+
106
+ this.log.debug("**Fakegato-timer: addData ", service.accessoryName, data, " immediate: ", immediateCallback);
107
+
108
+ if (immediateCallback) // door or motion -> replace
109
+ this.getSubscriber(service).backLog[0] = data;
110
+ else
111
+ this.getSubscriber(service).backLog.push(data);
112
+
113
+ if (immediateCallback) {
114
+ //setTimeout(this.executeImmediateCallback.bind(this), 0,service);
115
+ this.executeImmediateCallback(this.getSubscriber(service));
116
+ }
117
+
118
+ if (this.running === false)
119
+ this.start();
120
+ }
121
+ emptyData(service) {
122
+ this.log.debug("**Fakegato-timer: emptyData **", service.accessoryName);
123
+ let source = this.getSubscriber(service);
124
+
125
+ if (source.backLog.length) source.previousBackLog = source.backLog;
126
+ source.backLog = [];
127
+ }
128
+
129
+ }
130
+
131
+ module.exports = {
132
+ FakeGatoTimer: FakeGatoTimer
133
+ };
@@ -0,0 +1,25 @@
1
+ // https://github.com/homebridge/HAP-NodeJS/blob/master/src/lib/util/uuid.ts
2
+
3
+ const VALID_UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4
+
5
+ function isValid(UUID) {
6
+ return VALID_UUID_REGEX.test(UUID);
7
+ }
8
+ const VALID_SHORT_REGEX = /^[0-9a-f]{1,8}$/i;
9
+
10
+ function toLongFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
11
+ if (isValid(uuid)) return uuid.toUpperCase();
12
+ if (!VALID_SHORT_REGEX.test(uuid)) throw new TypeError('uuid was not a valid UUID or short form UUID');
13
+ if (!isValid('00000000' + base)) throw new TypeError('base was not a valid base UUID');
14
+
15
+ return (('00000000' + uuid).substr(-8) + base).toUpperCase();
16
+ }
17
+
18
+ function toShortFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
19
+ uuid = toLongFormUUID(uuid, base);
20
+ return (uuid.substr(0, 8));
21
+ }
22
+
23
+ exports.isValid = isValid;
24
+ exports.toLongFormUUID = toLongFormUUID;
25
+ exports.toShortFormUUID = toShortFormUUID;
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "fakegato-history",
3
+ "version": "0.6.7",
4
+ "main": "fakegato-history.js"
5
+ }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName": "Homebridge Easy MQTT",
5
5
  "description": "Homebridge plugin for easy control of MQTT devices",
6
6
  "type": "module",
7
- "version": "1.5.0-beta.0",
7
+ "version": "1.5.0-beta.2",
8
8
  "homepage": "https://github.com/mpatfield/homebridge-easy-mqtt#readme",
9
9
  "repository": {
10
10
  "type": "git",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@homebridge/plugin-ui-utils": "^2.0.2",
43
- "fakegato-history": "^0.6.7",
43
+ "fakegato-history": "file:./lib/fakegato-history",
44
44
  "homebridge-lib": "^7.1.6",
45
45
  "lodash.merge": "^4.6.2",
46
46
  "mqtt": "^5.7.0",