Merge branch 'master' of http://git.spacen.net/yunkong2/yunkong2.rsonoff
This commit is contained in:
commit
8f6c6a0555
@ -1,41 +1,6 @@
|
||||
'use strict';
|
||||
const common = require(__dirname + '/common.js');
|
||||
const Modbus = require('./jsmodbus');
|
||||
// expected
|
||||
// let options = {
|
||||
// config: {
|
||||
// type: 'tcp',
|
||||
// recon:
|
||||
// timeout:
|
||||
// pulsetime:
|
||||
// poll:
|
||||
// defaultDeviceId: 0,
|
||||
// tcp: { // only if type="tcp" or type="tcprtu"
|
||||
// bind: '0.0.0.0',
|
||||
// port: 502,
|
||||
// },
|
||||
// serial: { // only if type="serial"
|
||||
// comName: 'tty',
|
||||
// parity:
|
||||
// dataBits:
|
||||
// stopBits
|
||||
// baudRate
|
||||
// },
|
||||
// maxBlock
|
||||
// },
|
||||
// objects: {
|
||||
// }
|
||||
// coils: {
|
||||
// addressLow: 0,
|
||||
// length: 1000,
|
||||
// config: []
|
||||
// blocks: {},
|
||||
// cyclicWrite // only holdingRegs
|
||||
// },
|
||||
// inputRegs: ...,
|
||||
// disInputs: ...,
|
||||
// holdingRegs: ...
|
||||
// };
|
||||
|
||||
|
||||
function Master(options, adapter) {
|
||||
|
406
lib/slave.js
406
lib/slave.js
@ -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;
|
412
main.js
412
main.js
@ -4,13 +4,13 @@
|
||||
'use strict';
|
||||
|
||||
const utils = require(__dirname + '/lib/utils');
|
||||
let modbus = null;
|
||||
let rsonoff = null;
|
||||
let fs;
|
||||
|
||||
let serialport = null;
|
||||
|
||||
let adapter = utils.Adapter({
|
||||
name: 'modbus',
|
||||
name: 'rsonoff',
|
||||
unload: stop
|
||||
});
|
||||
|
||||
@ -50,9 +50,9 @@ adapter.on('message', function (obj) {
|
||||
});
|
||||
|
||||
function stop(callback) {
|
||||
if (modbus) {
|
||||
modbus.close();
|
||||
modbus = null;
|
||||
if (rsonoff) {
|
||||
rsonoff.close();
|
||||
rsonoff = null;
|
||||
}
|
||||
|
||||
if (adapter && adapter.setState && adapter.config && adapter.config.params) {
|
||||
@ -72,16 +72,16 @@ let infoRegExp = new RegExp(adapter.namespace.replace('.', '\\.') + '\\.info\\.'
|
||||
|
||||
adapter.on('stateChange', (id, state) => {
|
||||
if (state && !state.ack && id && !infoRegExp.test(id)) {
|
||||
if (!modbus) {
|
||||
if (!rsonoff) {
|
||||
adapter.log.warn('No connection')
|
||||
} else {
|
||||
if (objects[id]) {
|
||||
modbus.write(id, state);
|
||||
rsonoff.write(id, state);
|
||||
} else {
|
||||
adapter.getObject(id, (err, data) => {
|
||||
if (!err) {
|
||||
objects[id] = data;
|
||||
modbus.write(id, state);
|
||||
rsonoff.write(id, state);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -726,246 +726,6 @@ function parseConfig(callback) {
|
||||
iterateAddresses(true, deviceId, device.coils, 'coils', 'coils', localOptions);
|
||||
iterateAddresses(false, deviceId, device.inputRegs, 'inputRegisters', 'inputRegs', localOptions);
|
||||
iterateAddresses(false, deviceId, device.holdingRegs, 'holdingRegisters', 'holdingRegs', localOptions);
|
||||
/*let regs = adapter.config.disInputs;
|
||||
let res = device.disInputs;
|
||||
if (regs && regs.length) {
|
||||
res.addressLow = 0xFFFFFFFF;
|
||||
res.addressHigh = 0;
|
||||
for (i = regs.length - 1; i >= 0; i--) {
|
||||
address = parseInt(regs[i].address, 10);
|
||||
|
||||
if (address < 0) {
|
||||
adapter.log.error('Invalid discrete inputs address: ' + address);
|
||||
regs.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
regs[i].id = 'discreteInputs.';
|
||||
if (showAliases) {
|
||||
regs[i].id += address2alias('disInputs', address, directAddresses, res.offset, options.multiDeviceId, regs[i].deviceId);
|
||||
} else {
|
||||
regs[i].id += address;
|
||||
}
|
||||
regs[i].id += (regs[i].name ? '_' + (regs[i].name.replace('.', '_').replace(' ', '_')) : '');
|
||||
}
|
||||
|
||||
if (regs.length) {
|
||||
regs.sort(sortByAddress);
|
||||
if (!doNotRoundAddressToWord) {
|
||||
res.addressLow = Math.floor(regs[0].address / 16) * 16;
|
||||
}
|
||||
res.addressHigh = regs[regs.length - 1].address;
|
||||
res.length = res.addressHigh - res.addressLow + 1;
|
||||
if (!doNotRoundAddressToWord && (res.length % 16)) {
|
||||
res.length = (Math.floor(res.length / 16) + 1) * 16;
|
||||
}
|
||||
} else {
|
||||
res.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Coils
|
||||
regs = adapter.config.coils;
|
||||
res = device.coils;
|
||||
if (regs && regs.length) {
|
||||
res.addressLow = 0xFFFFFFFF;
|
||||
res.addressHigh = 0;
|
||||
for (i = regs.length - 1; i >= 0; i--) {
|
||||
address = parseInt(regs[i].address, 10);
|
||||
|
||||
if (address < 0) {
|
||||
adapter.log.error('Invalid coils address: ' + address);
|
||||
regs.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
regs[i].id = 'coils.';
|
||||
if (showAliases) {
|
||||
regs[i].id += address2alias('coils', address, directAddresses, res.offset, options.multiDeviceId, regs[i].deviceId);
|
||||
} else {
|
||||
regs[i].id += address;
|
||||
}
|
||||
regs[i].id += (regs[i].name ? '_' + (regs[i].name.replace('.', '_').replace(' ', '_')) : '');
|
||||
|
||||
if (options.config.slave || regs[i].poll) {
|
||||
if (address < res.addressLow) res.addressLow = address;
|
||||
if (address > res.addressHigh) res.addressHigh = address;
|
||||
}
|
||||
}
|
||||
if (regs.length) {
|
||||
regs.sort(sortByAddress);
|
||||
if (!doNotRoundAddressToWord) {
|
||||
res.addressLow = Math.floor(res.addressLow / 16) * 16;
|
||||
}
|
||||
|
||||
res.length = res.addressHigh - res.addressLow + 1;
|
||||
if (!doNotRoundAddressToWord && (res.length % 16)) {
|
||||
res.length = (Math.floor(res.length / 16) + 1) * 16;
|
||||
}
|
||||
} else {
|
||||
regs.length = 0;
|
||||
}
|
||||
if (regs.mapping) {
|
||||
for (i = 0; i < regs.length; i++) {
|
||||
regs.mapping[regs[i].address - res.addressLow] = adapter.namespace + '.' + regs[i].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Input registers
|
||||
regs = adapter.config.inputRegs;
|
||||
res = device.inputRegs;
|
||||
if (regs.length) {
|
||||
for (i = regs.length - 1; i >= 0; i--) {
|
||||
address = parseInt(regs[i].address, 10);
|
||||
if (address < 0) {
|
||||
adapter.log.error('Invalid input register address: ' + address);
|
||||
regs.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
regs[i].type = regs[i].type || 'uint16be';
|
||||
regs[i].offset = parseFloat(regs[i].offset) || 0;
|
||||
regs[i].factor = parseFloat(regs[i].factor) || 1;
|
||||
if (regs[i].type === 'string') {
|
||||
regs[i].len = parseInt(regs[i].len) || 1;
|
||||
} else {
|
||||
regs[i].len = type_items_len[regs[i].type];
|
||||
}
|
||||
regs[i].len = regs[i].len || 1;
|
||||
|
||||
if (!regs[i].len) regs[i].len = parseInt(regs[i].len) || 1;
|
||||
|
||||
regs[i].id = 'inputRegisters.';
|
||||
if (showAliases) {
|
||||
regs[i].id += address2alias('inputRegs', address, directAddresses, res.offset, options.multiDeviceId, regs[i].deviceId);
|
||||
} else {
|
||||
regs[i].id += address;
|
||||
}
|
||||
|
||||
regs[i].id += (regs[i].name ? '_' + (regs[i].name.replace('.', '_').replace(' ', '_')) : '');
|
||||
}
|
||||
|
||||
lastAddress = null;
|
||||
startIndex = 0;
|
||||
for (i = 0; i < regs.length; i++) {
|
||||
address = parseInt(regs[i].address, 10);
|
||||
if (address < 0) continue;
|
||||
if (lastAddress === null) {
|
||||
startIndex = i;
|
||||
blockStart = address;
|
||||
lastAddress = address + regs[i].len;
|
||||
}
|
||||
|
||||
// try to detect next block
|
||||
if (res.blocks) {
|
||||
if ((address - lastAddress > 10 && regs[i].len < 10) || (lastAddress - blockStart >= options.config.maxBlock)) {
|
||||
if (res.blocks.map(obj => obj.start).indexOf(blockStart) === -1) {
|
||||
res.blocks.push({start: blockStart, count: lastAddress - blockStart, startIndex: startIndex, endIndex: i});
|
||||
}
|
||||
blockStart = address;
|
||||
startIndex = i;
|
||||
}
|
||||
}
|
||||
lastAddress = address + regs[i].len;
|
||||
}
|
||||
if (res.blocks && res.blocks.map(obj => obj.start).indexOf(blockStart) === -1) {
|
||||
res.blocks.push({start: blockStart, count: lastAddress - blockStart, startIndex: startIndex, endIndex: i});
|
||||
}
|
||||
if (regs.length) {
|
||||
res.addressLow = regs[0].address;
|
||||
res.addressHigh = regs[regs.length - 1].address + regs[regs.length - 1].len;
|
||||
res.length = res.addressHigh - res.addressLow;
|
||||
} else {
|
||||
regs.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Holding registers
|
||||
regs = adapter.config.holdingRegs;
|
||||
res = device.holdingRegs;
|
||||
if (regs.length) {
|
||||
res.addressLow = 0xFFFFFFFF;
|
||||
res.addressHigh = 0;
|
||||
|
||||
for (i = regs.length - 1; i >= 0; i--) {
|
||||
address = parseInt(regs[i].address, 10);
|
||||
|
||||
if (address < 0) {
|
||||
adapter.log.error('Invalid holding register address: ' + address);
|
||||
regs.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
regs[i].type = regs[i].type || 'uint16be';
|
||||
regs[i].offset = parseFloat(regs[i].offset) || 0;
|
||||
regs[i].factor = parseFloat(regs[i].factor) || 1;
|
||||
if (regs[i].type === 'string') {
|
||||
regs[i].len = parseInt(regs[i].len) || 1;
|
||||
} else {
|
||||
regs[i].len = type_items_len[regs[i].type];
|
||||
}
|
||||
regs[i].len = regs[i].len || 1;
|
||||
|
||||
regs[i].id = 'holdingRegisters.';
|
||||
if (showAliases) {
|
||||
regs[i].id += address2alias('holdingRegs', address, directAddresses, res.offset, options.multiDeviceId, regs[i].deviceId);
|
||||
} else {
|
||||
regs[i].id += address;
|
||||
}
|
||||
regs[i].id += (regs[i].name ? '_' + (regs[i].name.replace('.', '_').replace(' ', '_')) : '');
|
||||
|
||||
// collect cyclic write registers
|
||||
if (regs[i].cw) {
|
||||
res.cyclicWrite.push(adapter.namespace + '.' + regs[i].id);
|
||||
}
|
||||
|
||||
if (options.config.slave || regs[i].poll) {
|
||||
if (address < res.addressLow) res.addressLow = address;
|
||||
if (address + regs[i].len > res.addressHigh) res.addressHigh = address + regs[i].len;
|
||||
}
|
||||
}
|
||||
|
||||
lastAddress = null;
|
||||
startIndex = 0;
|
||||
for (i = 0; i < regs.length; i++) {
|
||||
address = parseInt(regs[i].address, 10);
|
||||
if (address < 0) continue;
|
||||
if (lastAddress === null) {
|
||||
startIndex = i;
|
||||
blockStart = address;
|
||||
lastAddress = address + regs[i].len;
|
||||
}
|
||||
// try to detect next block
|
||||
if (res.blocks) {
|
||||
if ((address - lastAddress > 10 && regs[i].len < 10) || (lastAddress - blockStart >= options.config.maxBlock)) {
|
||||
if (res.blocks.map(obj => obj.start).indexOf(blockStart) === -1) {
|
||||
res.blocks.push({start: blockStart, count: lastAddress - blockStart, startIndex: startIndex, endIndex: i});
|
||||
}
|
||||
blockStart = address;
|
||||
startIndex = i;
|
||||
}
|
||||
}
|
||||
lastAddress = address + regs[i].len;
|
||||
}
|
||||
if (res.blocks && res.blocks.map(obj => obj.start).indexOf(blockStart) === -1) {
|
||||
res.blocks.push({start: blockStart, count: lastAddress - blockStart, startIndex: startIndex, endIndex: i});
|
||||
}
|
||||
|
||||
if (regs.length) {
|
||||
res.length = res.addressHigh - res.addressLow;
|
||||
} else {
|
||||
res.length = 0;
|
||||
}
|
||||
|
||||
lastAddress = null;
|
||||
|
||||
if (regs.mapping) {
|
||||
for (i = 0; i < regs.length; i++) {
|
||||
res.mapping[regs[i].address - res.addressLow] = adapter.namespace + '.' + regs[i].id;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// ------------- create states and objects ----------------------------
|
||||
checkObjects(adapter.config, 'disInputs', 'discreteInputs', 'Discrete inputs', tasks, newObjects);
|
||||
@ -980,152 +740,6 @@ function parseConfig(callback) {
|
||||
device.holdingRegs.fullIds = adapter.config.holdingRegs.filter(e => e.deviceId === deviceId).map(e => e.fullId);
|
||||
}
|
||||
|
||||
/*for (i = 0; regs.length > i; i++) {
|
||||
id = adapter.namespace + '.' + regs[i].id;
|
||||
regs[i].fullId = id;
|
||||
objects[id] = {
|
||||
_id: regs[i].id,
|
||||
type: 'state',
|
||||
common: {
|
||||
name: regs[i].description,
|
||||
role: regs[i].role,
|
||||
type: 'boolean',
|
||||
read: true,
|
||||
write: false,
|
||||
def: false
|
||||
},
|
||||
native: {
|
||||
regType: 'disInputs',
|
||||
address: regs[i].address
|
||||
}
|
||||
};
|
||||
tasks.push({
|
||||
id: regs[i].id,
|
||||
name: 'add',
|
||||
obj: objects[id]
|
||||
});
|
||||
tasks.push({
|
||||
id: id,
|
||||
name: 'syncEnums',
|
||||
obj: regs[i].room
|
||||
});
|
||||
newObjects.push(id);
|
||||
}
|
||||
|
||||
regs = adapter.config.coils;
|
||||
for (i = 0; regs.length > i; i++) {
|
||||
id = adapter.namespace + '.' + regs[i].id;
|
||||
regs[i].fullId = id;
|
||||
objects[id] = {
|
||||
_id: regs[i].id,
|
||||
type: 'state',
|
||||
common: {
|
||||
name: regs[i].description,
|
||||
role: regs[i].role,
|
||||
type: 'boolean',
|
||||
read: true,
|
||||
write: true,
|
||||
def: false
|
||||
},
|
||||
native: {
|
||||
regType: 'coils',
|
||||
address: regs[i].address,
|
||||
|
||||
poll: regs[i].poll,
|
||||
wp: regs[i].wp
|
||||
}
|
||||
};
|
||||
|
||||
tasks.push({
|
||||
id: regs[i].id,
|
||||
name: 'add',
|
||||
obj: objects[id]
|
||||
});
|
||||
tasks.push({
|
||||
id: id,
|
||||
name: 'syncEnums',
|
||||
obj: regs[i].room
|
||||
});
|
||||
newObjects.push(id);
|
||||
}
|
||||
|
||||
regs = adapter.config.inputRegs;
|
||||
for (i = 0; regs.length > i; i++) {
|
||||
id = adapter.namespace + '.' + regs[i].id;
|
||||
regs[i].fullId = id;
|
||||
objects[id] = {
|
||||
_id: regs[i].id,
|
||||
type: 'state',
|
||||
common: {
|
||||
name: regs[i].description,
|
||||
role: regs[i].role,
|
||||
type: 'number',
|
||||
read: true,
|
||||
write: false,
|
||||
def: 0,
|
||||
unit: regs[i].unit || ''
|
||||
},
|
||||
native: {
|
||||
regType: 'inputRegs',
|
||||
address: regs[i].address,
|
||||
type: regs[i].type,
|
||||
len: regs[i].len,
|
||||
offset: regs[i].offset,
|
||||
factor: regs[i].factor
|
||||
}
|
||||
};
|
||||
tasks.push({
|
||||
id: regs[i].id,
|
||||
name: 'add',
|
||||
obj: objects[id]
|
||||
});
|
||||
tasks.push({
|
||||
id: id,
|
||||
name: 'syncEnums',
|
||||
obj: regs[i].room
|
||||
});
|
||||
newObjects.push(id);
|
||||
}
|
||||
|
||||
regs = adapter.config.holdingRegs;
|
||||
for (i = 0; regs.length > i; i++) {
|
||||
id = adapter.namespace + '.' + regs[i].id;
|
||||
regs[i].fullId = id;
|
||||
objects[id] = {
|
||||
_id: regs[i].id,
|
||||
type: 'state',
|
||||
common: {
|
||||
name: regs[i].description,
|
||||
role: regs[i].role,
|
||||
type: 'number',
|
||||
read: true,
|
||||
write: true,
|
||||
def: 0,
|
||||
unit: regs[i].unit || ''
|
||||
},
|
||||
native: {
|
||||
regType: 'holdingRegs',
|
||||
address: regs[i].address,
|
||||
poll: regs[i].poll,
|
||||
// wp: adapter.config.coils[i].wp
|
||||
type: regs[i].type,
|
||||
len: regs[i].len,
|
||||
offset: regs[i].offset,
|
||||
factor: regs[i].factor
|
||||
}
|
||||
};
|
||||
tasks.push({
|
||||
id: regs[i].id,
|
||||
name: 'add',
|
||||
obj: objects[id]
|
||||
});
|
||||
tasks.push({
|
||||
id: id,
|
||||
name: 'syncEnums',
|
||||
obj: regs[i].room
|
||||
});
|
||||
newObjects.push(id);
|
||||
}*/
|
||||
|
||||
if (!options.config.multiDeviceId) {
|
||||
break;
|
||||
@ -1194,13 +808,9 @@ function parseConfig(callback) {
|
||||
function main() {
|
||||
parseConfig(options => {
|
||||
let Modbus;
|
||||
if (options.config.slave) {
|
||||
Modbus = require(__dirname + '/lib/slave');
|
||||
} else {
|
||||
Modbus = require(__dirname + '/lib/master');
|
||||
}
|
||||
modbus = new Modbus(options, adapter);
|
||||
modbus.start();
|
||||
Modbus = require(__dirname + '/lib/master');
|
||||
rsonoff = new Modbus(options, adapter);
|
||||
rsonoff.start();
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user