hm2mqtt 3.2.0 → 3.2.1
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/README.md +4 -4
- package/lib/compare.js +32 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,12 +35,12 @@ state directory; broker credentials can live in the shared `/etc/mqtt-interfaces
|
|
|
35
35
|
`--uninstall -n hm` removes the instance. `--config-schema` prints a JSON schema of all options
|
|
36
36
|
(management UIs like [she](https://github.com/hobbyquaker/she) build their config forms from it).
|
|
37
37
|
|
|
38
|
-
Docker (
|
|
38
|
+
Docker (multi-arch image for amd64, arm64 and armv7):
|
|
39
39
|
|
|
40
40
|
```
|
|
41
|
-
docker
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
docker run -d --name hm2mqtt --restart unless-stopped --network host -v hm2mqtt:/data \
|
|
42
|
+
-e HM2MQTT_CCU_ADDRESS=homematic-ccu3 -e HM2MQTT_MQTT_URL=mqtt://broker \
|
|
43
|
+
ghcr.io/hobbyquaker/hm2mqtt.js
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Host networking, or publish 2126/2127 and set `HM2MQTT_INIT_ADDRESS` to the docker host's address
|
package/lib/compare.js
CHANGED
|
@@ -39,12 +39,14 @@ function same(a, b) {
|
|
|
39
39
|
/**
|
|
40
40
|
* @param {Map<string, string>} left item → raw payload (the reference, e.g. the flow)
|
|
41
41
|
* @param {Map<string, string>} right item → raw payload (hm2mqtt)
|
|
42
|
-
* @returns {{leftOnly: string[], rightOnly: string[], differences: Array<{item: string, field: string, left: *, right: *}>,
|
|
42
|
+
* @returns {{leftOnly: string[], rightOnly: string[], differences: Array<{item: string, field: string, left: *, right: *}>,
|
|
43
|
+
* additions: Array<{item: string, field: string, right: *}>, same: number}}
|
|
43
44
|
*/
|
|
44
45
|
export function compareTrees(left, right) {
|
|
45
46
|
const leftOnly = [];
|
|
46
47
|
const rightOnly = [];
|
|
47
48
|
const differences = [];
|
|
49
|
+
const additions = [];
|
|
48
50
|
let sameCount = 0;
|
|
49
51
|
for (const item of left.keys()) {
|
|
50
52
|
if (!right.has(item)) {
|
|
@@ -73,7 +75,11 @@ export function compareTrees(left, right) {
|
|
|
73
75
|
if (IGNORED_HM_FIELDS.has(field)) {
|
|
74
76
|
continue;
|
|
75
77
|
}
|
|
76
|
-
if (
|
|
78
|
+
if (hl[field] === undefined && hr[field] !== undefined) {
|
|
79
|
+
// a field the reference never had: an addition, not a difference
|
|
80
|
+
if (!ADDED_HM_FIELDS.has(field)) {
|
|
81
|
+
additions.push({item, field: 'hm.' + field, right: hr[field]});
|
|
82
|
+
}
|
|
77
83
|
continue;
|
|
78
84
|
}
|
|
79
85
|
if (!same(hl[field], hr[field])) {
|
|
@@ -87,17 +93,38 @@ export function compareTrees(left, right) {
|
|
|
87
93
|
}
|
|
88
94
|
leftOnly.sort();
|
|
89
95
|
rightOnly.sort();
|
|
90
|
-
return {leftOnly, rightOnly, differences, same: sameCount};
|
|
96
|
+
return {leftOnly, rightOnly, differences, additions, same: sameCount};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function countBy(list, key) {
|
|
100
|
+
const counts = new Map();
|
|
101
|
+
for (const entry of list) {
|
|
102
|
+
counts.set(entry[key], (counts.get(entry[key]) || 0) + 1);
|
|
103
|
+
}
|
|
104
|
+
return [...counts].sort((a, b) => b[1] - a[1]);
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
export function formatReport(
|
|
94
|
-
{leftOnly, rightOnly, differences, same},
|
|
108
|
+
{leftOnly, rightOnly, differences, additions = [], same},
|
|
95
109
|
{leftName = 'left', rightName = 'right', limit = 50} = {},
|
|
96
110
|
) {
|
|
97
111
|
const lines = [];
|
|
112
|
+
const differing = new Set(differences.map((d) => d.item)).size;
|
|
98
113
|
lines.push(
|
|
99
|
-
`${same} items identical, ${differences.length} differences, ${leftOnly.length} only in ${leftName}, ${rightOnly.length} only in ${rightName}`,
|
|
114
|
+
`${same} items identical, ${differing} items with ${differences.length} differences, ${additions.length} added fields, ${leftOnly.length} only in ${leftName}, ${rightOnly.length} only in ${rightName}`,
|
|
100
115
|
);
|
|
116
|
+
if (differences.length > 0) {
|
|
117
|
+
lines.push('', 'differences by field:');
|
|
118
|
+
for (const [field, n] of countBy(differences, 'field')) {
|
|
119
|
+
lines.push(` ${field}: ${n}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (additions.length > 0) {
|
|
123
|
+
lines.push('', `fields only in ${rightName} (additions):`);
|
|
124
|
+
for (const [field, n] of countBy(additions, 'field')) {
|
|
125
|
+
lines.push(` ${field}: ${n}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
101
128
|
const list = (title, items) => {
|
|
102
129
|
if (items.length === 0) {
|
|
103
130
|
return;
|