first commit
parent
59a8ca7e51
commit
b201ab7930
File diff suppressed because one or more lines are too long
@ -0,0 +1,276 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Brandgefahren Configuration</title>
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"> -->
|
||||
<link href="/css/materialdesignicons.min.css" rel="stylesheet">
|
||||
<link href="/css/vuetify.min.css" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<v-app>
|
||||
<v-app-bar app>
|
||||
<v-toolbar-title>Brandgefahren Configuration</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="success" @click="storeConfig()">Store & Restart</v-btn>
|
||||
<v-checkbox label="Expert Mode" v-model="EXPERTMODE"></v-checkbox>
|
||||
</v-app-bar>
|
||||
<v-content>
|
||||
<v-form>
|
||||
<v-tabs v-model="configTab" next-icon="mdi-arrow-right-bold-box-outline"
|
||||
prev-icon="mdi-arrow-left-bold-box-outline" show-arrows>
|
||||
<v-tabs-slider></v-tabs-slider>
|
||||
<v-tab key="bradgefahren">Brandgefahren</v-tab>
|
||||
<v-tab v-show="EXPERTMODE" key="notificationConfig">Notification Configuration</v-tab>
|
||||
</v-tabs>
|
||||
<v-tabs-items v-model="configTab">
|
||||
<v-tab-item key="brandgefahren">
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-btn color="primary" fab dark small icon @click="addAlarm()">
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</v-row>
|
||||
|
||||
<v-row v-for="(alarmConfig, index) in configData.alarms" :key="alarmConfig._id">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<v-col cols="12">
|
||||
<v-btn color="error" dark small fab @click="configData.alarms.splice(index, 1)" icon>
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-row cols="6">
|
||||
<v-select :items="alarmSchedulingMode" v-model="alarmConfig.alarmSchedulingMode"
|
||||
item-text="k" item-value="v" label="Scheduling Mode"></v-select>
|
||||
<v-text-field v-model="alarmConfig.alarmTime" type="time" label="Time"></v-text-field>
|
||||
</v-row>
|
||||
<v-row cols="6" v-show="alarmConfig.alarmSchedulingMode == 'weekly'">
|
||||
<v-checkbox v-for="(WN, index) of weekDays" v-model="alarmConfig.weekDay[ index ]" :label="WN"></v-checkbox>
|
||||
</v-row>
|
||||
<v-row cols="6" v-show="alarmConfig.alarmSchedulingMode == 'monthlyFirstOccWeekday'">
|
||||
<v-select :items="weekDaysSelect" v-model="alarmConfig.firstOccWeekday" label="First Occurance of this Weekday"></v-select>
|
||||
</v-row>
|
||||
<v-row cols="6" v-show="alarmConfig.alarmSchedulingMode == 'monthlyAtSpecificDate'">
|
||||
<v-text-field v-model="alarmConfig.specificWeekday" label="Specific Date (xx-MM-YYYY)" type="number"></v-text-field>
|
||||
</v-row>
|
||||
</v-col>
|
||||
<v-row cols="12">
|
||||
<v-text-field v-model="alarmConfig.name" label="Name"></v-text-field>
|
||||
<v-autocomplete
|
||||
v-model="alarmConfig.preset"
|
||||
:items="presetSearchItems"
|
||||
:loading="!presetSearchItems.length > 0"
|
||||
color="white"
|
||||
hide-no-data
|
||||
label="Profile"
|
||||
placeholder="Start typing to Search"
|
||||
prepend-icon="mdi-database-search"
|
||||
></v-autocomplete>
|
||||
</v-row>
|
||||
<v-row cols="12">
|
||||
<v-checkbox v-model="alarmConfig.wbxEnabled" label="WBi"></v-checkbox>
|
||||
<v-autocomplete
|
||||
:readonly="!alarmConfig.wbxEnabled"
|
||||
v-model="alarmConfig.wbxCounty"
|
||||
:items="autocompleteData.wbx.countyNames"
|
||||
:loading="!autocompleteData.wbx.countyNames.length > 0"
|
||||
hide-no-data
|
||||
label="County"
|
||||
placeholder="WBi-Land"
|
||||
prepend-icon="mdi-map"
|
||||
></v-autocomplete>
|
||||
<v-autocomplete
|
||||
:readonly="!alarmConfig.wbxEnabled"
|
||||
v-model="alarmConfig.wbxStation"
|
||||
:items="acWBXStations(alarmConfig)"
|
||||
:loading="!autocompleteData.wbx.countyNames.length > 0"
|
||||
hide-no-data
|
||||
label="Station"
|
||||
placeholder="WBi-Station"
|
||||
prepend-icon="mdi-city"
|
||||
></v-autocomplete>
|
||||
</v-row>
|
||||
<v-row cols="12">
|
||||
<v-checkbox v-model="alarmConfig.gbxEnabled" label="GBi"></v-checkbox>
|
||||
<v-autocomplete
|
||||
:readonly="!alarmConfig.gbxEnabled"
|
||||
v-model="alarmConfig.gbxCounty"
|
||||
:items="autocompleteData.gbx.countyNames"
|
||||
:loading="!autocompleteData.gbx.countyNames.length > 0"
|
||||
hide-no-data
|
||||
label="County"
|
||||
placeholder="GBi-Land"
|
||||
prepend-icon="mdi-map"
|
||||
></v-autocomplete>
|
||||
<v-autocomplete
|
||||
:readonly="!alarmConfig.gbxEnabled"
|
||||
v-model="alarmConfig.gbxStation"
|
||||
:items="acGBXStations(alarmConfig)"
|
||||
:loading="!autocompleteData.gbx.countyNames.length > 0"
|
||||
hide-no-data
|
||||
label="Station"
|
||||
placeholder="GBi-Station"
|
||||
prepend-icon="mdi-city"
|
||||
></v-autocomplete>
|
||||
</v-row>
|
||||
<v-text-field v-model="alarmConfig.forecastLength" label="Days of forecast" type="number"></v-text-field>
|
||||
<v-btn color="warn" @click="testTrigger(index)">
|
||||
TEST (only saved config)
|
||||
</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-tab-item>
|
||||
<v-tab-item key="notificationConfig">
|
||||
<v-container>
|
||||
<b>Routing Paramters:</b>
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-text-field label="Daemon Endpoint URL" v-model="configData.pager.url">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-form>
|
||||
</v-content>
|
||||
</v-app>
|
||||
</div>
|
||||
|
||||
<script src="/js/moment-with-locales.min.js"></script>
|
||||
<script src="/js/vue/vue.js"></script>
|
||||
<script src="/js/vue/vuetify.js"></script>
|
||||
<script src="/js/vue/vue-resource_1.5.1.js"></script>
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(),
|
||||
http: { root: '/' },
|
||||
|
||||
data() {
|
||||
const weekDays = [
|
||||
'Monday','Tuesday','Wednesday','Thursday','Friday','Saturday', 'Sunday'
|
||||
]
|
||||
return {
|
||||
EXPERTMODE: false,
|
||||
configTab: null,
|
||||
alarmSchedulingMode: [
|
||||
{ k: 'Weekly', v: 'weekly' },
|
||||
{ k: 'Monthly at first occurance of a specific weekday', v: 'monthlyFirstOccWeekday' },
|
||||
{ k: 'Monthly at specific date', v: 'monthlyAtSpecificDate' },
|
||||
],
|
||||
weekDays,
|
||||
weekDaysSelect: weekDays.map((val,ind) => { return { value: ind, text: val } }),
|
||||
configData: {
|
||||
"bottoken": "",
|
||||
"pager": {
|
||||
"url": "",
|
||||
},
|
||||
"menuSupport": false,
|
||||
"deliveryModes": []
|
||||
},
|
||||
autocompleteData: {
|
||||
wbx: {counties: {}, countyNames: []},
|
||||
gbx: {counties: {}, countyNames: []},
|
||||
},
|
||||
presetSearchItems: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadPresets()
|
||||
this.loadConfig()
|
||||
this.loadAutocompletes()
|
||||
},
|
||||
methods: {
|
||||
acWBXStations(alarmConfig) {
|
||||
if (alarmConfig.wbxCounty && this.autocompleteData.wbx.countyNames.length > 0) {
|
||||
if (!this.autocompleteData.wbx.counties[ alarmConfig.wbxCounty ]) return []
|
||||
return this.autocompleteData.wbx.counties[ alarmConfig.wbxCounty ].stationNames
|
||||
}
|
||||
return []
|
||||
},
|
||||
acGBXStations(alarmConfig) {
|
||||
if (alarmConfig.gbxCounty && this.autocompleteData.gbx.countyNames.length > 0) {
|
||||
if (!this.autocompleteData.gbx.counties[ alarmConfig.gbxCounty ]) return []
|
||||
return this.autocompleteData.gbx.counties[ alarmConfig.gbxCounty ].stationNames
|
||||
}
|
||||
return []
|
||||
},
|
||||
testTrigger(index) {
|
||||
this.$http.get(window.location.pathname + 'api/trigger/' + index)
|
||||
.then(response => {})
|
||||
},
|
||||
loadPresets() {
|
||||
this.$http.get(window.location.pathname + 'api/deliveryPresets')
|
||||
.then(response => {
|
||||
this.presetSearchItems = response.body.map(x => { return {
|
||||
text: x.name,
|
||||
value: x.key,
|
||||
}})
|
||||
}, response => {
|
||||
})
|
||||
},
|
||||
loadConfig() {
|
||||
this.$http.get(window.location.pathname + 'config').then(response => {
|
||||
const newConfig = response.body
|
||||
newConfig.alarms = newConfig.alarms.map((x) => {
|
||||
x._id = btoa(JSON.stringify(x))
|
||||
return x
|
||||
})
|
||||
this.configData = newConfig
|
||||
}, response => {
|
||||
})
|
||||
},
|
||||
loadAutocompletes() {
|
||||
this.$http.get(window.location.pathname + 'wg/autocomplete').then(response => {
|
||||
this.autocompleteData = response.body
|
||||
}, response => {
|
||||
})
|
||||
},
|
||||
storeConfig() {
|
||||
const storeConfig = JSON.parse(JSON.stringify(this.configData))
|
||||
storeConfig.alarms = storeConfig.alarms.map(a=> {
|
||||
delete a._id
|
||||
return a
|
||||
})
|
||||
this.$http.post(window.location.pathname + 'config', storeConfig)
|
||||
.then(response => {})
|
||||
.then(this.$http.post(window.location.pathname + 'restart'))
|
||||
.then(() => {
|
||||
document.body.style = 'display:none'
|
||||
setTimeout(() => window.location.reload(), 1e3)
|
||||
})
|
||||
},
|
||||
addAlarm() {
|
||||
this.configData.alarms.push({
|
||||
name: "Alarm 1",
|
||||
preset: null,
|
||||
alarmSchedulingMode: "weekly",
|
||||
alarmTime: "13:37",
|
||||
weekDay: {
|
||||
"0": true,
|
||||
"1": true,
|
||||
"2": true,
|
||||
"3": true,
|
||||
"4": true,
|
||||
"5": true,
|
||||
"6": true
|
||||
},
|
||||
wbxEnabled: false,
|
||||
gbxEnabled: false,
|
||||
forecastLength: 3,
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,264 @@
|
||||
const config = require('./config.json')
|
||||
|
||||
const axios = require('axios')
|
||||
|
||||
const fs = require('fs')
|
||||
const moment = require('moment')
|
||||
moment.locale('yes', {
|
||||
week : {
|
||||
dow : 1
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const jsdom = require("jsdom")
|
||||
const { JSDOM } = jsdom
|
||||
|
||||
|
||||
const express = require('express')
|
||||
const appConfig = express()
|
||||
appConfig.use(express.json({ limit: '1mb' }))
|
||||
appConfig.use(express.static('html'))
|
||||
appConfig.use(express.static(__dirname + '/node_modules/@mdi/font'))
|
||||
|
||||
const umlautMapGermany = {
|
||||
'\u00dc': ']',
|
||||
'\u00c4': '[',
|
||||
'\u00d6': "\\",
|
||||
'\u00fc': '}',
|
||||
'\u00e4': '{',
|
||||
'\u00f6': '|',
|
||||
'\u00df': '~',
|
||||
}
|
||||
const umlautMapIntl = {
|
||||
'\u00dc': 'U',
|
||||
'\u00c4': 'A',
|
||||
'\u00d6': 'O',
|
||||
'\u00fc': 'u',
|
||||
'\u00e4': 'a',
|
||||
'\u00f6': 'o',
|
||||
'\u00df': 'ss',
|
||||
}
|
||||
|
||||
function itnlUmlaute(str) {
|
||||
let umlautMap = umlautMapIntl
|
||||
return str
|
||||
.replace(/[\u00dc|\u00c4|\u00d6][a-z]/g, (a) => {
|
||||
const big = umlautMap[a.slice(0, 1)];
|
||||
return big.charAt(0) + big.charAt(1).toLowerCase() + a.slice(1);
|
||||
})
|
||||
.replace(new RegExp('['+Object.keys(umlautMap).join('|')+']',"g"),
|
||||
(a) => umlautMapIntl[a]
|
||||
);
|
||||
}
|
||||
function replaceUmlaute(str) {
|
||||
let umlautMap = config.germanUmlautSupport
|
||||
? umlautMapGermany
|
||||
: umlautMapIntl
|
||||
return str
|
||||
.replace(/[\u00dc|\u00c4|\u00d6][a-z]/g, (a) => {
|
||||
const big = umlautMap[a.slice(0, 1)];
|
||||
return big.charAt(0) + big.charAt(1).toLowerCase() + a.slice(1);
|
||||
})
|
||||
.replace(new RegExp('['+Object.keys(umlautMap).join('|')+']',"g"),
|
||||
(a) => umlautMap[a]
|
||||
);
|
||||
}
|
||||
async function triggerAlert(alarmConfig) {
|
||||
console.log("sending msg for ", alarmConfig.name)
|
||||
if (alarmConfig.wbxEnabled) {
|
||||
wbxData = await axios.get("https://www.wettergefahren.de/warnungen/indizes/waldbrand.html")
|
||||
wbxData = parseWettergefahren(wbxData.data)
|
||||
//wbxData = JSON.parse(fs.readFileSync("./.waldbrand.json"))
|
||||
//fs.writeFileSync("./.waldbrand.json", JSON.stringify(wbxData))
|
||||
if (!wbxData.counties[ alarmConfig.wbxCounty ]) throw "County404"
|
||||
if (!wbxData.counties[ alarmConfig.wbxCounty ].stationData[ alarmConfig.wbxStation ]) throw 'Station404'
|
||||
|
||||
let stationData = wbxData.counties[ alarmConfig.wbxCounty ].stationData[ alarmConfig.wbxStation ]
|
||||
let dayCounter = 0
|
||||
dayStrs = []
|
||||
for (let dayKey of Object.keys(stationData)) {
|
||||
dayStrs.push(`${ dayKey.split(' ')[0] }=${ stationData[dayKey] }`)
|
||||
if (dayCounter > +alarmConfig.forecastLength) break
|
||||
dayCounter++
|
||||
}
|
||||
await axios.post(new URL(config.pager.url).origin + '/api/message/' + (!!alarmConfig.preset ? 'preset' : 'advanced'),
|
||||
Object.assign({ preset: alarmConfig.preset }, { payload: `WBI: ${ alarmConfig.wbxStation } ${ dayStrs.join('-') }` }))
|
||||
}
|
||||
if (alarmConfig.gbxEnabled) {
|
||||
gbxData = await axios.get("https://www.wettergefahren.de/warnungen/indizes/grasland.html")
|
||||
gbxData = parseWettergefahren(gbxData.data)
|
||||
//gbxData = JSON.parse(fs.readFileSync("./.grasland.json"))
|
||||
//fs.writeFileSync("./.waldbrand.json", JSON.stringify(wbxData))
|
||||
if (!gbxData.counties[ alarmConfig.gbxCounty ]) throw "County404"
|
||||
if (!gbxData.counties[ alarmConfig.gbxCounty ].stationData[ alarmConfig.gbxStation ]) throw 'Station404'
|
||||
|
||||
let stationData = gbxData.counties[ alarmConfig.gbxCounty ].stationData[ alarmConfig.gbxStation ]
|
||||
let dayCounter = 0
|
||||
dayStrs = []
|
||||
for (let dayKey of Object.keys(stationData)) {
|
||||
dayStrs.push(`${ dayKey.split(' ')[0] }=${ stationData[dayKey] }`)
|
||||
if (dayCounter >= +alarmConfig.forecastLength) break
|
||||
dayCounter++
|
||||
}
|
||||
await axios.post(new URL(config.pager.url).origin + '/api/message/' + (!!alarmConfig.preset ? 'preset' : 'advanced'),
|
||||
Object.assign({ preset: alarmConfig.preset }, { payload: `GBI: ${ alarmConfig.gbxStation } ${ dayStrs.join('-') }` }))
|
||||
}
|
||||
}
|
||||
async function minuteCheck() {
|
||||
let timeRN = moment()
|
||||
//console.log('timeRN', timeRN.format("HH:mm"))
|
||||
for (let alarm of config.alarms) {
|
||||
let alarmTime = moment()
|
||||
.hours(+alarm.alarmTime.split(':') [ 0 ])
|
||||
.minutes(+alarm.alarmTime.split(':') [ 1 ])
|
||||
let secDiff = alarmTime.diff(timeRN, 'seconds')
|
||||
//
|
||||
//console.log(alarmTime.format("HH:mm"), secDiff)
|
||||
if (alarmTime.format("HH:mm") == timeRN.format("HH:mm")) {
|
||||
//console.log("TRIGGER", alarm.alarmSchedulingMode)
|
||||
let alarmTrigger = false
|
||||
switch (alarm.alarmSchedulingMode) {
|
||||
case 'monthlyAtSpecificDate':
|
||||
alarmTrigger = (timeRN.date() == alarmTime.specificWeekday)
|
||||
break;
|
||||
case 'monthlyFirstOccWeekday':
|
||||
// wish Date = alarmTime.firstOccWeekday
|
||||
let thisMonthFirstWeekDayOccurance = -1
|
||||
let monthFirstDay = moment().startOf('month')
|
||||
while (monthFirstDay.weekday() != alarm.firstOccWeekday) monthFirstDay.add(1, 'day')
|
||||
thisMonthFirstWeekDayOccurance = monthFirstDay.date()
|
||||
|
||||
//console.log(monthFirstDay.date(), monthFirstDay.weekday())
|
||||
//console.log('monthly first occurance for', alarm.firstOccWeekday, 'is', thisMonthFirstWeekDayOccurance)
|
||||
alarmTrigger = (timeRN.date() == thisMonthFirstWeekDayOccurance)
|
||||
break;
|
||||
case 'weekly':
|
||||
for (let weekDayKey of Object.keys(alarm.weekDay)) {
|
||||
//console.log(weekDayKey, alarm.weekDay)
|
||||
if (+weekDayKey === +timeRN.weekday()) {
|
||||
//console.log('weekday match', 'result is', alarm.weekDay[weekDayKey] )
|
||||
alarmTrigger = alarm.weekDay[weekDayKey]
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (alarmTrigger === true) {
|
||||
console.log("TRIGGER!!!!!")
|
||||
await triggerAlert(alarm)
|
||||
/*await axios.post(new URL(config.pager.url).origin + '/api/message/' + (!!alarm.preset ? 'preset' : 'advanced'), Object.assign( !!alarm.preset
|
||||
? { preset: alarm.preset }
|
||||
: { ...alarm.params } // backward compatibility
|
||||
, { payload: alarm.payload }))
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseWettergefahren(rawHTML) {
|
||||
const wbiResponse = {
|
||||
counties: {},
|
||||
countyNames: [],
|
||||
}
|
||||
const { window } = new JSDOM(rawHTML)
|
||||
const sections = window.document.querySelectorAll("section[role='contentinfo']")
|
||||
for (let b of sections) {
|
||||
if ( b.getAttribute("aria-label") == "Legende" ) continue
|
||||
regionName = b.getAttribute("aria-label")
|
||||
wbiResponse.countyNames.push(regionName)
|
||||
|
||||
tableHead = b.querySelector("thead")
|
||||
tableRows = b.querySelectorAll("tr")
|
||||
let headers = {}, values = {}
|
||||
let i = 0
|
||||
for (let k of tableHead.querySelectorAll("th")) {
|
||||
headers[ i ] = k.textContent
|
||||
i++
|
||||
}
|
||||
for (let k of tableRows) {
|
||||
let i = 0
|
||||
let first = ''
|
||||
let l = 0
|
||||
for (let j of k.querySelectorAll("td")) {
|
||||
if (first == '') { first = j.textContent; if(first == "Stationsname") break; values[first] = {} }
|
||||
else values[ first ][headers[ l ]] = j.textContent
|
||||
l++
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
wbiResponse.counties[regionName] = {
|
||||
stationNames: Object.keys(values),
|
||||
stationData: values,
|
||||
}
|
||||
}
|
||||
|
||||
return wbiResponse
|
||||
}
|
||||
async function main() {
|
||||
let now = moment()
|
||||
|
||||
//await test()
|
||||
//table class="tab_rand"
|
||||
|
||||
await minuteCheck()
|
||||
setTimeout(() => setInterval(minuteCheck, 60e3), now.diff(moment().add(1, 'minute'), 'seconds') * 1e3 + 5e3)
|
||||
}
|
||||
main()
|
||||
|
||||
appConfig.get('/wg/autocomplete', async (req, res) => {
|
||||
if (req.query.refresh) {
|
||||
console.log("refreshing cached autocomplete jsons")
|
||||
try { fs.unlinkSync("./.waldbrand.json") } catch (e) {}
|
||||
try { fs.unlinkSync("./.grasland.json") } catch (e) {}
|
||||
}
|
||||
if (fs.existsSync("./.waldbrand.json") == false) {
|
||||
wbxData = await axios.get("https://www.wettergefahren.de/warnungen/indizes/waldbrand.html")
|
||||
fs.writeFileSync("./.waldbrand.json", JSON.stringify(parseWettergefahren(wbxData.data)))
|
||||
}
|
||||
if (fs.existsSync("./.grasland.json") == false) {
|
||||
gbxData = await axios.get("https://www.wettergefahren.de/warnungen/indizes/grasland.html")
|
||||
fs.writeFileSync("./.grasland.json", JSON.stringify(parseWettergefahren(gbxData.data)))
|
||||
}
|
||||
|
||||
const WBX = fs.readFileSync("./.waldbrand.json")
|
||||
const GBX = fs.readFileSync("./.grasland.json")
|
||||
return res.json({
|
||||
gbx: JSON.parse(GBX),
|
||||
wbx: JSON.parse(WBX),
|
||||
})
|
||||
})
|
||||
appConfig.get('/api/trigger/:index', async (req, res) => {
|
||||
let i = 0
|
||||
for (let alarm of config.alarms) {
|
||||
if (i == +req.params.index) await triggerAlert(alarm)
|
||||
i++
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/** CONFIG Routes */
|
||||
|
||||
appConfig.get('/config', async (req, res) => {
|
||||
return res.json(JSON.parse(fs.readFileSync('config.json')))
|
||||
})
|
||||
appConfig.get('/api/deliveryPresets', async (req, res) => {
|
||||
const presets = await axios.get(new URL(config.pager.url).origin + '/api/deliveryPresets')
|
||||
return res.json(presets.data)
|
||||
})
|
||||
|
||||
appConfig.post('/config', async (req, res) => {
|
||||
if (!(!!req.body.alarms)) return res.status(403).json(false)
|
||||
if (!(!!req.body.pager)) return res.status(403).json(false)
|
||||
console.log(req.body)
|
||||
fs.writeFileSync('config.json', JSON.stringify(req.body, null, "\t"))
|
||||
return res.json(true)
|
||||
})
|
||||
appConfig.post('/restart', (req, res) => {
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
appConfig.listen(3100, '0.0.0.0' || config.host || '127.0.0.1')
|
Loading…
Reference in New Issue