matterbridge-tado-hw
Version:
A Matterbridge plugin that connects Tado° V2/V3/V3+ hot water control to the Matter smart home ecosystem
71 lines • 2.86 kB
JavaScript
// Matterbridge plugin for Tado hot water control
// Copyright © 2025 Alexander Thoukydides
import assert from 'assert';
// Milliseconds in a second
export const MS = 1000;
// Type assertions
export function assertIsDefined(value) {
assert.notStrictEqual(value, undefined);
assert.notStrictEqual(value, null);
}
// Log an error
export function logError(log, when, err) {
try {
// Log the error message itself
log.error(`[${when}] ${String(err)}`);
// Log any stack backtrace
if (err instanceof Error && err.stack)
log.debug(err.stack);
}
catch { /* empty */ }
}
// Format a counted noun (handling most regular cases automatically)
export function plural(count, noun, showCount = true) {
const [singular, plural] = Array.isArray(noun) ? noun : [noun, ''];
noun = count === 1 ? singular : plural;
if (!noun) {
// Apply regular rules
const rules = [
['on$', 'a', 2], // phenomenon/phenomena criterion/criteria
['us$', 'i', 1], // cactus/cacti focus/foci
['[^aeiou]y$', 'ies', 1], // cty/cites puppy/puppies
['(ch|is|o|s|sh|x|z)$', 'es', 0], // iris/irises truss/trusses
['', 's', 0] // cat/cats house/houses
];
const rule = rules.find(([ending]) => new RegExp(ending, 'i').test(singular));
assertIsDefined(rule);
const matchCase = (s) => singular === singular.toUpperCase() ? s.toUpperCase() : s;
noun = singular.substring(0, singular.length - rule[2]).concat(matchCase(rule[1]));
}
return showCount ? `${count} ${noun}` : noun;
}
// Recursive object assignment, skipping undefined values
export function deepMerge(...objects) {
const isObject = (value) => value !== undefined && typeof value === 'object' && !Array.isArray(value);
return objects.reduce((acc, object) => {
Object.entries(object).forEach(([key, value]) => {
const accValue = acc[key];
if (value === undefined)
return;
if (isObject(accValue) && isObject(value))
acc[key] = deepMerge(accValue, value);
else
acc[key] = value;
});
return acc;
}, {});
}
// Convert checker validation error into lines of text
export function getValidationTree(errors) {
const lines = [];
errors.forEach((error, index) => {
const prefix = (a, b) => index < errors.length - 1 ? a : b;
lines.push(`${prefix('├─ ', '└─ ')}${error.path} ${error.message}`);
if (error.nested) {
const nested = getValidationTree(error.nested);
lines.push(...nested.map(line => `${prefix('│ ', ' ')} ${line}`));
}
});
return lines;
}
//# sourceMappingURL=utils.js.map