homebridge-logo-platform
Version:
This is a Siemens LOGO! Platform Plugin.
488 lines • 19.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModBusLogo = exports.LogoAddress = exports.WordLen = exports.AddressType = void 0;
let ModbusRTU = require('modbus-serial');
const error_1 = require("./error");
var AddressType;
(function (AddressType) {
AddressType[AddressType["MBATDiscreteInput"] = 0] = "MBATDiscreteInput";
AddressType[AddressType["MBATCoil"] = 1] = "MBATCoil";
AddressType[AddressType["MBATInputRegister"] = 2] = "MBATInputRegister";
AddressType[AddressType["MBATHoldingRegister"] = 3] = "MBATHoldingRegister";
})(AddressType = exports.AddressType || (exports.AddressType = {}));
var WordLen;
(function (WordLen) {
WordLen[WordLen["MBWLBit"] = 0] = "MBWLBit";
WordLen[WordLen["MBWLByte"] = 1] = "MBWLByte";
WordLen[WordLen["MBWLWord"] = 2] = "MBWLWord";
WordLen[WordLen["MBWLDWord"] = 3] = "MBWLDWord";
})(WordLen = exports.WordLen || (exports.WordLen = {}));
class LogoAddress {
constructor(addr, type, wLen, readOnly) {
this.addr = addr;
this.type = type;
this.wLen = wLen;
this.readOnly = readOnly;
}
}
exports.LogoAddress = LogoAddress;
class ModBusLogo {
constructor(ip, port, debug, logFunction, retrys) {
this.timeout = 500; // original 100
this.sleeptime = 100;
this.ip = ip;
this.port = port;
this.debugMsgLog = debug;
this.log = logFunction;
this.retryCnt = retrys;
}
ReadLogo(item, callBack) {
if (!item) {
if (this.debugMsgLog == 1) {
this.log('ReadLogo() ModBus - No LOGO! Address!');
}
callBack(error_1.ErrorNumber.noData);
return error_1.ErrorNumber.noData;
}
var addr = this.getLogoAddress(item);
switch (addr.type) {
case AddressType.MBATDiscreteInput:
this.readDiscreteInput(addr, callBack, this.debugMsgLog, this.log, this.retryCnt);
break;
case AddressType.MBATCoil:
this.readCoil(addr, callBack, this.debugMsgLog, this.log, this.retryCnt);
break;
case AddressType.MBATInputRegister:
this.readInputRegister(addr, callBack, this.debugMsgLog, this.log, this.retryCnt);
break;
case AddressType.MBATHoldingRegister:
this.readHoldingRegister(addr, callBack, this.debugMsgLog, this.log, this.retryCnt);
break;
}
}
WriteLogo(item, value) {
if (!item) {
if (this.debugMsgLog == 1) {
this.log('WriteLogo() ModBus - No LOGO! Address!');
}
return error_1.ErrorNumber.noData;
}
var addr = this.getLogoAddress(item);
if ((addr.readOnly == false) && (value >= 0)) {
if (addr.type == AddressType.MBATCoil) {
this.writeCoil(addr.addr, (value == 1 ? true : false), this.debugMsgLog, this.log, this.retryCnt);
}
if (addr.type == AddressType.MBATHoldingRegister) {
switch (addr.wLen) {
case WordLen.MBWLByte:
this.writeRegister(addr.addr, ((value & 0b11111111) << 8), this.debugMsgLog, this.log, this.retryCnt);
break;
case WordLen.MBWLWord:
this.writeRegister(addr.addr, value, this.debugMsgLog, this.log, this.retryCnt);
break;
case WordLen.MBWLDWord:
this.writeRegisters(addr.addr, [((value & 0b11111111111111110000000000000000) >> 16), (value & 0b00000000000000001111111111111111)], this.debugMsgLog, this.log, this.retryCnt);
break;
}
}
}
}
DisconnectS7() {
if (this.debugMsgLog == 1) {
this.log('DisconnectS7() - ModBus LOGO! has no disconnect.');
}
}
withConnection(client, debugLog, log, onReady, onConnectFail) {
let failed = false;
const fail = (reason) => {
if (failed)
return;
failed = true;
if (debugLog == 1) {
log('ModBus connect failed: ' + reason);
}
try {
client.close(() => { });
}
catch (e) { /* ignore */ }
sleep(this.sleeptime).then(onConnectFail);
};
try {
client.connectTcpRTUBuffered(this.ip, { port: this.port }, (connectErr) => {
if (connectErr) {
fail(connectErr.message || String(connectErr));
return;
}
const port = client._port;
if (port) {
port.on('error', (err) => {
if (debugLog == 1)
log('ModBus port error: ' + err.message);
});
if (port._client && typeof port._client.on === 'function') {
port._client.on('error', (err) => {
if (debugLog == 1)
log('ModBus raw socket error: ' + err.message);
});
}
}
client.setTimeout(this.timeout);
client.setID(1);
onReady();
});
}
catch (e) {
fail('exception: ' + (e && e.message ? e.message : String(e)));
}
}
readDiscreteInput(addr, callBack, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log('readDiscreteInput() - Retry counter reached max value');
}
callBack(error_1.ErrorNumber.noData);
return error_1.ErrorNumber.noData;
}
let len = 1;
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.readDiscreteInputs(addr.addr, len, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.readDiscreteInput(addr, callBack, debugLog, log, retryCount);
});
}
else {
callBack((data.data[0] == true ? 1 : 0));
}
client.close();
});
}, () => this.readDiscreteInput(addr, callBack, debugLog, log, retryCount));
}
readCoil(addr, callBack, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log('readCoil() - Retry counter reached max value');
}
callBack(error_1.ErrorNumber.noData);
return error_1.ErrorNumber.noData;
}
let len = 1;
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.readCoils(addr.addr, len, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.readCoil(addr, callBack, debugLog, log, retryCount);
});
}
else {
callBack((data.data[0] == true ? 1 : 0));
}
client.close();
});
}, () => this.readCoil(addr, callBack, debugLog, log, retryCount));
}
readInputRegister(addr, callBack, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log('readInputRegister() - Retry counter reached max value');
}
callBack(error_1.ErrorNumber.noData);
return error_1.ErrorNumber.noData;
}
let len = 1;
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.readInputRegisters(addr.addr, len, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.readInputRegister(addr, callBack, debugLog, log, retryCount);
});
}
else {
let num = data.data[0];
if (num > error_1.ErrorNumber.maxPositivNumber) {
num = num - error_1.ErrorNumber.max16BitNumber;
}
callBack(num);
}
client.close();
});
}, () => this.readInputRegister(addr, callBack, debugLog, log, retryCount));
}
readHoldingRegister(addr, callBack, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log('readHoldingRegister() - Retry counter reached max value');
}
callBack(error_1.ErrorNumber.noData);
return error_1.ErrorNumber.noData;
}
let len = (addr.wLen == WordLen.MBWLDWord ? 2 : 1);
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.readHoldingRegisters(addr.addr, len, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.readHoldingRegister(addr, callBack, debugLog, log, retryCount);
});
}
else {
let num = 0;
switch (addr.wLen) {
case WordLen.MBWLByte:
num = (data.data[0] & 0b1111111100000000) >> 8;
if (num > error_1.ErrorNumber.maxPositivNumber) {
num = num - error_1.ErrorNumber.max16BitNumber;
}
callBack(num);
break;
case WordLen.MBWLWord:
num = data.data[0];
if (num > error_1.ErrorNumber.maxPositivNumber) {
num = num - error_1.ErrorNumber.max16BitNumber;
}
callBack(num);
break;
case WordLen.MBWLDWord:
num = (data.data[0] << 16) | data.data[1];
if (num > error_1.ErrorNumber.maxPositivNumber) {
num = num - error_1.ErrorNumber.max16BitNumber;
}
callBack(num);
break;
}
}
client.close();
});
}, () => this.readHoldingRegister(addr, callBack, debugLog, log, retryCount));
}
writeCoil(addr, state, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log('writeCoil() - Retry counter reached max value');
}
return error_1.ErrorNumber.noData;
}
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.writeCoil(addr, state, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.writeCoil(addr, state, debugLog, log, retryCount);
});
}
client.close();
});
}, () => this.writeCoil(addr, state, debugLog, log, retryCount));
}
writeRegister(addr, value, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log('writeRegister() - Retry counter reached max value');
}
return error_1.ErrorNumber.noData;
}
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.writeRegister(addr, value, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.writeRegister(addr, value, debugLog, log, retryCount);
});
}
client.close();
});
}, () => this.writeRegister(addr, value, debugLog, log, retryCount));
}
writeRegisters(addr, value, debugLog, log, retryCount) {
if (retryCount == 0) {
if (debugLog == 1) {
log(' writeRegisters() - Retry counter reached max value');
}
return error_1.ErrorNumber.noData;
}
let client = new ModbusRTU();
client.on('error', (err) => {
if (debugLog == 1) {
log('ModBus socket error: ' + err.message);
}
});
retryCount = retryCount - 1;
this.withConnection(client, debugLog, log, () => {
client.writeRegisters(addr, value, (err, data) => {
if (err) {
this.logError(log, err, debugLog, retryCount);
sleep(this.sleeptime).then(() => {
this.writeRegisters(addr, value, debugLog, log, retryCount);
});
}
client.close();
});
}, () => this.writeRegisters(addr, value, debugLog, log, retryCount));
}
logError(log, err, debugLog, retryCount) {
if ((debugLog == 1) && (retryCount == 1)) {
log(err);
}
}
getLogoAddress(name) {
if (name.match("AI[0-9]{1,2}")) {
var num = parseInt(name.replace("AI", ""), 10);
return new LogoAddress(num - 1, AddressType.MBATInputRegister, WordLen.MBWLWord, true); // Start: 0, Lenght: 8
}
if (name.match("AQ[0-9]{1,2}")) {
var num = parseInt(name.replace("AQ", ""), 10);
return new LogoAddress((511 + num), AddressType.MBATHoldingRegister, WordLen.MBWLWord, false); // Start: 512, Lenght: 8
}
if (name.match("AM[0-9]{1,2}")) {
var num = parseInt(name.replace("AM", ""), 10);
return new LogoAddress((527 + num), AddressType.MBATHoldingRegister, WordLen.MBWLWord, false); // Start: 528, Lenght: 8
}
if (name.match("I[0-9]{1,2}")) {
var num = parseInt(name.replace("I", ""), 10);
return new LogoAddress(num - 1, AddressType.MBATDiscreteInput, WordLen.MBWLBit, true); // Start: 0, Lenght: 24
}
if (name.match("Q[0-9]{1,2}")) {
var num = parseInt(name.replace("Q", ""), 10);
return new LogoAddress((8191 + num), AddressType.MBATCoil, WordLen.MBWLBit, false); // Start: 8192, Lenght: 20
}
if (name.match("M[0-9]{1,2}")) {
var num = parseInt(name.replace("M", ""), 10);
return new LogoAddress((8255 + num), AddressType.MBATCoil, WordLen.MBWLBit, false); // Start: 8256, Lenght: 64
}
if (name.match("V[0-9]{1,4}\.[0-7]{1}")) {
var str = name.replace("V", "");
var a = parseInt(str.split(".", 2)[0], 10);
var b = parseInt(str.split(".", 2)[1], 10);
return new LogoAddress(((a * 8) + b), AddressType.MBATCoil, WordLen.MBWLBit, false); // Start: 0, Lenght: 6808 (850*8+8)
}
if (name.match("VB[0-9]{1,4}")) {
var num = parseInt(name.replace("VB", ""), 10);
return new LogoAddress(Math.floor(num / 2), AddressType.MBATHoldingRegister, WordLen.MBWLByte, false); // Start: 0, Lenght: 425 (850/2)
}
if (name.match("VW[0-9]{1,4}")) {
var num = parseInt(name.replace("VW", ""), 10);
return new LogoAddress(Math.floor(num / 2), AddressType.MBATHoldingRegister, WordLen.MBWLWord, false); // Start: 0, Lenght: 425 (850/2)
}
if (name.match("VD[0-9]{1,4}")) {
var num = parseInt(name.replace("VD", ""), 10);
return new LogoAddress(Math.floor(num / 2), AddressType.MBATHoldingRegister, WordLen.MBWLDWord, false); // Start: 0, Lenght: 425 (850/2)
}
return new LogoAddress(0, AddressType.MBATCoil, WordLen.MBWLBit, false);
}
isValidLogoAddress(name) {
if (name.match("AI[0-9]{1,2}")) {
return true;
}
if (name.match("AQ[0-9]{1,2}")) {
return true;
}
if (name.match("AM[0-9]{1,2}")) {
return true;
}
if (name.match("I[0-9]{1,2}")) {
return true;
}
if (name.match("Q[0-9]{1,2}")) {
return true;
}
if (name.match("M[0-9]{1,2}")) {
return true;
}
if (name.match("V[0-9]{1,4}\.[0-7]{1}")) {
return true;
}
if (name.match("VB[0-9]{1,4}")) {
return true;
}
if (name.match("VW[0-9]{1,4}")) {
return true;
}
if (name.match("VD[0-9]{1,4}")) {
return true;
}
return false;
}
isAnalogLogoAddress(name) {
if (name.match("AI[0-9]{1,2}")) {
return true;
}
if (name.match("AQ[0-9]{1,2}")) {
return true;
}
if (name.match("AM[0-9]{1,2}")) {
return true;
}
if (name.match("I[0-9]{1,2}")) {
return false;
}
if (name.match("Q[0-9]{1,2}")) {
return false;
}
if (name.match("M[0-9]{1,2}")) {
return false;
}
if (name.match("V[0-9]{1,4}\.[0-7]{1}")) {
return false;
}
if (name.match("VB[0-9]{1,4}")) {
return true;
}
if (name.match("VW[0-9]{1,4}")) {
return true;
}
if (name.match("VD[0-9]{1,4}")) {
return true;
}
return false;
}
}
exports.ModBusLogo = ModBusLogo;
const sleep = (milliseconds) => {
return new Promise(resolve => setTimeout(resolve, milliseconds));
};
//# sourceMappingURL=modbus-logo.js.map