236 lines
8.2 KiB
JavaScript
236 lines
8.2 KiB
JavaScript
var mqttData = {};
|
||
|
||
const solarMQTT = {
|
||
getMQTT: function () {
|
||
const id = Math.random().toString(36).substring(7);
|
||
const topic = "#";
|
||
const connection = "wss://mqtt.nas.el-wa.org:443"
|
||
mqttsolarTreeDone = false;
|
||
// const connection = "ws://username:password@37.97.203.138:8083" // Works
|
||
// const connection = "wss://public:public@public.cloud.shiftr.io" // Works
|
||
const client = mqtt.connect(connection, {
|
||
rejectUnauthorized: false,
|
||
});
|
||
|
||
client.on("message", messageReceived);
|
||
client.on("connect", function () {
|
||
client.subscribe("solarManager/#");
|
||
client.subscribe("wattpilot/properties/lmo/state");
|
||
client.subscribe("wattpilot/properties/ftt/state");
|
||
client.subscribe("wattpilot/properties/fte/state");
|
||
client.subscribe("wattpilot/properties/amp/state");
|
||
client.subscribe("wattpilot/properties/car/state");
|
||
client.subscribe("go-eCharger/270003/amp");
|
||
client.subscribe("go-eCharger/270003/ate");
|
||
client.subscribe("go-eCharger/270003/lmo");
|
||
client.subscribe("go-eCharger/270003/att");
|
||
client.subscribe("go-eCharger/270003/car");
|
||
client.subscribe("weatherStation/#");
|
||
});
|
||
client.on("error", function (error) {
|
||
//alert("MQTT Error: " + error);
|
||
});
|
||
client.on('end', function () {
|
||
setTimeout(getMQTT, 5000);
|
||
alert("MQTT Disconnected, try to reconnect in 5 secs.");
|
||
})
|
||
|
||
function getNestedProp(obj, path) {
|
||
return path.split('/').reduce((acc, key) => acc && acc[key], obj);
|
||
}
|
||
function setNestedProp(obj, path, value) {
|
||
var schema = obj; // a moving reference to internal objects within obj
|
||
var pList = path.split('/');
|
||
var len = pList.length;
|
||
for (var i = 0; i < len - 1; i++) {
|
||
var elem = pList[i];
|
||
if (!schema[elem]) schema[elem] = {}
|
||
schema = schema[elem];
|
||
}
|
||
|
||
schema[pList[len - 1]] = value;
|
||
}
|
||
|
||
function messageReceived(topic, message) {
|
||
setNestedProp(mqttData, topic, message);
|
||
if (topic == "solarManager/P_Load") {
|
||
setTimeout(function () { solarSVG.updateValuesMQTT(mqttData) }, 200); //give the object tree some time to build up and receive all values
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
const solarSVG = {
|
||
updateCnt: 99,
|
||
updateValuesMQTT: function (mqttData) {
|
||
if (this.updateCnt > 10) {
|
||
this.updateCnt = 0;
|
||
var obj = document.querySelector("object");
|
||
var htmlNode = obj.contentDocument;
|
||
htmlNode.getElementById("PufferOtxt").innerHTML = mqttData["solarManager"]["t_buffT"] + " °C";
|
||
htmlNode.getElementById("PufferMtxt").innerHTML = mqttData["solarManager"]["t_buffM"] + " °C";
|
||
htmlNode.getElementById("PufferUtxt").innerHTML = mqttData["solarManager"]["t_buffB"] + " °C";
|
||
htmlNode.getElementById("heaterVL").innerHTML = mqttData["solarManager"]["t_heatVL"] + " °C";
|
||
htmlNode.getElementById("heaterRL").innerHTML = mqttData["solarManager"]["t_heatRL"] + " °C";
|
||
htmlNode.getElementById("thermeVLfb").innerHTML = mqttData["solarManager"]["t_gasVLu"] + " °C";
|
||
htmlNode.getElementById("thermeVLww").innerHTML = mqttData["solarManager"]["t_gasVLo"] + " °C";
|
||
htmlNode.getElementById("thermeRL").innerHTML = mqttData["solarManager"]["t_gasRL"] + " °C";
|
||
htmlNode.getElementById("fbVL").innerHTML = mqttData["solarManager"]["t_fbVL"] + " °C";
|
||
htmlNode.getElementById("fbRL").innerHTML = mqttData["solarManager"]["t_fbRL"] + " °C";
|
||
htmlNode.getElementById("triac").innerHTML = mqttData["solarManager"]["t_triac"] + " °C";
|
||
}
|
||
this.updateCnt++;
|
||
}
|
||
|
||
}
|
||
|
||
var chartSettings = {
|
||
type: 'line',
|
||
options: {
|
||
animation: true,
|
||
plugins: {
|
||
annotation: {
|
||
common: { type: 'box', drawTime: 'beforeDatasetsDraw', yScaleID: 'y-axis-0', backgroundColor: 'rgba(255, 255, 255, 0.05)', init: true },
|
||
annotations: []
|
||
},
|
||
tooltip: {
|
||
position: 'nearest',
|
||
pointStyle: "circle",
|
||
boxWidth: 4,
|
||
usePointStyle: true,
|
||
callbacks: {
|
||
label: function (context) {
|
||
let label = context.dataset.label || '';
|
||
if (label) {
|
||
label += ': ';
|
||
}
|
||
if (context.dataset.yAxisID == "y1") {
|
||
label += Math.round(context.parsed.y * 10) / 10 + " " + "L/min";
|
||
} else {
|
||
if (context.parsed.y !== null) {
|
||
ret = scale(Math.round(context.parsed.y), false);
|
||
label += ret[0] + " " + ret[1] + "°C";
|
||
}
|
||
}
|
||
return label;
|
||
},
|
||
},
|
||
},
|
||
legend: {
|
||
position: "bottom",
|
||
labels: {
|
||
pointStyleWidth: 10,
|
||
usePointStyle: true,
|
||
pointStyle: "line",
|
||
}
|
||
},
|
||
},
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
interaction: {
|
||
intersect: false,
|
||
mode: 'index',
|
||
},
|
||
scales: {
|
||
x: {
|
||
adapters: {
|
||
date: {
|
||
locale: "DE-de"
|
||
}
|
||
},
|
||
ticks: {
|
||
|
||
},
|
||
type: 'timestack',
|
||
},
|
||
y: {
|
||
stacked: false,
|
||
display: true,
|
||
position: 'left',
|
||
ticks: {
|
||
callback: value => `${value} °C`,
|
||
},
|
||
title: {
|
||
display: true,
|
||
text: "Temperatur"
|
||
}
|
||
},
|
||
y1: {
|
||
stacked: false,
|
||
display: true,
|
||
position: 'right',
|
||
ticks: {
|
||
callback: value => `${value} L/min`,
|
||
},
|
||
title: {
|
||
display: true,
|
||
text: "Wasserverbrauch"
|
||
},
|
||
data:{}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
var chartData = {};
|
||
const heatChart = new Chart(
|
||
document.querySelector('#heat-chart'),
|
||
Object.assign({}, chartSettings)
|
||
);
|
||
const waterChart = new Chart(
|
||
document.querySelector('#water-chart'),
|
||
Object.assign({}, chartSettings)
|
||
);
|
||
|
||
document.addEventListener('readystatechange', function () {
|
||
if (event.target.readyState === "complete") {
|
||
solarMQTT.getMQTT();
|
||
getData(heatChart, 'ajax/getHeaterData.php');
|
||
getData(waterChart, 'ajax/getWaterData.php');
|
||
}
|
||
});
|
||
|
||
String.prototype.toHHMM = function () {
|
||
var sec_num = parseInt(this, 10); // don't forget the second param
|
||
var hours = Math.floor(sec_num / 3600);
|
||
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
||
var seconds = sec_num - (hours * 3600) - (minutes * 60);
|
||
|
||
if (hours < 10) { hours = "0" + hours; }
|
||
if (minutes < 10) { minutes = "0" + minutes; }
|
||
return hours + ':' + minutes;
|
||
}
|
||
|
||
async function getData(chart, url, sunrise=true) {
|
||
try {
|
||
console.log("fetching");
|
||
const response = await fetch(url);
|
||
if (!response.ok) {
|
||
console.log("err");
|
||
throw new Error(`Response status: ${response.status}`);
|
||
}
|
||
chart.data = await response.json();
|
||
if(sunrise){
|
||
const response2 = await fetch("ajax/getSunrise.php?FROM=-24&TO=0");
|
||
if (!response2.ok) {
|
||
console.log("err");
|
||
throw new Error(`Response status: ${response2.status}`);
|
||
}
|
||
chart.options.plugins.annotation.annotations = await response2.json();
|
||
}
|
||
chart.update();
|
||
} catch (error) {
|
||
console.log(error.message);
|
||
}
|
||
setTimeout(function () { getData(chart, url, sunrise) }, 5 * 60 * 1000); //renew data every 5 min.
|
||
}
|
||
|
||
function powerToString(power) {
|
||
if (Math.abs(power) > 999) {
|
||
power = power / 1000
|
||
return power.toPrecision(3) + " kW"
|
||
} else {
|
||
return Math.round(power) + " W"
|
||
}
|
||
|
||
} |