Sineos / redmatic-flow-sysinfo

Display CCU system information in a dashboard
GNU General Public License v3.0
7 stars 2 forks source link

Bei Verwendung eines Gatways schlagen Angaben zum Duty Cycle fehl #9

Closed HMelzer closed 2 years ago

HMelzer commented 2 years ago

Wird in in der RaspberryMatic-Umgebung ein oder mehrerer Gateways verwendet, gibt es dafür, aber auch für die Zentrale keine Angaben zum Duty Cycle mehr. Auch die RSSI-Werte werden nicht mehr ausgegeben. Lässt sich hier eine Ergänzung implementieren?

Sineos commented 2 years ago

Im Prinzip ja. Leider habe ich keine Gateways im Einsatz, deshalb kann ich das nicht nachstellen, bzw. anpassen. Wie sieht denn die Debugausgabe der rssiInfo Abfrage mit Gateway aus?

HMelzer commented 2 years ago

Anbei habe ich mal eine auf das Wesentliche gekürzte Datei mit der Debugausgabe des rssiInfo Knotens angehängt.

RSSI-debug-Ausgabe.txt

Zur Information: OEQ0606784 ist die CCU, in diesem Falle die RaspberryMatic, REQ1359302 ist das Gateway.

QEQ0714358, QEQ0714741 und QEQ1054845 hängen direkt an der CCU, NEQ0968020, HM-TPH0001, HM-TPH0002, HM-TPH0003 hängen am Gateway. Die Sensoren, die mit HM-beginnen sind Eigenbaukomponenten, die immer schon nur einen RSSI-Wert zurückgegeben haben. Relevant wäre hier eher der Sensor NEQ0968020, der ja beide Werte zurückgibt.

HMelzer commented 2 years ago

Hatte es versehentlich geschlossen.

Sineos commented 2 years ago

Puh, da bricht irgendwie die gesamte bisherige Logik zusammen. Bitte mal das komplette Objekt und wenn möglich einen passenden RSSI Screenshot aus der "DevConfig" Seite der CCU anhängen.

HMelzer commented 2 years ago

Wie soll ich das gesamte Objekt der Debug-Ausgabe speichern? Siehst du da die Möglichkeit, die ich derzeit nicht sehe. Auch der RSSI-Screenshot wird mindestens in drei Objekten zu speichern sein.

HMelzer commented 2 years ago

Wäre das so recht? rssiInfoObjekt.txt

HMelzer commented 2 years ago

Hier noch die Screenshots aus dem "DevConfig": Screenshot 2022-02-25 191153 Screenshot 2022-02-25 191542

Sineos commented 2 years ago

Wäre das so recht?

Danke. Ist das der Output, der bei Dir im Node-Red Debug Fenster erscheint, beispielsweise bei sowas:

[{"id":"2897afe7.2e3048","type":"ccu-rpc","z":"721e71e2.b201b8","name":"","ccuConfig":"38263145.35ea0e","iface":"BidCos-RF","method":"rssiInfo","params":"[]","topic":"${CCU}/${Interface}/${Method}","x":300,"y":1080,"wires":[["52a73334.5b7dc4"]]},{"id":"52a73334.5b7dc4","type":"debug","z":"721e71e2.b201b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":450,"y":1080,"wires":[]},{"id":"1ea13736.5ba511","type":"inject","z":"721e71e2.b201b8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":1080,"wires":[["2897afe7.2e3048"]]},{"id":"38263145.35ea0e","type":"ccu-connection","name":"localhost","host":"localhost","regaEnabled":true,"bcrfEnabled":true,"iprfEnabled":true,"virtEnabled":true,"bcwiEnabled":false,"cuxdEnabled":false,"regaPoll":true,"regaInterval":"30","rpcPingTimeout":"60","rpcInitAddress":"192.168.178.18","rpcServerHost":"192.168.178.18","rpcBinPort":"2047","rpcXmlPort":"2048","tls":false,"inSecure":false,"authentication":false,"username":"","password":"","queueTimeout":"5000","queuePause":"250","contextStore":"default"}]

--> Code kopieren und in Node-Red importieren

Debug Output sollte dann etwa so aussehen: grafik

HMelzer commented 2 years ago

Wenn das so genügt:

grafik

Sineos commented 2 years ago

Bitte einmal testen:

[{"id":"43c7216a.58de68","type":"function","z":"721e71e2.b201b8","name":"Extract RSSI values","func":"const rssi = msg.payload,\n      DBValues = [];\n\nlet msg2 = {},\n    centrals = [];\n\n// Identify available centrals: CCU, Gatesways, etc\n// If multiple centrals exist then the \"BidCoS-RF\" object exists\nif (rssi['BidCoS-RF']) {\n  centrals = Object.keys(rssi['BidCoS-RF']);\n} else {\n  // Object is unordered: Make sure we do not catch the CCU\n  const temp0 = Object.keys(rssi)[0];\n  const temp1 = Object.keys(rssi)[1];\n  if (Object.keys(rssi[temp0]).length === 1) {\n    centrals = (Object.keys(rssi[temp0]));\n  } else if (Object.keys(rssi[temp1]).length === 1) {\n    centrals = (Object.keys(rssi[temp1]));\n  } else {\n    node.error('No central identified');\n  }\n}\n\nfor (const central of centrals) {\n  for (const MyDevice of Object.keys((rssi)[central])) {\n    if (MyDevice !== 'BidCoS-RF') {\n      const device = {\n        central: central,\n        device: MyDevice,\n        down: (rssi[central][MyDevice][1] === 65536)? 'N/A':rssi[central][MyDevice][1],\n        up: (rssi[central][MyDevice][0] === 65536)? 'N/A':rssi[central][MyDevice][0]\n      };\n      DBValues.push(device);\n    }\n  }\n}\n\nmsg2 = {\n  payload: DBValues,\n  topic: msg.topic\n};\n\nreturn msg2;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":640,"wires":[["6982e9d1.146ed"]]},{"id":"6982e9d1.146ed","type":"change","z":"721e71e2.b201b8","name":"ui_control","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"tabulator\":{\"columnResized\":\"function(column){var newColumn = {field: column._column.field, visible: column._column.visible, width: column._column.width, widthFixed: column._column.widthFixed, widthStyled: column._column.widthStyled};this.send({topic:this.config.topic,ui_control:{callback:'columnResized',columnWidths:newColumn}});}\",\"columnMoved\":\"function(column, columns){var newColumns=[];columns.forEach(function (column) {newColumns.push({'field': column._column.field});});this.send({topic:this.config.topic,ui_control:{callback:'columnMoved',columns:newColumns}});}\",\"layout\":\"fitColumns\",\"columns\":[{\"title\":\"Gerät\",\"field\":\"device\",\"formatter\":\"function(cell, formatterParams, onRendered){return cell.getValue();}\"},{\"title\":\"<div style='text-align:center'><i class='fa fa-arrow-circle-up' aria-hidden='true'></i></div>\",\"align\":\"center\",\"field\":\"up\",\"formatter\":\"function(cell, formatterParams){ var value = cell.getValue(); if (value >= -50) { cell.getElement().style.backgroundColor='#00cc44'; } else if (value <= -51 && value >= -100) { cell.getElement().style.backgroundColor='#66ff66'; } else if (value <= -101 && value >= -120) { cell.getElement().style.backgroundColor='#ff8c66'; } else if (value <= -120) { cell.getElement().style.backgroundColor='#ff6666'} return value;}\"},{\"title\":\"<div style='text-align:center'><i class='fa fa-arrow-circle-down' aria-hidden='true'></i></div>\",\"field\":\"down\",\"align\":\"center\",\"formatter\":\"function(cell, formatterParams){ var value = cell.getValue(); if (value >= -50) { cell.getElement().style.backgroundColor='#00cc44'; } else if (value <= -51 && value >= -100) { cell.getElement().style.backgroundColor='#66ff66'; } else if (value <= -101 && value >= -120) { cell.getElement().style.backgroundColor='#ff8c66'; } else if (value <= -120) { cell.getElement().style.backgroundColor='#ff6666'} return value;}\"}],\"movableColumns\":true,\"groupBy\":\"central\"},\"customHeight\":55}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":640,"wires":[["b30e50c8.b1e23"]]},{"id":"b30e50c8.b1e23","type":"ui_table","z":"721e71e2.b201b8","group":"4bbfb1c3.d86a","name":"RSSI Table","order":2,"width":"6","height":"12","columns":[],"outputs":1,"cts":true,"x":750,"y":640,"wires":[[]]},{"id":"4bbfb1c3.d86a","type":"ui_group","name":"CCU","tab":"189e0ea3.dd5dd1","order":2,"disp":true,"width":"6","collapse":false},{"id":"189e0ea3.dd5dd1","type":"ui_tab","name":"System","icon":"computer","order":7}]
Sineos commented 2 years ago

Bevor ich es vergesse: grafik

Bitte hier auch noch den kompletten Debug Output als Text rein kopieren / anhängen.

HMelzer commented 2 years ago

Sieht erst einmal soweit gut aus, obwohl ja alle BidCos-RF-Geräte nun doppelt aufgeführt werden, einmal für die CCU, einmal für das Gateway, Tatsächlich kommunizieren diese aber ja nur mit jeweils einem Partner. Das da auch Werte zum/für den anderen Partner generiert werden, die sich so auch unterscheiden ist sicher richtig, aber im vorliegenden Fall wohl uninteressant. Wie schon am 25.02. erwähnt hier noch mal beispielhaft folgende Information.

Zur Information: OEQ0606784 ist die CCU, in diesem Falle die RaspberryMatic, REQ1359302 ist das Gateway.

QEQ0714358, QEQ0714741 und QEQ1054845 hängen direkt an der CCU, NEQ0968020, HM-TPH0001, HM-TPH0002, HM-TPH0003 hängen am Gateway.

Das gewünschte Debug-Output folg hier: grafik Wenn gewünscht, kann ich natürlich eine vollständige Liste der einzelnen Zuordnungen liefern.

Ich habe mir gerade noch einmal die Debug-Ausgabe des rssiInfo-Knotens angesehen. Da ist mit tatsächlich nicht aufgefallen, wonach man unterscheiden kann, woran ein Gerät hängt.

Sineos commented 2 years ago

Sieht erst einmal soweit gut aus, obwohl ja alle BidCos-RF-Geräte nun doppelt aufgeführt werden, einmal für die CCU, einmal für das Gateway, Tatsächlich kommunizieren diese aber ja nur mit jeweils einem Partner.

Ja, leider geht diese Information aus der RSSI Abfrage nicht hervor. Siehe auch den Screenshot aus "DevConfig". Was die Methode in der Redmatic macht ist nichts anderes.

Bezüglich der Duty Cycle Thematik:

grafik

Wie würdest du es dir vorstellen? Das Zeigerinstrument macht bei zwei oder mehr Duty Cycle Werten nur noch eingeschränkt Sinn:

HMelzer commented 2 years ago

Tut mir leid, dass ich erst so spät antworte, aber ich quäle mich gerade mit einem PID-Regler herum und, es gib da auch eben noch Anderes. Das Zeigerinstrument ist ja nun mal wenig geignet mehr als eine Ausgabe zu machen. Aus meiner Sicht reicht es doch vollkommen die Werte als Balkendiagram in einer Chart-Node darzustellen. Vorteilhaft wäre wohl aber auch, das nicht in einer Node zu machen, sondern eben in mehreren (ähnlich, wie es ja auch auf der Startseite der CCU ist). Die Chart-Node Duty Cycle (1 hour) kann ja so bleiben und mit den Werten der CCU und des/der Gateways gefüllt werden.

Sineos commented 2 years ago

grafik

So hab ich es jetzt mal gelöst. An einer Visualisierung kann und darf ja jeder basteln wie er möchte

Anbei mal die letzten Stände:

RSSI:

[{"id":"43c7216a.58de68","type":"function","z":"721e71e2.b201b8","name":"Extract RSSI values","func":"const rssi = msg.payload,\n      DBValues = [];\n\nlet msg2 = {},\n    centrals = [];\n\n// Identify available centrals: CCU, Gatesways, etc\n// If multiple centrals exist then the \"BidCoS-RF\" object exists\nif (rssi['BidCoS-RF']) {\n  centrals = Object.keys(rssi['BidCoS-RF']);\n} else {\n  // Object is unordered: Make sure we do not catch the CCU\n  const temp0 = Object.keys(rssi)[0];\n  const temp1 = Object.keys(rssi)[1];\n  if (Object.keys(rssi[temp0]).length === 1) {\n    centrals = (Object.keys(rssi[temp0]));\n  } else if (Object.keys(rssi[temp1]).length === 1) {\n    centrals = (Object.keys(rssi[temp1]));\n  } else {\n    node.error('No central identified');\n  }\n}\n\nfor (const central of centrals) {\n  for (const MyDevice of Object.keys((rssi)[central])) {\n    if (MyDevice !== 'BidCoS-RF') {\n      const device = {\n        central: central,\n        device: MyDevice,\n        down: (rssi[central][MyDevice][1] === 65536)? 'N/A':rssi[central][MyDevice][1],\n        up: (rssi[central][MyDevice][0] === 65536)? 'N/A':rssi[central][MyDevice][0]\n      };\n      DBValues.push(device);\n    }\n  }\n}\n\nmsg2 = {\n  payload: DBValues,\n  topic: msg.topic\n};\n\nreturn msg2;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":640,"wires":[["6982e9d1.146ed"]]},{"id":"6982e9d1.146ed","type":"change","z":"721e71e2.b201b8","name":"ui_control","rules":[{"t":"set","p":"ui_control","pt":"msg","to":"{\"tabulator\":{\"columnResized\":\"function(column){var newColumn = {field: column._column.field, visible: column._column.visible, width: column._column.width, widthFixed: column._column.widthFixed, widthStyled: column._column.widthStyled};this.send({topic:this.config.topic,ui_control:{callback:'columnResized',columnWidths:newColumn}});}\",\"columnMoved\":\"function(column, columns){var newColumns=[];columns.forEach(function (column) {newColumns.push({'field': column._column.field});});this.send({topic:this.config.topic,ui_control:{callback:'columnMoved',columns:newColumns}});}\",\"layout\":\"fitColumns\",\"columns\":[{\"title\":\"Device\",\"field\":\"device\",\"formatter\":\"function(cell, formatterParams, onRendered){return cell.getValue();}\"},{\"title\":\"<div style='text-align:center'><i class='fa fa-arrow-circle-up' aria-hidden='true'></i></div>\",\"align\":\"center\",\"field\":\"up\",\"formatter\":\"function(cell, formatterParams){ var html_excel = 'style=\\\"color:#00cc44\\\"></i>'; var html_good = 'style=\\\"color:#66ff66\\\"></i>'; var html_aver = 'style=\\\"color:#ff8c66\\\"></i>'; var html_bad = 'style=\\\"color:#ff6666\\\"></i>'; var html='<i class=\\\"fa fa-circle fa-fw\\\" '; var value = cell.getValue(); if (value >= -50) { value = value + html + html_excel} else if (value <= -51 && value >= -100) { value = value + html + html_good; } else if (value <= -101 && value >= -120) { value = value + html + html_aver; } else if (value <= -120) { value = value + html + html_bad}; return value;}\"},{\"title\":\"<div style='text-align:center'><i class='fa fa-arrow-circle-down' aria-hidden='true'></i></div>\",\"field\":\"down\",\"align\":\"center\",\"formatter\":\"function(cell, formatterParams){ var html_excel = 'style=\\\"color:#00cc44\\\"></i>'; var html_good = 'style=\\\"color:#66ff66\\\"></i>'; var html_aver = 'style=\\\"color:#ff8c66\\\"></i>'; var html_bad = 'style=\\\"color:#ff6666\\\"></i>'; var html='<i class=\\\"fa fa-circle fa-fw\\\" '; var value = cell.getValue(); if (value >= -50) { value = value + html + html_excel} else if (value <= -51 && value >= -100) { value = value + html + html_good; } else if (value <= -101 && value >= -120) { value = value + html + html_aver; } else if (value <= -120) { value = value + html + html_bad}; return value;}\"}],\"movableColumns\":true,\"groupBy\":\"central\"},\"customHeight\":55}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":640,"wires":[["b30e50c8.b1e23"]]},{"id":"b30e50c8.b1e23","type":"ui_table","z":"721e71e2.b201b8","group":"b533a88a.2e9378","name":"RSSI Table","order":2,"width":"6","height":"11","columns":[],"outputs":1,"cts":true,"x":750,"y":640,"wires":[[]]},{"id":"b533a88a.2e9378","type":"ui_group","name":"CCU RSSI","tab":"189e0ea3.dd5dd1","order":7,"disp":true,"width":"6","collapse":false,"className":""},{"id":"189e0ea3.dd5dd1","type":"ui_tab","name":"System","icon":"computer","order":7}]

Duty Cycle:

[{"id":"15e18e55.7728e2","type":"function","z":"721e71e2.b201b8","name":"Extract DC values","func":"const DutyCycle = msg.payload,\n      OutMsgs = [];\n\nfor (const element of DutyCycle) {\n  const result = {\n    topic: element['ADDRESS'],\n    payload: element['DUTY_CYCLE']\n  };\n  OutMsgs.push(result);\n}\n\n\nreturn [OutMsgs];\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1330,"y":640,"wires":[["934645d.5a566b8","933be049.370c28"]]},{"id":"934645d.5a566b8","type":"ui_chart","z":"721e71e2.b201b8","name":"Duty Cycle (1 hour)","group":"4bbfb1c3.d86a","order":2,"width":0,"height":0,"label":"Duty Cycle (1 hour)","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"100","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":1570,"y":620,"wires":[[]]},{"id":"933be049.370c28","type":"ui_chart","z":"721e71e2.b201b8","name":"Duty Cycle (Current)","group":"4bbfb1c3.d86a","order":1,"width":0,"height":0,"label":"Duty Cycle (Current)","chartType":"bar","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"100","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":1580,"y":660,"wires":[[]]},{"id":"4bbfb1c3.d86a","type":"ui_group","name":"CCU Duty Cycle","tab":"189e0ea3.dd5dd1","order":2,"disp":true,"width":"6","collapse":false,"className":""},{"id":"189e0ea3.dd5dd1","type":"ui_tab","name":"System","icon":"computer","order":7}]

Duty Cycle muss dann so aussehen: grafik

HMelzer commented 2 years ago

Es gefällt mir jetzt gut! Bei kleinen Duty Cycle-Werten ist ja kaum etwas zu sehen, da ist es aber auch nicht so wichtig. Wenn die Werte dann größer werden kann man das schon gut sehen. Eine kleine Anmerkung hätte ich noch: Gehen wir mal davon aus, dass es Anwender gibt, die mehr als ein Gateway haben, dann teilt ja die Chart-Node die vorhandene Breite unter der CCU und allen Gateways auf. Da könnte es unter Umständen knapp werden mit dem Platz für die Geräte-ID. Wäre es da nicht günstiger, die Balken waagerecht auszurichten?

HMelzer commented 2 years ago

Hier als Beispiel:

grafik

Sineos commented 2 years ago

Da könnte es unter Umständen knapp werden mit dem Platz für die Geräte-ID. Wäre es da nicht günstiger, die Balken waagerecht auszurichten?

Die Idee ist gut und ich werde es so als Update für den Flow einchecken.

Nur als Randbemerkung: Die Flows, die ich geteilt habe, sollten ja kein fertiges Produkt sein, sondern nur ein bisschen zeigen, was mit Node Red im Allgemeinen und speziell im Zusammenhang mit der CCU möglich ist. Dadurch, dass alles offengelegt und durch Node Red auch die Einstiegshürde m.E. recht gering ist, kann jeder daran basteln wie er möchte (ich bin selber ein grauenvoller N00b-Coder). Bei mir verwaltet die CCU nur noch die Hardware und die gesamte Logik habe ich in NR ausgelagert (zumal ich die Logik und das Scripting in der CCU absolut gruselig finde)

Ich werde für meinen Flow sicher das Zeigerinstrument beibehalten, da ich keine Gateways habe und es deswegen schicker finde.

HMelzer commented 2 years ago

Ja, natürlich kann jeder in den Flows Anpasssungen nach seiner Fassong vornehmen. Aber es ist manchmal schon nicht schlecht, wenn man, insbesondere dann, wenn die Flows so umfangreich sind, eine geschlossene Lösung nutzen kann. ging mir jedenfalls so. Und ehrlicherweise tue ich mich schon auch schwer bei gewissen Anpassungen hinsichtlich Funktions-Nodes und auch Tabellen und Templates.

Ansonsten ist es auch bei mir so, dass die CCU eigentlich nur noch die Geräte verwaltet und die Funktionalität in Node-Red ausgelagert ist.