@andrei-tatar/node-red-contrib-nibetcp
Version:
Node-red integration for Nibe S series heatpumps using modbus over TCP
91 lines (90 loc) • 3.86 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadAllRegisters = loadAllRegisters;
const promises_1 = require("fs/promises");
const VALID_REGISTER_TYPES = [
"MODBUS_INPUT_REGISTER",
"MODBUS_HOLDING_REGISTER",
];
const SIZE_MAP = new Map([
[1, "s8"],
[2, "s16"],
[3, "s32"],
[4, "u8"],
[5, "u16"],
[6, "u32"],
]);
function loadAllRegisters(registerFile) {
return __awaiter(this, void 0, void 0, function* () {
const data = yield (0, promises_1.readFile)(registerFile);
const registersString = data.toString("utf-8");
const lines = registersString.split(/[\n\r]/gm).filter((l) => !!l);
const headers = lines[0].split("\t").filter((p) => !!p);
const titleIndex = headers.indexOf("Title");
const typeIndex = headers.indexOf("Register type");
const address = headers.indexOf("Register");
const divisionFactor = headers.indexOf("Division factor");
const unit = headers.indexOf("Unit");
const sizeIndex = headers.indexOf("Size of variable");
const minValue = headers.indexOf("Min value");
const maxValue = headers.indexOf("Max value");
const defaultValue = headers.indexOf("Default value");
const registers = lines
.slice(1)
.map((l) => {
const parts = l.split("\t");
const size = /(?:s|u)(?:8|16|32)/.test(parts[sizeIndex])
? parts[sizeIndex]
: parseInt(parts[sizeIndex], 10) || 5;
const registerType = parts[typeIndex];
let registerAddress = parseInt(parts[address], 10);
if (registerType === "MODBUS_INPUT_REGISTER") {
registerAddress += 40000;
}
if (registerType === "MODBUS_HOLDING_REGISTER") {
registerAddress += 30000;
}
const regFromFile = {
label: parts[titleIndex],
type: registerType,
address: registerAddress,
divisionFactor: parseInt(parts[divisionFactor], 10),
unit: parts[unit],
size: typeof size === "number" ? SIZE_MAP.get(size) : size,
minValue: parts[minValue] === "-" ? null : parseInt(parts[minValue], 10),
maxValue: parts[maxValue] === "-" ? null : parseInt(parts[maxValue], 10),
defaultValue: parts[defaultValue] === "-"
? null
: parseInt(parts[defaultValue], 10),
};
return regFromFile;
})
.filter(validate);
return registers;
});
}
function validate(reg) {
if (!isNumber(reg.address) ||
!isNumber(reg.divisionFactor) ||
!isNumber(reg.minValue, true) ||
!isNumber(reg.maxValue, true) ||
!isNumber(reg.defaultValue, true) ||
!VALID_REGISTER_TYPES.includes(reg.type) ||
!reg.size) {
return false;
}
return true;
}
function isNumber(val, allowNull = false) {
return ((allowNull && val === null) ||
(typeof val === "number" && !isNaN(val) && isFinite(val)));
}