Skip to content

Instantly share code, notes, and snippets.

@rossnelson
Last active May 28, 2021 18:13
Show Gist options
  • Save rossnelson/a33ae9401759f0f4d044fc7c639a5e7b to your computer and use it in GitHub Desktop.
Save rossnelson/a33ae9401759f0f4d044fc7c639a5e7b to your computer and use it in GitHub Desktop.
const _ = require("lodash");
const manifest = {
common: {
device_id: {
compressed: "d",
},
access_method_id: {
compressed: "ami",
},
internal_temperature: {
compressed: "it",
},
climate_mode: {
compressed: "cm",
},
},
thermostat: {
rcs: {
TZ45HR: {
internal_temperature: {
type: "integer",
raw: "49-1-1",
},
climate_mode: {
type: "enum",
raw: "64-1-0",
enum: {
Off: "off",
Heat: "heat",
Cool: "cool",
Auto: "auto",
"Aux Heat": "aux heat",
},
metric_name: "thermostat_mode",
can_be_changed_manually: true,
},
},
TW45HR: {
internal_temperature: {
type: "integer",
raw: "T",
},
climate_mode: {
type: "enum",
raw: "M",
enum: {
O: "off",
C: "cool",
H: "heat",
A: "auto",
},
can_be_changed_manually: true,
metric_name: "thermostat_mode",
},
},
},
},
};
device = {
id: "44b18ef1-2b4f-11eb-b186-3f82b6627395",
node_id: "7",
type: "thermostat",
make: "rcs",
model: "TZ45HR",
};
events = [
{
node_id: 7,
class_id: 49,
instance: 1,
index: 1,
units: "c",
value_id: "7-49-1-1",
value: 24,
},
{
node_id: 7,
class_id: 49,
instance: 1,
index: 1,
units: "F",
value_id: "7-49-1-1",
value: 75,
},
{
node_id: 7,
class_id: 64,
instance: 1,
index: 0,
value_id: "7-64-1-0",
value: "Cool",
},
];
processors = {
integer: (val, config) => parseInt(val),
enum: (val, config) => config.enum[val],
reverse_enum: (val, config) => {
e = {};
Object.keys(config.enum).forEach((k) => (e[config.enum[k]] = k));
return e[val];
},
internal_temperature: (event, val) => {
event.units = (event.units || "F").toString().toLowerCase();
if (event.units === "f") return val;
return _.round((val * 9) / 5 + 32, 2);
},
};
events.forEach((event) => {
console.log();
console.log("EVENT", event.value_id);
console.log();
console.log(device);
console.log(event);
// normalize
model_config = manifest[device.type][device.make][device.model];
matched_keys = Object.keys(model_config).filter((p) => {
return `${device.node_id}-${model_config[p].raw}` === event.value_id;
});
matched_key = matched_keys[0];
matched_config = model_config[matched_key];
normalized = {
device_id: device.id,
};
val = processors[matched_config.type](event.value, matched_config);
if (processors[matched_key]) {
val = processors[matched_key](event, val);
}
normalized[matched_key] = val;
console.log(normalized);
// compress
compressed = {};
Object.keys(normalized).forEach((k) => {
compressed_key = manifest.common[k].compressed;
compressed[compressed_key || k] = normalized[k];
});
console.log(JSON.stringify(compressed));
// re-normalize
reversed = {};
Object.keys(manifest.common).forEach((k) => {
key = manifest.common[k].compressed;
val = k;
reversed[key] = k;
});
renormalized = {};
Object.keys(compressed).forEach((k) => {
normalized_key = reversed[k];
renormalized[normalized_key || k] = compressed[k];
});
console.log(renormalized);
// re-raw
raw = {
node_id: device.node_id,
};
Object.keys(renormalized).forEach((k) => {
config = _.get(model_config, `${k}`);
raw_key = _.get(model_config, `${k}.raw`);
if (!raw_key) return;
[class_id, instance, index] = raw_key.split("-");
raw.value_id = `${raw.node_id}-${raw_key}`;
value = renormalized[k];
processor = processors[`reverse_${config.type}`];
if (processor) value = processor(value, config);
value = raw = {
...raw,
class_id,
instance,
index,
value,
};
});
console.log(raw);
});
EVENT 7-49-1-1
{
id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
node_id: '7',
type: 'thermostat',
make: 'rcs',
model: 'TZ45HR'
}
{
node_id: 7,
class_id: 49,
instance: 1,
index: 1,
units: 'c',
value_id: '7-49-1-1',
value: 24
}
{
device_id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
internal_temperature: 75.2
}
{"d":"44b18ef1-2b4f-11eb-b186-3f82b6627395","it":75.2}
{
device_id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
internal_temperature: 75.2
}
{
node_id: '7',
value_id: '7-49-1-1',
class_id: '49',
instance: '1',
index: '1',
value: 75.2
}
EVENT 7-49-1-1
{
id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
node_id: '7',
type: 'thermostat',
make: 'rcs',
model: 'TZ45HR'
}
{
node_id: 7,
class_id: 49,
instance: 1,
index: 1,
units: 'F',
value_id: '7-49-1-1',
value: 75
}
{
device_id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
internal_temperature: 75
}
{"d":"44b18ef1-2b4f-11eb-b186-3f82b6627395","it":75}
{
device_id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
internal_temperature: 75
}
{
node_id: '7',
value_id: '7-49-1-1',
class_id: '49',
instance: '1',
index: '1',
value: 75
}
EVENT 7-64-1-0
{
id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
node_id: '7',
type: 'thermostat',
make: 'rcs',
model: 'TZ45HR'
}
{
node_id: 7,
class_id: 64,
instance: 1,
index: 0,
value_id: '7-64-1-0',
value: 'Cool'
}
{
device_id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
climate_mode: 'cool'
}
{"d":"44b18ef1-2b4f-11eb-b186-3f82b6627395","cm":"cool"}
{
device_id: '44b18ef1-2b4f-11eb-b186-3f82b6627395',
climate_mode: 'cool'
}
{
node_id: '7',
value_id: '7-64-1-0',
class_id: '64',
instance: '1',
index: '0',
value: 'Cool'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment