Ajout gestion Look & Sync firmwares, et routes BST
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
const dbcontroller = require('../db');
|
||||
const util = require('../util');
|
||||
|
||||
const postRequestToDo = async function (data, msn) {
|
||||
const postRequestToDo = async function (msn, body) {
|
||||
try {
|
||||
await dbcontroller.addDevice(body, null)
|
||||
|
||||
body.inventory.forEach(async device => {
|
||||
await dbcontroller.addDevice(device, body.relayMsn)
|
||||
});
|
||||
|
||||
return { success: true }
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
@@ -10,13 +17,315 @@ const postRequestToDo = async function (data, msn) {
|
||||
|
||||
const getRequestToDo = async function (msn) {
|
||||
try {
|
||||
return { success: true }
|
||||
var todos = []
|
||||
const children = await dbcontroller.getDeviceChildren(msn)
|
||||
|
||||
for (const child of children) {
|
||||
///// Retrieve child
|
||||
const device = await dbcontroller.getDevice(child.msn)
|
||||
|
||||
var todo = { msn : child.msn }
|
||||
|
||||
///// Programs
|
||||
if (device.programs != undefined) {
|
||||
if (child.programmingTimestamp < device.programs.timestamp) { todo.programs = 1 }
|
||||
else if (child.programmingTimestamp > device.programs.timestamp) { todo.programs = 2 }
|
||||
}
|
||||
|
||||
///// Configuration
|
||||
if (device.configuration != undefined) {
|
||||
if (child.configurationTimestamp < device.configuration.timestamp) { todo.configuration = 1 }
|
||||
else if (child.configurationTimestamp > device.configuration.timestamp) { todo.configuration = 2 }
|
||||
}
|
||||
|
||||
///// Slots
|
||||
if (device.slots != undefined) {
|
||||
if (child.programmingTimestamp < device.slots.timestamp) { todo.slots = 1 }
|
||||
else if (child.programmingTimestamp > device.slots.timestamp) { todo.slots = 2 }
|
||||
}
|
||||
|
||||
///// Status
|
||||
if (device.statusCommand != undefined) { todo.status = 1 }
|
||||
|
||||
///// Manual
|
||||
if (device.manualCommand != undefined) { todo.manual = 1 }
|
||||
|
||||
///// Acknowledged
|
||||
if (device.acknowledgedAlerts != undefined) { todo.acknowledged = 1 }
|
||||
|
||||
///// Firmware
|
||||
if (device.firmware != undefined) { device.firmware = 1 }
|
||||
|
||||
///// Add objet to todos only if something to do
|
||||
if (Object.keys(todo).length > 1) { todos.push(todo) }
|
||||
}
|
||||
|
||||
return todos
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const getStatus = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.status || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const updateStatus = async function (msn, status, timestamp) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
var device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { await dbcontroller.addDevice({"msn": msn}); }
|
||||
|
||||
device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variables
|
||||
if (status) {
|
||||
device.status = { timestamp: timestamp || util.unixTimestamp(), status: status }
|
||||
} else {
|
||||
device.status = undefined
|
||||
}
|
||||
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device);
|
||||
|
||||
return 200;
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const getPrograms = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.programs || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const postPrograms = async function (msn, programs, timestamp) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
var device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variables
|
||||
if (programs) {
|
||||
device.programs = { timestamp: timestamp || util.unixTimestamp(), programs: programs }
|
||||
} else {
|
||||
device.programmingTimestamp = device.programs.timestamp;
|
||||
// device.programs = undefined
|
||||
}
|
||||
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device)
|
||||
|
||||
return device.programs
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const getConfiguration = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.configuration || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const postConfiguration = async function (msn, configuration, timestamp) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variables
|
||||
if (configuration) {
|
||||
device.configuration = { timestamp: timestamp || util.unixTimestamp(), configuration: configuration }
|
||||
} else {
|
||||
device.configurationTimestamp = device.configuration.timestamp;
|
||||
// device.configuration = undefined
|
||||
}
|
||||
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device)
|
||||
|
||||
return device.configuration
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const getSlots = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.slots || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const postSlots = async function (msn, slots, timestamp) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variables
|
||||
if (slots) {
|
||||
device.slots = { timestamp: timestamp || util.unixTimestamp(), slots: slots }
|
||||
} else {
|
||||
device.programmingTimestamp = device.slots.timestamp;
|
||||
// device.slots = undefined
|
||||
}
|
||||
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device, msn)
|
||||
|
||||
return device.slots
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const getManualCommand = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.manualCommand || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const postManualCommand = async function (msn, manualCommand) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variable
|
||||
if (manualCommand) {
|
||||
device.manualCommand = { timestamp: util.unixTimestamp(), manualCommand: manualCommand }
|
||||
} else {
|
||||
device.manualCommand = undefined
|
||||
}
|
||||
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device, msn)
|
||||
|
||||
return device.manualCommand
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const getStatusCommand = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.statusCommand || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const postStatusCommand = async function (msn, statusCommand) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variable
|
||||
if (statusCommand) {
|
||||
device.statusCommand = { timestamp: util.unixTimestamp(), statusCommand: statusCommand }
|
||||
} else {
|
||||
device.statusCommand = undefined
|
||||
}
|
||||
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device, msn)
|
||||
|
||||
return device.statusCommand
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const getAcknowledgedAlerts = async function (msn) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
return device.acknowledgedAlerts || {}
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const postAcknowledgedAlerts = async function (msn, acknowledgedAlerts) {
|
||||
try {
|
||||
///// Retrieve device
|
||||
const device = await dbcontroller.getDevice(msn)
|
||||
if (!device) { throw({message: "module_not_found_for_this_identifier"}) }
|
||||
|
||||
///// Set variable
|
||||
if (acknowledgedAlerts) {
|
||||
device.acknowledgedAlerts = { timestamp: util.unixTimestamp(), acknowledgedAlerts: acknowledgedAlerts }
|
||||
} else {
|
||||
device.acknowledgedAlerts = undefined
|
||||
}
|
||||
///// Update device
|
||||
await dbcontroller.updateDevice(device, msn)
|
||||
|
||||
return device.acknowledgedAlerts
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
getStatus,
|
||||
updateStatus,
|
||||
postRequestToDo,
|
||||
getRequestToDo,
|
||||
getPrograms,
|
||||
postPrograms,
|
||||
getConfiguration,
|
||||
postConfiguration,
|
||||
getSlots,
|
||||
postSlots,
|
||||
getManualCommand,
|
||||
postManualCommand,
|
||||
getStatusCommand,
|
||||
postStatusCommand,
|
||||
getAcknowledgedAlerts,
|
||||
postAcknowledgedAlerts,
|
||||
}
|
||||
|
||||
@@ -1,20 +1,191 @@
|
||||
const lookFirmware = (serialNumber, hash, version, type, hardwareIndex, hardwareVersion) => {
|
||||
var fs = require('fs').promises;
|
||||
var path = require('path');
|
||||
var crc = require('crc');
|
||||
var chokidar = require('chokidar');
|
||||
|
||||
var firmwares = []
|
||||
|
||||
const parseVersion = (version) => {
|
||||
try {
|
||||
return {}
|
||||
const array = version.split('.')
|
||||
|
||||
if (!array || array.length != 3) { throw ({ message: 'invalid_version' }) }
|
||||
|
||||
return {
|
||||
major: array[0],
|
||||
minor: array[1],
|
||||
build: array[2],
|
||||
}
|
||||
} catch (e) { return null; }
|
||||
}
|
||||
|
||||
const compareVersions = (v1, v2) => {
|
||||
var normalized1 = (v1.major << 16) | (v1.minor << 8) | (v1.build);
|
||||
var normalized2 = (v2.major << 16) | (v2.minor << 8) | (v2.build);
|
||||
|
||||
return (normalized1 > normalized2) ? -1 : (normalized1 < normalized2) ? 1 : 0;
|
||||
}
|
||||
|
||||
const validateHardwareVersion = (list, version) => {
|
||||
for (element of list) {
|
||||
if (element.minor == version.minor && element.build == version.build) { return true }
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const getBinFiles = async (dir) => {
|
||||
const dirents = await fs.opendir(dir)
|
||||
var files = []
|
||||
|
||||
for await (const dirent of dirents) {
|
||||
const filePath = path.join(dir, dirent.name)
|
||||
|
||||
if (dirent.isDirectory()) {
|
||||
files = files.concat(await getBinFiles(filePath))
|
||||
} else if (path.extname(dirent.name) === '.bin') {
|
||||
files.push(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
const validateFirmware = async (filePath) => {
|
||||
const fileBuffer = await fs.readFile(filePath);
|
||||
const stats = await fs.stat(filePath);
|
||||
const startPattern = Buffer.from('5C2A5C', 'hex');
|
||||
const endPattern = Buffer.from('5C2B5C', 'hex');
|
||||
var firmware = {}
|
||||
var offset = 0;
|
||||
|
||||
///// Check file is bin file
|
||||
if (path.extname(filePath) != '.bin') { throw ({ message: 'not_a_bin_file' }) }
|
||||
|
||||
///// Check firmware size
|
||||
if (stats.size < 18) { throw ({ message: 'invalid_firmware' }) }
|
||||
|
||||
///// Find patterns first
|
||||
var startMatch = fileBuffer.indexOf(startPattern, 0)
|
||||
var endMatch = fileBuffer.indexOf(endPattern, 0)
|
||||
if (startMatch < 0 || endMatch < 0) { throw ({ message: 'invalid_firmware' }) }
|
||||
|
||||
///// Version
|
||||
offset = 0x0000;
|
||||
firmware.version = {
|
||||
major: fileBuffer.readUInt8(offset++),
|
||||
minor: fileBuffer.readUInt8(offset++),
|
||||
build: fileBuffer.readUInt8(offset++)
|
||||
}
|
||||
|
||||
///// Hardware Type
|
||||
offset = 0x0003;
|
||||
firmware.hardware_type = fileBuffer.readUInt8(offset++)
|
||||
|
||||
///// Module Type
|
||||
offset = 0x0008;
|
||||
firmware.moduleType = fileBuffer.toString('ascii', offset, Math.min(fileBuffer.indexOf(0x00, offset), offset + 10)).trim();
|
||||
|
||||
///// Hardware compatibility
|
||||
offset = startMatch + 3
|
||||
let compatibility = []
|
||||
while (offset < endMatch) {
|
||||
compatibility.push({
|
||||
major: fileBuffer.readUInt8(offset++),
|
||||
minor: fileBuffer.readUInt8(offset++),
|
||||
build: fileBuffer.readUInt8(offset++)
|
||||
})
|
||||
}
|
||||
|
||||
firmware.compatibility = compatibility
|
||||
|
||||
///// Hash
|
||||
firmware.firmwareHash = crc.crc32(fileBuffer).toString(16)
|
||||
|
||||
///// Size
|
||||
firmware.firmwareSize = stats.size
|
||||
|
||||
///// Path
|
||||
firmware.path = filePath;
|
||||
|
||||
return firmware
|
||||
}
|
||||
|
||||
const init = async (path) => {
|
||||
try {
|
||||
this.path = path;
|
||||
|
||||
var watcher = chokidar.watch(this.path + '/**/*.bin', { ignored: /^\./, persistent: true });
|
||||
|
||||
watcher
|
||||
.on('add', async function (path) {
|
||||
///// Try validating firmware
|
||||
try {
|
||||
firmwares.push(await validateFirmware(path))
|
||||
} catch (e) { }
|
||||
})
|
||||
.on('unlink', async function (path) {
|
||||
///// Remove firmware from list
|
||||
firmwares = firmwares.filter((element) => { return element.path != path })
|
||||
})
|
||||
.on('change', async function (path) {
|
||||
///// Remove firmware from list
|
||||
firmwares = firmwares.filter((element) => { return element.path != path })
|
||||
|
||||
///// Try validating firmware
|
||||
try {
|
||||
firmwares.push(await validateFirmware(path))
|
||||
} catch (e) { }
|
||||
})
|
||||
.on('error', async function (error) { console.error('Error happened', error); })
|
||||
|
||||
return null
|
||||
} catch (exception) {
|
||||
return exception.message
|
||||
}
|
||||
}
|
||||
|
||||
const lookFirmware = (serialNumber, firmwareHash, version, moduleType, hardwareIndex, hardwareVersion) => {
|
||||
try {
|
||||
///// Retrieve best firmware
|
||||
const firmware = firmwares.filter((element) => {
|
||||
const parsedHardwareVersion = parseVersion(hardwareVersion);
|
||||
|
||||
if (!hardwareVersion) { return false; }
|
||||
if (!validateHardwareVersion(element.compatibility, parsedHardwareVersion)) { return false; }
|
||||
if (moduleType && element.moduleType != moduleType) { return false; }
|
||||
if (firmwareHash && (firmwareHash != 'init' && element.firmwareHash == firmwareHash)) { return false; }
|
||||
|
||||
return true;
|
||||
}).sort((f1, f2) => {
|
||||
return compareVersions(f1.version, f2.version);
|
||||
})[0]
|
||||
|
||||
return firmware
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const syncFirmware = (serialNumber, hash, version, type, hardwareIndex, hardwareVersion) => {
|
||||
const syncFirmware = async (serialNumber, firmwareHash, moduleType, position, length) => {
|
||||
try {
|
||||
return {}
|
||||
///// Retrieve firmware
|
||||
const firmware = firmwares.find((element) => { return element.firmwareHash == firmwareHash; })
|
||||
|
||||
///// Check module type
|
||||
if (moduleType && firmware.moduleType != moduleType) { return false; }
|
||||
|
||||
///// Read file
|
||||
const fileBuffer = await fs.readFile(firmware.path);
|
||||
|
||||
return fileBuffer.subarray(parseInt(position), parseInt(position) + parseInt(length));
|
||||
} catch (e) {
|
||||
throw new Error(e.message)
|
||||
throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init,
|
||||
lookFirmware,
|
||||
syncFirmware,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const status = require('./status.service')
|
||||
const data = require('./data.service')
|
||||
const senbus_value = require('./senbus_value.service')
|
||||
const firmware = require('./firmware.service')
|
||||
const ipx = require('./ipx.service')
|
||||
const journal = require('./journal.service')
|
||||
@@ -9,6 +10,7 @@ const device = require('./device.service')
|
||||
module.exports = {
|
||||
status,
|
||||
data,
|
||||
senbus_value,
|
||||
firmware,
|
||||
ipx,
|
||||
journal,
|
||||
|
||||
9
services/senbus_value.service.js
Normal file
9
services/senbus_value.service.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const dbcontroller = require('../db');
|
||||
|
||||
const createSenbusValue = async function (data) {
|
||||
return { success: true }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createSenbusValue,
|
||||
}
|
||||
Reference in New Issue
Block a user