const homeMQTT = { 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("Raumtemp/#"); }); 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); setTimeout(function () { homeSVG.updateValuesMQTT(mqttData) }, 200); //give the object tree some time to build up and receive all values } } } const homeSVG = { updateCnt: 99, fillElementArray: function () { }, updateValuesMQTT: function (mqttData) { // homeRooms liefert restricted/rooms.php (in home.php eingebettet). // Jeder Raum bekommt die gleiche Behandlung - Raeume kommen dort dazu, // nicht hier. homeRooms.forEach(function (room) { const values = mqttData["Raumtemp"]?.[room.floor]?.[room.mqtt]; if (!values) return; // Topic noch nicht empfangen const el = (part) => document.getElementById(room.floor + "_" + part); if (typeof (values["Heating"]) != "undefined") el(room.id + "_heater").setAttribute("display", values["Heating"] == "false" ? "none" : ""); if (typeof (values["mode"]) != "undefined") el(room.id + "_buffer").setAttribute("display", values["mode"] == "Overheating" ? "" : "none"); if (typeof (values["Set Temp[degC]"]) != "undefined") el("pres_" + room.id).innerHTML = Math.floor(values["Set Temp[degC]"]) + "\u2009\u00b0C"; if (typeof (values["Temp[degC]"]) != "undefined") el("tmp_" + room.id).innerHTML = values["Temp[degC]"] + "\u2009\u00b0C"; if (typeof (values["rHum[%]"]) != "undefined") el("hum_" + room.id).innerHTML = values["rHum[%]"] + "\u2009%rF"; }); } } var currentFloor = "OG"; function addClass(el, classNameToAdd){ el.className += ' ' + classNameToAdd; } function removeClass(el, classNameToRemove){ var elClass = ' ' + el.className + ' '; while(elClass.indexOf(' ' + classNameToRemove + ' ') !== -1){ elClass = elClass.replace(' ' + classNameToRemove + ' ', ''); } el.className = elClass; } function switchTab(newtab){ newContent = document.getElementById(newtab); newTabBtn = document.getElementById(newtab+"-tab"); removeClass(document.getElementById("actions-OG-tab"),"active"); removeClass(document.getElementById("actions-EG-tab"),"active"); removeClass(document.getElementById("actions-UG-tab"),"active"); removeClass(document.getElementById("actions-OG"),"active show"); removeClass(document.getElementById("actions-EG"),"active show"); removeClass(document.getElementById("actions-UG"),"active show"); addClass(newTabBtn,"active"); addClass(newContent,"active show"); } function switchFloor(floor){ if(currentFloor == floor) return; const targetIn = document.getElementById(floor+'_Info'); const targetOut = document.getElementById(currentFloor+'_Info'); var blendIn = new KeyframeEffect( targetIn, [{opacity: '0'},{opacity: '100'}], { duration: 500, easing: "ease-in-out", fill: "forwards", iterations: 1, } ); var blendOut = new KeyframeEffect( targetOut, [{opacity: '100'},{opacity: '0'}], { duration: 500, easing: "ease-in-out", fill: "forwards", iterations: 1, } ); var inAnim = new Animation(blendIn,document.timeline); var outAnim = new Animation(blendOut,document.timeline); targetIn.setAttribute("display",""); outAnim.onfinish= (event) => { targetOut.setAttribute("display","none"); }; inAnim.play(); outAnim.play(); currentFloor = floor; } var modalEV = new bootstrap.Modal(document.getElementById('modalEV'), { keyboard: false }); var offcanvas = new bootstrap.Offcanvas(document.getElementById('offcanvas'), { keyboard: false }); var mqttData = {}; function openHeaterSettings(heater){ openModal(heater) } document.addEventListener('readystatechange', function () { if (event.target.readyState === "complete") { homeMQTT.getMQTT(); mountMeteogram(); } }); function openModal(heater) { var contentURL = "./ajax/roomtemp.php?heater="+heater; let heaterMQTT = heater.toString().split("_"); document.getElementById("modal-title").innerHTML = "Thermostat "+heater.replace("_"," ").replace("ue","ü").replace("ae","ä").replace("oe","ö"); modalBodyElement = document.getElementById("modal-body"); modalBodyElement.innerHTML = loadingHTML("Wird geladen..."); document.getElementById("modalSaveBtn").addEventListener("click", submitFormAjax); document.getElementById("modalSaveBtn").contentURL = contentURL; modalEV.show(); fetch(contentURL, { method: 'GET', headers: { 'X-Requested-From-Modal': 'a', 'Requested-With-Ajax': 'ajax' } }) .then(response => response.text()) .then(html => { modalBodyElement.innerHTML = html; var slider = document.getElementById("modal-slider"); var span = document.getElementById("modal-slider-label"); bindModalSlider(slider, span, value => value + " °C"); if(typeof(mqttData["Raumtemp"][heaterMQTT[0]][heaterMQTT[1]]["Set Temp[degC]"])!= "undefined") slider.setAttribute("value",mqttData["Raumtemp"][heaterMQTT[0]][heaterMQTT[1]]["Set Temp[degC]"]); else slider.setAttribute("value",10); slider.dispatchEvent(new Event('input')); }) .catch(error => { modalBodyElement.innerHTML += error.message; }); }