@victronenergy/mfd-modules 9.4.0 → 9.5.0
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.
|
@@ -12,10 +12,65 @@ export declare class MqttStore {
|
|
|
12
12
|
keepAliveHandlerRef: any;
|
|
13
13
|
queueWorker: any;
|
|
14
14
|
meanQueueWorkerPassDuration: number;
|
|
15
|
+
urgentTopicPrefixes: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Returns the current cached message for a given MQTT topic.
|
|
18
|
+
*
|
|
19
|
+
* React Components using this method will re-render when their specific
|
|
20
|
+
* topic's message changes.
|
|
21
|
+
*
|
|
22
|
+
* Using comparer.identity will trigger the re-renders any time
|
|
23
|
+
* a message arrives for the given topic. We rely on the fact
|
|
24
|
+
* that MQTT will only re-send a message when the value changes,
|
|
25
|
+
* or on a full keep alive.
|
|
26
|
+
*
|
|
27
|
+
* Note: Receiving the same message for a given topic will cause re-renders,
|
|
28
|
+
* as we do not check structural identity of the message.
|
|
29
|
+
*
|
|
30
|
+
* @param topic - The MQTT topic to retrieve the message for
|
|
31
|
+
* @returns The message object for the topic, or undefined if topic is not provided or not found
|
|
32
|
+
*/
|
|
15
33
|
messageFromTopic: (topic?: string) => MqttMessage;
|
|
34
|
+
/**
|
|
35
|
+
* Returns the current cached messages for a given set of MQTT topics.
|
|
36
|
+
*
|
|
37
|
+
* This is a memoized computed function - each set of topics has its own cached value.
|
|
38
|
+
*
|
|
39
|
+
* React Components using this method will re-render when
|
|
40
|
+
* any of the messages for specified topics change.
|
|
41
|
+
*
|
|
42
|
+
* Using comparer.identity will trigger the re-renders any time
|
|
43
|
+
* a message arrives for any of the specified topics. We rely on the fact
|
|
44
|
+
* that MQTT will only re-send a message when the value changes,
|
|
45
|
+
* or on a full keep alive.
|
|
46
|
+
|
|
47
|
+
* Note: Receiving the same message for a given topic will cause re-renders,
|
|
48
|
+
* as we do not check structural identity of the message.
|
|
49
|
+
*
|
|
50
|
+
* @param topics - The MQTT topics to retrieve the messages for
|
|
51
|
+
* @returns The messages objects for the given topics, or empty dictionary if topics not found
|
|
52
|
+
*/
|
|
16
53
|
messagesByTopics: (topics?: Topics) => {
|
|
17
54
|
[key: string]: MqttMessage | MqttMessage[];
|
|
18
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* Returns the current cached messages for MQTT topics specified via regex.
|
|
58
|
+
*
|
|
59
|
+
* React Components using this method will re-render when
|
|
60
|
+
* values of any of the matched topics change. The components also re-render
|
|
61
|
+
* when new MQTT topics are received and match needs to be checked.
|
|
62
|
+
*
|
|
63
|
+
* Using comparer.identity will trigger the re-renders any time
|
|
64
|
+
* a message arrives for any of the matched topics. We rely on the fact
|
|
65
|
+
* that MQTT will only re-send a message when the value changes,
|
|
66
|
+
* or on a full keep alive.
|
|
67
|
+
*
|
|
68
|
+
* Note: Receiving the same message for a given topic will cause re-renders,
|
|
69
|
+
* as we do not check structural identity of the message.
|
|
70
|
+
*
|
|
71
|
+
* @param wildcard - The MQTT wildcard to retrieve the message for
|
|
72
|
+
* @returns The messages objects for the given topics, or empty dictionary if topics not found
|
|
73
|
+
*/
|
|
19
74
|
messagesByWildcard: (wildcard?: string) => any;
|
|
20
75
|
constructor();
|
|
21
76
|
get isConnected(): boolean;
|
|
@@ -23,8 +78,8 @@ export declare class MqttStore {
|
|
|
23
78
|
clearSubscribedTopics(): void;
|
|
24
79
|
addMessage: (topic: string, message: {
|
|
25
80
|
value: string | null;
|
|
26
|
-
}) =>
|
|
27
|
-
addMessagesFromQueue: () =>
|
|
81
|
+
}) => void;
|
|
82
|
+
addMessagesFromQueue: () => void;
|
|
28
83
|
scheduleNextQueueWorkerPass: (timeout: number) => void;
|
|
29
84
|
setupQueueWorker: () => void;
|
|
30
85
|
removeQueueWorker: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mqtt.store.d.ts","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,qBAAqB,EAAE,UAAU,EAAC,MAAM,MAAM,CAAA;AACtD,OAAO,EAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAU,MAAM,EAAC,MAAM,SAAS,CAAA;AAQ3E,qBAAa,SAAS;IAClB,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAoB;IAClC,QAAQ,EAAE,YAAY,CAAK;IAC3B,YAAY,EAAE,YAAY,CAAK;IAC/B,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAoB;IACjD,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,MAAM,CAA0C;IAC1D,mBAAmB,EAAE,GAAG,CAAA;IACxB,WAAW,EAAE,GAAG,CAAA;IAChB,2BAA2B,EAAE,MAAM,CAAI;
|
|
1
|
+
{"version":3,"file":"Mqtt.store.d.ts","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,qBAAqB,EAAE,UAAU,EAAC,MAAM,MAAM,CAAA;AACtD,OAAO,EAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAU,MAAM,EAAC,MAAM,SAAS,CAAA;AAQ3E,qBAAa,SAAS;IAClB,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAoB;IAClC,QAAQ,EAAE,YAAY,CAAK;IAC3B,YAAY,EAAE,YAAY,CAAK;IAC/B,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAoB;IACjD,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,MAAM,CAA0C;IAC1D,mBAAmB,EAAE,GAAG,CAAA;IACxB,WAAW,EAAE,GAAG,CAAA;IAChB,2BAA2B,EAAE,MAAM,CAAI;IACvC,mBAAmB,EAAE,MAAM,EAAE,CAAK;IAElC;;;;;;;;;;;;;;;;QAgBI;IACJ,gBAAgB,WAAuB,MAAM,iBAIyB;IAEtE;;;;;;;;;;;;;;;;;;QAkBI;IACJ,gBAAgB,YAAwB,MAAM;;MAoBwB;IAEtE;;;;;;;;;;;;;;;;;QAiBI;IACJ,kBAAkB,cAA0B,MAAM,SAiBsB;;IAmBxE,IAAI,WAAW,YAEd;IAED,gBAAgB,GAAI,QAAQ,MAAM,UAmBjC;IAED,qBAAqB;IAMrB,UAAU,GAAI,OAAO,MAAM,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,UAW7D;IAED,oBAAoB,aAOnB;IAED,2BAA2B,GAAI,SAAS,MAAM,UAW7C;IAED,gBAAgB,aAKf;IAED,iBAAiB,aAKhB;IAED,WAAW,GAAI,UAAU,MAAM,UAK9B;IAED,SAAS,CAAC,MAAM,EAAE,MAAM;IAIxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;IAIvC,IAAI,GACA,UAAU,MAAM,EAChB,MAAM,MAAM,YAAc,EAC1B,MAAM,MAAM,GAAG,IAAI,EACnB,OAAM,MAAyB,EAC/B,SAAQ,OAAe,EACvB,WAAW,MAAM,UAkGpB;IAED,oBAAoB,aA4BnB;IAED,uBAAuB,aAStB;IAED,iBAAiB,aAQhB;IAED,mBAAmB,aAMlB;IAED,mBAAmB,aAMlB;IAED,OAAO,GAAI,OAAO,MAAM,EAAE,MAAM,MAAM,GAAG,MAAM,EAAE,UAAU,qBAAqB,UAS/E;CACJ;AA2BD,wBAAgB,OAAO,cAEtB"}
|
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
-
function step(op) {
|
|
15
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
-
switch (op[0]) {
|
|
20
|
-
case 0: case 1: t = op; break;
|
|
21
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
-
default:
|
|
25
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
-
if (t[2]) _.ops.pop();
|
|
30
|
-
_.trys.pop(); continue;
|
|
31
|
-
}
|
|
32
|
-
op = body.call(thisArg, _);
|
|
33
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
1
|
import { comparer, makeAutoObservable, runInAction } from "mobx";
|
|
38
2
|
import { computedFn } from "mobx-utils";
|
|
39
3
|
import * as mqtt from "mqtt";
|
|
@@ -112,10 +76,29 @@ var MqttStore = /** @class */ (function () {
|
|
|
112
76
|
writable: true,
|
|
113
77
|
value: 0
|
|
114
78
|
});
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
79
|
+
Object.defineProperty(this, "urgentTopicPrefixes", {
|
|
80
|
+
enumerable: true,
|
|
81
|
+
configurable: true,
|
|
82
|
+
writable: true,
|
|
83
|
+
value: []
|
|
84
|
+
});
|
|
85
|
+
/**
|
|
86
|
+
* Returns the current cached message for a given MQTT topic.
|
|
87
|
+
*
|
|
88
|
+
* React Components using this method will re-render when their specific
|
|
89
|
+
* topic's message changes.
|
|
90
|
+
*
|
|
91
|
+
* Using comparer.identity will trigger the re-renders any time
|
|
92
|
+
* a message arrives for the given topic. We rely on the fact
|
|
93
|
+
* that MQTT will only re-send a message when the value changes,
|
|
94
|
+
* or on a full keep alive.
|
|
95
|
+
*
|
|
96
|
+
* Note: Receiving the same message for a given topic will cause re-renders,
|
|
97
|
+
* as we do not check structural identity of the message.
|
|
98
|
+
*
|
|
99
|
+
* @param topic - The MQTT topic to retrieve the message for
|
|
100
|
+
* @returns The message object for the topic, or undefined if topic is not provided or not found
|
|
101
|
+
*/
|
|
119
102
|
Object.defineProperty(this, "messageFromTopic", {
|
|
120
103
|
enumerable: true,
|
|
121
104
|
configurable: true,
|
|
@@ -126,10 +109,25 @@ var MqttStore = /** @class */ (function () {
|
|
|
126
109
|
return topic ? _this.messages[topic] : undefined;
|
|
127
110
|
}, { name: "Mqtt.store.messageFromTopic", equals: comparer.identity })
|
|
128
111
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Returns the current cached messages for a given set of MQTT topics.
|
|
114
|
+
*
|
|
115
|
+
* This is a memoized computed function - each set of topics has its own cached value.
|
|
116
|
+
*
|
|
117
|
+
* React Components using this method will re-render when
|
|
118
|
+
* any of the messages for specified topics change.
|
|
119
|
+
*
|
|
120
|
+
* Using comparer.identity will trigger the re-renders any time
|
|
121
|
+
* a message arrives for any of the specified topics. We rely on the fact
|
|
122
|
+
* that MQTT will only re-send a message when the value changes,
|
|
123
|
+
* or on a full keep alive.
|
|
124
|
+
|
|
125
|
+
* Note: Receiving the same message for a given topic will cause re-renders,
|
|
126
|
+
* as we do not check structural identity of the message.
|
|
127
|
+
*
|
|
128
|
+
* @param topics - The MQTT topics to retrieve the messages for
|
|
129
|
+
* @returns The messages objects for the given topics, or empty dictionary if topics not found
|
|
130
|
+
*/
|
|
133
131
|
Object.defineProperty(this, "messagesByTopics", {
|
|
134
132
|
enumerable: true,
|
|
135
133
|
configurable: true,
|
|
@@ -156,16 +154,24 @@ var MqttStore = /** @class */ (function () {
|
|
|
156
154
|
return result;
|
|
157
155
|
}, { name: "Mqtt.store.messagesByTopics", equals: comparer.identity })
|
|
158
156
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Returns the current cached messages for MQTT topics specified via regex.
|
|
159
|
+
*
|
|
160
|
+
* React Components using this method will re-render when
|
|
161
|
+
* values of any of the matched topics change. The components also re-render
|
|
162
|
+
* when new MQTT topics are received and match needs to be checked.
|
|
163
|
+
*
|
|
164
|
+
* Using comparer.identity will trigger the re-renders any time
|
|
165
|
+
* a message arrives for any of the matched topics. We rely on the fact
|
|
166
|
+
* that MQTT will only re-send a message when the value changes,
|
|
167
|
+
* or on a full keep alive.
|
|
168
|
+
*
|
|
169
|
+
* Note: Receiving the same message for a given topic will cause re-renders,
|
|
170
|
+
* as we do not check structural identity of the message.
|
|
171
|
+
*
|
|
172
|
+
* @param wildcard - The MQTT wildcard to retrieve the message for
|
|
173
|
+
* @returns The messages objects for the given topics, or empty dictionary if topics not found
|
|
174
|
+
*/
|
|
169
175
|
Object.defineProperty(this, "messagesByWildcard", {
|
|
170
176
|
enumerable: true,
|
|
171
177
|
configurable: true,
|
|
@@ -216,52 +222,49 @@ var MqttStore = /** @class */ (function () {
|
|
|
216
222
|
enumerable: true,
|
|
217
223
|
configurable: true,
|
|
218
224
|
writable: true,
|
|
219
|
-
value: function (topic, message) {
|
|
220
|
-
var _a;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
value: function (topic, message) {
|
|
226
|
+
var _a, _b;
|
|
227
|
+
// Logger.log(`DEBUG: addMessage: topic: ${topic}, urgentPrefixes: ${JSON.stringify(this.urgentTopicPrefixes)}`)
|
|
228
|
+
if (_this.urgentTopicPrefixes.some(function (prefix) { return topic.startsWith(prefix); })) {
|
|
229
|
+
Logger.log("DEBUG: addMessage: topic: ".concat(topic));
|
|
230
|
+
// NOTE: If topic starts with one of the urgent prefixes, deliver it immediately
|
|
231
|
+
_this.messages[topic] = (_a = message.value) !== null && _a !== void 0 ? _a : undefined;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// NOTE: Otherwise store message to the queue, and move messages from the queue
|
|
235
|
+
// NOTE: to the React components that are MobX observers periodically and in batches
|
|
236
|
+
_this.messageQueue[topic] = (_b = message.value) !== null && _b !== void 0 ? _b : undefined;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
226
239
|
});
|
|
227
240
|
Object.defineProperty(this, "addMessagesFromQueue", {
|
|
228
241
|
enumerable: true,
|
|
229
242
|
configurable: true,
|
|
230
243
|
writable: true,
|
|
231
|
-
value: function () {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return [2 /*return*/];
|
|
240
|
-
});
|
|
241
|
-
}); }
|
|
244
|
+
value: function () {
|
|
245
|
+
if (Object.values(_this.messageQueue).length > 0) {
|
|
246
|
+
// Logger.log(`DEBUG: addMessagesFromQueue: in queue: ${JSON.stringify(Object.values(this.messageQueue).length)}`)
|
|
247
|
+
assign(_this.messages, _this.messageQueue);
|
|
248
|
+
// Logger.log(`DEBUG: addMessagesFromQueue: to process: ${JSON.stringify(Object.values(this.messages).length)}`)
|
|
249
|
+
_this.messageQueue = {};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
242
252
|
});
|
|
243
253
|
Object.defineProperty(this, "scheduleNextQueueWorkerPass", {
|
|
244
254
|
enumerable: true,
|
|
245
255
|
configurable: true,
|
|
246
256
|
writable: true,
|
|
247
257
|
value: function (timeout) {
|
|
248
|
-
_this.queueWorker = setTimeout(function () {
|
|
249
|
-
var started
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
this.meanQueueWorkerPassDuration = addToMean(this.meanQueueWorkerPassDuration, 10, ended - started);
|
|
259
|
-
newTimeout = Math.max(1000, Math.min(this.meanQueueWorkerPassDuration * 50, 3000));
|
|
260
|
-
this.scheduleNextQueueWorkerPass(newTimeout);
|
|
261
|
-
return [2 /*return*/];
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
}); }, timeout);
|
|
258
|
+
_this.queueWorker = setTimeout(function () {
|
|
259
|
+
var started = performance.now();
|
|
260
|
+
_this.addMessagesFromQueue();
|
|
261
|
+
var ended = performance.now();
|
|
262
|
+
_this.meanQueueWorkerPassDuration = addToMean(_this.meanQueueWorkerPassDuration, 10, ended - started);
|
|
263
|
+
// Schedule next update after 1 - 3 seconds
|
|
264
|
+
// depending on how fast we were able to process the incoming messages
|
|
265
|
+
var newTimeout = Math.max(1000, Math.min(_this.meanQueueWorkerPassDuration * 50, 3000));
|
|
266
|
+
_this.scheduleNextQueueWorkerPass(newTimeout);
|
|
267
|
+
}, timeout);
|
|
265
268
|
}
|
|
266
269
|
});
|
|
267
270
|
Object.defineProperty(this, "setupQueueWorker", {
|
|
@@ -291,6 +294,9 @@ var MqttStore = /** @class */ (function () {
|
|
|
291
294
|
writable: true,
|
|
292
295
|
value: function (portalId) {
|
|
293
296
|
_this.portalId = portalId;
|
|
297
|
+
_this.urgentTopicPrefixes = [
|
|
298
|
+
"N/".concat(portalId, "/switch/"),
|
|
299
|
+
];
|
|
294
300
|
}
|
|
295
301
|
});
|
|
296
302
|
Object.defineProperty(this, "boot", {
|
|
@@ -308,6 +314,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
308
314
|
_this.client = undefined;
|
|
309
315
|
_this.portalId = undefined;
|
|
310
316
|
_this.topicsSubscribed = new Set();
|
|
317
|
+
_this.urgentTopicPrefixes = [];
|
|
311
318
|
}
|
|
312
319
|
var url;
|
|
313
320
|
if (remote) {
|
|
@@ -361,39 +368,27 @@ var MqttStore = /** @class */ (function () {
|
|
|
361
368
|
_this.setupKeepaliveTimer();
|
|
362
369
|
});
|
|
363
370
|
});
|
|
364
|
-
client.on("message", function (topic, message) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
// Logger.log(`DEBUG: Message received: ${topic} - ${message.toString()}`)
|
|
371
|
-
if (topic.endsWith("/system/0/Serial") && !this.portalId) {
|
|
372
|
-
portalId_1 = getMessageJson(message).value;
|
|
373
|
-
if (this.portalId !== portalId_1 && portalId_1 !== undefined) {
|
|
374
|
-
this.setPortalId(portalId_1);
|
|
375
|
-
}
|
|
376
|
-
runInAction(function () { return _this.subscribeToAllTopics(); });
|
|
377
|
-
}
|
|
378
|
-
if (!topic.endsWith("full_publish_completed")) return [3 /*break*/, 2];
|
|
379
|
-
uniqueId = getMessageJson(message)["full-publish-completed-echo"] || "";
|
|
380
|
-
Logger.log("Received full_publish_completed for ".concat(this.portalId, " with full-publish-completed-echo: '").concat(uniqueId, "'"));
|
|
381
|
-
if (!(uniqueId === this.uniqueId)) return [3 /*break*/, 2];
|
|
382
|
-
return [4 /*yield*/, this.addMessagesFromQueue()];
|
|
383
|
-
case 1:
|
|
384
|
-
_a.sent();
|
|
385
|
-
this.setupQueueWorker();
|
|
386
|
-
_a.label = 2;
|
|
387
|
-
case 2:
|
|
388
|
-
if (!(message.toString() !== "")) return [3 /*break*/, 4];
|
|
389
|
-
return [4 /*yield*/, this.addMessage(topic, getMessageJson(message))];
|
|
390
|
-
case 3:
|
|
391
|
-
_a.sent();
|
|
392
|
-
_a.label = 4;
|
|
393
|
-
case 4: return [2 /*return*/];
|
|
371
|
+
client.on("message", function (topic, message) {
|
|
372
|
+
// Logger.log(`DEBUG: Message received: ${topic} - ${message.toString()}`)
|
|
373
|
+
if (topic.endsWith("/system/0/Serial") && !_this.portalId) {
|
|
374
|
+
var portalId_1 = getMessageJson(message).value;
|
|
375
|
+
if (_this.portalId !== portalId_1 && portalId_1 !== undefined) {
|
|
376
|
+
_this.setPortalId(portalId_1);
|
|
394
377
|
}
|
|
395
|
-
|
|
396
|
-
|
|
378
|
+
runInAction(function () { return _this.subscribeToAllTopics(); });
|
|
379
|
+
}
|
|
380
|
+
if (topic.endsWith("full_publish_completed")) {
|
|
381
|
+
var uniqueId = getMessageJson(message)["full-publish-completed-echo"] || "";
|
|
382
|
+
Logger.log("Received full_publish_completed for ".concat(_this.portalId, " with full-publish-completed-echo: '").concat(uniqueId, "'"));
|
|
383
|
+
if (uniqueId === _this.uniqueId) {
|
|
384
|
+
_this.addMessagesFromQueue();
|
|
385
|
+
_this.setupQueueWorker();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (message.toString() !== "") {
|
|
389
|
+
_this.addMessage(topic, getMessageJson(message));
|
|
390
|
+
}
|
|
391
|
+
});
|
|
397
392
|
Logger.log("MQTT booted");
|
|
398
393
|
}
|
|
399
394
|
});
|
|
@@ -495,6 +490,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
495
490
|
});
|
|
496
491
|
makeAutoObservable(this, {
|
|
497
492
|
messageQueue: false,
|
|
493
|
+
urgentTopicPrefixes: false,
|
|
498
494
|
setupKeepaliveTimer: false,
|
|
499
495
|
clearKeepaliveTimer: false,
|
|
500
496
|
sendFullKeepalive: false,
|
|
@@ -521,6 +517,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
521
517
|
value: function () {
|
|
522
518
|
this.topicsSubscribed.clear();
|
|
523
519
|
this.portalId = undefined;
|
|
520
|
+
this.urgentTopicPrefixes = [];
|
|
524
521
|
}
|
|
525
522
|
});
|
|
526
523
|
Object.defineProperty(MqttStore.prototype, "setStatus", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mqtt.store.js","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"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","sourcesContent":["import {comparer, makeAutoObservable, runInAction} from \"mobx\"\nimport {computedFn} from \"mobx-utils\"\nimport * as mqtt from \"mqtt\"\nimport {IClientPublishOptions, MqttClient} from \"mqtt\"\nimport {MqttMessage, MqttMessages, PortalId, STATUS, Topics} from \"../Mqtt\"\nimport Logger from \"../../utils/logger\"\nimport {getMessageJson} from \"../../utils/util\"\nimport {useMemo} from \"react\"\nimport {assign} from \"lodash-es\"\n\nlet store: MqttStore\n\nexport class MqttStore {\n client?: MqttClient | null\n error?: object | null | boolean\n status: string = STATUS.CONNECTING\n messages: MqttMessages = {}\n messageQueue: MqttMessages = {}\n topicsSubscribed: Set<string> = new Set<string>()\n portalId: PortalId\n uniqueId: string = Math.random().toString(16).substr(2, 8)\n keepAliveHandlerRef: any\n queueWorker: any\n meanQueueWorkerPassDuration: number = 0\n\n // Use comparer.identity to check the message we get for given topic.\n // Will cause re-render when new message for given topic arrives.\n // We rely on the fact that MQTT will only re-send a message when it\n // changes, and on full keep alive only.\n messageFromTopic = computedFn((topic?: string) => {\n // Logger.log(`DEBUG: messageFromTopic: ${JSON.stringify(topic)}`)\n // trace()\n return topic ? this.messages[topic] : undefined\n }, { name: \"Mqtt.store.messageFromTopic\", equals: comparer.identity })\n\n // Use comparer.identity to check the messages we get for given topics.\n // Will cause re-render when any new message for one of the topics arrives.\n // We rely on the fact that MQTT will only re-send a message when it\n // changes, and on full keep alive only.\n messagesByTopics = computedFn((topics?: Topics) => {\n // Logger.log(`DEBUG: messagesByTopics: ${JSON.stringify(topics)}`)\n // trace()\n if (!topics) {\n return {}\n }\n\n const result: { [key: string]: MqttMessage | MqttMessage[] } = {}\n\n Object.entries(topics).forEach(([label, topic]) => {\n if (Array.isArray(topic)) {\n result[label] = topic.map((t) => this.messageFromTopic(t))\n } else if (topic === undefined) {\n result[label] = undefined\n } else {\n result[label] = this.messageFromTopic(topic)\n }\n })\n\n return result\n }, { name: \"Mqtt.store.messagesByTopics\", equals: comparer.identity })\n\n // Use comparer.identity to check the messages we get for given topics.\n // Will cause re-render when any new message for one of the topic arrives,\n // or when we receive a new (yet unseen) topic.\n // We rely on the fact that MQTT will only re-send a message when it\n // changes, and on full keep alive\n // Only access Object.keys(this.messages),\n // and this.messages[k], where k matches the wildcard regex,\n // to make sure we invalidate:\n // - when new topics arrive\n // - when message with matching topic changes\n messagesByWildcard = computedFn((wildcard?: string) => {\n // Logger.log(`DEBUG: messagesByWildcard: ${JSON.stringify(wildcard)}`)\n // trace()\n if (wildcard === undefined || wildcard === \"\" || wildcard === null) return {}\n\n const topicRegex = new RegExp(wildcard.replace(/\\+/g, \"\\\\w*\")) // + in mqtt is anything -> .*\n\n return Object.fromEntries(\n Object.keys(this.messages)\n .filter((topic) => topic.match(topicRegex))\n .map((topic) => [topic, this.messages[topic]])\n // Filter out empty results\n .filter(([_, message]) =>\n message !== undefined && message !== null\n && (!Array.isArray(message) || (message.length !== 0 && !message.every((v) => v === undefined || v === null)))\n ),\n )\n }, { name: \"Mqtt.store.messagesByWildcard\", equals: comparer.identity })\n\n constructor() {\n makeAutoObservable(this, {\n messageQueue: false,\n setupKeepaliveTimer: false,\n clearKeepaliveTimer: false,\n sendFullKeepalive: false,\n sendSuppressedKeepalive: false,\n setupQueueWorker: false,\n removeQueueWorker: false,\n scheduleNextQueueWorkerPass: false,\n subscribeToTopic: false,\n subscribeToAllTopics: false,\n clearSubscribedTopics: false,\n })\n }\n\n get isConnected() {\n return this.status === STATUS.CONNECTED\n }\n\n subscribeToTopic = (topic?: string) => {\n if (!topic) return\n if (topic.includes(\"undefined\")) return\n\n if (!this.topicsSubscribed.has(topic)) {\n Logger.log(`Subscribing to ${topic}`)\n this.client?.subscribe(topic, (err, granted) => {\n if (err) {\n Logger.error(err)\n return\n }\n\n (granted !== undefined && granted[0])\n ? Logger.log(`Subscribed to ${granted[0].topic} with Qos ${granted[0].qos}`)\n : Logger.log(`Subscribed to ${topic} with Qos unknown`);\n })\n\n this.topicsSubscribed.add(topic)\n }\n }\n\n clearSubscribedTopics() {\n this.topicsSubscribed.clear()\n this.portalId = undefined\n }\n\n addMessage = async (topic: string, message: { value: string | null }) => {\n this.messageQueue[topic] = message.value ?? undefined\n }\n\n addMessagesFromQueue = async () => {\n if (Object.values(this.messageQueue).length > 0) {\n // Logger.log(`DEBUG: addMessagesFromQueue: in queue: ${JSON.stringify(Object.values(this.messageQueue).length)}`)\n assign(this.messages, this.messageQueue)\n // Logger.log(`DEBUG: addMessagesFromQueue: to process: ${JSON.stringify(Object.values(this.messages).length)}`)\n this.messageQueue = {}\n }\n }\n\n scheduleNextQueueWorkerPass = (timeout: number) => {\n this.queueWorker = setTimeout(async () => {\n const started = performance.now()\n await this.addMessagesFromQueue()\n const ended = performance.now()\n this.meanQueueWorkerPassDuration = addToMean(this.meanQueueWorkerPassDuration, 10, ended - started)\n // Schedule next update after 1 - 3 seconds\n // depending on how fast we were able to process the incoming messages\n const newTimeout = Math.max(1000, Math.min(this.meanQueueWorkerPassDuration * 50, 3000))\n this.scheduleNextQueueWorkerPass(newTimeout)\n }, timeout)\n }\n\n setupQueueWorker = () => {\n this.removeQueueWorker()\n\n this.meanQueueWorkerPassDuration = 20 // ms\n this.scheduleNextQueueWorkerPass(1000) // ms\n }\n\n removeQueueWorker = () => {\n if (this.queueWorker) {\n clearInterval(this.queueWorker)\n }\n this.queueWorker = undefined\n }\n\n setPortalId = (portalId: string) => {\n this.portalId = portalId\n }\n\n setStatus(status: string) {\n this.status = status\n }\n\n setError(error: object | null | boolean) {\n this.error = error\n }\n\n boot = (\n protocol: string,\n host: string = \"localhost\",\n port: number | null,\n path: string = \"websocket-mqtt\",\n remote: boolean = false,\n portalId?: string,\n ) => {\n Logger.log(\"MQTT booting\")\n\n let client = this.client\n\n if (client) {\n client.end(true)\n this.client = undefined\n this.portalId = undefined\n this.topicsSubscribed = new Set<string>()\n }\n\n let url\n if (remote) {\n if (!host) {\n return\n }\n // remote connection to VRM broker always uses MQTTS over 443\n url = `mqtts://${host}:443`\n } else {\n // local connection derives websocket protocol from web app protocol\n const wsproto = protocol === \"https:\" ? \"wss:\" : \"ws:\"\n if (port) {\n url = `${wsproto}//${host}:${port}/${path}`\n } else {\n url = `${wsproto}//${host}/${path}`\n }\n }\n\n Logger.log(`MQTT connecting to ${url}`)\n client = mqtt.connect(url, { resubscribe: false })\n\n this.client = client\n this.portalId = portalId\n\n client.on(\"error\", (error) => {\n Logger.log(\"MQTT error\")\n runInAction(() => {\n this.setError(error)\n this.setStatus(STATUS.DISCONNECTED)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"offline\", () => {\n Logger.log(\"MQTT offline\")\n runInAction(() => {\n this.setError(true)\n this.setStatus(STATUS.OFFLINE)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"connect\", () => {\n Logger.log(\"MQTT connected\")\n runInAction(() => {\n this.setError(null)\n this.setStatus(STATUS.CONNECTED)\n // Never use wildcard when connecting remotely\n this.subscribeToTopic(`N/${remote ? portalId : \"+\"}/system/0/Serial`)\n this.setupKeepaliveTimer()\n })\n })\n\n client.on(\"message\", async (topic, message) => {\n // Logger.log(`DEBUG: Message received: ${topic} - ${message.toString()}`)\n\n if (topic.endsWith(\"/system/0/Serial\") && !this.portalId) {\n const portalId = getMessageJson(message).value\n\n if (this.portalId !== portalId && portalId !== undefined) {\n this.setPortalId(portalId)\n }\n\n runInAction(() => this.subscribeToAllTopics())\n }\n if (topic.endsWith(\"full_publish_completed\")) {\n const uniqueId = getMessageJson(message)[\"full-publish-completed-echo\"] || \"\"\n Logger.log(`Received full_publish_completed for ${this.portalId} with full-publish-completed-echo: '${uniqueId}'`)\n if (uniqueId === this.uniqueId) {\n await this.addMessagesFromQueue()\n this.setupQueueWorker()\n }\n }\n\n if (message.toString() !== \"\") {\n await this.addMessage(topic, getMessageJson(message))\n }\n })\n\n Logger.log(\"MQTT booted\")\n }\n\n subscribeToAllTopics = () => {\n const topics = [\n `N/${this.portalId}/settings/#`,\n `N/${this.portalId}/system/#`,\n `N/${this.portalId}/vebus/#`,\n `N/${this.portalId}/alternator/#`,\n `N/${this.portalId}/battery/#`,\n `N/${this.portalId}/charger/#`,\n `N/${this.portalId}/dcsource/#`,\n `N/${this.portalId}/generator/#`,\n `N/${this.portalId}/genset/#`,\n `N/${this.portalId}/dcgenset/#`,\n `N/${this.portalId}/inverter/#`,\n `N/${this.portalId}/tank/#`,\n `N/${this.portalId}/temperature/#`,\n `N/${this.portalId}/switch/#`,\n `N/${this.portalId}/full_publish_completed`\n ]\n\n this.client?.subscribe(topics, err => {\n if (err) {\n Logger.error(err)\n return\n }\n\n // When we received all topics we send a full keepalive.\n this.sendFullKeepalive()\n })\n }\n\n sendSuppressedKeepalive = () => {\n if (this.portalId) {\n\n const options = JSON.stringify({\"keepalive-options\": [\"suppress-republish\"]})\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending keepalive for ${this.portalId} with ${options}`)\n this.client?.publish(topic, options)\n }\n }\n\n sendFullKeepalive = () => {\n if (this.portalId) {\n\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending first keepalive for ${this.portalId} with full-publish-completed-echo: '${this.uniqueId}'`)\n this.client && this.client?.publish(topic, `{ \"keepalive-options\" : [ {\"full-publish-completed-echo\": \"${this.uniqueId}\" } ] }`)\n }\n }\n\n setupKeepaliveTimer = () => {\n this.clearKeepaliveTimer()\n\n this.keepAliveHandlerRef = setInterval(this.sendSuppressedKeepalive, 30000)\n\n this.sendFullKeepalive()\n }\n\n clearKeepaliveTimer = () => {\n const ref = this.keepAliveHandlerRef\n if (ref) {\n clearInterval(ref)\n }\n this.keepAliveHandlerRef = undefined\n }\n\n publish = (topic: string, data: string | number, options?: IClientPublishOptions) => {\n if (this.status !== STATUS.CONNECTED || !this.client) {\n Logger.log(\"Could not publish value, not connected to MQTT broker\")\n }\n const message = JSON.stringify({value: data})\n\n Logger.log(`Publishing to ${topic}: ${message}`)\n\n this.client?.publish(topic, message, options ?? {})\n }\n}\n\n/**\n * Compute mean by providing existing mean, number of samples, and new sample.\n *\n * @param {number} mean current mean\n * @param {number} n number of sampled values\n * @param {number} newValue the sample\n * @returns {number} the new mean\n *\n * @example\n * addToMean(14, 5, 53); // => 20.5\n */\nfunction addToMean(mean: number, n: number, newValue: number): number {\n return mean + (newValue - mean) / (n + 1);\n}\n\nfunction initializeStore() {\n const _store = store ?? new MqttStore()\n // For SSG and SSR always create a new store\n if (typeof window === \"undefined\") return _store\n // Create the store once in the client\n if (!store) store = _store\n\n return _store\n}\n\nexport function useMqtt() {\n return useMemo(() => initializeStore(), [])\n}"]}
|
|
1
|
+
{"version":3,"file":"Mqtt.store.js","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"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","sourcesContent":["import {comparer, makeAutoObservable, runInAction} from \"mobx\"\nimport {computedFn} from \"mobx-utils\"\nimport * as mqtt from \"mqtt\"\nimport {IClientPublishOptions, MqttClient} from \"mqtt\"\nimport {MqttMessage, MqttMessages, PortalId, STATUS, Topics} from \"../Mqtt\"\nimport Logger from \"../../utils/logger\"\nimport {getMessageJson} from \"../../utils/util\"\nimport {useMemo} from \"react\"\nimport {assign} from \"lodash-es\"\n\nlet store: MqttStore\n\nexport class MqttStore {\n client?: MqttClient | null\n error?: object | null | boolean\n status: string = STATUS.CONNECTING\n messages: MqttMessages = {}\n messageQueue: MqttMessages = {}\n topicsSubscribed: Set<string> = new Set<string>()\n portalId: PortalId\n uniqueId: string = Math.random().toString(16).substr(2, 8)\n keepAliveHandlerRef: any\n queueWorker: any\n meanQueueWorkerPassDuration: number = 0\n urgentTopicPrefixes: string[] = []\n\n /**\n * Returns the current cached message for a given MQTT topic.\n *\n * React Components using this method will re-render when their specific\n * topic's message changes.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for the given topic. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n *\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param topic - The MQTT topic to retrieve the message for\n * @returns The message object for the topic, or undefined if topic is not provided or not found\n */\n messageFromTopic = computedFn((topic?: string) => {\n // Logger.log(`DEBUG: messageFromTopic: ${JSON.stringify(topic)}`)\n // trace()\n return topic ? this.messages[topic] : undefined\n }, { name: \"Mqtt.store.messageFromTopic\", equals: comparer.identity })\n\n /**\n * Returns the current cached messages for a given set of MQTT topics.\n *\n * This is a memoized computed function - each set of topics has its own cached value.\n *\n * React Components using this method will re-render when\n * any of the messages for specified topics change.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for any of the specified topics. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param topics - The MQTT topics to retrieve the messages for\n * @returns The messages objects for the given topics, or empty dictionary if topics not found\n */\n messagesByTopics = computedFn((topics?: Topics) => {\n // Logger.log(`DEBUG: messagesByTopics: ${JSON.stringify(topics)}`)\n // trace()\n if (!topics) {\n return {}\n }\n\n const result: { [key: string]: MqttMessage | MqttMessage[] } = {}\n\n Object.entries(topics).forEach(([label, topic]) => {\n if (Array.isArray(topic)) {\n result[label] = topic.map((t) => this.messageFromTopic(t))\n } else if (topic === undefined) {\n result[label] = undefined\n } else {\n result[label] = this.messageFromTopic(topic)\n }\n })\n\n return result\n }, { name: \"Mqtt.store.messagesByTopics\", equals: comparer.identity })\n\n /**\n * Returns the current cached messages for MQTT topics specified via regex.\n *\n * React Components using this method will re-render when\n * values of any of the matched topics change. The components also re-render\n * when new MQTT topics are received and match needs to be checked.\n *\n * Using comparer.identity will trigger the re-renders any time\n * a message arrives for any of the matched topics. We rely on the fact\n * that MQTT will only re-send a message when the value changes,\n * or on a full keep alive.\n *\n * Note: Receiving the same message for a given topic will cause re-renders,\n * as we do not check structural identity of the message.\n *\n * @param wildcard - The MQTT wildcard to retrieve the message for\n * @returns The messages objects for the given topics, or empty dictionary if topics not found\n */\n messagesByWildcard = computedFn((wildcard?: string) => {\n // Logger.log(`DEBUG: messagesByWildcard: ${JSON.stringify(wildcard)}`)\n // trace()\n if (wildcard === undefined || wildcard === \"\" || wildcard === null) return {}\n\n const topicRegex = new RegExp(wildcard.replace(/\\+/g, \"\\\\w*\")) // + in mqtt is anything -> .*\n\n return Object.fromEntries(\n Object.keys(this.messages)\n .filter((topic) => topic.match(topicRegex))\n .map((topic) => [topic, this.messages[topic]])\n // Filter out empty results\n .filter(([_, message]) =>\n message !== undefined && message !== null\n && (!Array.isArray(message) || (message.length !== 0 && !message.every((v) => v === undefined || v === null)))\n ),\n )\n }, { name: \"Mqtt.store.messagesByWildcard\", equals: comparer.identity })\n\n constructor() {\n makeAutoObservable(this, {\n messageQueue: false,\n urgentTopicPrefixes: false,\n setupKeepaliveTimer: false,\n clearKeepaliveTimer: false,\n sendFullKeepalive: false,\n sendSuppressedKeepalive: false,\n setupQueueWorker: false,\n removeQueueWorker: false,\n scheduleNextQueueWorkerPass: false,\n subscribeToTopic: false,\n subscribeToAllTopics: false,\n clearSubscribedTopics: false,\n })\n }\n\n get isConnected() {\n return this.status === STATUS.CONNECTED\n }\n\n subscribeToTopic = (topic?: string) => {\n if (!topic) return\n if (topic.includes(\"undefined\")) return\n\n if (!this.topicsSubscribed.has(topic)) {\n Logger.log(`Subscribing to ${topic}`)\n this.client?.subscribe(topic, (err, granted) => {\n if (err) {\n Logger.error(err)\n return\n }\n\n (granted !== undefined && granted[0])\n ? Logger.log(`Subscribed to ${granted[0].topic} with Qos ${granted[0].qos}`)\n : Logger.log(`Subscribed to ${topic} with Qos unknown`);\n })\n\n this.topicsSubscribed.add(topic)\n }\n }\n\n clearSubscribedTopics() {\n this.topicsSubscribed.clear()\n this.portalId = undefined\n this.urgentTopicPrefixes = []\n }\n\n addMessage = (topic: string, message: { value: string | null }) => {\n // Logger.log(`DEBUG: addMessage: topic: ${topic}, urgentPrefixes: ${JSON.stringify(this.urgentTopicPrefixes)}`)\n if (this.urgentTopicPrefixes.some((prefix) => topic.startsWith(prefix))) {\n Logger.log(`DEBUG: addMessage: topic: ${topic}`)\n // NOTE: If topic starts with one of the urgent prefixes, deliver it immediately\n this.messages[topic] = message.value ?? undefined\n } else {\n // NOTE: Otherwise store message to the queue, and move messages from the queue\n // NOTE: to the React components that are MobX observers periodically and in batches\n this.messageQueue[topic] = message.value ?? undefined\n }\n }\n\n addMessagesFromQueue = () => {\n if (Object.values(this.messageQueue).length > 0) {\n // Logger.log(`DEBUG: addMessagesFromQueue: in queue: ${JSON.stringify(Object.values(this.messageQueue).length)}`)\n assign(this.messages, this.messageQueue)\n // Logger.log(`DEBUG: addMessagesFromQueue: to process: ${JSON.stringify(Object.values(this.messages).length)}`)\n this.messageQueue = {}\n }\n }\n\n scheduleNextQueueWorkerPass = (timeout: number) => {\n this.queueWorker = setTimeout(() => {\n const started = performance.now()\n this.addMessagesFromQueue()\n const ended = performance.now()\n this.meanQueueWorkerPassDuration = addToMean(this.meanQueueWorkerPassDuration, 10, ended - started)\n // Schedule next update after 1 - 3 seconds\n // depending on how fast we were able to process the incoming messages\n const newTimeout = Math.max(1000, Math.min(this.meanQueueWorkerPassDuration * 50, 3000))\n this.scheduleNextQueueWorkerPass(newTimeout)\n }, timeout)\n }\n\n setupQueueWorker = () => {\n this.removeQueueWorker()\n\n this.meanQueueWorkerPassDuration = 20 // ms\n this.scheduleNextQueueWorkerPass(1000) // ms\n }\n\n removeQueueWorker = () => {\n if (this.queueWorker) {\n clearInterval(this.queueWorker)\n }\n this.queueWorker = undefined\n }\n\n setPortalId = (portalId: string) => {\n this.portalId = portalId\n this.urgentTopicPrefixes = [\n `N/${portalId}/switch/`,\n ]\n }\n\n setStatus(status: string) {\n this.status = status\n }\n\n setError(error: object | null | boolean) {\n this.error = error\n }\n\n boot = (\n protocol: string,\n host: string = \"localhost\",\n port: number | null,\n path: string = \"websocket-mqtt\",\n remote: boolean = false,\n portalId?: string,\n ) => {\n Logger.log(\"MQTT booting\")\n\n let client = this.client\n\n if (client) {\n client.end(true)\n this.client = undefined\n this.portalId = undefined\n this.topicsSubscribed = new Set<string>()\n this.urgentTopicPrefixes = []\n }\n\n let url\n if (remote) {\n if (!host) {\n return\n }\n // remote connection to VRM broker always uses MQTTS over 443\n url = `mqtts://${host}:443`\n } else {\n // local connection derives websocket protocol from web app protocol\n const wsproto = protocol === \"https:\" ? \"wss:\" : \"ws:\"\n if (port) {\n url = `${wsproto}//${host}:${port}/${path}`\n } else {\n url = `${wsproto}//${host}/${path}`\n }\n }\n\n Logger.log(`MQTT connecting to ${url}`)\n client = mqtt.connect(url, { resubscribe: false })\n\n this.client = client\n this.portalId = portalId\n\n client.on(\"error\", (error) => {\n Logger.log(\"MQTT error\")\n runInAction(() => {\n this.setError(error)\n this.setStatus(STATUS.DISCONNECTED)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"offline\", () => {\n Logger.log(\"MQTT offline\")\n runInAction(() => {\n this.setError(true)\n this.setStatus(STATUS.OFFLINE)\n })\n this.removeQueueWorker()\n this.clearKeepaliveTimer()\n this.clearSubscribedTopics()\n })\n\n client.on(\"connect\", () => {\n Logger.log(\"MQTT connected\")\n runInAction(() => {\n this.setError(null)\n this.setStatus(STATUS.CONNECTED)\n // Never use wildcard when connecting remotely\n this.subscribeToTopic(`N/${remote ? portalId : \"+\"}/system/0/Serial`)\n this.setupKeepaliveTimer()\n })\n })\n\n client.on(\"message\",\n (topic, message) => {\n // Logger.log(`DEBUG: Message received: ${topic} - ${message.toString()}`)\n\n if (topic.endsWith(\"/system/0/Serial\") && !this.portalId) {\n const portalId = getMessageJson(message).value\n\n if (this.portalId !== portalId && portalId !== undefined) {\n this.setPortalId(portalId)\n }\n\n runInAction(() => this.subscribeToAllTopics())\n }\n if (topic.endsWith(\"full_publish_completed\")) {\n const uniqueId = getMessageJson(message)[\"full-publish-completed-echo\"] || \"\"\n Logger.log(`Received full_publish_completed for ${this.portalId} with full-publish-completed-echo: '${uniqueId}'`)\n if (uniqueId === this.uniqueId) {\n this.addMessagesFromQueue()\n this.setupQueueWorker()\n }\n }\n\n if (message.toString() !== \"\") {\n this.addMessage(topic, getMessageJson(message))\n }\n })\n\n Logger.log(\"MQTT booted\")\n }\n\n subscribeToAllTopics = () => {\n const topics = [\n `N/${this.portalId}/settings/#`,\n `N/${this.portalId}/system/#`,\n `N/${this.portalId}/vebus/#`,\n `N/${this.portalId}/alternator/#`,\n `N/${this.portalId}/battery/#`,\n `N/${this.portalId}/charger/#`,\n `N/${this.portalId}/dcsource/#`,\n `N/${this.portalId}/generator/#`,\n `N/${this.portalId}/genset/#`,\n `N/${this.portalId}/dcgenset/#`,\n `N/${this.portalId}/inverter/#`,\n `N/${this.portalId}/tank/#`,\n `N/${this.portalId}/temperature/#`,\n `N/${this.portalId}/switch/#`,\n `N/${this.portalId}/full_publish_completed`\n ]\n\n this.client?.subscribe(topics, err => {\n if (err) {\n Logger.error(err)\n return\n }\n\n // When we received all topics we send a full keepalive.\n this.sendFullKeepalive()\n })\n }\n\n sendSuppressedKeepalive = () => {\n if (this.portalId) {\n\n const options = JSON.stringify({\"keepalive-options\": [\"suppress-republish\"]})\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending keepalive for ${this.portalId} with ${options}`)\n this.client?.publish(topic, options)\n }\n }\n\n sendFullKeepalive = () => {\n if (this.portalId) {\n\n const topic = `R/${this.portalId}/keepalive`\n\n Logger.log(`Sending first keepalive for ${this.portalId} with full-publish-completed-echo: '${this.uniqueId}'`)\n this.client && this.client?.publish(topic, `{ \"keepalive-options\" : [ {\"full-publish-completed-echo\": \"${this.uniqueId}\" } ] }`)\n }\n }\n\n setupKeepaliveTimer = () => {\n this.clearKeepaliveTimer()\n\n this.keepAliveHandlerRef = setInterval(this.sendSuppressedKeepalive, 30000)\n\n this.sendFullKeepalive()\n }\n\n clearKeepaliveTimer = () => {\n const ref = this.keepAliveHandlerRef\n if (ref) {\n clearInterval(ref)\n }\n this.keepAliveHandlerRef = undefined\n }\n\n publish = (topic: string, data: string | number, options?: IClientPublishOptions) => {\n if (this.status !== STATUS.CONNECTED || !this.client) {\n Logger.log(\"Could not publish value, not connected to MQTT broker\")\n }\n const message = JSON.stringify({value: data})\n\n Logger.log(`Publishing to ${topic}: ${message}`)\n\n this.client?.publish(topic, message, options ?? {})\n }\n}\n\n/**\n * Compute mean by providing existing mean, number of samples, and new sample.\n *\n * @param {number} mean current mean\n * @param {number} n number of sampled values\n * @param {number} newValue the sample\n * @returns {number} the new mean\n *\n * @example\n * addToMean(14, 5, 53); // => 20.5\n */\nfunction addToMean(mean: number, n: number, newValue: number): number {\n return mean + (newValue - mean) / (n + 1);\n}\n\nfunction initializeStore() {\n const _store = store ?? new MqttStore()\n // For SSG and SSR always create a new store\n if (typeof window === \"undefined\") return _store\n // Create the store once in the client\n if (!store) store = _store\n\n return _store\n}\n\nexport function useMqtt() {\n return useMemo(() => initializeStore(), [])\n}"]}
|