vastra-radiator-valve
Version:
Node.js library to query and configure Vastra's smart radiator valves.
148 lines (147 loc) • 6.44 kB
JavaScript
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStateWritePackets = exports.createStateReadPacket = exports.createWakeUpPacket = exports.decodeStateField = exports.encodeStateField = exports.RESPONSE_FOOTER_LENGTH = exports.PACKET_HEADER_LENGTH = exports.PacketId = void 0;
var binary_writer_1 = require("./binary-writer");
var constants_1 = require("./constants");
var utils_1 = require("./utils");
var PacketId;
(function (PacketId) {
PacketId[PacketId["WakeUp"] = 235] = "WakeUp";
PacketId[PacketId["StateChunk"] = 165] = "StateChunk";
PacketId[PacketId["SaveSuccess"] = 130] = "SaveSuccess";
PacketId[PacketId["ReadSuccess"] = 129] = "ReadSuccess";
})(PacketId || (exports.PacketId = PacketId = {}));
exports.PACKET_HEADER_LENGTH = 5;
exports.RESPONSE_FOOTER_LENGTH = 3; // crc + \r + \n
var STATE_OP_READ = 1;
var STATE_OP_WRITE = 2;
var CRC8_MAXIM_TABLE = [
0, 94, -68, -30, 97, 63, -35, -125, -62, -100, 126, 32, -93, -3, 31, 65, -99, -61, 33, 127, -4,
-94, 64, 30, 95, 1, -29, -67, 62, 96, -126, -36, 35, 125, -97, -63, 66, 28, -2, -96, -31, -65, 93,
3, -128, -34, 60, 98, -66, -32, 2, 92, -33, -127, 99, 61, 124, 34, -64, -98, 29, 67, -95, -1, 70,
24, -6, -92, 39, 121, -101, -59, -124, -38, 56, 102, -27, -69, 89, 7, -37, -123, 103, 57, -70,
-28, 6, 88, 25, 71, -91, -5, 120, 38, -60, -102, 101, 59, -39, -121, 4, 90, -72, -26, -89, -7, 27,
69, -58, -104, 122, 36, -8, -90, 68, 26, -103, -57, 37, 123, 58, 100, -122, -40, 91, 5, -25, -71,
-116, -46, 48, 110, -19, -77, 81, 15, 78, 16, -14, -84, 47, 113, -109, -51, 17, 79, -83, -13, 112,
46, -52, -110, -45, -115, 111, 49, -78, -20, 14, 80, -81, -15, 19, 77, -50, -112, 114, 44, 109,
51, -47, -113, 12, 82, -80, -18, 50, 108, -114, -48, 83, 13, -17, -79, -16, -82, 76, 18, -111,
-49, 45, 115, -54, -108, 118, 40, -85, -11, 23, 73, 8, 86, -76, -22, 105, 55, -43, -117, 87, 9,
-21, -75, 54, 104, -118, -44, -107, -53, 41, 119, -12, -86, 72, 22, -23, -73, 85, 11, -120, -42,
52, 106, 43, 117, -105, -55, 74, 20, -10, -88, 116, 42, -56, -106, 21, 75, -87, -9, -74, -24, 10,
84, -41, -119, 107, 53,
];
function calculateChecksum(buffer) {
var value = 0;
for (var i = 1; i < 1 + buffer.length - 1; i++) {
value = CRC8_MAXIM_TABLE[(value ^ buffer[i]) & 255];
}
return value;
}
function encodeStateField(value, method) {
if (value instanceof Buffer) {
return value;
}
switch (method) {
case "direct":
return Buffer.from(Array.isArray(value) ? value : [value]);
case "byte-to-float-05":
return Buffer.from([(value / 0.5) & 255]);
case "string":
case "hex-string":
return Buffer.from(value);
default:
throw new Error("Unsupported field encoding: " + method);
}
}
exports.encodeStateField = encodeStateField;
function decodeStateField(value, method) {
switch (method) {
case "direct":
return value.length === 1 ? value[0] : value;
case "battery-voltage":
return ((value[0] & 255) + 170) / 100;
case "byte-to-float-01":
return value[0] * 0.1;
case "byte-to-float-05":
return (value[0] & 255) * 0.5;
case "short-to-float-01":
return ((value[1] & 255) | (value[0] << 8)) * 0.1;
case "string":
return value.toString("utf8");
case "hex-string":
return __spreadArray([], __read(value), false).map(function (x) { return x.toString(16); }).join("");
default:
throw new Error("Unsupported field encoding: " + method);
}
}
exports.decodeStateField = decodeStateField;
// General packet structure:
// ---------------------------
// Offset | Type | Description
// ---------------------------
// 0 | uint8 | Packet ID
// 1 | uint8 | Packet data length (excluding \r\n)
// 2 | N | Data
// N | uint8 | CRC
// N+1 | uint8 | \r (not in wakeup)
// N+2 | uint8 | \n (not in wakeup, only sometimes?)
function createWakeUpPacket() {
var writer = new binary_writer_1.default();
writer.writeUInt8(PacketId.WakeUp);
return writer.toBuffer();
}
exports.createWakeUpPacket = createWakeUpPacket;
function createStateReadPacket(offset, length) {
if (length === void 0) { length = 48; }
var writer = new binary_writer_1.default();
writer.writeUInt8(PacketId.StateChunk);
writer.writeUInt8(5);
writer.writeUInt8(STATE_OP_READ);
writer.writeUInt16(offset);
writer.writeUInt8(length);
writer.writeUInt8(calculateChecksum(writer.toBuffer()));
writer.writeUInt8(13);
return writer.toBuffer();
}
exports.createStateReadPacket = createStateReadPacket;
function createStateWritePackets(data, startOffset) {
return (0, utils_1.chunk)(__spreadArray([], __read(data), false), constants_1.MAX_STATE_WRITE_CHUNK).map(function (chunk, chunkIndex) {
var relativeOffset = chunkIndex * constants_1.MAX_STATE_WRITE_CHUNK;
var writer = new binary_writer_1.default();
writer.writeUInt8(PacketId.StateChunk);
writer.writeUInt8(chunk.length + 4);
writer.writeUInt8(STATE_OP_WRITE);
writer.writeUInt16(startOffset + relativeOffset);
writer.write(__spreadArray([], __read(chunk), false));
writer.writeUInt8(calculateChecksum(writer.toBuffer()));
writer.writeUInt8(13);
writer.writeUInt8(10);
return writer.toBuffer();
});
}
exports.createStateWritePackets = createStateWritePackets;