Skip to content

Instantly share code, notes, and snippets.

@LucaLanziani
Created November 25, 2022 08:33
Show Gist options
  • Save LucaLanziani/77460162ff1b83c348fc29e714e64ec7 to your computer and use it in GitHub Desktop.
Save LucaLanziani/77460162ff1b83c348fc29e714e64ec7 to your computer and use it in GitHub Desktop.
const fs = require('fs');
const htmlparser = require('htmlparser2');
function Project(xmlConfigPath) {
var self = this;
this.xmlConfigPath = xmlConfigPath;
this.devices = {};
this.groups = {};
self.GroupAddressPrefix = [];
self.BuildingPartPrefix = [];
self.DeviceIdPrefix = [];
self.DeviceNamePrefix = [];
function pushTo(listName, attr) {
return function (name, attrs) {
self[listName].push(attrs[attr]);
};
}
var onclosetag = {
GroupRange: function () {
self.GroupAddressPrefix.pop();
},
BuildingPart: function () {
self.BuildingPartPrefix.pop();
},
Area: function () {
self.DeviceIdPrefix.pop();
self.DeviceNamePrefix.pop();
},
Line: function () {
self.DeviceIdPrefix.pop();
self.DeviceNamePrefix.pop();
},
};
var onopentag = {
BuildingPart: pushTo('BuildingPartPrefix', 'Name'),
DeviceInstanceRef: pushTo('BuildingPartPrefix', 'RefId'),
GroupRange: pushTo('GroupAddressPrefix', 'Name'),
GroupAddress: function (name, attrs) {
var address = self._fromDecTo3LevelGroupAddress(attrs.Address);
self.groups[address] = {
groupName: self.GroupAddressPrefix.join(' '),
description: attrs.Name,
address: address,
};
if (attrs.DatapointType) {
self.groups[address].datapoint = self._fromDPSTtoDPT(
attrs.DatapointType
);
}
},
Area: function (name, attrs) {
pushTo('DeviceIdPrefix', 'Address')(name, attrs);
pushTo('DeviceNamePrefix', 'Name')(name, attrs);
},
Line: function (name, attrs) {
pushTo('DeviceIdPrefix', 'Address')(name, attrs);
pushTo('DeviceNamePrefix', 'Name')(name, attrs);
},
DeviceInstance: function (name, attrs) {
if (attrs.Address) {
//console.log(address, DeviceNamePrefix.concat(attrs.Name));
var address = self.DeviceIdPrefix.concat(attrs.Address).join('.');
self.devices[address] = self.DeviceNamePrefix.concat(attrs.Name).join(
' '
);
}
},
};
this.parser = new htmlparser.Parser(
{
onopentag: function (name, attrs) {
var action = onopentag[name];
if (action) {
action(name, attrs);
}
},
onclosetag: function (name) {
var action = onclosetag[name];
if (action) {
action(name);
}
},
},
{ xmlMode: true, decodeEntities: true }
);
}
Project.prototype._fromDPSTtoDPT = function _fromDPSTtoDPT(dpst) {
var bits = '000';
var value = dpst.split('-');
var result = [];
if (value[0] != 'DPST') {
throw new Error('Expecting a DPST received %s', dpst);
}
result.push(value[1]);
result.push(bits.slice(0, 3 - value[2].length) + value[2]);
return result.join('.');
};
Project.prototype._fromDecTo3LevelGroupAddress = function fromDecTo3LevelGroupAddress(
dec
) {
var bits = '0000000000000000';
var chunks = [5, 3, 8];
var bitRepresentation = (+dec).toString(2);
var padded = bits.slice(0, 16 - bitRepresentation.length) + bitRepresentation;
var result = [];
var start = 0;
chunks.forEach(function (size) {
result.push(parseInt(padded.slice(start, start + size), 2));
start += size;
});
return result
.map(function (value) {
return value.toString();
})
.join('/');
};
Project.prototype.setGroupStatus = function setGroupStatus(
groupAddress,
status
) {
let group = this.groups[groupAddress] || (this.groups[groupAddress] = {});
group['status'] = status;
};
Project.prototype.parseETSConfig = function parseETSConfig(cb) {
var self = this;
this.GroupAddressPrefix = [];
this.BuildingPartPrefix = [];
this.DeviceIdPrefix = [];
this.DeviceNamePrefix = [];
fs.createReadStream(this.xmlConfigPath)
.on('data', function (chunk) {
self.parser.write(chunk);
})
.on('end', () => {
self.parser.end();
cb(null, self);
})
.on('error', (err) => {
console.log(err); // eslint-disable-line no-console
cb(err);
});
};
module.exports.Project = Project;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment