Tag zusammen,
ich hab mal versucht, die Funktionalität der Sonos REST API über ein Script wieder auf Datenpunkte im ioBroker abzubilden.
https://github.com/dwm66/iobroker-scripts/tree/master/SonosAPI
Klappt bis jetzt ganz gut
Tag zusammen,
ich hab mal versucht, die Funktionalität der Sonos REST API über ein Script wieder auf Datenpunkte im ioBroker abzubilden.
https://github.com/dwm66/iobroker-scripts/tree/master/SonosAPI
Klappt bis jetzt ganz gut
Ich hab nur Reboot implementiert, über den Aufruf einer URL ins CuxD - könnte man einfach erweitern
function sendCCUCommand (command) {
switch (command) {
case "reboot":
try {
require("request")( "http://"+HomematicAdr+"/addons/cuxd/index.ccc?maintenance=5&pass=&cmd=" ).on("error", function () {console.error(e);});
} catch (e) { console.error(e); }
break;
}
}
1.) Ja.
2.) Hm, noch nie ausprobiert. Grundsätzlich würd ich zeitnah setzen
3.) Working heisst, dass der Timer läuft, also mit "On_TIME" eingeschaltet wurde.
Muss ich heut auf dem CuxD nachschauen …
Im Grunde, wenn der CuxD das in dem "maintainance" Menu anbietet, kann man das natürlich auch aufrufen, ist einfach ne andere URL.
Man findet auch noch zusätzliche Information ...
https://github.com/jishi/node-sonos-http-api/issues/587
https://github.com/jishi/node-sonos-http-api/issues/382
https://github.com/jishi/node-sonos-http-api/issues/709 ( Nicht uninteressant )
Was der jishi momentan als Workaround empfiehlt, ist einen entsprechenden preset anzulegen.
Probier mal folgendes:
Code: Alles auswählen
function sendCCUCommand (command) {
switch (command) {
case "reboot":
try {
require("request")( "http://"+HomematicAdr+"/addons/cuxd/index.ccc?maintenance=5&pass=&cmd=" ).on("error", function () {console.error(e);});
} catch (e) { console.error(e); }
break;
case "halt":
try {
require("request")( "http://"+HomematicAdr+"/addons/cuxd/index.ccc?maintenance=9&pass=&cmd=halt" ).on("error", function () {console.error(e);});
} catch (e) { console.error(e); }
break; }
}
Nach der Fehlermeldung schauts doch so aus, als ob die Sonos API Probleme hat, das Sonos System bzw. das Sonos Netzwerk einzulesen.
So richtig schlau aus dem #77 Issue wird man auch nicht ... aber ich glaub ehrlich gesagt nicht, dass es auf der ioBroker Seite liegt, vor allem nachdem's ja auch vom Browser aus nicht mehr funktioniert.
Mein Ansatz wär erst mal, irgendwelche Netzwerk-Probleme auszuschließen, evt. auch nochmal versuchen, ob man im Log der SonosAPI was auffälliges findet.
Wie schauts denn mit der Hardware aus - läuft das auf dem gleichen Raspi? Geht dem vielleicht die Luft aus (Speicher etc).
Den SonosAPI Server neu zu starten ... hm. Das ist, wie wenn ein Auto alle 50km stehen bleibt, und in der Werkstatt sagen sie Dir "bleib halt alle 30km die stehen und schalt die Zündung aus". Kann man machen, ist halt dann ...
Was mir dazu so durch den Kopf schiesst:
13 * * * * systemctl restart sonosapi.service > /dev/null 2>>
für den root user sollte einen Neustart jeweils um die 13. Minute jeder Stunde verursachen.
Um's ganz klar zu sagen, das ist ein GANZ grober Flicken, der ein anderes Problem unter den Tisch kehrt. Das ist aber dann nicht weg, und deswegen würde ich da durchaus Aufwand reinstecken, um rauszufinden warum das abraucht. Evt. kann ja auch der Ersteller der Sonos API da noch weiterhelfen ...
Ich hab übrigens mein Script für die Sonos API noch ein bisschen aufgebohrt...
https://github.com/dwm66/iobroker-scripts/tree/master/SonosAPI
Version 0.9.1
@maloross ... im Prinzip sollte die Geschichte mit dem TV-Mode jetzt einigermassen klappen, zumindest als Workaround
@skokarl ... Keine Ahnung, worans liegt.
Der Autostart funktioniert schon so, wie beschrieben, das passt schon. Ohne log-Ausgabe ist das nur Raten, das führt zu nix. Irgendwas ist da halt falsch zusammengestöpselt.
@martin
... müsst jetzt bei Blockly schauen, ich verwende da direkt Javascript ...
Grundsätzlich repräsentieren die MQTT Datenpunkte ja die Nuki MQTT API wie hier im PDF beschrieben: https://developer.nuki.io/t/mqtt-api-specification-v1-4/19223
D.h. Du schreibst nach "LockAction" eben die zum Beispiel die 1 für "unlock", dann sperrt das Ding auf.
Folgende Lock Actions sind möglich:
1 unlock activate rto
2 lock deactivate rto
3 unlatch electric strike actuation
4 lock ‘n’ go activate continuous mode
5 lock ‘n’ go with unlatch deactivate continuous mode
6 full lock
Fallen in die man tappen kann:
var MqttAdapterId ='mqtt.0';
var NukiId = '1234565x';
// reset MQTT lockAction data point to null after 5 sec. for security reasons
on ({id: [
MqttAdapterId+'.nuki.'+NukiId+'.lockAction',
MqttAdapterId+'.nuki.'+NukiId+'.lock',
MqttAdapterId+'.nuki.'+NukiId+'.unlock'
], valNe: null, change: 'any'},
function(dp) {
setStateDelayed ( dp.id, null, 5000, true );
});
@dbu828 Nur den grusligen workaround, den ich weiter oben beschrieben hab.
Hab da auch beim MQTT Adapter seit 2 Mon. Ein issue, noch kein Bild, kein Ton, leider ...
Vielleich noch ein paar Worte zum "LockActionState" ...
Hab da mal auf github beim MQTT Adapter ein issue eingetragen, und ich glaub die bei Nuki haben das auch schon gehört ... braucht halt alles Zeit.
Es gibt bei den Nukis übrigens grade anscheinend ne Beta-Firmware, die angeblich die angesprochenen Problemchen mit WLAN und MQTT lokal etc. adressiert. Mal schaun.
Ich hab jetzt mal einen extrem üblen und grauslichen Workaround gebaut ...
Grundidee: Nachdem die richtigen Daten ja im debug log stehen, muss man die ja eigentlich nur da rausholen ...
Also:
Ich hab die Liste auf 20 Einträge beschränkt. Damit hab ich eine Liste mit den 20 letzten MQTT LockEvent data payloads
Wenn jetzt auf mqtt.0 ein LockActionEvent kommt (das Event ist ja da, auch wenn mehr oder weniger Unsinn drinsteht), mache ich beim Logparser ein "ForceUpdate", und lese bisschen später das payload aus dem log aus. Voila.
Grobes Code Snippet zur Illustration:
function bin2String(arr) {
let result = '';
for (let i = 0; i < arr.length; i++) {
result += String.fromCharCode(arr[i]);
}
return result;
}
function getLastestLockActionEvent(){
let result = {
lockActionEventStr : null,
ts : null,
};
let logEntry = getState('logparser.1.filters.NukiLockActionEvent.json'/*Json*/).val;
try {
let logObj = JSON.parse(logEntry);
if (logObj.length == 0) return null;
let logMessage = JSON.parse(logObj[0].message);
result.lockActionEventStr = bin2String(logMessage.payload.data);
result.ts = logObj[0].ts;
let dt = new Date(result.ts);
result.timeStamp = dt.toISOString();
} catch (e) {
return null;
}
return result;
}
function NukiLockActionEventVerification(){
let lockActionEvt = getLatestLockActionEvent();
// debug output
console.log(JSON.stringify(lockActionEvt));
if (lockActionEvt !== null){
let tokenized = lockActionEvt.lockActionEventStr.split(',');
// act accordingly ...
} else {
// error handling
}
}
function NukiLockActionEventChange(dp){
setStateDelayed('logparser.1.forceUpdate'/*Force updating all states immediately*/, true,50);
setTimeout( NukiLockActionEventVerification , 250, dp.ts );
}
on ({id: MqttAdapterId+'.nuki.'+NukiId+'.lockActionEvent', change: 'any' }, NukiLockActionEventChange );
Ich hoffe mal, das ist einigermassen verständlich.
Das Ganze klappt grundsätzlich ganz nett, aber ist aber halt schon recht komplex dafür, dass der String ja einfach so dastehen sollt ... .
@martin
... müsst jetzt bei Blockly schauen, ich verwende da direkt Javascript ...
Grundsätzlich repräsentieren die MQTT Datenpunkte ja die Nuki MQTT API wie hier im PDF beschrieben: https://developer.nuki.io/t/mqtt-api-specification-v1-4/19223
D.h. Du schreibst nach "LockAction" eben die zum Beispiel die 1 für "unlock", dann sperrt das Ding auf.
Folgende Lock Actions sind möglich:
1 unlock activate rto
2 lock deactivate rto
3 unlatch electric strike actuation
4 lock ‘n’ go activate continuous mode
5 lock ‘n’ go with unlatch deactivate continuous mode
6 full lock
Fallen in die man tappen kann:
var MqttAdapterId ='mqtt.0';
var NukiId = '1234565x';
// reset MQTT lockAction data point to null after 5 sec. for security reasons
on ({id: [
MqttAdapterId+'.nuki.'+NukiId+'.lockAction',
MqttAdapterId+'.nuki.'+NukiId+'.lock',
MqttAdapterId+'.nuki.'+NukiId+'.unlock'
], valNe: null, change: 'any'},
function(dp) {
setStateDelayed ( dp.id, null, 5000, true );
});
Die ungewollten Öffnungsversuche hab ich ganz am Anfang gesehen - das ist genau das hier beschriebene Problem mit "Publish after Subscribe" - das ist unter Kontrolle.
Was ich halt gern machen würde wär speziell bei "Unlatch" rauszufinden wer's war.
Der Adapter ist von @Bluefox, wenn ich mich nicht irre ... ich mach da mal ein issue rein.
So, ich hab jetzt auch mal mit Nuki und MQTT angefangen ...
Ich finde es schon störend, dass das LockActionEvent nicht richtig funktioniert - schon weil man immer die logs von der API abrufen muss, es evt. doch Probleme mit Synchronisation und Latenzzeiten gibt.
Deswegen hab ich mal den MQTT Adapter auf Debug gestellt, ob man da was sieht ... sehr interessant.
Beispiel: Die MQTT API sagt dem Nuki, es soll aufschließen ...
mqtt.0 (14027) Client [SL3P_123456XX] received publish package {"cmd":"publish","retain":true,"qos":0,"dup":false,"length":22,"topic":"nuki/123456XX/state","payload":{"type":"Buffer","data":[50]}}
mqtt.0 (14027) Server received "nuki/123456XX/state" (number): 2
Hier kommt also nach "state" der ... Status halt, also die Nummer zwei. In der ersten Zeile steht auch im data array die "50".
50 Dezimal, Hex 32, ASCII "2". Soweit alles klar.
Es folgt:
mqtt.0 (14027) Client [SL3P_123456XX] received publish package {"cmd":"publish","retain":false,"qos":2,"dup":false,"length":44,"topic":"nuki/123456XX/lockActionEvent","payload":{"type":"Buffer","data":[49,44,49,55,50,44,48,44,48,44,48]},"messageId":4}
Server received "nuki/123456XX/lockActionEvent" (string): "\u0001¬\u0000\u0000\u0000"
Erst mal also der publish, mit unserem bekannten data buffer. Wenn man jetzt mal das array händisch in ASCII Werte übersetzt, steht da:
"1,172,0,0,0"
also genau der erwartete String für das LockActionEvent, ausgelöst von MQTT - Trigger ist 172.
Das Problem liegt in der folgenden Zeile, der Server empfängt irgend was wild binäres und interpretiert das als String.
So, hier verlässt mich jetzt mein Wissen: Liegt das am Nuki oder am MQTT Broker? Wär schön, wenn die MQTT Profis das mal ankucken könnten.
CU
Werner
Muss da mal bisschen damit experimentieren, möglichst nicht auf dem "Production" System ;), aber dafür ist Docker ja perfekt.
Es gibt auf jeden Fall mal das puppeteer-troubleshooting als Ansatzpunkt:
https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
Nachdem ich auch gern VIS und Grafana screens in Status-Reports verwenden würde, hab ich heute mal puppeteer ausprobiert:
Puppeteer startet nicht, und liefert folgende Fehler im log:
eteer.0
2023-10-27 11:26:04.506 error Failed to launch the browser process![1027/112604.128429:FATAL:zygote_host_impl_linux.cc(127)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.#0 0x564aa1039f72 base::debug::CollectStackTrace()#1 0x564aa10264b3 base::debug::StackTrace::StackTrace()#2 0x564aa0f78fbf logging::LogMessage::~LogMessage()#3 0x564a9f795c16 content::ZygoteHostImpl::Init()#4 0x564aa04cfb23 content::ContentMainRunnerImpl::Initialize()#5 0x564aa04cd427 content::RunContentProcess()#6 0x564aa04cd606 content::ContentMain()#7 0x564aa0ab71fa headless::HeadlessShellMain()#8 0x564a9cbee255 ChromeMain#9 0x7fbbe3716d0a __libc_start_main#10 0x564a9cbee02a _startTROUBLESHOOTING: https://pptr.dev/troubleshooting
puppeteer.0
2023-10-27 11:26:04.505 error Error: Failed to launch the browser process![1027/112604.128429:FATAL:zygote_host_impl_linux.cc(127)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.#0 0x564aa1039f72 base::debug::CollectStackTrace()#1 0x564aa10264b3 base::debug::StackTrace::StackTrace()#2 0x564aa0f78fbf logging::LogMessage::~LogMessage()#3 0x564a9f795c16 content::ZygoteHostImpl::Init()#4 0x564aa04cfb23 content::ContentMainRunnerImpl::Initialize()#5 0x564aa04cd427 content::RunContentProcess()#6 0x564aa04cd606 content::ContentMain()#7 0x564aa0ab71fa headless::HeadlessShellMain()#8 0x564a9cbee255 ChromeMain#9 0x7fbbe3716d0a __libc_start_main#10 0x564a9cbee02a _startTROUBLESHOOTING: https://pptr.dev/troubleshooting at Interface.onClose (/opt/iobroker/node_modules/@puppeteer/browsers/lib/cjs/launch.js:262:24) at Interface.emit (node:events:526:35) at Interface.close (node:internal/readline/interface:533:10) at Socket.onend (node:internal/readline/interface:259:10) at Socket.emit (node:events:526:35) at endReadableNT (node:internal/streams/readable:1359:12) at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
puppeteer.0
2023-10-27 11:26:04.503 error unhandled promise rejection: Failed to launch the browser process![1027/112604.128429:FATAL:zygote_host_impl_linux.cc(127)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.#0 0x564aa1039f72 base::debug::CollectStackTrace()#1 0x564aa10264b3 base::debug::StackTrace::StackTrace()#2 0x564aa0f78fbf logging::LogMessage::~LogMessage()#3 0x564a9f795c16 content::ZygoteHostImpl::Init()#4 0x564aa04cfb23 content::ContentMainRunnerImpl::Initialize()#5 0x564aa04cd427 content::RunContentProcess()#6 0x564aa04cd606 content::ContentMain()#7 0x564aa0ab71fa headless::HeadlessShellMain()#8 0x564a9cbee255 ChromeMain#9 0x7fbbe3716d0a __libc_start_main#10 0x564a9cbee02a _startTROUBLESHOOTING: https://pptr.dev/troubleshooting
Die Umgebung ist ein buanet/iobroker Docker container, Version 8.1.0, also ein Debian 11.
Die package-installation ist durchgelaufen, die sind alle installiert.
Kleine Anmerkung zu den Packages: In dem Image wird standardmäßig die apt package Liste gelöscht, vermutlich um Platz im Filesystem zu sparen. Deswegen muss man vor der puppeteer Installation manuell ein
apt-get update
aufrufen, dann werden die Listen wieder installiert, und apt-get install ... funktioniert.
Aber zum jetzigen "no useable sandbox" Fehler fällt mir grad nix ein ... gibts eventuell Ideen?
Dank
Werner
@nobl Ein kleines Problem mit den "Alltime" Werten ... die werden offensichtlich auf ganze kWh gerundet. Damit kann man natürlich schlecht den Tagesverlauf darstellen, dafür werden genauere Werte benötigt.
Der Charme der Alltime Werte in Verbindung mit Grafana ist ja gerade, dass man so die gleichen Daten sehr flexibel für variierende Zeiträume nutzen kann.
Könnte man hier nicht auf drei Nachkommastellen runden? Wenn das für jemand zu granular ist, kann man das in der Visualisierung ja immer noch runden.
CU
@nobl Gerade gesehen ... supergut, und nochmal ein herzliches Dankschön. Muss ich gleich mal ausprobieren!
@nobl
Nobl, vielen Dank für Deine Mühe! Der Senec Adapter ist in meiner Automatisierung und in der Integration der PV ein wirklicher Lichtblick
Jetzt noch ein Wunsch ... es wäre schön, wenn man im _calc Baum die "RefValues" jetzt aus der API beschicken könnte - natürlich muss man dann den täglichen "Turnaround" wegrechnen.
Damit erhielte man wieder kontinuierlich steigende Zähler für die Werte. Warum?
Ich hab mir mit Grafana da eine graphische Auswertung gebaut, die halt aus so einem kontinuierlich steigenden Zähler die entsprechenden Werte darstellt. Man kann dann das Zeitfenster frei hin- und herschieben, und das machts wirklich komfortabel.
Dann noch eine Frage an die Community allgemein (nobl kennt das schon aus den Issues )
Hat jemand schon einen Wert in der ganzen Senec-Geschichte gefunden, an dem man den aktuellen Drosselungsbetrieb ablesen kann?
Wäre komfortabler ... hab da gerade an einem Script gebastelt, das sowas anhand der Ladekurven ableitet, aber des muss doch eleganter gehen ... vielleicht kommt da ja auch was in der API response, die Handy App weiß das ja.
CU