删除 slave.js

master
钟进 6 years ago
parent 524596ac25
commit a89d232562

@ -1,406 +0,0 @@
'use strict';
const common = require(__dirname + '/common.js');
const Modbus = require('./jsmodbus');
// expected
// let options = {
// config: {
// round: 1,
// tcp: {
// port: 502
// }
// },
// objects: {
// }
// coils: {
// config: ...
// changed: true,
// addressHigh: 0,
// addressLow: 0,
// values: [],
// mapping: {}
// },
// inputRegs: ...,
// disInputs: ...,
// holdingRegs: ...
// };
function Slave(options, adapter) {
let objects = options.objects;
let device = options.devices[Object.keys(options.devices)[0]];
let delayStart = true;
let modbusServer;
function getListOfClients(clients) {
let list = [];
for(let c in clients) {
if (clients.hasOwnProperty(c)) {
let address = clients[c].address().address;
if (address) list.push(address);
}
}
return list.join(',');
}
this.write = (id, state) => {
if (!objects[id] || !objects[id].native) {
adapter.log.error('Can not set state ' + id + ': unknown object');
return;
}
if (objects[id].native.float === undefined) {
objects[id].native.float =
objects[id].native.type === 'floatle' || objects[id].native.type === 'floatbe' || objects[id].native.type === 'floatsw' ||
objects[id].native.type === 'doublele' || objects[id].native.type === 'doublebe' || objects[id].native.type === 'floatsb';
}
let val;
let buffer;
let b;
let t = typeof state.val;
let type = objects[id].native.regType;
let regs = device[type];
if (!regs) {
adapter.log.error('Invalid type ' + type);
return;
}
regs.changed = true;
if (type === 'disInputs' || type === 'coils') {
if (t === 'boolean' || t === 'number') {
regs.values[objects[id].native.address - regs.addressLow] = state.val ? 1 : 0;
} else {
regs.values[objects[id].native.address - regs.addressLow] = parseInt(state.val, 10) ? 1 : 0;
}
} else if (type === 'inputRegs' || type === 'holdingRegs') {
if (objects[id].native.type !== 'string') {
if (t === 'boolean') {
val = state.val ? 1 : 0;
} else if (t === 'number') {
val = state.val;
} else {
val = parseFloat(state.val);
}
val = (val - objects[id].native.offset) / objects[id].native.factor;
if (!objects[id].native.float) val = Math.round(val);
} else {
val = state.val;
}
buffer = common.writeValue(objects[id].native.type, val, objects[id].native.len);
for (b = 0; b < buffer.length; b++) {
regs.values[(objects[id].native.address - regs.addressLow) * 2 + b] = buffer[b];
}
} else {
adapter.log.error('Unknown state "' + id + '" type: ' + objects[id].native.regType);
}
};
this.start = () => {
if (!delayStart && !modbusServer) {
modbusServer = Modbus('server', 'tcp')({
options: {
log: adapter.log,
tcp: {
port: parseInt(options.config.tcp.port, 10) || 502,
hostname: options.config.tcp.bind || '127.0.0.1',
}
},
responseDelay: 100,
coils: new Buffer((device.coils.addressHigh >> 3) + ((device.coils.addressHigh - 1) % 8 ? 1 : 0)),
discrete: new Buffer((device.disInputs.addressHigh >> 3) + ((device.disInputs.addressHigh - 1) % 8 ? 1 : 0)),
input: new Buffer(device.inputRegs.addressHigh * 2),
holding: new Buffer(device.holdingRegs.addressHigh * 2)
});
modbusServer.on('readCoilsRequest', function (start, quantity) {
let regs = device.coils;
if (regs.changed || (regs.lastStart > start || regs.lastEnd < start + quantity)) {
regs.lastStart = start;
regs.lastEnd = start + quantity;
regs.changed = false;
let resp = new Array(Math.ceil(quantity / 16) * 2);
let i = 0;
let data = this.getCoils();
let j;
for (j = 0; j < resp.length && start + j < data.byteLength; j++) {
resp[j] = data.readUInt8(start + j);
}
for (; j < resp.length; j++) {
resp[j] = 0;
}
while (i < quantity && i + start < regs.addressHigh) {
if (regs.values[i + start - regs.addressLow]) {
resp[Math.floor(i / 8)] |= 1 << (i % 8);
} else {
resp[Math.floor(i / 8)] &= ~(1 << (i % 8));
}
i++;
}
let len = data.length;
for (i = 0; i < resp.length; i++) {
if (start + i >= len) break;
data.writeUInt8(resp[i], start + i);
}
}
});
modbusServer.on('readDiscreteInputsRequest', function (start, quantity) {
let regs = device.disInputs;
if (regs.changed || (regs.lastStart > start || regs.lastEnd < start + quantity)) {
regs.lastStart = start;
regs.lastEnd = start + quantity;
regs.changed = false;
let resp = new Array(Math.ceil(quantity / 16) * 2);
let i = 0;
let data = this.getDiscrete();
let j;
for (j = 0; j < resp.length && start + j < data.byteLength; j++) {
resp[j] = data.readUInt8(start + j);
}
for (; j < resp.length; j++) {
resp[j] = 0;
}
while (i < quantity && i + start < regs.addressHigh) {
if (regs.values[i + start - regs.addressLow]) {
resp[Math.floor(i / 8)] |= 1 << (i % 8);
} else {
resp[Math.floor(i / 8)] &= ~(1 << (i % 8));
}
i++;
}
let len = data.length;
for (i = 0; i < resp.length; i++) {
if (start + i >= len) break;
data.writeUInt8(resp[i], start + i);
}
}
});
modbusServer.on('readInputRegistersRequest', function (start, quantity) {
let regs = device.inputRegs;
if (regs.changed || (regs.lastStart > start || regs.lastEnd < start + quantity)) {
regs.lastStart = start;
regs.lastEnd = start + quantity;
regs.changed = false;
let data = this.getInput();
const end = start + quantity * 2;
const low = regs.addressLow * 2;
const high = regs.addressHigh * 2;
for (let i = start; i < end; i++) {
if (i >= data.length) break;
if (i >= low && i < high) {
data.writeUInt8(regs.values[i - low], i);
} else {
data.writeUInt8(0, i);
}
}
}
});
modbusServer.on('readHoldingRegistersRequest', function (start, quantity) {
let regs = device.holdingRegs;
if (regs.changed || (regs.lastStart > start || regs.lastEnd < start + quantity)) {
regs.lastStart = start;
regs.lastEnd = start + quantity;
regs.changed = false;
let data = this.getHolding();
const end = start + quantity * 2;
const low = regs.addressLow * 2;
const high = regs.addressHigh * 2;
for (let i = start; i < end; i++) {
if (i >= data.length) break;
if (i >= low && i < high) {
data.writeUInt8(regs.values[i - low], i);
} else {
data.writeUInt8(0, i);
}
}
}
});
modbusServer.on('postWriteSingleCoilRequest', function (start, value) {
let regs = device.coils;
let a = start - regs.addressLow;
if (a >= 0 && regs.mapping[a]) {
adapter.setState(regs.mapping[a], value, true, function (err) {
// analyse if the state could be set (because of permissions)
if (err) adapter.log.error('Can not set state: ' + err);
});
regs.values[a] = value;
}
});
const mPow2 = [
0x01,
0x02,
0x04,
0x08,
0x10,
0x20,
0x40,
0x80
];
modbusServer.on('postWriteMultipleCoilsRequest', function (start, length /* , byteLength*/) {
let regs = device.coils;
let i = 0;
let data = this.getCoils();
if (start < regs.addressLow) {
start = regs.addressLow;
}
while (i < length && i + start < regs.addressHigh) {
let a = i + start - regs.addressLow;
if (a >= 0 && regs.mapping[a]) {
let value = data.readUInt8((i + start) >> 3);
value = value & mPow2[(i + start) % 8];
adapter.setState(regs.mapping[a], !!value, true, function (err) {
// analyse if the state could be set (because of permissions)
if (err) adapter.log.error('Can not set state: ' + err);
});
regs.values[a] = !!value;
}
i++;
}
});
modbusServer.on('postWriteSingleRegisterRequest', function (start, value) {
let regs = device.holdingRegs;
start = start >> 1;
let a = start - regs.addressLow;
if (a >= 0 && regs.mapping[a]) {
let native = options.objects[regs.mapping[a]].native;
let buf = new Buffer(2);
buf.writeUInt16BE(value);
let val = common.extractValue(native.type, native.len, buf, 0);
if (native.type !== 'string') {
val = (val - native.offset) / native.factor;
val = Math.round(val * options.config.round) / options.config.round;
}
adapter.setState(regs.mapping[a], val, true, function (err) {
// analyse if the state could be set (because of permissions)
if (err) adapter.log.error('Can not set state: ' + err);
});
regs.values[a] = buf[0];
regs.values[a + 1] = buf[1];
}
});
modbusServer.on('postWriteMultipleRegistersRequest', function (start, length /* , byteLength*/) {
let regs = device.holdingRegs;
let data = this.getHolding();
let i = 0;
start = start >> 1;
if (start < regs.addressLow) {
start = regs.addressLow;
}
while (i < length && i + start < regs.addressHigh) {
let a = i + start - regs.addressLow;
if (a >= 0 && regs.mapping[a]) {
let native = options.objects[regs.mapping[a]].native;
let val = common.extractValue(native.type, native.len, data, i + start);
if (native.type !== 'string') {
val = val * native.factor + native.offset;
val = Math.round(val * options.config.round) / options.config.round;
}
adapter.setState(regs.mapping[a], val, true, function (err) {
// analyse if the state could be set (because of permissions)
if (err) adapter.log.error('Can not set state: ' + err);
});
for (let k = 0; k < native.len * 2; k++) {
regs.values[a * 2 + k] = data.readUInt8(start * 2 + k);
}
i += native.len;
} else {
i++;
}
}
});
modbusServer.on('connection', client => {
let list = getListOfClients(modbusServer.getClients());
adapter.log.debug('+ Clients connected: ' + list);
adapter.setState('info.connection', list, true);
}).on('close', client => {
let list = getListOfClients(modbusServer.getClients());
adapter.log.debug('- Client connected: ' + list);
adapter.setState('info.connection', list, true);
}).on('error', err => {
let list = getListOfClients(modbusServer.getClients());
adapter.log.info('- Clients connected: ' + list);
adapter.setState('info.connection', list, true);
adapter.log.warn('Error on connection: ' + JSON.stringify(err));
});
}
};
this.close = () => {
if (modbusServer) {
try {
modbusServer.close();
} catch (e) {
}
modbusServer = null;
}
};
this._initValues = (states, regs) => {
// build ready arrays
for (let i = 0; regs.fullIds.length > i; i++) {
let id = regs.fullIds[i];
if (states[id] && states[id].val !== undefined) {
this.write(id, states[id]);
} else {
adapter.setState(id, 0, true, err => {
// analyse if the state could be set (because of permissions)
if (err) adapter.log.error('Can not set state ' + id + ': ' + err);
});
}
}
// fill with 0 empty values
for (let i = 0; i < regs.values.length; i++) {
if (regs.values[i] === undefined || regs.values[i] === null) {
regs.values[i] = 0;
} else if (typeof regs.values[i] === 'boolean') {
regs.values[i] = regs.values[i] ? 1 : 0;
} else if (typeof regs.values[i] !== 'number') {
regs.values[i] = parseInt(regs.values[i], 10) ? 1 : 0;
}
}
};
this.initValues = callback => {
// read all states
adapter.getStates('*', (err, states) => {
this._initValues(states, device.disInputs);
this._initValues(states, device.coils);
this._initValues(states, device.inputRegs);
this._initValues(states, device.holdingRegs);
callback();
});
};
(function _constructor() {
adapter.setState('info.connection', 0, true);
this.initValues(() => {
delayStart = false;
adapter.log.debug('Slave ready to start');
this.start();
});
}.bind(this))();
return this;
}
module.exports = Slave;
Loading…
Cancel
Save