compose.yml für dockge dazu
This commit is contained in:
245
routes/switch.js
245
routes/switch.js
@@ -1,118 +1,169 @@
|
||||
var express = require('express');
|
||||
let router = express.Router();
|
||||
let mqtt = require('mqtt');
|
||||
let moment = require('moment');
|
||||
const fs = require('await-fs');
|
||||
var router = express.Router();
|
||||
var mqtt = require('mqtt');
|
||||
var moment = require('moment');
|
||||
var fs = require('fs/promises');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var DEFAULT_BRENNDAUER = 300;
|
||||
var brenndauer = DEFAULT_BRENNDAUER;
|
||||
|
||||
const configName = "config.json"
|
||||
var MQTTHOST = process.env.MQTTHOST || 'localhost';
|
||||
var MQTTPORT = process.env.MQTTPORT || 1883;
|
||||
var MQTTUSR = process.env.MQTTUSR || '';
|
||||
var MQTTPWD = process.env.MQTTPWD || '';
|
||||
var TOPIC = process.env.TOPIC || 'sonoff';
|
||||
var SWITCH_API_TOKEN = process.env.SWITCH_API_TOKEN || '';
|
||||
|
||||
var switchOffTimer;
|
||||
var state = {
|
||||
connect: 'disconnected',
|
||||
relais: 'UNKNOWN',
|
||||
offtime: undefined,
|
||||
lastError: undefined
|
||||
};
|
||||
|
||||
let brenndauer = 300; // 20sec Relais ON
|
||||
var client = mqtt.connect('mqtt://' + MQTTHOST + ':' + MQTTPORT, {
|
||||
username: MQTTUSR,
|
||||
password: MQTTPWD
|
||||
});
|
||||
|
||||
// MQTT:
|
||||
let MQTTHOST = process.env.MQTTHOST;
|
||||
let MQTTPORT = process.env.MQTTPORT;
|
||||
let MQTTUSR = process.env.MQTTUSR;
|
||||
let MQTTPWD = process.env.MQTTPWD;
|
||||
let TOPIC=process.env.TOPIC;
|
||||
|
||||
|
||||
if (MQTTHOST === undefined) { MQTTHOST = 'localhost';}
|
||||
if (MQTTPORT === undefined) { MQTTPORT = 1883;}
|
||||
if (MQTTUSR === undefined) { MQTTUSR = "";}
|
||||
if (MQTTPWD === undefined) { MQTTPWD = "";}
|
||||
if (TOPIC === undefined) { TOPIC = "sonoff";}
|
||||
|
||||
/*
|
||||
if (MQTTHOST === undefined) { MQTTHOST = 'laufschrift.rexfue.de';}
|
||||
if (MQTTPORT === undefined) { MQTTPORT = 1883;}
|
||||
if (MQTTUSR === undefined) { MQTTUSR = "stwLauf";}
|
||||
if (MQTTPWD === undefined) { MQTTPWD = "37CrNcgP";}
|
||||
*/
|
||||
// console.log("H",MQTTHOST," P",MQTTPORT," U",MQTTUSR," p",MQTTPWD);
|
||||
|
||||
let tio;
|
||||
let connected = false;
|
||||
let relais = 'MIST';
|
||||
let client = mqtt.connect("mqtt://" + MQTTHOST + ":" + MQTTPORT,{username: MQTTUSR, password: MQTTPWD});
|
||||
let offtime = "";
|
||||
let retur = {};
|
||||
|
||||
console.log("Start: ", moment().format("YYYY-MM-DD HH:mm"));
|
||||
console.log('Start: ', moment().format('YYYY-MM-DD HH:mm'));
|
||||
|
||||
client.on('connect', function() {
|
||||
connected = true;
|
||||
retur.connect = 'connected';
|
||||
client.subscribe('stat/'+TOPIC+'/POWER');
|
||||
})
|
||||
|
||||
client.on('message',function(topix,message) {
|
||||
relais = message.toString();
|
||||
console.log("Status = ",relais);
|
||||
if (relais == 'OFF') {
|
||||
delete retur.offtime;
|
||||
}
|
||||
retur.relais = relais;
|
||||
});
|
||||
|
||||
client.on('reconnect', function(){
|
||||
retur.connect = 'reconnect';
|
||||
});
|
||||
|
||||
|
||||
// Konfig einlesen und entsprechende Variablen einstellen
|
||||
(async () => {
|
||||
try{
|
||||
let json = await fs.readFile('config/config.json','utf8')
|
||||
js = JSON.parse(json);
|
||||
if(js.brenndauer != undefined) {
|
||||
brenndauer = js.brenndauer;
|
||||
state.connect = 'connected';
|
||||
state.lastError = undefined;
|
||||
client.subscribe('stat/' + TOPIC + '/POWER', function(err) {
|
||||
if (err) {
|
||||
state.lastError = 'subscribe failed: ' + err.message;
|
||||
}
|
||||
console.log(brenndauer);
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
});
|
||||
});
|
||||
|
||||
client.on('reconnect', function() {
|
||||
state.connect = 'reconnect';
|
||||
});
|
||||
|
||||
client.on('offline', function() {
|
||||
state.connect = 'offline';
|
||||
});
|
||||
|
||||
client.on('error', function(err) {
|
||||
state.lastError = err.message;
|
||||
});
|
||||
|
||||
client.on('message', function(_topic, message) {
|
||||
state.relais = message.toString();
|
||||
if (state.relais === 'OFF') {
|
||||
state.offtime = undefined;
|
||||
}
|
||||
})()
|
||||
|
||||
|
||||
// beim start mal den Zustand abfragen
|
||||
doPublish("");
|
||||
});
|
||||
|
||||
function getResponse() {
|
||||
return {
|
||||
connect: state.connect,
|
||||
relais: state.relais,
|
||||
offtime: state.offtime,
|
||||
lastError: state.lastError
|
||||
};
|
||||
}
|
||||
|
||||
function doPublish(payload) {
|
||||
// retur.relais='pending';
|
||||
client.publish('cmnd/'+TOPIC+'/Power',payload);
|
||||
if (payload == 'On') {
|
||||
offtime = moment().add(brenndauer, 's').format("HH.mm");
|
||||
tio = setTimeout(doPublish, brenndauer * 1000, "Off");
|
||||
retur.offtime = offtime;
|
||||
} else if (payload == 'Off') {
|
||||
clearTimeout(tio);
|
||||
client.publish('cmnd/' + TOPIC + '/Power', payload, function(err) {
|
||||
if (err) {
|
||||
state.lastError = err.message;
|
||||
}
|
||||
});
|
||||
|
||||
if (payload === 'On') {
|
||||
clearTimeout(switchOffTimer);
|
||||
state.offtime = moment().add(brenndauer, 's').format('HH.mm');
|
||||
switchOffTimer = setTimeout(doPublish, brenndauer * 1000, 'Off');
|
||||
} else if (payload === 'Off') {
|
||||
clearTimeout(switchOffTimer);
|
||||
state.offtime = undefined;
|
||||
}
|
||||
}
|
||||
// end MQTT
|
||||
|
||||
/* GET switch data */
|
||||
router.get('/:cmd', function(req, res, next) {
|
||||
let cmd = req.params.cmd;
|
||||
let wert = req.query.wert;
|
||||
|
||||
if (cmd == 'get_status') {
|
||||
doPublish("");
|
||||
} else if (cmd == 'switch_on') {
|
||||
doPublish("On");
|
||||
} else if (cmd == 'switch_off') {
|
||||
doPublish("Off");
|
||||
} else if (cmd == 'check') {
|
||||
|
||||
} else {
|
||||
retur = { error: "invalid command"};
|
||||
res.json(retur);
|
||||
// Read optional runtime config.
|
||||
(async function loadConfig() {
|
||||
try {
|
||||
var json = await fs.readFile('config/config.json', 'utf8');
|
||||
var cfg = JSON.parse(json);
|
||||
if (cfg.brenndauer !== undefined) {
|
||||
brenndauer = Number(cfg.brenndauer) || DEFAULT_BRENNDAUER;
|
||||
}
|
||||
} catch (err) {
|
||||
state.lastError = 'config load failed: ' + err.message;
|
||||
}
|
||||
console.log("return: ",retur)
|
||||
res.json(retur);
|
||||
})();
|
||||
|
||||
// Query initial state once at startup.
|
||||
doPublish('');
|
||||
|
||||
function timingSafeEqualString(a, b) {
|
||||
var aBuf = Buffer.from(String(a));
|
||||
var bBuf = Buffer.from(String(b));
|
||||
if (aBuf.length !== bBuf.length) {
|
||||
return false;
|
||||
}
|
||||
return crypto.timingSafeEqual(aBuf, bBuf);
|
||||
}
|
||||
|
||||
function extractRequestToken(req) {
|
||||
var authHeader = req.get('authorization') || '';
|
||||
if (authHeader.startsWith('Bearer ')) {
|
||||
return authHeader.slice(7).trim();
|
||||
}
|
||||
|
||||
var apiKeyHeader = req.get('x-api-key');
|
||||
if (apiKeyHeader) {
|
||||
return apiKeyHeader;
|
||||
}
|
||||
|
||||
if (typeof req.query.token === 'string') {
|
||||
return req.query.token;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
router.use(function(req, res, next) {
|
||||
if (!SWITCH_API_TOKEN) {
|
||||
return next();
|
||||
}
|
||||
|
||||
var providedToken = extractRequestToken(req);
|
||||
if (!providedToken || !timingSafeEqualString(providedToken, SWITCH_API_TOKEN)) {
|
||||
return res.status(401).json({ error: 'unauthorized' });
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
router.get('/:cmd', function(req, res) {
|
||||
var cmd = req.params.cmd;
|
||||
|
||||
if (cmd === 'get_status') {
|
||||
doPublish('');
|
||||
return res.json(getResponse());
|
||||
}
|
||||
|
||||
if (cmd === 'switch_on') {
|
||||
doPublish('On');
|
||||
return res.json(getResponse());
|
||||
}
|
||||
|
||||
if (cmd === 'switch_off') {
|
||||
doPublish('Off');
|
||||
return res.json(getResponse());
|
||||
}
|
||||
|
||||
if (cmd === 'check') {
|
||||
return res.json(getResponse());
|
||||
}
|
||||
|
||||
return res.status(400).json({ error: 'invalid command' });
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user