|
|
|
const fs = require('fs')
|
|
|
|
|
|
|
|
const config = require('./config.json')
|
|
|
|
|
|
|
|
const io = require("socket.io-client")
|
|
|
|
const axios = require('axios')
|
|
|
|
const socket = io(new URL(config.pager.url).origin)
|
|
|
|
|
|
|
|
const { read } = require('feed-reader')
|
|
|
|
|
|
|
|
const stateMachine = {}
|
|
|
|
socket.on('msgmgr:event', async (eventType, eventData) => {
|
|
|
|
console.log(eventType, eventData)
|
|
|
|
})
|
|
|
|
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 sendPage(preset, payload) {
|
|
|
|
console.log(preset, payload)
|
|
|
|
try {
|
|
|
|
|
|
|
|
await axios.post(new URL(config.pager.url).origin + '/api/message/' + (!!preset ? 'preset' : 'advanced'), Object.assign( !!preset
|
|
|
|
? { preset }
|
|
|
|
: { ...config.pager.params } // backward compatibility
|
|
|
|
, { payload: payload }))
|
|
|
|
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
function analyzeCategory(txt) {
|
|
|
|
//console.log('analyzing text', txt)
|
|
|
|
|
|
|
|
if (txt.indexOf('WINDBOEN')>-1) return 'wind_storm'
|
|
|
|
if (txt.indexOf('STURMBOEN')>-1) return 'wind_storm'
|
|
|
|
if (txt.indexOf('ORKANBOEN')>-1) return 'wind_storm'
|
|
|
|
|
|
|
|
if (txt.indexOf('STARKREGEN')>-1) return 'rain1'
|
|
|
|
if (txt.indexOf('DAUERREGEN')>-1) return 'rain2'
|
|
|
|
|
|
|
|
if (txt.indexOf('GEWITTER')>-1) return 'thunderstorm'
|
|
|
|
|
|
|
|
if (txt.indexOf('SCHNEE')>-1) return 'snow'
|
|
|
|
if (txt.indexOf('FROST')>-1) return 'frost'
|
|
|
|
if (txt.indexOf('GLATTE')>-1) return 'ice'
|
|
|
|
if (txt.indexOf('NEBEL')>-1) return 'fog'
|
|
|
|
return 'none'
|
|
|
|
}
|
|
|
|
function analyzeLevel(txt) {
|
|
|
|
if (txt.indexOf('STUFE 1 VON ')>-1) return 1
|
|
|
|
if (txt.indexOf('STUFE 2 VON ')>-1) return 2
|
|
|
|
if (txt.indexOf('STUFE 3 VON ')>-1) return 3
|
|
|
|
if (txt.indexOf('STUFE 4 VON ')>-1) return 4
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkDWD() {
|
|
|
|
for (region of config.regions) {
|
|
|
|
if (!region.active) continue
|
|
|
|
try {
|
|
|
|
let rssData = await read('https://wettwarn.de/rss/' + region.dwdID + '.rss')
|
|
|
|
let msg = ""
|
|
|
|
rssData.entries.sort((a,b) => new Date(b.published).valueOf() - new Date(a.published).valueOf())
|
|
|
|
if (rssData.entries.length > 0) {
|
|
|
|
msg = rssData.entries[0].description
|
|
|
|
const msgCategory = analyzeCategory(itnlUmlaute(msg.toUpperCase()))
|
|
|
|
const msgLevel = analyzeLevel(itnlUmlaute(msg.toUpperCase()))
|
|
|
|
//console.log('type', msgCategory, 'level', msgLevel)
|
|
|
|
const msgLevelTrigger = !!region.levels[msgCategory]
|
|
|
|
? region.levels[msgCategory]
|
|
|
|
: 0
|
|
|
|
//console.log(msgLevelTrigger, 'is the trigger level for', msgCategory)
|
|
|
|
if (msgLevel >= msgLevelTrigger) { } else continue // ignore the stuff we want to ignore
|
|
|
|
msg = msg.replace('DWD UNWETTERWARNUNG:', 'DWD:')
|
|
|
|
msg = msg.replace('DWD WETTERWARNUNG:', 'DWD:')
|
|
|
|
msg = msg.replace(' in ', ' ')
|
|
|
|
msg = msg.replace(' von ', '/')
|
|
|
|
msg = msg.indexOf('Quelle:') > -1
|
|
|
|
? msg.split('Quelle:')[0]
|
|
|
|
: msg
|
|
|
|
msg = replaceUmlaute(msg)
|
|
|
|
|
|
|
|
if (!!stateMachine[ region.dwdID ]) {
|
|
|
|
if (stateMachine [ region.dwdID ] != msg) {
|
|
|
|
await sendPage( region.preset, msg )
|
|
|
|
stateMachine [ region.dwdID ] = msg
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
stateMachine [ region.dwdID ] = msg
|
|
|
|
// if initial state is unknown and we have an alert, send it anyway
|
|
|
|
if (msg.indexOf('Es sind keine Warnungen') == -1) {
|
|
|
|
await sendPage( region.preset, msg )
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (e) {console.error(e)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function main() {
|
|
|
|
// listen
|
|
|
|
setTimeout(checkDWD, 0)
|
|
|
|
setInterval(checkDWD, 5 * 60 * 1e3)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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'))
|
|
|
|
|
|
|
|
/** 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.pager)) return res.status(403).json(false)
|
|
|
|
if (!(!!req.body.regions)) 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(3050, '0.0.0.0' || config.host || '127.0.0.1')
|