@victronenergy/mfd-modules 9.9.1 → 9.11.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.
- package/dist/src/Modules/Mqtt/Mqtt.provider.d.ts.map +1 -1
- package/dist/src/Modules/Mqtt/Mqtt.provider.js.map +1 -1
- package/dist/src/Modules/Mqtt/Mqtt.store.d.ts +54 -52
- package/dist/src/Modules/Mqtt/Mqtt.store.d.ts.map +1 -1
- package/dist/src/Modules/Mqtt/Mqtt.store.js +61 -60
- package/dist/src/Modules/Mqtt/Mqtt.store.js.map +1 -1
- package/dist/src/Modules/SwitchableOutputs/SwitchableOutput.provider.d.ts +5 -0
- package/dist/src/Modules/SwitchableOutputs/SwitchableOutput.provider.d.ts.map +1 -1
- package/dist/src/Modules/SwitchableOutputs/SwitchableOutput.provider.js +7 -1
- package/dist/src/Modules/SwitchableOutputs/SwitchableOutput.provider.js.map +1 -1
- package/dist/src/utils/constants.d.ts +5 -2
- package/dist/src/utils/constants.d.ts.map +1 -1
- package/dist/src/utils/constants.js +4 -1
- package/dist/src/utils/constants.js.map +1 -1
- package/dist/src/utils/hsvw.d.ts +26 -0
- package/dist/src/utils/hsvw.d.ts.map +1 -0
- package/dist/src/utils/hsvw.js +44 -0
- package/dist/src/utils/hsvw.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mqtt.provider.d.ts","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.provider.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"Mqtt.provider.d.ts","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAElD,eAAO,MAAM,aAAa,GAAI,QAAQ,GAAG,WAAW,EAAE,QAAQ,MAAM,KAAG,QAAQ,GAAG,SAGjF,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,SAAS,GAAG,GAAG,EAAE,QAAQ,MAAM,KAAG,SAGhE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mqtt.provider.js","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.provider.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Mqtt.provider.js","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAGtC,MAAM,CAAC,IAAM,aAAa,GAAG,UAAyB,KAAc;IAClE,IAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAwB,CAAA;AAC5D,CAAC,CAAA;AAED,MAAM,CAAC,IAAM,cAAc,GAAG,UAAkB,MAAc;IAC5D,IAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAyB,CAAA;AAC9D,CAAC,CAAA","sourcesContent":["import { useMqtt } from \"./Mqtt.store\"\nimport { MqttMessage, Topics } from \"./Mqtt.types\"\n\nexport const useTopicState = <TMessage = MqttMessage>(topic?: string): TMessage | undefined => {\n const mqtt = useMqtt()\n return mqtt.messageFromTopic(topic) as unknown as TMessage\n}\n\nexport const useTopicsState = <TMessages = any>(topics: Topics): TMessages => {\n const mqtt = useMqtt()\n return mqtt.messagesByTopics(topics) as unknown as TMessages\n}\n"]}
|
|
@@ -14,63 +14,63 @@ export declare class MqttStore {
|
|
|
14
14
|
meanQueueWorkerPassDuration: number;
|
|
15
15
|
urgentTopicPrefixes: string[];
|
|
16
16
|
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
+
*/
|
|
33
33
|
messageFromTopic: (topic?: string) => MqttMessage;
|
|
34
34
|
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
+
*/
|
|
53
53
|
messagesByTopics: (topics?: Topics) => {
|
|
54
54
|
[key: string]: MqttMessage | MqttMessage[];
|
|
55
55
|
};
|
|
56
56
|
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
+
*/
|
|
74
74
|
messagesByWildcard: (wildcard?: string) => any;
|
|
75
75
|
constructor();
|
|
76
76
|
get isConnected(): boolean;
|
|
@@ -92,7 +92,9 @@ export declare class MqttStore {
|
|
|
92
92
|
sendFullKeepalive: () => void;
|
|
93
93
|
setupKeepaliveTimer: () => void;
|
|
94
94
|
clearKeepaliveTimer: () => void;
|
|
95
|
-
publish: (topic: string, data: string | number
|
|
95
|
+
publish: (topic: string, data: string | number | {
|
|
96
|
+
raw: string;
|
|
97
|
+
}, options?: IClientPublishOptions) => void;
|
|
96
98
|
}
|
|
97
99
|
export declare function useMqtt(): MqttStore;
|
|
98
100
|
//# sourceMappingURL=Mqtt.store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mqtt.store.d.ts","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"Mqtt.store.d.ts","sourceRoot":"/","sources":["src/Modules/Mqtt/Mqtt.store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAU,MAAM,EAAE,MAAM,SAAS,CAAA;AAQ7E,qBAAa,SAAS;IACpB,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;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,WACL,MAAM,iBAMhB;IAED;;;;;;;;;;;;;;;;;;UAkBM;IACN,gBAAgB,YACJ,MAAM;;MAsBjB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,kBAAkB,cACJ,MAAM,SAsBnB;;IAmBD,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,UAU7D;IAED,oBAAoB,aAOnB;IAED,2BAA2B,GAAI,SAAS,MAAM,UAW7C;IAED,gBAAgB,aAKf;IAED,iBAAiB,aAKhB;IAED,WAAW,GAAI,UAAU,MAAM,UAG9B;IAED,SAAS,CAAC,MAAM,EAAE,MAAM;IAIxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO;IAIvC,IAAI,GACF,UAAU,MAAM,EAChB,MAAM,MAAM,YAAc,EAC1B,MAAM,MAAM,GAAG,IAAI,EACnB,OAAM,MAAyB,EAC/B,SAAQ,OAAe,EACvB,WAAW,MAAM,UAmGlB;IAED,oBAAoB,aA4BnB;IAED,uBAAuB,aAQtB;IAED,iBAAiB,aAWhB;IAED,mBAAmB,aAMlB;IAED,mBAAmB,aAMlB;IAED,OAAO,GAAI,OAAO,MAAM,EAAE,MAAM,MAAM,GAAG,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,UAAU,qBAAqB,UAUjG;CACF;AA2BD,wBAAgB,OAAO,cAEtB"}
|
|
@@ -83,22 +83,22 @@ var MqttStore = /** @class */ (function () {
|
|
|
83
83
|
value: []
|
|
84
84
|
});
|
|
85
85
|
/**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
+
*/
|
|
102
102
|
Object.defineProperty(this, "messageFromTopic", {
|
|
103
103
|
enumerable: true,
|
|
104
104
|
configurable: true,
|
|
@@ -110,24 +110,24 @@ var MqttStore = /** @class */ (function () {
|
|
|
110
110
|
}, { name: "Mqtt.store.messageFromTopic", equals: comparer.identity })
|
|
111
111
|
});
|
|
112
112
|
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
+
*/
|
|
131
131
|
Object.defineProperty(this, "messagesByTopics", {
|
|
132
132
|
enumerable: true,
|
|
133
133
|
configurable: true,
|
|
@@ -155,23 +155,23 @@ var MqttStore = /** @class */ (function () {
|
|
|
155
155
|
}, { name: "Mqtt.store.messagesByTopics", equals: comparer.identity })
|
|
156
156
|
});
|
|
157
157
|
/**
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
+
*/
|
|
175
175
|
Object.defineProperty(this, "messagesByWildcard", {
|
|
176
176
|
enumerable: true,
|
|
177
177
|
configurable: true,
|
|
@@ -188,8 +188,10 @@ var MqttStore = /** @class */ (function () {
|
|
|
188
188
|
// Filter out empty results
|
|
189
189
|
.filter(function (_a) {
|
|
190
190
|
var _ = _a[0], message = _a[1];
|
|
191
|
-
return message !== undefined &&
|
|
192
|
-
|
|
191
|
+
return message !== undefined &&
|
|
192
|
+
message !== null &&
|
|
193
|
+
(!Array.isArray(message) ||
|
|
194
|
+
(message.length !== 0 && !message.every(function (v) { return v === undefined || v === null; })));
|
|
193
195
|
}));
|
|
194
196
|
}, { name: "Mqtt.store.messagesByWildcard", equals: comparer.identity })
|
|
195
197
|
});
|
|
@@ -210,7 +212,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
210
212
|
Logger.error(err);
|
|
211
213
|
return;
|
|
212
214
|
}
|
|
213
|
-
|
|
215
|
+
granted !== undefined && granted[0]
|
|
214
216
|
? Logger.log("Subscribed to ".concat(granted[0].topic, " with Qos ").concat(granted[0].qos))
|
|
215
217
|
: Logger.log("Subscribed to ".concat(topic, " with Qos unknown"));
|
|
216
218
|
});
|
|
@@ -293,9 +295,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
293
295
|
writable: true,
|
|
294
296
|
value: function (portalId) {
|
|
295
297
|
_this.portalId = portalId;
|
|
296
|
-
_this.urgentTopicPrefixes = [
|
|
297
|
-
"N/".concat(portalId, "/switch/"),
|
|
298
|
-
];
|
|
298
|
+
_this.urgentTopicPrefixes = ["N/".concat(portalId, "/switch/")];
|
|
299
299
|
}
|
|
300
300
|
});
|
|
301
301
|
Object.defineProperty(this, "boot", {
|
|
@@ -412,7 +412,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
412
412
|
"N/".concat(_this.portalId, "/tank/#"),
|
|
413
413
|
"N/".concat(_this.portalId, "/temperature/#"),
|
|
414
414
|
"N/".concat(_this.portalId, "/switch/#"),
|
|
415
|
-
"N/".concat(_this.portalId, "/full_publish_completed")
|
|
415
|
+
"N/".concat(_this.portalId, "/full_publish_completed"),
|
|
416
416
|
];
|
|
417
417
|
(_a = _this.client) === null || _a === void 0 ? void 0 : _a.subscribe(topics, function (err) {
|
|
418
418
|
if (err) {
|
|
@@ -447,7 +447,8 @@ var MqttStore = /** @class */ (function () {
|
|
|
447
447
|
if (_this.portalId) {
|
|
448
448
|
var topic = "R/".concat(_this.portalId, "/keepalive");
|
|
449
449
|
Logger.log("Sending first keepalive for ".concat(_this.portalId, " with full-publish-completed-echo: '").concat(_this.uniqueId, "'"));
|
|
450
|
-
_this.client &&
|
|
450
|
+
_this.client &&
|
|
451
|
+
((_a = _this.client) === null || _a === void 0 ? void 0 : _a.publish(topic, "{ \"keepalive-options\" : [ {\"full-publish-completed-echo\": \"".concat(_this.uniqueId, "\" } ] }")));
|
|
451
452
|
}
|
|
452
453
|
}
|
|
453
454
|
});
|
|
@@ -482,7 +483,7 @@ var MqttStore = /** @class */ (function () {
|
|
|
482
483
|
if (_this.status !== STATUS.CONNECTED || !_this.client) {
|
|
483
484
|
Logger.log("Could not publish value, not connected to MQTT broker");
|
|
484
485
|
}
|
|
485
|
-
var message = JSON.stringify({ value: data });
|
|
486
|
+
var message = typeof data === "object" && data !== null && "raw" in data ? data.raw : JSON.stringify({ value: data });
|
|
486
487
|
Logger.log("Publishing to ".concat(topic, ": ").concat(message));
|
|
487
488
|
(_a = _this.client) === null || _a === void 0 ? void 0 : _a.publish(topic, message, options !== null && options !== void 0 ? options : {});
|
|
488
489
|
}
|
|
@@ -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 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 // 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}"]}
|
|
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(\n (topic?: string) => {\n // Logger.log(`DEBUG: messageFromTopic: ${JSON.stringify(topic)}`)\n // trace()\n return topic ? this.messages[topic] : undefined\n },\n { name: \"Mqtt.store.messageFromTopic\", equals: comparer.identity }\n )\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(\n (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 },\n { name: \"Mqtt.store.messagesByTopics\", equals: comparer.identity }\n )\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(\n (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(\n ([_, message]) =>\n message !== undefined &&\n message !== null &&\n (!Array.isArray(message) ||\n (message.length !== 0 && !message.every((v) => v === undefined || v === null)))\n )\n )\n },\n { name: \"Mqtt.store.messagesByWildcard\", equals: comparer.identity }\n )\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 // 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/${portalId}/switch/`]\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\", (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(\n `Received full_publish_completed for ${this.portalId} with full-publish-completed-echo: '${uniqueId}'`\n )\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 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 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 &&\n this.client?.publish(\n topic,\n `{ \"keepalive-options\" : [ {\"full-publish-completed-echo\": \"${this.uniqueId}\" } ] }`\n )\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 | { raw: string }, 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 =\n typeof data === \"object\" && data !== null && \"raw\" in data ? data.raw : 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}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PortalId, Topics } from "../Mqtt";
|
|
2
2
|
import { SwitchingDeviceInstanceId } from "./SwitchingDevice.provider";
|
|
3
3
|
import { SwitchableOutputStatus, SwitchableOutputType } from "../../utils/constants";
|
|
4
|
+
import { HSVWColorArray } from "../../utils/hsvw";
|
|
4
5
|
export type SwitchableOutputId = string;
|
|
5
6
|
export type SwitchableOutputUnit = string | "/Speed" | "/Temperature" | "/Volume";
|
|
6
7
|
export interface SwitchableOutputState {
|
|
@@ -23,11 +24,13 @@ export interface SwitchableOutputState {
|
|
|
23
24
|
unit: SwitchableOutputUnit;
|
|
24
25
|
decimals?: number;
|
|
25
26
|
labels: string;
|
|
27
|
+
lightControls: HSVWColorArray;
|
|
26
28
|
}
|
|
27
29
|
export interface SwitchableOutputProvider extends SwitchableOutputState {
|
|
28
30
|
updateAuto: (auto: 0 | 1) => void;
|
|
29
31
|
updateState: (state: 0 | 1) => void;
|
|
30
32
|
updateDimming: (dimming: number) => void;
|
|
33
|
+
updateLightControls: (hsvwa: HSVWColorArray) => void;
|
|
31
34
|
}
|
|
32
35
|
export interface SwitchableOutputTopics extends Topics {
|
|
33
36
|
type?: string;
|
|
@@ -64,11 +67,13 @@ export declare const getSwitchableOutputStateTopics: (portalId: PortalId, device
|
|
|
64
67
|
unit: string;
|
|
65
68
|
decimals: string;
|
|
66
69
|
labels: string;
|
|
70
|
+
lightControls: string;
|
|
67
71
|
};
|
|
68
72
|
export declare const getSwitchableOutputWriteTopics: (portalId: PortalId, deviceId: SwitchingDeviceInstanceId, outputId: SwitchableOutputId) => {
|
|
69
73
|
auto: string;
|
|
70
74
|
state: string;
|
|
71
75
|
dimming: string;
|
|
76
|
+
lightControls: string;
|
|
72
77
|
};
|
|
73
78
|
export declare function useSwitchableOutput(deviceId: SwitchingDeviceInstanceId, outputId: SwitchableOutputId): SwitchableOutputProvider;
|
|
74
79
|
//# sourceMappingURL=SwitchableOutput.provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwitchableOutput.provider.d.ts","sourceRoot":"/","sources":["src/Modules/SwitchableOutputs/SwitchableOutput.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAA2B,MAAM,SAAS,CAAA;AAEnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"SwitchableOutput.provider.d.ts","sourceRoot":"/","sources":["src/Modules/SwitchableOutputs/SwitchableOutput.provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
11
11
|
};
|
|
12
12
|
import { useMqtt, useTopicsState } from "../Mqtt";
|
|
13
13
|
import { useMemo } from "react";
|
|
14
|
+
import { hsvwArrayToJSON } from "../../utils/hsvw";
|
|
14
15
|
export var getSwitchableOutputNameForDisplay = function (state, switchingDeviceName) {
|
|
15
16
|
// when custom name defined, or group not overriden
|
|
16
17
|
if (state.customName || state.group === "") {
|
|
@@ -36,11 +37,13 @@ export var getSwitchableOutputStateTopics = function (portalId, deviceId, output
|
|
|
36
37
|
unit: "N/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/Settings/Unit"),
|
|
37
38
|
decimals: "N/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/Settings/Decimals"),
|
|
38
39
|
labels: "N/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/Settings/Labels"),
|
|
40
|
+
lightControls: "N/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/LightControls"),
|
|
39
41
|
}); };
|
|
40
42
|
export var getSwitchableOutputWriteTopics = function (portalId, deviceId, outputId) { return ({
|
|
41
43
|
auto: "W/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/Auto"),
|
|
42
44
|
state: "W/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/State"),
|
|
43
45
|
dimming: "W/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/Dimming"),
|
|
46
|
+
lightControls: "W/".concat(portalId, "/switch/").concat(deviceId, "/SwitchableOutput/").concat(outputId, "/LightControls"),
|
|
44
47
|
}); };
|
|
45
48
|
export function useSwitchableOutput(deviceId, outputId) {
|
|
46
49
|
var mqtt = useMqtt();
|
|
@@ -49,6 +52,9 @@ export function useSwitchableOutput(deviceId, outputId) {
|
|
|
49
52
|
var updateAuto = function (auto) { return mqtt.publish(writeTopics.auto, auto); };
|
|
50
53
|
var updateState = function (state) { return mqtt.publish(writeTopics.state, state); };
|
|
51
54
|
var updateDimming = function (dimming) { return mqtt.publish(writeTopics.dimming, dimming); };
|
|
52
|
-
|
|
55
|
+
var updateLightControls = function (hsvwa) {
|
|
56
|
+
return mqtt.publish(writeTopics.lightControls, { raw: hsvwArrayToJSON(hsvwa) });
|
|
57
|
+
};
|
|
58
|
+
return __assign(__assign({}, useTopicsState(topics)), { updateAuto: updateAuto, updateState: updateState, updateDimming: updateDimming, updateLightControls: updateLightControls });
|
|
53
59
|
}
|
|
54
60
|
//# sourceMappingURL=SwitchableOutput.provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwitchableOutput.provider.js","sourceRoot":"/","sources":["src/Modules/SwitchableOutputs/SwitchableOutput.provider.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAoB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"SwitchableOutput.provider.js","sourceRoot":"/","sources":["src/Modules/SwitchableOutputs/SwitchableOutput.provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { PortalId, Topics, useMqtt, useTopicsState } from \"../Mqtt\"\nimport { useMemo } from \"react\"\nimport { SwitchingDeviceInstanceId } from \"./SwitchingDevice.provider\"\nimport { SwitchableOutputStatus, SwitchableOutputType } from \"../../utils/constants\"\nimport { hsvwArrayToJSON, HSVWColorArray } from \"../../utils/hsvw\"\n\nexport type SwitchableOutputId = string\nexport type SwitchableOutputUnit = string | \"/Speed\" | \"/Temperature\" | \"/Volume\"\n\nexport interface SwitchableOutputState {\n deviceId: SwitchingDeviceInstanceId\n outputId: SwitchableOutputId\n type: SwitchableOutputType\n status: SwitchableOutputStatus\n name: string\n customName: string\n group: string\n parentDeviceName: string\n showUIControl: 0 | 1\n auto: 0 | 1\n state: 0 | 1\n dimming?: number\n dimmingMin?: number\n dimmingMax?: number\n // NOTE: stepSize can be of any precision, respect the precision in the UI\n stepSize?: number\n measurement?: number\n unit: SwitchableOutputUnit\n decimals?: number\n // NOTE: JSON encoded string array\n labels: string\n lightControls: HSVWColorArray\n}\n\nexport interface SwitchableOutputProvider extends SwitchableOutputState {\n updateAuto: (auto: 0 | 1) => void\n updateState: (state: 0 | 1) => void\n updateDimming: (dimming: number) => void\n updateLightControls: (hsvwa: HSVWColorArray) => void\n}\n\nexport interface SwitchableOutputTopics extends Topics {\n type?: string\n status?: string\n name?: string\n customName?: string\n group?: string\n showUIControl?: string\n auto?: string\n state?: string\n dimming?: string\n dimmingMin?: string\n dimmingMax?: string\n stepSize?: string\n measurement?: string\n unit?: string\n labels?: string[]\n}\n\nexport const getSwitchableOutputNameForDisplay = (state: SwitchableOutputState, switchingDeviceName: string) => {\n // when custom name defined, or group not overriden\n if (state.customName || state.group === \"\") {\n return state.customName || state.name\n }\n // otherwise prepend switching device name\n return `${switchingDeviceName} | ${state.name}`\n}\n\nexport const getSwitchableOutputStateTopics = (\n portalId: PortalId,\n deviceId: SwitchingDeviceInstanceId,\n outputId: SwitchableOutputId\n) => ({\n type: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/Type`,\n status: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Status`,\n name: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Name`,\n customName: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/CustomName`,\n group: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/Group`,\n showUIControl: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/ShowUIControl`,\n auto: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Auto`,\n state: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/State`,\n dimming: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Dimming`,\n dimmingMin: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/DimmingMin`,\n dimmingMax: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/DimmingMax`,\n stepSize: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/StepSize`,\n measurement: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Measurement`,\n unit: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/Unit`,\n decimals: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/Decimals`,\n labels: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Settings/Labels`,\n lightControls: `N/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/LightControls`,\n})\n\nexport const getSwitchableOutputWriteTopics = (\n portalId: PortalId,\n deviceId: SwitchingDeviceInstanceId,\n outputId: SwitchableOutputId\n) => ({\n auto: `W/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Auto`,\n state: `W/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/State`,\n dimming: `W/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/Dimming`,\n lightControls: `W/${portalId}/switch/${deviceId}/SwitchableOutput/${outputId}/LightControls`,\n})\n\nexport function useSwitchableOutput(\n deviceId: SwitchingDeviceInstanceId,\n outputId: SwitchableOutputId\n): SwitchableOutputProvider {\n const mqtt = useMqtt()\n const topics = useMemo(\n () => getSwitchableOutputStateTopics(mqtt.portalId, deviceId, outputId),\n [mqtt.portalId, deviceId, outputId]\n )\n const writeTopics = useMemo(\n () => getSwitchableOutputWriteTopics(mqtt.portalId, deviceId, outputId),\n [mqtt.portalId, deviceId, outputId]\n )\n\n const updateAuto = (auto: 0 | 1) => mqtt.publish(writeTopics!.auto, auto)\n const updateState = (state: 0 | 1) => mqtt.publish(writeTopics!.state, state)\n const updateDimming = (dimming: number) => mqtt.publish(writeTopics!.dimming, dimming)\n const updateLightControls = (hsvwa: HSVWColorArray) =>\n mqtt.publish(writeTopics!.lightControls, { raw: hsvwArrayToJSON(hsvwa) })\n\n return {\n ...useTopicsState<SwitchableOutputState>(topics),\n updateAuto,\n updateState,\n updateDimming,\n updateLightControls,\n }\n}\n"]}
|
|
@@ -96,8 +96,11 @@ export declare const SWITCHABLE_OUTPUT_TYPE: {
|
|
|
96
96
|
readonly UNRANGED_SETPOINT: 8;
|
|
97
97
|
readonly THREE_STATE_SWITCH: 9;
|
|
98
98
|
readonly BILGE_PUMP_CONTROL: 10;
|
|
99
|
+
readonly RGB_COLOR_WHEEL: 11;
|
|
100
|
+
readonly CCT_COLOR_WHEEL: 12;
|
|
101
|
+
readonly RGBW_COLOR_WHEEL: 13;
|
|
99
102
|
};
|
|
100
|
-
export type SwitchableOutputType = typeof SWITCHABLE_OUTPUT_TYPE[keyof typeof SWITCHABLE_OUTPUT_TYPE];
|
|
103
|
+
export type SwitchableOutputType = (typeof SWITCHABLE_OUTPUT_TYPE)[keyof typeof SWITCHABLE_OUTPUT_TYPE];
|
|
101
104
|
export declare const SWITCHABLE_OUTPUT_STATUS: {
|
|
102
105
|
readonly STATUS_OFF: 0;
|
|
103
106
|
readonly STATUS_ON: 9;
|
|
@@ -109,7 +112,7 @@ export declare const SWITCHABLE_OUTPUT_STATUS: {
|
|
|
109
112
|
readonly STATUS_DISABLED: 32;
|
|
110
113
|
readonly STATUS_BYPASSED: 64;
|
|
111
114
|
};
|
|
112
|
-
export type SwitchableOutputStatus = typeof SWITCHABLE_OUTPUT_STATUS[keyof typeof SWITCHABLE_OUTPUT_STATUS];
|
|
115
|
+
export type SwitchableOutputStatus = (typeof SWITCHABLE_OUTPUT_STATUS)[keyof typeof SWITCHABLE_OUTPUT_STATUS];
|
|
113
116
|
export declare const VIEWS: {
|
|
114
117
|
CONNECTING: string;
|
|
115
118
|
METRICS: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"/","sources":["src/utils/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;;;;CAIzB,CAAA;AAED,eAAO,MAAM,sBAAsB;;CAElC,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;CAe9B,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAA;AAED,eAAO,MAAM,cAAc;;;;;CAK1B,CAAA;AAED,eAAO,MAAM,YAAY;;;;CAIxB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;CAKvB,CAAA;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAED,eAAO,MAAM,aAAa;;;;;CAKzB,CAAA;AAED,eAAO,MAAM,+BAA+B,QAAQ,CAAA;AAEpD,eAAO,MAAM,8BAA8B;;;CAG1C,CAAA;AAED,eAAO,MAAM,cAAc;;CAE1B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;CAKhC,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;CAa3B,CAAA;AAGD,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"/","sources":["src/utils/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;;;;CAIzB,CAAA;AAED,eAAO,MAAM,sBAAsB;;CAElC,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;CAe9B,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAA;AAED,eAAO,MAAM,cAAc;;;;;CAK1B,CAAA;AAED,eAAO,MAAM,YAAY;;;;CAIxB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;CAKvB,CAAA;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAED,eAAO,MAAM,aAAa;;;;;CAKzB,CAAA;AAED,eAAO,MAAM,+BAA+B,QAAQ,CAAA;AAEpD,eAAO,MAAM,8BAA8B;;;CAG1C,CAAA;AAED,eAAO,MAAM,cAAc;;CAE1B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;CAKhC,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;CAa3B,CAAA;AAGD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;CAezB,CAAA;AAEV,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,OAAO,sBAAsB,CAAC,CAAA;AAGvG,eAAO,MAAM,wBAAwB;;;;;;;;;;CAU3B,CAAA;AAEV,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAA;AAG7G,eAAO,MAAM,KAAK;;;;;;;CAOjB,CAAA"}
|
|
@@ -82,7 +82,7 @@ export var TANK_FLUID_TYPE = {
|
|
|
82
82
|
LPG: 7,
|
|
83
83
|
LNG: 8,
|
|
84
84
|
HYDRAULIC_OIL: 9,
|
|
85
|
-
RAW_WATER: 10
|
|
85
|
+
RAW_WATER: 10,
|
|
86
86
|
};
|
|
87
87
|
// Taken from: https://github.com/victronenergy/venus/wiki/dbus#switch
|
|
88
88
|
export var SWITCHABLE_OUTPUT_TYPE = {
|
|
@@ -97,6 +97,9 @@ export var SWITCHABLE_OUTPUT_TYPE = {
|
|
|
97
97
|
UNRANGED_SETPOINT: 8,
|
|
98
98
|
THREE_STATE_SWITCH: 9,
|
|
99
99
|
BILGE_PUMP_CONTROL: 10,
|
|
100
|
+
RGB_COLOR_WHEEL: 11,
|
|
101
|
+
CCT_COLOR_WHEEL: 12,
|
|
102
|
+
RGBW_COLOR_WHEEL: 13,
|
|
100
103
|
};
|
|
101
104
|
// Taken from: https://github.com/victronenergy/venus/wiki/dbus#switch
|
|
102
105
|
export var SWITCHABLE_OUTPUT_STATUS = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"/","sources":["src/utils/constants.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"/","sources":["src/utils/constants.ts"],"names":[],"mappings":"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","sourcesContent":["export const BATTERY_STATE = {\n IDLE: 0,\n CHARGING: 1,\n DISCHARGING: 2,\n}\n\nexport const DC_SOURCE_MONITOR_MODE = {\n WIND_GENERATOR: -8,\n}\n\nexport const VEBUS_SYSTEM_STATE = {\n OFF: 0,\n LOW_POWER: 1,\n FAULT_CONDITION: 2,\n BULK_CHARGING: 3,\n ABSORPTION_CHARGINNG: 4,\n FLOAT_CHARGING: 5,\n STORAGE_MODE: 6,\n EQUALISATION_CHARGING: 7,\n PASSTHRU: 8,\n INVERTING: 9,\n ASSISTING: 10,\n POWER_SUPPLY_MODE: 11,\n DISCHARGING: 256,\n SUSTAIN: 257,\n}\n\nexport const AC_SOURCE = {\n NOT_AVAILABLE: 0,\n GRID: 1,\n GENSET: 2,\n SHORE: 3,\n INVERTING_ISLAND_MODE: 240,\n}\n\nexport const AC_SOURCE_TYPE = {\n NOT_IN_USE: 0,\n GRID: 1,\n GENERATOR: 2,\n SHORE: 3,\n}\n\nexport const ACTIVE_INPUT = {\n INPUT_0: 0,\n INPUT_1: 1,\n NONE: 240, // Inverting\n}\n\nexport const SYSTEM_MODE = {\n CHARGER_ONLY: 1,\n INVERTER_ONLY: 2,\n ON: 3,\n OFF: 4,\n}\n\nexport const CHARGER_MODE = {\n OFF: 4,\n ON: 1,\n}\n\nexport const INVERTER_MODE = {\n ON: 2,\n VEBUS_ON: 3, // Vebus inverters use mode 3 in stead of 2 for ON.\n OFF: 4,\n ECO: 5,\n}\n\nexport const FISCHER_PANDA_GENSET_PRODUCT_ID = 45120 /// 0xB040 VE_PROD_ID_FISCHER_PANDA_GENSET\n\nexport const FISCHER_PANDA_GENSET_AUTOSTART = {\n DISABLED: 0,\n ENABLED: 1,\n}\n\nexport const RELAY_FUNCTION = {\n GENERATOR_START_STOP: 1,\n}\n\nexport const GENERATOR_START_STOP = {\n STOP: 0,\n START: 1,\n AUTO_ON: 1,\n AUTO_OFF: 0,\n}\n\nexport const TANK_FLUID_TYPE = {\n FUEL: 0,\n FRESH_WATER: 1,\n WASTE_WATER: 2,\n LIVE_WELL: 3,\n OIL: 4,\n BLACK_WATER: 5,\n GASOLINE: 5,\n DIESEL: 6,\n LPG: 7,\n LNG: 8,\n HYDRAULIC_OIL: 9,\n RAW_WATER: 10,\n}\n\n// Taken from: https://github.com/victronenergy/venus/wiki/dbus#switch\nexport const SWITCHABLE_OUTPUT_TYPE = {\n MOMENTARY_SWITCH: 0,\n TOGGLE_SWITCH: 1,\n DIMMABLE: 2,\n TEMPERATURE_SETPOINT: 3,\n STEPPED_SWITCH: 4,\n SLAVE_MODE: 5,\n DROPDOWN: 6,\n SLIDER: 7,\n UNRANGED_SETPOINT: 8,\n THREE_STATE_SWITCH: 9,\n BILGE_PUMP_CONTROL: 10,\n RGB_COLOR_WHEEL: 11,\n CCT_COLOR_WHEEL: 12,\n RGBW_COLOR_WHEEL: 13,\n} as const\n\nexport type SwitchableOutputType = (typeof SWITCHABLE_OUTPUT_TYPE)[keyof typeof SWITCHABLE_OUTPUT_TYPE]\n\n// Taken from: https://github.com/victronenergy/venus/wiki/dbus#switch\nexport const SWITCHABLE_OUTPUT_STATUS = {\n STATUS_OFF: 0x00,\n STATUS_ON: 0x09,\n STATUS_POWERED: 0x01,\n STATUS_TRIPPED: 0x02,\n STATUS_OVER_TEMPERATURE: 0x04,\n STATUS_OUTPUT_FAULT: 0x08,\n STATUS_SHORT_FAULT: 0x10,\n STATUS_DISABLED: 0x20,\n STATUS_BYPASSED: 0x40,\n} as const\n\nexport type SwitchableOutputStatus = (typeof SWITCHABLE_OUTPUT_STATUS)[keyof typeof SWITCHABLE_OUTPUT_STATUS]\n\n\nexport const VIEWS = {\n CONNECTING: \"CONNECTING\",\n METRICS: \"METRICS\",\n INVERTER_CHARGER_INPUT_LIMIT_SELECTOR: \"INVERTER_CHARGER_INPUT_LIMIT_SELECTOR\",\n REMOTE_CONSOLE: \"REMOTE_CONSOLE\",\n MQTT_UNAVAILABLE: \"MQTT_UNAVAILABLE\",\n ERROR: \"ERROR\",\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type Hue = number & {
|
|
2
|
+
__brand: "Hue";
|
|
3
|
+
};
|
|
4
|
+
type Percentage = number & {
|
|
5
|
+
__brand: "Percentage";
|
|
6
|
+
};
|
|
7
|
+
type ColorTemperature = number & {
|
|
8
|
+
__brand: "ColorTemperature";
|
|
9
|
+
};
|
|
10
|
+
export interface HSVWColor {
|
|
11
|
+
hue: Hue;
|
|
12
|
+
saturation: Percentage;
|
|
13
|
+
brightness: Percentage;
|
|
14
|
+
white: Percentage;
|
|
15
|
+
colorTemperature: ColorTemperature;
|
|
16
|
+
}
|
|
17
|
+
export type HSVWColorArray = [number, number, number, number, number];
|
|
18
|
+
export declare function createHue(value: number): Hue;
|
|
19
|
+
export declare function createPercentage(value: number): Percentage;
|
|
20
|
+
export declare function createColorTemperature(value: number): ColorTemperature;
|
|
21
|
+
export declare function arrayToHSVW(arr: HSVWColorArray): HSVWColor;
|
|
22
|
+
export declare function hsvwToArray(color: HSVWColor): HSVWColorArray;
|
|
23
|
+
export declare function hsvwArrayToJSON(arr: HSVWColorArray): string;
|
|
24
|
+
export declare function createHSVWColor(hue: number, saturation: number, brightness: number, white: number, colorTemp: number): HSVWColor;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=hsvw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hsvw.d.ts","sourceRoot":"/","sources":["src/utils/hsvw.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,CAAA;AACtC,KAAK,UAAU,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAAA;AACpD,KAAK,gBAAgB,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAEhE,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,GAAG,CAAA;IACR,UAAU,EAAE,UAAU,CAAA;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,UAAU,CAAA;IACjB,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAErE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAG5C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAG1D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAGtE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,CAS1D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,cAAc,CAE5D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAS3D;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,SAAS,CAQX"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function createHue(value) {
|
|
2
|
+
var clamped = Math.max(0, Math.min(360, value));
|
|
3
|
+
return clamped;
|
|
4
|
+
}
|
|
5
|
+
export function createPercentage(value) {
|
|
6
|
+
var clamped = Math.max(0, Math.min(100, value));
|
|
7
|
+
return clamped;
|
|
8
|
+
}
|
|
9
|
+
export function createColorTemperature(value) {
|
|
10
|
+
var clamped = Math.max(0, Math.min(6500, value));
|
|
11
|
+
return clamped;
|
|
12
|
+
}
|
|
13
|
+
export function arrayToHSVW(arr) {
|
|
14
|
+
var hue = arr[0], saturation = arr[1], brightness = arr[2], white = arr[3], colorTemp = arr[4];
|
|
15
|
+
return {
|
|
16
|
+
hue: createHue(hue),
|
|
17
|
+
saturation: createPercentage(saturation),
|
|
18
|
+
brightness: createPercentage(brightness),
|
|
19
|
+
white: createPercentage(white),
|
|
20
|
+
colorTemperature: createColorTemperature(colorTemp),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function hsvwToArray(color) {
|
|
24
|
+
return [color.hue, color.saturation, color.brightness, color.white, color.colorTemperature];
|
|
25
|
+
}
|
|
26
|
+
export function hsvwArrayToJSON(arr) {
|
|
27
|
+
var formattedNumbers = arr
|
|
28
|
+
.map(function (n) {
|
|
29
|
+
// If integer, add .0, otherwise keep as is
|
|
30
|
+
return Number.isInteger(n) ? "".concat(n, ".0") : String(n);
|
|
31
|
+
})
|
|
32
|
+
.join(",");
|
|
33
|
+
return "{\"value\":[".concat(formattedNumbers, "]}");
|
|
34
|
+
}
|
|
35
|
+
export function createHSVWColor(hue, saturation, brightness, white, colorTemp) {
|
|
36
|
+
return {
|
|
37
|
+
hue: createHue(hue),
|
|
38
|
+
saturation: createPercentage(saturation),
|
|
39
|
+
brightness: createPercentage(brightness),
|
|
40
|
+
white: createPercentage(white),
|
|
41
|
+
colorTemperature: createColorTemperature(colorTemp),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=hsvw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hsvw.js","sourceRoot":"/","sources":["src/utils/hsvw.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IACjD,OAAO,OAAc,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IACjD,OAAO,OAAqB,CAAA;AAC9B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,IAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAClD,OAAO,OAA2B,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAmB;IACtC,IAAA,GAAG,GAA8C,GAAG,GAAjD,EAAE,UAAU,GAAkC,GAAG,GAArC,EAAE,UAAU,GAAsB,GAAG,GAAzB,EAAE,KAAK,GAAe,GAAG,GAAlB,EAAE,SAAS,GAAI,GAAG,GAAP,CAAO;IAC3D,OAAO;QACL,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC;QACnB,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC;QACxC,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC;QACxC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC;QAC9B,gBAAgB,EAAE,sBAAsB,CAAC,SAAS,CAAC;KACpD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAgB;IAC1C,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;AAC7F,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAmB;IACjD,IAAM,gBAAgB,GAAG,GAAG;SACzB,GAAG,CAAC,UAAC,CAAC;QACL,2CAA2C;QAC3C,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAG,CAAC,OAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,OAAO,sBAAa,gBAAgB,OAAI,CAAA;AAC1C,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,KAAa,EACb,SAAiB;IAEjB,OAAO;QACL,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC;QACnB,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC;QACxC,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC;QACxC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC;QAC9B,gBAAgB,EAAE,sBAAsB,CAAC,SAAS,CAAC;KACpD,CAAA;AACH,CAAC","sourcesContent":["type Hue = number & { __brand: \"Hue\" } // 0-360 degrees\ntype Percentage = number & { __brand: \"Percentage\" } // 0-100\ntype ColorTemperature = number & { __brand: \"ColorTemperature\" } // 0-6500 K\n\nexport interface HSVWColor {\n hue: Hue\n saturation: Percentage\n brightness: Percentage\n white: Percentage\n colorTemperature: ColorTemperature\n}\n\nexport type HSVWColorArray = [number, number, number, number, number]\n\nexport function createHue(value: number): Hue {\n const clamped = Math.max(0, Math.min(360, value))\n return clamped as Hue\n}\n\nexport function createPercentage(value: number): Percentage {\n const clamped = Math.max(0, Math.min(100, value))\n return clamped as Percentage\n}\n\nexport function createColorTemperature(value: number): ColorTemperature {\n const clamped = Math.max(0, Math.min(6500, value))\n return clamped as ColorTemperature\n}\n\nexport function arrayToHSVW(arr: HSVWColorArray): HSVWColor {\n const [hue, saturation, brightness, white, colorTemp] = arr\n return {\n hue: createHue(hue),\n saturation: createPercentage(saturation),\n brightness: createPercentage(brightness),\n white: createPercentage(white),\n colorTemperature: createColorTemperature(colorTemp),\n }\n}\n\nexport function hsvwToArray(color: HSVWColor): HSVWColorArray {\n return [color.hue, color.saturation, color.brightness, color.white, color.colorTemperature]\n}\n\nexport function hsvwArrayToJSON(arr: HSVWColorArray): string {\n const formattedNumbers = arr\n .map((n) => {\n // If integer, add .0, otherwise keep as is\n return Number.isInteger(n) ? `${n}.0` : String(n)\n })\n .join(\",\")\n\n return `{\"value\":[${formattedNumbers}]}`\n}\n\nexport function createHSVWColor(\n hue: number,\n saturation: number,\n brightness: number,\n white: number,\n colorTemp: number\n): HSVWColor {\n return {\n hue: createHue(hue),\n saturation: createPercentage(saturation),\n brightness: createPercentage(brightness),\n white: createPercentage(white),\n colorTemperature: createColorTemperature(colorTemp),\n }\n}\n"]}
|