291 lines
10 KiB
JavaScript
291 lines
10 KiB
JavaScript
|
|
var Database = require('../../../models/database');
|
|
var manifest = require('./manifest.json');
|
|
const { createWinstonLogger } = require('../../../utils/logging');
|
|
const Basedata = require('../../../models/basedata');
|
|
const Feedbackstates = require('../../../models/feedbackstates');
|
|
const Feedbackstore = require('../../../models/core/feedbackstore');
|
|
const Operations = require('../../../models/operationshelper');
|
|
const Groups = require('../../../models/groups');
|
|
// axios session
|
|
const axios = require('axios').default;
|
|
const { CookieJar } = require('tough-cookie');
|
|
const { wrapper } = require('axios-cookiejar-support');
|
|
const jar = new CookieJar();
|
|
const client = wrapper(axios.create({ jar }));
|
|
|
|
|
|
global.manifest = manifest;
|
|
global.apiAdress = null;
|
|
var serviceState = 0;
|
|
var config = null;
|
|
var pulled_data = {};
|
|
const AUTH_ENDPOINT = "https://app.divera247.com/monitor/"
|
|
const PULL_ENDPOINT = "https://app.divera247.com/api/pull"
|
|
|
|
async function getFeedbackStateIDbyName(name){
|
|
return new Promise((resolve, reject) => {
|
|
var feedbackstates = new Feedbackstates(global.logger);
|
|
feedbackstates.getAllActiveStates((rows)=>{
|
|
if(rows !== null){
|
|
rows.forEach((e)=>{
|
|
if(name == e.stateLabel){
|
|
resolve(e.id)
|
|
}
|
|
})
|
|
}
|
|
resolve(null)
|
|
})
|
|
});
|
|
}
|
|
|
|
function setFeedback(operationUUID, basedataUUID, feedbackState) {
|
|
var feedbackstore = new Feedbackstore(global.logger);
|
|
global.logger.debug('DIVERA_STATUS | FEEDBACK | ' + Math.floor(new Date().getTime()) + ' setFeedback | persisting feedback now ..');
|
|
feedbackstore.setFeedback(basedataUUID, operationUUID, feedbackState, (success) => {
|
|
if (success) {
|
|
global.logger.debug('DIVERA_STATUS | FEEDBACK | ' + Math.floor(new Date().getTime()) + ' setFeedback | successfully persisted feedback');
|
|
var feedbackInfo = {
|
|
basedataUUID: basedataUUID,
|
|
operationUUID: operationUUID,
|
|
feedbackState: feedbackState
|
|
}
|
|
var sendMessage = {
|
|
feedbackState : feedbackInfo
|
|
}
|
|
process.send(JSON.stringify(sendMessage));
|
|
|
|
} else {
|
|
global.logger.debug('DIVERA_STATUS | FEEDBACK | ' + Math.floor(new Date().getTime()) + ' setFeedback | ERROR - Could not persist feedback');
|
|
}
|
|
})
|
|
}
|
|
|
|
async function getMemberByName(firstname,lastname){
|
|
return new Promise((resolve, reject) => {
|
|
new Basedata(global.logger).getListOfBasedata((rows)=>{
|
|
if(rows !== null){
|
|
rows.forEach((e)=> {
|
|
if(e.firstname == firstname && e.lastname == lastname){
|
|
resolve(e.uuid)
|
|
}
|
|
})
|
|
}
|
|
resolve(null)
|
|
})
|
|
});
|
|
}
|
|
|
|
async function setGroupsMutedStateForMember(member_guid, muted = false){
|
|
var b= new Basedata(global.logger)
|
|
b.getBaseDataForUUID(member_guid,(_rows)=> {
|
|
if(_rows !== null){
|
|
_rows.forEach((_e)=>{
|
|
var g = new Groups(global.logger)
|
|
g.setAllGroupsMutedStateForBasedata(_e.id,muted?1:0,(success)=>{})
|
|
})
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
async function getActiveOperation(){
|
|
return new Promise((resolve, reject) => {
|
|
|
|
new Operations(global.logger).getListOfActiveOperations((rows)=>{
|
|
if(rows !== null && rows.length > 0){
|
|
resolve(rows[0].uuid)
|
|
}
|
|
resolve(null)
|
|
})
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Log Function for inter process communication
|
|
*/
|
|
function LogAtMain(msg) {
|
|
process.send('{"logmessage" : "' + msg + '"}');
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Wire messages coming from Plugin base.js
|
|
*
|
|
*/
|
|
process.on('message', (msg) => {
|
|
if (typeof msg.config != 'undefined') {
|
|
config = msg.config;
|
|
global.apiAdress = config.apiAdress || null;
|
|
serviceState = 1;
|
|
LogAtMain('Recieved Configuration from CORE');
|
|
} else if (typeof msg.start != 'undefined') {
|
|
if (msg.start === 1) {
|
|
startAPI();
|
|
}
|
|
}
|
|
});
|
|
|
|
// GENERIC Error Handling
|
|
process.on('unhandledRejection', (reason, p) => {
|
|
console.log('PLUGIN | DIVERA_STATUS | Unhandled Rejection at: Promise', p, 'reason:', reason.stack);
|
|
LogAtMain('Unhandled Rejection at: Promise', p, 'reason:', reason.stack);
|
|
});
|
|
process.on('uncaughtException', function (err) {
|
|
console.log('PLUGIN | DIVERA_STATUS | Caught exception: ' + err);
|
|
process.send('{"error" : "' + err.message + '"}');
|
|
});
|
|
|
|
/**
|
|
* Start API Logger
|
|
*/
|
|
|
|
// create a rolling file logger based on date/time that fires process events
|
|
global.appRoot = __dirname + '/../../../';
|
|
|
|
global.logger = createWinstonLogger('DIVERA_STATUS ', global.appRoot + '/logs/api/DIVERA_STATUS-%DATE%.log');
|
|
global.logger.info('Started DIVERA_STATUS Sync', {label: 'APPJS '});
|
|
|
|
/**
|
|
* connect to database
|
|
*/
|
|
var coreDb = new Database(global.logger);
|
|
|
|
coreDb.openCoreDatabase((successDatabase) => {
|
|
if (successDatabase) {
|
|
global.coreDb = coreDb.db;
|
|
global.logger.info('database started', {label: 'APPJS '});
|
|
} else {
|
|
global.logger.error('Could not connect to database', {label: 'APPJS '});
|
|
}
|
|
});
|
|
|
|
/**
|
|
* authenticate Divera Monitor with Autologin Key
|
|
* @returns boolean
|
|
*/
|
|
async function auth(){
|
|
let resp = await client.get(`${AUTH_ENDPOINT}${config.MONITOR_ID}.html?autologin=${config.AUTOLOGIN_KEY}`)
|
|
if(resp.status === 200){
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Get Data from Divera pull Endpoint. With ts=0 all data is pulled.
|
|
* If ?ts={timestamp}, data changed since this timestamp is pulled.
|
|
* We just pull all data.
|
|
*
|
|
* The Divera Monitor App also connects to a websocket connection where changes are pushed.
|
|
* Maybe this is a better idea to pull data in the future than pulling in a while loop
|
|
*
|
|
* @returns {dict|null}
|
|
*/
|
|
async function pull(){
|
|
let resp = await client.get(`${PULL_ENDPOINT}?ts=0`)
|
|
if(resp.status === 200){
|
|
return resp.data
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Function handling the state change of an User.
|
|
* The feedback-status-id is identified by name and basedata(user)-(uu)id is identified by firstname and lastname
|
|
* So Divera feedback-status/firstname & lastname must be the same as in ALARMiator
|
|
*
|
|
* Feedback-state changes are applyed to the lates active operation
|
|
*
|
|
* if STATUS_EB/STATUS_NED is set, all groups for this user are muted/unmuted if the name is matching
|
|
*
|
|
* @param {Number} consumer_id
|
|
* @param {Number} status_id
|
|
*/
|
|
async function onStateChange(consumer_id, status_id){
|
|
|
|
var d_consumer = pulled_data['consumer'][consumer_id]
|
|
var d_status = pulled_data['status'][status_id]
|
|
global.logger.info(`${d_consumer.stdformat_name.trim()}: ${d_status.name.trim()}`)
|
|
|
|
let a_consumer = await getMemberByName(d_consumer.firstname.trim(), d_consumer.lastname.trim())
|
|
if(a_consumer === null){
|
|
global.logger.info(`no matching basedata for \'${d_consumer.firstname.trim()}\' \'${d_consumer.lastname.trim()}\'`)
|
|
return
|
|
}
|
|
|
|
let a_status = await getFeedbackStateIDbyName(d_status.name.trim())
|
|
if(a_status !== null){
|
|
// state is feedback to an operation
|
|
let a_operation = await getActiveOperation()
|
|
if(a_consumer === null){
|
|
global.logger.info(`no active operation running`)
|
|
return
|
|
}
|
|
// set feedback go last operation
|
|
setFeedback(a_operation, a_consumer, a_status)
|
|
}else{
|
|
// Status auf einsatzbereit/nicht einsatzbereit prüfen
|
|
if(config.STATUS_EB.trim() == d_status.name.trim()){
|
|
//Alle Gruppen alamieren
|
|
setGroupsMutedStateForMember(a_consumer,false)
|
|
}
|
|
if(config.STATUS_NEB.trim() == d_status.name.trim()){
|
|
//Alle Gruppen alamieren deaktivieren
|
|
setGroupsMutedStateForMember(a_consumer,true)
|
|
}
|
|
}
|
|
}
|
|
|
|
function sleep(ms) {
|
|
return new Promise((resolve) => {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
}
|
|
|
|
async function startAPI() {
|
|
while(true){
|
|
try{
|
|
let _auth = await auth()
|
|
if(_auth){
|
|
global.logger.info('auth OK')
|
|
var _pulled_data = await pull()
|
|
while(_pulled_data !== null){
|
|
if(_pulled_data !== null){
|
|
if(_pulled_data.success){
|
|
var d = _pulled_data.data
|
|
if('cluster' in d){
|
|
pulled_data['consumer'] = d['cluster']['consumer']
|
|
pulled_data['status'] = d['cluster']['status']
|
|
}
|
|
if('monitor' in d){
|
|
var m = d['monitor'][config.MONITOR_ID]
|
|
Object.entries(m).forEach(([key, value]) => {
|
|
// wenn 'monitor' nicht in pulled_data ist das der erste pull, dann alle status in ALARMiator abgleichen (betrifft hautsächlich den EB/NEB status)
|
|
if(!('monitor' in pulled_data) || ('monitor' in pulled_data && value.status !== pulled_data['monitor'][key]['status'])){
|
|
onStateChange(value.id,value.status )
|
|
}
|
|
});
|
|
pulled_data['monitor'] = d['monitor'][config.MONITOR_ID]
|
|
}
|
|
}
|
|
}
|
|
_pulled_data = await pull()
|
|
if(_pulled_data === null){
|
|
global.logger.debug('_pulled_data === null, reauth')
|
|
_auth = await auth()
|
|
_pulled_data = await pull()
|
|
if(_pulled_data === null){
|
|
global.logger.debug('_pulled_data === null after reauth, EXIT!!')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}catch(err){
|
|
console.error(err);
|
|
}
|
|
await sleep(10000);
|
|
global.logger.info('auth mit API_KEY war nicht erfolgreich. Service ist gestoppt und startet nicht mehr automatisch??')
|
|
}
|
|
} |