Hallo zusammen,
es gibt bereits mehrere Anfragen von Nutzern (u.a. von mir), wie man Dyson Ventilatoren einbindet. Skipper hat mir ein paar Denkanstösse gegeben (Danke) und so habe ich mich drangemacht. Die Einbindung basiert auf MQTT. MQTT2 habe ich nicht verwendet, müsste aber gehen.
1. Voraussetzung
a) Der Dyson ist bereits in Eurem Homenetzwerk integriert, Ihr habt die IP-Adresse
b) Für Begrifflichkeiten unbedingt die ersten paar Kapitel hiervon lesen [1] https://www.hackster.io/uladzislau-bayouski/merge-the-dyson-link-b763c3 (https://www.hackster.io/uladzislau-bayouski/merge-the-dyson-link-b763c3)
c) MQTT Client ist installiert falls Ihr nicht MQTT2 verwendet: [2] https://wiki.fhem.de/wiki/MQTT_Einf%C3%BChrung (https://wiki.fhem.de/wiki/MQTT_Einf%C3%BChrung)
2. Password Hash
Password Hash erzeugen. Danke an Skipper für das Windows Powershell Script. Wer Python bevorzugt: [3] https://github.com/mecks52/openhab2-dyson475 (https://github.com/mecks52/openhab2-dyson475)
function Hash($textToHash)
{
$hasher = new-object System.Security.Cryptography.SHA256Managed
$hasher = new-object System.Security.Cryptography.SHA512Managed
$toHash = [System.Text.Encoding]::UTF8.GetBytes($textToHash)
$hashByteArray = $hasher.ComputeHash($toHash)
$EncodedText =[Convert]::ToBase64String($hashByteArray)
$res = $EncodedText
#foreach($byte in $hashByteArray)
#{
# $res += $byte.ToString()
#}
return $res;
}
$consumerkey ="HIER DAS WIFI PW DES DYSON"
Hash($consumerkey)
3. MQTT Broker
MQTT Broker anlegen. IP-Adresse Eures Dyson, Benutzername, Password Hash
defmod dyson_broker MQTT <IP EURES DYSON>:1883 [<username>] [<PASSWORD HASH>] ### siehe LINK [1] wie man da rankommt
attr dyson_broker DbLogExclude .*
attr dyson_broker room Server
4. MQTT Device
MQTT Device anlegen. Problem bei publishSet ist, dass normalerweise die Kommandos auch direkt an das Topic gesendet werden. Das funktioniert beim Dyson aber nicht, da vom Dyson und an den Dyson ein JSON kommt bzw. hingesendet werden muss. Also "macht" dieses Device erstmal nichts ausser Nachrichten parsen (die alle 30s reinkommen). die 469/NB2-EU-HEA4515A müsst Ihr gegen die Codierung Eures Modells ersetzen, siehe hierzu auch Link [1]
defmod mqtt_Dyson_Arbeitszimmer MQTT_DEVICE
attr mqtt_Dyson_Arbeitszimmer DbLogExclude .*
attr mqtt_Dyson_Arbeitszimmer IODev dyson_broker
attr mqtt_Dyson_Arbeitszimmer alias Arbeitszimmer Dyson Ventilator
attr mqtt_Dyson_Arbeitszimmer icon fhem_dyson_air
attr mqtt_Dyson_Arbeitszimmer publishSet_command_JSON 469/NB2-EU-HEA4515A/command
attr mqtt_Dyson_Arbeitszimmer room Server
attr mqtt_Dyson_Arbeitszimmer stateFormat act_mode:act_fan_HML
attr mqtt_Dyson_Arbeitszimmer subscribeReading_command 469/NB2-EU-HEA4515A/command
attr mqtt_Dyson_Arbeitszimmer subscribeReading_connection 469/NB2-EU-HEA4515A/status/connection
attr mqtt_Dyson_Arbeitszimmer subscribeReading_current 469/NB2-EU-HEA4515A/status/current
attr mqtt_Dyson_Arbeitszimmer subscribeReading_faults 469/NB2-EU-HEA4515A/status/faults
attr mqtt_Dyson_Arbeitszimmer userReadings act_temperature:data_tact:.* { (sprintf("%.1f °C", (ReadingsNum("$NAME","data_tact",0) - 2731.5)/10)) },\
act_humidity:data_hact:.* { (sprintf("%.1f %", ReadingsNum("$NAME","data_hact",0))) },\
act_p-value:data_pact:.* { (sprintf("%.1f %", ReadingsNum("$NAME","data_pact",0))) },\
act_v-value:data_vact:.* { (sprintf("%.1f %", ReadingsNum("$NAME","data_vact",0))) },\
act_mode:product-state_fmod:.* { (ReadingsVal("$NAME", "product-state_fmod", "")) },\
act_quality_target:product-state_qtar:.* { (ReadingsVal("$NAME", "product-state_qtar", 0)) },\
act_oscillation:product-state_oson:.* { (ReadingsVal("$NAME", "product-state_oson", "")) },\
act_nightmode:product-state_nmod:.* { (ReadingsVal("$NAME", "product-state_nmod", "")) },\
act_continous_measure:product-state_rhtm:.* { (ReadingsVal("$NAME", "product-state_rhtm", "")) },\
act_filter_hours:product-state_filf:.* { (ReadingsVal("$NAME", "product-state_filf", "")) },\
act_fan_speed:product-state_fnsp:.* { (sprintf("%.0f ", ReadingsNum("$NAME","product-state_fnsp",0))) },\
act_fan_activity:product-state_fnst:.* { (sprintf("%.0f ", ReadingsNum("$NAME","product-state_fnst",0))) },\
act_fan_HML:product-state_fnsp:.* { \
my $speed= ReadingsNum("$NAME","product-state_fnsp",0);;\
my $HML = "low";;\
if ($speed>6) {$HML = "high"} elsif ($speed>3) {$HML = "medium"};;\
return $HML;;\
}
5a. JSON parsen
Zur Bequemlichkeit lassen wir die einkommenden Meldungen über einen expandJSON umwandeln und generieren später über userreadings lesbares draus.
defmod dyson_expandJSON expandJSON mqtt_Dyson_Arbeitszimmer:(current):.\{.*} (data_hact|data_vact|data_pact|data_tact|data_sltm|dial|msg|product-state_ercd|product-state_filf|product-state_fmod|product-state_fnsp|product-state_fnst|product-state_nmod|product-state_oson|product-state_qtar|product-state_rhtm|product-state_wacd|rssi|scheduler_dstv|scheduler_srsc|scheduler_tzid|time|state-reason)
attr dyson_expandJSON DbLogExclude .*
attr dyson_expandJSON room Server
5b. JSON basteln
Um das Kommandostring in JSON zu basteln, am besten diesen Code in die 99_myUtils.pm:
######################################################
######## JSON für Dyson basteln
########
######################################################
sub dyson_json_compose {
my ($command,$value) = @_;
# das spezielle Format für die Zeit im JSON für den Dyson
my $t = time;
my $date = strftime "%Y-%m-%dT%H:%M:%S", gmtime $t;
$date .= sprintf ".%03dZ", ($t-int($t))*1000; # without rounding
my $commandString = "{\"msg\":\"STATE-SET\",\"time\":\"".$date."\",\"mode-reason\":\"LAPP\","; # der erste Teil ist immer Kommando & Datum
if ($command eq "fmod") { $commandString .= "\"data\":{\"fmod\":\"".$value."\"}"} # Fan-Mode, VALID: OFF, AUTO, FAN
elsif ($command eq "fnsp") { $commandString .= "\"data\":{\"fnsp\":\"".$value."\"}"} # Fan-Speed, VALID: 1..10
elsif ($command eq "qtar") { $commandString .= "\"data\":{\"qtar\":\"".$value."\"}"} # Quality?
elsif ($command eq "nmod") { $commandString .= "\"data\":{\"nmod\":\"".$value."\"}"} # nmod?
elsif ($command eq "oson") { $commandString .= "\"data\":{\"oson\":\"".$value."\"}"} # Oszillation, VALID: OFF, ON
elsif ($command eq "rhtm") { $commandString .= "\"data\":{\"fmod\":\"FAN\", \"rhtm\":\"".$value."\", }"} # Fan-Mode + rhtm?, VALID (Fan-Mode: OFF, AUTO, FAN) + (rhtm: OFF, ON)
else { $commandString .= "\"data\":{\"fmod\":\"OFF\"}" }; # notfalls aus
# und noch die Klammer zu
$commandString .= "}";
# Wenn das Kommando Status Request war ist der Commandstring simpel
if ($command eq "sreq") { $commandString = "{\"msg\":\"REQUEST-CURRENT-STATE\",\"time\":\"".$date."\"}"};
return $commandString;
}
6. DOIF
Wegen der o.a. Einschränkungen mit dem Command über JSON steuere ich den Dyson (einschl. Statusanzeige) nur über ein DOIF. Falls das jemand eleganter abbilden kann, nur her mit dem Feedback
defmod DOIF_update_Dyson DOIF ([$SELF:desired_fanspeed])\
(\
set mqtt_Dyson_Arbeitszimmer command_JSON [$SELF:command_JSON_fanspeed];;\
sleep 1;;\
set mqtt_Dyson_Arbeitszimmer command_JSON [$SELF:command_JSON_statusrequest];; \
)\
DOELSEIF ([$SELF:desired_oscillation])\
(\
set mqtt_Dyson_Arbeitszimmer command_JSON [$SELF:command_JSON_oscillation];;\
sleep 1;;\
set mqtt_Dyson_Arbeitszimmer command_JSON [$SELF:command_JSON_statusrequest];; \
)\
DOELSEIF ([$SELF:desired_mode])\
(\
set mqtt_Dyson_Arbeitszimmer command_JSON [$SELF:command_JSON_mode];;\
sleep 1;;\
set mqtt_Dyson_Arbeitszimmer command_JSON [$SELF:command_JSON_statusrequest];; \
)\
DOELSEIF (\
(([mqtt_Dyson_Arbeitszimmer:act_mode] eq "FAN") or \
([mqtt_Dyson_Arbeitszimmer:act_mode] eq "AUTO")) and \
([mqtt_Dyson_Arbeitszimmer:act_fan_HML] eq "low")\
) (\
setreading $SELF desired_fanspeed [mqtt_Dyson_Arbeitszimmer:act_fan_speed];;\
setreading $SELF desired_oscillation [mqtt_Dyson_Arbeitszimmer:act_oscillation];;\
setreading $SELF desired_mode [mqtt_Dyson_Arbeitszimmer:act_mode];;\
)\
DOELSEIF (\
(([mqtt_Dyson_Arbeitszimmer:act_mode] eq "FAN") or \
([mqtt_Dyson_Arbeitszimmer:act_mode] eq "AUTO")) and \
([mqtt_Dyson_Arbeitszimmer:act_fan_HML] eq "medium")\
) (\
setreading $SELF desired_fanspeed [mqtt_Dyson_Arbeitszimmer:act_fan_speed];;\
setreading $SELF desired_oscillation [mqtt_Dyson_Arbeitszimmer:act_oscillation];;\
setreading $SELF desired_mode [mqtt_Dyson_Arbeitszimmer:act_mode];;\
)\
DOELSEIF (\
(([mqtt_Dyson_Arbeitszimmer:act_mode] eq "FAN") or \
([mqtt_Dyson_Arbeitszimmer:act_mode] eq "AUTO")) and \
([mqtt_Dyson_Arbeitszimmer:act_fan_HML] eq "high")\
) (\
setreading $SELF desired_fanspeed [mqtt_Dyson_Arbeitszimmer:act_fan_speed];;\
setreading $SELF desired_oscillation [mqtt_Dyson_Arbeitszimmer:act_oscillation];;\
setreading $SELF desired_mode [mqtt_Dyson_Arbeitszimmer:act_mode];;\
)\
DOELSEIF (\
([mqtt_Dyson_Arbeitszimmer:act_mode] eq "OFF")\
) (\
setreading $SELF desired_fanspeed [mqtt_Dyson_Arbeitszimmer:act_fan_speed];;\
setreading $SELF desired_oscillation [mqtt_Dyson_Arbeitszimmer:act_oscillation];;\
setreading $SELF desired_mode [mqtt_Dyson_Arbeitszimmer:act_mode];;\
)\
attr DOIF_update_Dyson DbLogExclude .*
attr DOIF_update_Dyson DbLogInclude cmd
attr DOIF_update_Dyson alias Arbeitszimmer Dyson Ventilator
attr DOIF_update_Dyson cmdState set_fanspeed|set_oscillation|set_mode|stat_AnLow|stat_AnMedium|stat_AnHigh|stat_Off
attr DOIF_update_Dyson devStateIcon set_.*:vent_ventilation stat_AnLow:vent_ventilation_level_0@green stat_AnMedium:vent_ventilation_level_1@orange stat_AnHigh:vent_ventilation_level_3@red stat_Off:vent_ventilation_level_0@grey
attr DOIF_update_Dyson do always
attr DOIF_update_Dyson group Klima,Sonstige Events
attr DOIF_update_Dyson icon fhem_dyson_air
attr DOIF_update_Dyson readingList desired_fanspeed,desired_oscillation,desired_mode
attr DOIF_update_Dyson room ControlCenter,Tagesablauf
attr DOIF_update_Dyson setList desired_fanspeed:slider,0,1,10 desired_oscillation:ON,OFF desired_mode:FAN,AUTO,OFF
attr DOIF_update_Dyson userReadings command_JSON_fanspeed { (dyson_json_compose("fnsp", ReadingsVal("$NAME", "desired_fanspeed", "1"))) }, \
command_JSON_oscillation { (dyson_json_compose("oson", ReadingsVal("$NAME", "desired_oscillation", "OFF"))) }, \
command_JSON_mode { (dyson_json_compose("fmod", ReadingsVal("$NAME", "desired_mode", "OFF"))) },\
command_JSON_staterequest { (dyson_json_compose("sreq", "dummy")) }
attr DOIF_update_Dyson webCmd desired_fanspeed:desired_oscillation:desired_mode
attr DOIF_update_Dyson webCmdLabel Fanspeed:Drehen:Modus
7. Homebridge
Das könnte man natürlich nun über Siri auch an den Homebridge FHEM Skin geben, aber es ginbt einen Native Skin https://www.npmjs.com/package/homebridge-dyson-link (https://www.npmjs.com/package/homebridge-dyson-link), der in Homekit gleich noch schöne Symbole erzeugt. Ist natürlich Geschmackssache.
8. Wiki
Lassen wir diesen Thread mal etwas laufen, vielleicht kommen noch Verbesserungsvorschläge, danach kann ich mich an ein Wiki machen
9. Andere Modelle
Siehe Link [3]. Ich denke, über diese Methode sollten noch mehr Modelle einbindbar sein, da ich nur den einen habe, kann ich nicht mehr testen.
Hallo zusammen,
ich habe meinen Dyson nun auch erfolgreich eingebunden. Wobei so ganz erfolgreich noch nicht, meine Readings ändern sich nicht und irgendwie läuft das mit dem korrekten Konvertieren der Readings aus dem JSON noch nicht ganz rund. Ich wollte auch nur mal zurück melden, dass die Anleitung grundsätzlich geht. Ich gehe bei mir von einem Fehler von mir aus. Ich suche weiter.
Beste Grüße
Skipper
Moin Feedback von mir: prima erklärt und vielen Dank!
Selbst ich als blutiger Anfänger habe es zum Laufen bekommen.
Desired-Readings funktionieren ebenfalls.
Ich werde das Beispiel nutzen, um ein wenig daran zu üben und FHEM zu verstehen (ich weiß - dafür ist es nicht gedacht).
Welche Readings natürlich nicht umgesetzt worden sind, ist die Anzeige ob Sensordaten gesammelt werden (fhtm) und richtig interessant und die Frage ob die Implementierung
von allgemeinem Interesse wäre: die Auswertung der Sensordaten (tact für Temperatur in Kelvin (mit 1/10 K Auflösung), hact (relative Luftfeuchtigkeit)).
Wie die Information für die Luftqualität übermittelt wird, weiß ich allerdings nicht - zwar gibt es dafür die Daten pact (Staub) und vact (flüchtige organische Verbindungen (die kann mein Dyson generationsbedingt noch nicht)),
allerdings stehen diese Daten bei mir immer auf '0' obwohl die App einen Verlauf anzeigt:
475/NNX-EU-xxxxxx/status/
{"msg":"ENVIRONMENTAL-CURRENT-SENSOR-DATA","time":"2019-01-01T16:25:20.001Z","data":{"tact":"2942","hact":"0054","pact":"0000","vact":"0000","sltm":"OFF"}}
Grüße und frohes Neues!
Brandon
Hallöchen,
BrandonQuest: verstehe nicht ganz was Du meinst... Unter Punkt 4 werden doch die Readings für Temp, Luftfeuchtigkeit etc angelegt?
Skipper: Kannst Du das Problem etwas eingrenzen und genauer beschreiben?
Grüße
Ed
Stimmt - jetzt sehe ich das auch ...
Allerdings auftauchen in fhem tun sie letztendlich nicht.
Aber ich sehe schon: das ist der Teil, den ich ja erst noch verstehen will.
Die Readings werden nicht angezeigt, weil man sie in den nachfolgenden Schritten (nach 4) erstmal zu Readings aufbereiten muss.
Grüße
Brandon
eddy242:
bist Du so nett, mir einmal Teile des Userreadings zu erklären?
act_fan_HML:product-state_fnsp:.* { \
my $speed= ReadingsNum("$NAME","product-state_fnsp",0);;\
my $HML = "low";;\
if ($speed>6) {$HML = "high"} elsif ($speed>3) {$HML = "medium"};;\
return $HML;;\
}
Ich weiß, es ist wohl eher Perl- denn FHEM-spezifisch.
Aber ich hangle mich jetzt seit Tagen Zeile für Zeile an Deinem Code entlang
und hänge speziell an dieser Stelle seit ein paar Stunden:
Wann wie und weshalb funktionieren die Anschnitte nur mit Doppel
Semikolon?
Wenn ich danach Google komme ich nicht wirklich zu konsistenten Aussagen
über die konkreten Anwendungsfälle.
Um die Funktionsweise zu verstehen würde es mir außerdem helfen, wenn
Du mir vielleicht alternative Schreibvarianten darstellen könntest.
Danke und beste Grüße
Moin,
Ich versuche auch gerade einen Dyson Pure Cool einzubinden.
Leider habe ich keine Ahnung wo ich das Standart-WLAN-Passwort herbekomme.
Auf dem Aufkleber ist leider nur eine Zahl im Format 1234:5678 und eine MAC Adresse.
Kann mir jeamd auf dei Sprünge helfen wie ich einen Passwort-Hash erzeugen kann?
MfG
@BrandonQuest - sorry das nennt man wohl miserable Reaktionszeit...
das Doppel ;; ist dem Perl-Editor in FHEM geschuldet. Wenn Du das in 99_myUtils eingibst, tippst Du nur 1 ein.
HTH, Ed
@Shadow3561
sieh Dir mal den Link in meinem Post an. [1] https://www.hackster.io/uladzislau-bayouski/merge-the-dyson-link-b763c3
Da steht es ziemlich gut beschrieben drin.
Danke.
Das habe ich mir durchgelesen. Problem ist nur, dass die neuen Dyson Modelle diesen Aufkleber mit dem en Passwort nicht mehr haben und anders verbunden werden.
Nun fehlt mir leider das Passwort um es in Fhem im Dyson_broker einzutragen.
Habe schon versucht diese 8-stellige Zahl im Format 1234:5678 und das Passwort aus der App zu nutzen, jeweils verschlüsselt und unverschlüsselt, aber er verbindet einfach nicht.
Habes es mit mqqt2 versucht.
Werde aus Mqqt aber auch nicht wirklich schlau.
Habe den Mqqt2_broker mit port 1883 konfiguriert und bin dann genau deiner Anleitung gefolgt.
Habe ich evtl etwas vergessen oder falsch gemacht? Muss ich auch noch einen mqqt2_client definieren?
Mir würde es helfen wenn du mir die ganze Sache mal genau beschreibst (dein mqqt system).
MfG
Hallo ihr Lieben,
Danke schonmal für die tolle Anleitung :)
ich habe von meinem Mann einen Dyson pure cool link (TP02) zu Weihnachten bekommen.
Leider bekomme ich aber beim Verbinden (step 3) immer nur ein disconnect zu sehen.
Das log schweigt auch bei verbose 5.
Habe das Passwort und den user mit und ohne Klammern versucht. Ebenso gehashed und nicht gehashed.
Pakete für MQTT habe ich nachinstalliert, die waren es wahrscheinlich auch nicht.
Mit dem Modul MQTT2_DEVICE bekomme ich immerhin eine Rückmeldung Connection refused.
Hat dyson den Zugriff blockiert? Oder wurde am Modul MQTT etwas angepasst, dass etwas hier geändert werden muss?
Vielleicht übersehe ich auch etwas ::)
Vielen Dank für eure Hilfe und noch frohe Weihnachten
Scheinbar hatte sich mein Dyson etwas verschluckt, habe ihn komplett auf Werkseinstellung zurückgesetzt, neu verbunden und jetzt geht es.
Sehr gut gefällt mir, dass man die Dyson Cloud Verbindung entfernen kann und somit wieder ein reines "offline" Device hat. ;D
Ich konnte mit der Lib https://libpurecoollink.readthedocs.io/en/stable/ einige Werte lesen und frage mich ob das auch in FHEM ginge
DysonEnvironmentalSensorState received
DysonEnvironmentalSensorState(humidity=38,air quality=0,temperature=294.7,dust=3,sleep_timer=0)
DysonPureCoolState message received
DysonPureCoolState(fan_mode=AUTO,fan_state=OFF,night_mode=OFF,speed=AUTO,oscillation=OFF,filter_life=4289,quality_target=0003,standby_monitoring=OFF)
PS: Stabiler läuft es bei mir über den MQTT2 Broker ;)
Wo hast du denn das Passwort her?
Auf meinem Dyson ist kein Wlan Passwort Aufkleber gewesen und ich benötigte auch keines zum verbinden.
Zitat von: Blackcat am 29 Dezember 2019, 19:29:31
Scheinbar hatte sich mein Dyson etwas verschluckt, habe ihn komplett auf Werkseinstellung zurückgesetzt, neu verbunden und jetzt geht es.
Sehr gut gefällt mir, dass man die Dyson Cloud Verbindung entfernen kann und somit wieder ein reines "offline" Device hat. ;D
Ich konnte mit der Lib https://libpurecoollink.readthedocs.io/en/stable/ einige Werte lesen und frage mich ob das auch in FHEM ginge
DysonEnvironmentalSensorState received
DysonEnvironmentalSensorState(humidity=38,air quality=0,temperature=294.7,dust=3,sleep_timer=0)
DysonPureCoolState message received
DysonPureCoolState(fan_mode=AUTO,fan_state=OFF,night_mode=OFF,speed=AUTO,oscillation=OFF,filter_life=4289,quality_target=0003,standby_monitoring=OFF)
PS: Stabiler läuft es bei mir über den MQTT2 Broker ;)
Deine Temperatur Würste wohl noch umrechnen müssen ;D
Es war vorne ein Aufkleber auf dem Gerät. Zusätzlich ist noch einer auf der Anleitung.
Alternativ habe ich aber durch mein Testen auch gelernt, dann man sich das Passwort auch aus den localcredentials aus der Json Antwort des Dyson Servers generieren kann. Der hash ist dann der gleiche wie der von eddy. Das war bei mir dann der Grund zum zurücksetzen 😅 aber vielleicht für dich interessant
Ich habe dafür mit der genannten lib die Dyson Account Antwort ausgeben (einfaches Print in Python) und dann bin ich auf diese lib gestoßen:
https://github.com/patrickvaler/dyson-cloud
Ich habe nur noch die Entschlüsselung genutzt, aber für dich wäre es bestimmt einfacher sie gleich zu nutzen. Benötigt wird Note.js
Welches Gerät hast du denn? Ggf. gab es auch noch kein Passwort für das Gerät
PS: Dank MQTT.fx konnte ich nun alle Werte ermitteln und als Reading übertragen. Ich weiß nur nicht was ercd und wacd sein könnten. Beide haben den Wert none
Wenn Interesse besteht kann ich euch die fertige MQTT2 config zur Verfügung stellen. Ich baue gerade aber noch das publish neu und muss dafür noch das Befehlsmapping machen
Hallo,
ich habe diesen Dyson
https://shop.dyson.de/ventilatoren-und-heizluefter/luftreiniger/dyson-pure-cool-tower-310130-01 (https://shop.dyson.de/ventilatoren-und-heizluefter/luftreiniger/dyson-pure-cool-tower-310130-01)
Auf diesem Gerät ist, wie gesagt, kein Aufkleber mit einem Wlan-Passwort. Auch in der Beschreibung ist keines vorhanden.
Man benötigt aber auch keines um ihn ins Heimnetz zu integrieren. Das macht die App alles irgendwie automatisch.
Kannst du mir ein wenig auf die Sprünge helfen wie ich, die von dir erwähnte, lib ausführe?
https://github.com/patrickvaler/dyson-cloud
Ich habe nur noch die Entschlüsselung genutzt, aber für dich wäre es bestimmt einfacher sie gleich zu nutzen. Benötigt wird Note.js
MfG
Das ist der neue TP04. Dieser unterscheided sich etwas von den Messages was ich herausfinden konnte.
Als erstes benötigst du Node.js auf deinem Rechner:
https://docs.microsoft.com/de-de/windows/nodejs/setup-on-windows
Schritte 1-11.
Dann legst du irgendwo einen Ordner an. z.B. C:\dyson
Öffne nun cmd und navigiere zum Ordner (cd C:\dyson).
dann die lib laden:
npm install --save dyson-cloud
sollte jetzt im Ordner sein
als letztes eine Datei (dysonabfrage.js) anlegen (Mail und PW ändern):
const DysonCloud = require('dyson-cloud');
const myAccount = new DysonCloud("<dysonemail>","<dysonpwimklartext");
myAccount.getDevices()
.then(devices => console.log(devices));
und ausführen in der noch offnen cmd:
node dysonabfrage.js
weitere hilfreiche Seite: https://glossar.hs-augsburg.de/Node.js-Tutorium:_Hello_World:_Konsole
@CoolTux
Ja das habe ich gestern Nacht noch gemacht, Kelvin ist zwar auch ganz nett aber Celsius ist mir lieber
PS: im Anhang mal meine entschlüsselten Readings so far
Danke Sandra für deine ausführliche Hilfestellung.
Leider funktioniert es bei mir weder in Windows noch Ubuntu.
Die Fehlermeldung lauten bei beiden Systemen identisch.
/root/node_modules/dyson-cloud$ node dysonabfrage.js
(node:5222) UnhandledPromiseRejectionWarning: #<Object>
(node:5222) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
(node:5222) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
MfG
das Script scheint bei dir in der lib zu liegen und das mag er nicht.
so müsste der Aufbau der Ordner aussehen (nicht wundern bei mir heißen die Dateien anders)
Kann mir jemand weiterhelfen wie man die SetList von MQTT2 Devices nutzt?
mit MQTT.fx kann ich ein json publishen, in FHEM will das aber so nicht
attr sz_dyson_device_tp02 setList publish 475/.../command {"msg":"STATE-SET","time":"2019-12-29T23:01:30.063Z","mode-reason":"LAPP","data":{"fmod":"OFF"}}
habe es auch schon mit $EVENT versucht
ist mein erstes Device mit MQTT also seid nachsichtig für meine Fragen ::)
Das erstellte Script "dysonabfrage" liegt nicht im lib-Ordner.
Zitatroot@nuc-server:~/node_modules/dyson-cloud# ls
CONTRIBUTING.md dysonabfrage.js index.js lib LICENSE.md node_modules package.json README.md
root@nuc-server:~/node_modules/dyson-cloud#
Edit: Ein Neustart vom Server hat geholfen.
Danke
Zitatin FHEM will das aber so nicht
Was genau heisst das?
Mit dem gezeigten attr erscheint bei mir nach "set sz_dyson_device_tp02 publish" Folgendes:
% mosquitto_sub -t # -v
475/.../command {"msg":"STATE-SET","time":"2019-12-29T23:01:30.063Z","mode-reason":"LAPP","data":{"fmod":"OFF"}}
hm.. brauche ich zum Senden dann einen Mosquitto?
Der Dyson hat einen Server incl. deshalb habe ich nur einen MQTT2_CLIENT und dann das MQTT2_DEVICE.
das kommt bei versose 5 wenn ich drücke, aber der befehl kommt am Gerät nicht an.
2019.12.30 16:49:35 4: MQTT2_DEVICE_Parse: sz_dyson_device_tp02 475/<Dysonserial>/command => command
2019.12.30 16:49:35 4: MQTT2_DEVICE_Parse: sz_dyson_device_tp02 475/<Dysonserial>/status/current => current
2019.12.30 16:49:54 4: MQTT2_DEVICE_Parse: sz_dyson_device_tp02 475/<Dysonserial>/command => command
2019.12.30 16:49:54 4: MQTT2_DEVICE_Parse: sz_dyson_device_tp02 475/<Dysonserial>/status/current => current
Die Readinglist geht z.B. super:
attr sz_dyson_device_tp02 readingList 475/<Dysonserial>/command:.* command\
475/<Dysonserial>/status/current:.* current\
475/<Dysonserial>/status/connection:.* connection\
475/<Dysonserial>/status/faults:.* faults\
475/<Dysonserial>/status/software:.* software\
475/<Dysonserial>/status/summary:.* summary
ich tippe einfach nur drauf dass ich irgendwie die Syntax zum Senden falsch habe, komisch nur dass kein Fehler kommt
@Shadow: hast du ein Device als Antwort bekommen, dass ein PW hat?
ich habe das attr noch mal gelöscht und neu eingeben, siehe da es geht ::)
Jetzt nur noch die nächste Hürde:
set sz_dyson_device_tp02 publish {...JSON...}
wäre das dann
attr sz_dyson_device_tp02 setList publish 475/<serial>/command $EVENT
oder
attr sz_dyson_device_tp02 setList publish 475/<serial>/command $EVTPART0
Ziel wäre der Aufruf (ggf. ist der aber falsch)
set sz_dyson_device_tp02 publish {dyson_json_compose("fnsp", "10")}
----
Problem war wirklich der Befehl ::)
{fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("fnsp", "10"))}
hiermit geht es :)
plus:
attr sz_dyson_device_tp02 setList publish 475/<serial>/command
Zitat von: Blackcat am 30 Dezember 2019, 17:11:43
ich habe das attr noch mal gelöscht und neu eingeben, siehe da es geht ::)
Jetzt nur noch die nächste Hürde:
set sz_dyson_device_tp02 publish {...JSON...}
wäre das dann
attr sz_dyson_device_tp02 setList publish 475/<serial>/command $EVENT
oder
attr sz_dyson_device_tp02 setList publish 475/<serial>/command $EVTPART0
Ziel wäre der Aufruf (ggf. ist der aber falsch)
set sz_dyson_device_tp02 publish {dyson_json_compose("fnsp", "10")}
----
Problem war wirklich der Befehl ::)
{fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("fnsp", "10"))}
hiermit geht es :)
plus:
attr sz_dyson_device_tp02 setList publish 475/<serial>/command
Hallo Blackcat, ich bin auch gerade dabei den Dyson Pure Cool mittels MQTT2 einzubinden, ich scheitere jedoch. Kannst du deine komplette Konfiguration posten? Der MQTT2_Client springt bei mir zwischen "opened" und "disconnected" hin und her. im MQTT2_DEVICE habe ich das attribut setList publish 475/meine_seriennummer/command eingebunden.
lg, Emanuel
Hi Emanuel,
hier meine laufende Umgebung, leider aber noch nicht ganz perfekt, wollte noch wechselnde Statusicons und eine Sycronisation zu den Steuerungsbuttons machen. Eigentlich wollte ich auch noch einen Blogbeitrag mit Tutorial schreiben ::) bin aber bisher nicht dazu gekommen
Habe eine eigene Abruffunktion gebaut und nur eddys composer angepasst, damit es läuft.
Hier mal alle configs, serial jeweil anpassen:
define sz_dyson_device_tp02 MQTT2_DEVICE
attr sz_dyson_device_tp02 IODev Dyson_broker
attr sz_dyson_device_tp02 alias Dyson TP02
attr sz_dyson_device_tp02 event-on-change-reading .*
attr sz_dyson_device_tp02 event-on-update-reading .*
attr sz_dyson_device_tp02 group Schlafzimmer
attr sz_dyson_device_tp02 icon dyson-tp02
attr sz_dyson_device_tp02 readingList 475/serial/command:.* command\
475/serial/status/current:.* current\
475/serial/status/connection:.* connection\
475/serial/status/faults:.* faults\
475/serial/status/software:.* software\
475/serial/status/summary:.* summary
attr sz_dyson_device_tp02 room Lüftung
attr sz_dyson_device_tp02 setList publish 475/serial/command
attr sz_dyson_device_tp02 stateFormat {"M: " . ReadingsVal($name,"fan_mode",0) . " S: " . ReadingsVal($name,"fan_speed",0) }
attr sz_dyson_device_tp02 verbose 5
define FileLog_sz_dyson_device_tp02 FileLog ./log/sz_dyson_device_tp02-%Y-%m.log sz_dyson_device_tp02:dust:.*|sz_dyson_device_tp02:fan_speed:.*|sz_dyson_device_tp02:filter_life:.*|sz_dyson_device_tp02:humidity:.*|sz_dyson_device_tp02:quality_target:.*|sz_dyson_device_tp02:temperature:.*|sz_dyson_device_tp02:volatil_organic_compounds:.*
attr FileLog_sz_dyson_device_tp02 logtype text
attr FileLog_sz_dyson_device_tp02 room hidden
define DOIF_update_Dyson DOIF ([$SELF:desired_fanspeed])\
(\
setreading $SELF desired_mode FAN;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_fanspeed];;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_mode];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_statusrequest];; \
)\
DOELSEIF ([$SELF:desired_oscillation])\
(\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_oscillation];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_statusrequest];; \
)\
DOELSEIF ([$SELF:desired_mode])\
(\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_mode];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_statusrequest];; \
)\
DOELSEIF (\
(([sz_dyson_device_tp02:fan_mode] eq "FAN") or \
([sz_dyson_device_tp02:fan_mode] eq "AUTO") or \
([sz_dyson_device_tp02:fan_mode] eq "OFF"))\
) (\
setreading $SELF desired_fanspeed [sz_dyson_device_tp02:fan_speed];;\
setreading $SELF desired_oscillation [sz_dyson_device_tp02:oscillation];;\
setreading $SELF desired_mode [sz_dyson_device_tp02:fan_mode];;\
)
attr DOIF_update_Dyson alias Dyson TP02
attr DOIF_update_Dyson cmdState set_fanspeed|set_oscillation|set_mode|stat_AnLow|stat_AnMedium|stat_AnHigh|stat_Off
attr DOIF_update_Dyson devStateIcon set_.*:Ventilator_fett
attr DOIF_update_Dyson do always
attr DOIF_update_Dyson group Schlafzimmer
attr DOIF_update_Dyson icon dyson-tp02
attr DOIF_update_Dyson readingList desired_fanspeed,desired_oscillation,desired_mode
attr DOIF_update_Dyson room Lüftung
attr DOIF_update_Dyson setList desired_fanspeed:slider,1,1,10 desired_oscillation:ON,OFF desired_mode:FAN,AUTO,OFF
attr DOIF_update_Dyson userReadings command_JSON_fanspeed { (dyson_json_compose("fnsp", ReadingsVal("$NAME", "desired_fanspeed", "1"))) }, \
command_JSON_oscillation { (dyson_json_compose("oson", ReadingsVal("$NAME", "desired_oscillation", "OFF"))) }, \
command_JSON_mode { (dyson_json_compose("fmod", ReadingsVal("$NAME", "desired_mode", "OFF"))) },\
command_JSON_staterequest { (dyson_json_compose("sreq", "dummy")) },\
command_JSON_environmentrequest { (dyson_json_compose("ereq", "dummy")) }
attr DOIF_update_Dyson webCmd desired_fanspeed:desired_oscillation:desired_mode
define Dyson_Notify notify sz_dyson_device_tp02:.* {dyson_json_read_current("sz_dyson_device_tp02","sz_dyson_doif_tp02")}
define mqtt_status_request at +*00:02:00 {fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("ereq", "10"));;fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("sreq", "10"))}
attr mqtt_status_request alias Dyson MQTT Status Request
attr mqtt_status_request group Steuerung - Dyson
attr mqtt_status_request icon dyson-tp02
attr mqtt_status_request room Steuerung
define SVG_FileLog_sz_dyson_device_tp02_1 SVG FileLog_sz_dyson_device_tp02:SVG_FileLog_sz_dyson_device_tp02_1:CURRENT
attr SVG_FileLog_sz_dyson_device_tp02_1 group Schlafzimmer
attr SVG_FileLog_sz_dyson_device_tp02_1 room Lüftung
meine 99_myUtilsDyson.pm:
######################################################
########
######## Dyson TP02 Integration - Sandra Ohmayer (Blackcat) foodcat.de
########
######################################################
use JSON;
## dyson_json_read_current(mqtt2_device)
sub
dyson_json_read_current {
# Dyson MQTT2 Device
my $device = $_[0];
my $currentJsonString = ReadingsVal($device, "current", "{}");
my $currentObj = decode_json($currentJsonString);
if ($currentObj->{msg} eq "ENVIRONMENTAL-CURRENT-SENSOR-DATA") {
my $humidity = $currentObj->{data}->{hact};
if ($humidity eq "OFF") {
$humidity = 0;
}
fhem("setreading ".$device." humidity ".($humidity+0));
my $volatil_organic_compounds = $currentObj->{data}->{vact};
if ($volatil_organic_compounds eq "INIT") {
$volatil_organic_compounds = 0;
}
fhem("setreading ".$device." volatil_organic_compounds ".($volatil_organic_compounds+0));
my $temperature = $currentObj->{data}->{tact};
if ($temperature eq "OFF") {
$temperature = 0;
} else {
$temperature = ($temperature/10)-273.15;
}
fhem("setreading ".$device." temperature ".$temperature);
my $dust = $currentObj->{data}->{pact};
fhem("setreading ".$device." dust ".($dust+0));
my $sleep_timer = $currentObj->{data}->{sltm};
if ($sleep_timer ne "OFF") {
$sleep_timer = $sleep_timer+0;
}
fhem("setreading ".$device." sleep_timer ".$sleep_timer);
}
if ($currentObj->{msg} eq "STATE-CHANGE") {
my $fan_mode = $currentObj->{"product-state"}->{fmod}->[1];
fhem("setreading ".$device." fan_mode ".$fan_mode); #OFF, AUTO, FAN
my $fan_state = $currentObj->{"product-state"}->{fnst}->[1];
fhem("setreading ".$device." fan_state ".$fan_state); #Running yes:FAN no:OFF
my $fan_speed = $currentObj->{"product-state"}->{fnsp}->[1];
fhem("setreading ".$device." fan_speed ".($fan_speed+0)); #1-10
my $quality_target = $currentObj->{"product-state"}->{qtar}->[1];
fhem("setreading ".$device." quality_target ".($quality_target+0));
my $oscillation = $currentObj->{"product-state"}->{oson}->[1];
fhem("setreading ".$device." oscillation ".$oscillation);
my $standby_monitoring = $currentObj->{"product-state"}->{rhtm}->[1];
fhem("setreading ".$device." standby_monitoring ".$standby_monitoring); #ON, OFF
my $filter_life = $currentObj->{"product-state"}->{filf}->[1];
fhem("setreading ".$device." filter_life ".$filter_life);
my $ercd = $currentObj->{"product-state"}->{ercd}->[1];
fhem("setreading ".$device." ercd ".$ercd); #?????????????????
my $night_mode = $currentObj->{"product-state"}->{nmod}->[1];
fhem("setreading ".$device." night_mode ".$night_mode); #ON, OFF
my $wacd = $currentObj->{"product-state"}->{wacd}->[1];
fhem("setreading ".$device." wacd ".$wacd); #?????????????????
}
}
######################################################
########
######## Dyson command string composer - eddy242 last edit Sandra Ohmayer (Blackcat)
########
######################################################
sub dyson_json_compose {
my ($command,$value) = @_;
# das spezielle Format für die Zeit im JSON für den Dyson
my $t = time;
my $date = strftime "%Y-%m-%dT%H:%M:%S", gmtime $t;
$date .= sprintf ".%03dZ", ($t-int($t))*1000; # without rounding
my $commandString = "{\"msg\":\"STATE-SET\",\"time\":\"".$date."\",\"mode-reason\":\"LAPP\""; # der erste Teil ist immer Kommando & Datum
if ($command eq "fmod") { $commandString .= ",\"data\":{\"fmod\":\"".$value."\"}"} # Fan-Mode, VALID: OFF, AUTO, FAN
elsif ($command eq "fnsp") { $commandString .= ",\"data\":{\"fnsp\":\"".$value."\"}"} # Fan-Speed, VALID: 1..10
elsif ($command eq "qtar") { $commandString .= ",\"data\":{\"qtar\":\"".$value."\"}"} # Quality?
elsif ($command eq "nmod") { $commandString .= ",\"data\":{\"nmod\":\"".$value."\"}"} # nmod?
elsif ($command eq "oson") { $commandString .= ",\"data\":{\"oson\":\"".$value."\"}"} # Oszillation, VALID: OFF, ON
elsif ($command eq "rhtm") { $commandString .= ",\"data\":{\"fmod\":\"FAN\", \"rhtm\":\"".$value."\", }"} # Fan-Mode + rhtm?, VALID (Fan-Mode: OFF, AUTO, FAN) + (rhtm: OFF, ON)
else { $commandString .= ",\"data\":{\"fmod\":\"OFF\"}" }; # notfalls aus
# und noch die Klammer zu
$commandString .= "}";
# Wenn das Kommando Status Request war ist der Commandstring simpel
if ($command eq "sreq") { $commandString = "{\"msg\":\"REQUEST-CURRENT-STATE\",\"time\":\"".$date."\"}"};
if ($command eq "ereq") { $commandString = "{\"msg\":\"REQUEST-PRODUCT-ENVIRONMENT-CURRENT-SENSOR-DATA\",\"time\":\"".$date."\"}"};
Log3 (undef, 3, $commandString);
return $commandString;
}
wenn das nicht geht, setzte den Dyson zurück auf Werkseinstellungen und verbinde ihn neu mit dem WLAN, bei mir war das am Anfang auch ein Problem mit Abbrüchen
PS: so sieht das ganze dann laufend aus. Das svg icon habe ich auch erstellt, jedoch ist es auch noch nicht perfekt (da es immer schwarz bleibt), wenn ich fertig bin lade ich alles dann im Blog hoch und verlinke es hier ;)
Ich habe es jetzt vergeblich versucht.
Bekomme meinen Dyson TP04 einfach nicht eingebunden.
Habe alles gemacht wie im 1.Post aber kann den Dyson weder steuern noch bekomme ich den Status angezeigt.
Ich habe mit Wireshark den Username und das Passwort rausgefunden und alle "469/NB2-EU-HEA4515A" durch "438/VS9-EU-KHB1111A" ersetzt,
aber leider ohne Erfolg.
Mqtt läuft auf dem Server und ich steuere damit bereits meine Shelly-Devices.
Hat schon jemand einen 438 zum laufen bekommen? Wenn ja, wie?
Langsam verzweifele ich. :'(
Dies kommt vom Dyson beim Statusrequest
438/serial/status/current{"msg":"CURRENT-STATE","time":"2020-05-28T17:02:17.000Z","mode-reason":"PRC",
"state-reason":"MODE","rssi":"-52","channel":"108","fqhp":"103888","fghp":"0","product-state":
{"fpwr":"OFF","auto":"ON","oscs":"OFF","oson":"ON","nmod":"ON","rhtm":"ON","fnst":"OFF","ercd":"NONE","wacd":
"NONE","nmdv":"0004","fnsp":"AUTO","bril":"0002","corf":"ON","cflr":"0100","hflr":"0100","cflt":"CARF","hflt":
"GHEP","sltm":"OFF","osal":"0115","osau":"0160","ancp":"0090","fdir":"OFF"},"scheduler":
{"srsc":"0000000000000000","dstv":"0001","tzid":"0001"}}
und dies
438/serial/command{
"mode-reason": "LAPP",
"time": "2020-05-28T17:02:18Z",
"msg": "REQUEST-CURRENT-STATE"
}438/serial/command{
"mode-reason": "LAPP",
"time": "2020-05-28T17:02:18Z",
"msg": "REQUEST-PRODUCT-ENVIRONMENT-CURRENT-SENSOR-DATA"
}438/Vserial/command{
"mode-reason": "LAPP",
"time": "2020-05-28T17:02:18Z",
"msg": "REQUEST-CURRENT-FAULTS"
}438/serial/command{
"mode-reason": "LAPP",
"time": "2020-05-28T17:02:18Z",
"msg": "REQUEST-CURRENT-STATE
Kann damit jemand etwas anfangen?
Hier eine MQTT message wenn ich den Lüfter einschalte
438/VS9-EU-KHB1111A/command {
"data": {
"fpwr": "ON"
},
"mode-reason": "LAPP",
"time": "2020-05-28T17:02:23Z",
"msg": "STATE-SET"
}
Mit freundlichen Grüßen
So,
ich habe es geschafft meinen TP04 einzubinden.
Hier meine laufende Config.
Leider lässt sich beim DOIF zwar der Fan steuern, aber wenn man mit der Handy-App was ändert, ändert sich der Status im DOIF nicht.
Als 1. das Passwort besorgen (steht leider beim TP04 nirgends drauf).
Ich habe mit der Handy-App "tPacketCapture" den Datenverkehr gesnifft und die entstandene Datei dann mit "Wireshark" am Macbook importiert.
Dann nach MQTT-Protokol gefiltert und nach "Connect Command" gesucht.
Dann ist der Username und das Passwort im Klartext sichtbar.
Beides notieren, es wird für den MQTT2-Client benötigt.
define dyson_broker_mqtt2 MQTT2_CLIENT <IP-vom-Lüfter:1883>
attr dyson_broker_mqtt2 autocreate simple
attr dyson_broker_mqtt2 keepaliveTimeout 5
attr dyson_broker_mqtt2 mqttVersion 3.1.1
attr dyson_broker_mqtt2 rawEvents 1
attr dyson_broker_mqtt2 room mqtt
attr dyson_broker_mqtt2 subscriptions 438/VS9-EU-KHB1111A/status/current
attr dyson_broker_mqtt2 username XXX-XX-XXXXXXXX #hier der username den ihr notiert habt
attr dyson_broker_mqtt2 verbose 0
jetzt noch ein "set dyson_broker_mqtt2 password <notiertes Passwort>" in der fhem-Eingabezeile
Jetzt den Lüfter
define sz_dyson_device_tp02 MQTT2_DEVICE
attr sz_dyson_device_tp02 DbLogExclude .*
attr sz_dyson_device_tp02 IODev dyson_broker_mqtt2
attr sz_dyson_device_tp02 alias Dyson TP02
attr sz_dyson_device_tp02 autocreate 1
attr sz_dyson_device_tp02 event-on-change-reading .*
attr sz_dyson_device_tp02 event-on-update-reading .*
attr sz_dyson_device_tp02 icon dyson-tp02
attr sz_dyson_device_tp02 readingList 438/XXX-XX-XXXXXXXX/status/current:.* current
attr sz_dyson_device_tp02 room mqtt
attr sz_dyson_device_tp02 setList publish 438/XXX-XX-XXXXXXXX/command
attr sz_dyson_device_tp02 stateFormat {"Power: " . ReadingsVal($name,"dy_fan_state",0) . " Fanspeed: " . ReadingsVal($name,"dy_fan_speed",0) }
attr sz_dyson_device_tp02 verbose 0
Als Nächstes das Dorf zum steuern des Lüfters
define DOIF_update_Dyson DOIF ([$SELF:desired_fanspeed])\
(\
\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_fanspeed];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_staterequest];; \
)\
DOELSEIF ([$SELF:desired_oscillation])\
(\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_oscillation];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_staterequest];; \
)\
DOELSEIF ([$SELF:desired_auto])\
(\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_auto];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_staterequest];; \
)\
DOELSEIF ([$SELF:desired_mode])\
(\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_mode];;\
sleep 1;;\
set sz_dyson_device_tp02 publish [$SELF:command_JSON_staterequest];; \
)\
DOELSEIF (\
(([sz_dyson_device_tp02:dy_fan_state] eq "ON") or \
([sz_dyson_device_tp02:dy_fan_state] eq "OFF"))\
) (\
setreading $SELF desired_fanspeed [sz_dyson_device_tp02:dy_fan_speed:d];;\
setreading $SELF desired_oscillation [sz_dyson_device_tp02:dy_fan_oszilation:d];;\
setreading $SELF desired_mode [sz_dyson_device_tp02:dy_fan_state:d];;\
setreading $SELF desired_auto [sz_dyson_device_tp02:dy_fan_auto:d];;\
)
attr DOIF_update_Dyson alias Dyson
attr DOIF_update_Dyson cmdState set_fanspeed|set_auto|set_oscillation|set_mode
attr DOIF_update_Dyson devStateIcon set_.*:Ventilator_fett
attr DOIF_update_Dyson do always
attr DOIF_update_Dyson icon dyson-tp02
attr DOIF_update_Dyson readingList desired_fanspeed,desired_auto,desired_oscillation,desired_mode
attr DOIF_update_Dyson room Schlafzimmer,mqtt
attr DOIF_update_Dyson setList desired_fanspeed:slider,1,1,10 desired_auto:ON,OFF desired_oscillation:ON,OFF desired_mode:ON,OFF
attr DOIF_update_Dyson userReadings command_JSON_fanspeed { (dyson_json_compose("fnsp", ReadingsVal("$NAME", "desired_fanspeed", "1"))) }, \
command_JSON_auto { (dyson_json_compose("auto", ReadingsVal("$NAME", "desired_auto", "OFF"))) },\
command_JSON_oscillation { (dyson_json_compose("oson", ReadingsVal("$NAME", "desired_oscillation", "OFF"))) }, \
command_JSON_mode { (dyson_json_compose("fpwr", ReadingsVal("$NAME", "desired_mode", "OFF"))) },\
command_JSON_staterequest { (dyson_json_compose("sreq", "dummy")) },\
command_JSON_environmentrequest { (dyson_json_compose("ereq", "dummy"))}\
attr DOIF_update_Dyson verbose 0
attr DOIF_update_Dyson webCmd desired_fanspeed:desired_auto:desired_oscillation:desired_mode
dann noch DOIF und notify
define Dyson_Notify notify sz_dyson_device_tp02:.* {dyson_json_read_current("sz_dyson_device_tp02","DOIF_update_Dyson")}
attr Dyson_Notify room mqtt
attr Dyson_Notify verbose 0
define mqtt_status_request at +*00:02:00 {fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("ereq", "10"));;;;fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("sreq", "10"))}
attr mqtt_status_request alias Dyson MQTT Status Request
attr mqtt_status_request icon dyson-tp02
attr mqtt_status_request room mqtt
attr mqtt_status_request verbose 0
Dann muss noch ein Teil in die 99_myUtils.pm damit das MQTT2-Device. Hier musste ich für den TP04 einiges ändern weil die MQTT-Requests und die MQTT-Commands wohl bei den neuen Modellen geändert wurden.
######################################################
########
######## Dyson TP02 Integration - Sandra Ohmayer (Blackcat) foodcat.de
########
######################################################
use JSON;
## dyson_json_read_current(mqtt2_device)
sub
dyson_json_read_current {
# Dyson MQTT2 Device
my $device = $_[0];
my $currentJsonString = ReadingsVal($device, "current", "{}");
my $currentObj = decode_json($currentJsonString);
if ($currentObj->{msg} eq "ENVIRONMENTAL-CURRENT-SENSOR-DATA") {
my $humidity = $currentObj->{data}->{hact};
if ($humidity eq "OFF") {
$humidity = 0;
}
fhem("setreading ".$device." dy_humidity ".($humidity+0));
my $volatil_organic_compounds = $currentObj->{data}->{va10};
if ($volatil_organic_compounds eq "INIT") {
$volatil_organic_compounds = 0;
}
fhem("setreading ".$device." dy_VOCs ".($volatil_organic_compounds+0));
my $temperature = $currentObj->{data}->{tact};
if ($temperature eq "OFF") {
$temperature = 0;
} else {
$temperature = ($temperature/10)-273.15;
}
fhem("setreading ".$device." dy_temperature ".$temperature);
my $pm10 = $currentObj->{data}->{pm10};
fhem("setreading ".$device." dy_pm10 ".($pm10+0));
my $pm25 = $currentObj->{data}->{pm25};
fhem("setreading ".$device." dy_pm2.5 ".($pm25+0));
my $va10 = $currentObj->{data}->{va10};
fhem("setreading ".$device." dy_va10 ".($va10+0));
my $noxl = $currentObj->{data}->{noxl};
fhem("setreading ".$device." dy_NOx ".($noxl+0));
my $sleep_timer = $currentObj->{data}->{sltm};
if ($sleep_timer ne "OFF") {
$sleep_timer = $sleep_timer+0;
}
fhem("setreading ".$device." dy_sleep_timer ".$sleep_timer);
}
if ($currentObj->{msg} eq "CURRENT-STATE") {
my $power = $currentObj->{"product-state"}->{fpwr};
fhem("setreading ".$device." dy_power ".$power); #OFF, ON
my $fan_auto = $currentObj->{"product-state"}->{auto};
fhem("setreading ".$device." dy_fan_auto ".$fan_auto); #OFF, ON
my $fan_state = $currentObj->{"product-state"}->{fnst};
my $fan = "ON";
if ($fan_state eq "FAN") {
fhem("setreading ".$device." dy_fan_state ".$fan)};
if ($fan_state eq "OFF") {
fhem("setreading ".$device." dy_fan_state ".$fan_state)}; #Running yes:FAN no:OFF
my $fan_speed = $currentObj->{"product-state"}->{fnsp};
my $automatic = ReadingsVal($device,"dy_fan_auto","OFF");
my $write = "AUTO";
#fhem("setreading ".$device." dy_fan_speed ".($fan_speed+0));
if (($fan_speed >= 1) && ($fan_speed <= 10) && ($automatic eq "OFF")) {
fhem("setreading ".$device." dy_fan_speed ".($fan_speed+0))};
if ($automatic eq "ON") {
fhem("setreading ".$device." dy_fan_speed ".$write)};
my $fan_airflow = $currentObj->{"product-state"}->{fdir};
my $airflow_front = "FRONT";
my $airflow_rear = "REAR";
if ($fan_airflow eq "ON") {
fhem("setreading ".$device." dy_fan_airflow ".$airflow_front)};
if ($fan_airflow eq "OFF") {
fhem("setreading ".$device." dy_fan_airflow ".$airflow_rear)};
my $fan_osc = $currentObj->{"product-state"}->{oson};
fhem("setreading ".$device." dy_fan_oszilation ".$fan_osc); #OFF, ON
my $night_mode = $currentObj->{"product-state"}->{nmod};
fhem("setreading ".$device." dy_night_mode ".$night_mode); #OFF, ON
my $standby_monitoring = $currentObj->{"product-state"}->{rhtm};
fhem("setreading ".$device." dy_standby_monitoring ".$standby_monitoring); #OFF, ON
}
}
######################################################
########
######## Dyson command string composer - eddy242 last edit Sandra Ohmayer (Blackcat)
########
######################################################
sub dyson_json_compose {
my ($command,$value) = @_;
# das spezielle Format für die Zeit im JSON für den Dyson
my $t = time;
my $date = strftime "%Y-%m-%dT%H:%M:%S", gmtime $t;
$date .= sprintf ".%03dZ", ($t-int($t))*1000; # without rounding
my $commandString = "{\"data\":";
if ($command eq "fpwr") { $commandString .= "{\"fpwr\":\"".$value."\"},\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"STATE-SET\""} # Fan-Mode, VALID: OFF, AUTO,
elsif ($command eq "fnsp") { $commandString .= "{\"fnsp\":\"".$value."\"},\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"STATE-SET\""}# Fan-Speed, VALID: 1..10
elsif ($command eq "auto") { $commandString .= "{\"auto\":\"".$value."\"},\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"STATE-SET\""}# Fan-Speed, VALID: 1..10
elsif ($command eq "qtar") { $commandString .= ",\"data\":{\"qtar\":\"".$value."\"}"} # Quality?
elsif ($command eq "nmod") { $commandString .= ",\"data\":{\"nmod\":\"".$value."\"}"} # nmod?
elsif ($command eq "oson") { $commandString .= "{\"oson\":\"".$value."\"},\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"STATE-SET\""} # Oszillation, VALID: OFF, ON
elsif ($command eq "osau") { $commandString .= "{\"osau\":\"".$value."\"},\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"STATE-SET\""} # Oszillation_Grad, VALID: OFF, ON
elsif ($command eq "fpwr") { $commandString .= ",\"data\":{\"fpwr\":\"".$value."\"}"} # Power, VALID: OFF, ON
elsif ($command eq "rhtm") { $commandString .= ",\"data\":{\"fmod\":\"FAN\", \"rhtm\":\"".$value."\", }"} # Fan-Mode + rhtm?, VALID (Fan-Mode: OFF, AUTO, FAN) + (rhtm: OFF, ON)
else { $commandString .= ",\"data\":{\"fmod\":\"OFF\"}" }; # notfalls aus
# und noch die Klammer zu
$commandString .= "}";
# Wenn das Kommando Status Request war ist der Commandstring simpel
if ($command eq "sreq") { $commandString = "{\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"REQUEST-CURRENT-STATE\"}"};
if ($command eq "ereq") { $commandString = "{\"mode-reason\":\"LAPP\",\"time\":\"".$date."\",\"msg\":\"REQUEST-PRODUCT-ENVIRONMENT-CURRENT-SENSOR-DATA\"}"};
#if ($command eq "sreq") { $commandString = "{\"msg\":\"REQUEST-CURRENT-STATE\",\"time\":\"".$date."\"}"};
#if ($command eq "ereq") { $commandString = "{\"msg\":\"REQUEST-PRODUCT-ENVIRONMENT-CURRENT-SENSOR-DATA\",\"time\":\"".$date."\"}"};
# Log3 (undef, 3, $commandString);
return $commandString;
}
Mit freundlichen Grüßen
Scheint mit dem TP04 nicht zu funktionieren. Da kommt immer nur disconnected. Schade.
Mein TP04 läuft super mit FHEM.
Hast du die Anleitung oben befolgt? Passwort und Benutzername gesnifft?
Wenn dann immer ein diconnect kommt liegt es höchstwahrscheinlich an FHEM/MQTT.
Mit freundlichen Grüßen
Danke, sorry, mein Fehler. Ich hatte nur den Beitrag mit dem FHEM-Code gelesen.
Ich werde mich durchwursteln.
Nochmals vielen Dank, funktioniert nun. War alles neu für mich mit den externen Programmen, aber ging.
Noch ne Frage: Kann da die Gradzahl der Oszillation noch eingefügt werden? In der App ist das einstellbar.
Beim tp02 gab es das noch nicht, daher habe ich die Funktion noch nicht eingebaut. Wenn du den Parameter kennst kann ich das aber nachholen
Kann man den irgendwie auslesen/ermitteln?
Es gibt da noch mehr zur Steuerung, z. B. kann man den Osziilationskegel komplett verschieben, als würde man den Lüfter per Hand drehen. Die eingestellte Gradzahl bleibt dabei erhalten.
Somit muss mandas Gerät gar nicht mehr anfassen, ausser zur äusseren Reinigung.
Wie kommt man an die Parameter? Ich könnte Dyson fragen, aber die werden mir wohl eher was husten und vielleicht sogar noch den Zugang dicht machen.
EDIT:
Ich habe hier etwas gefunden. Hilft das ? Würde mich freuen.
https://www.home-assistant.io/integrations/climate/#service-climateturn_on (https://www.home-assistant.io/integrations/climate/#service-climateturn_on)
https://github.com/CharlesBlonde/libpurecoollink/tree/master/libpurecoollink (https://github.com/CharlesBlonde/libpurecoollink/tree/master/libpurecoollink)
Und der letzte hier schein der beste zu sein:
https://libpurecool.readthedocs.io/en/latest/ (https://libpurecool.readthedocs.io/en/latest/)
@Shadow3561
Ich scheitere daran, an das Kennwort des TP04 zu gelangen:
Leider habe ich kein Android Mobiltelefon und versuche mich an einen Android Emulator. Dort habe ich schon verschiedene Versionen der Dyson Link App installiert und kann auch Pakete mit tPackedCapture mit schreiben, nur wenn ich die Dateien in verschiedenen Versionen von WireShark öffnen, bleibt die Anzeige nach aktivieren des MQTT Filters leer. Auch eine Suche nach "connect command" findet keine Pakete...
ich starte tPackedCapture und klicke auf Capture
Dann öffne ich die Dyson Link App, die denn auch eine Verbindung zum Fan herstellt.
Nun bediene ich die App und beende das Capture
Hast Du noch einen Tipp?
Danke.
Ich habe leider keinen Tipp für dich.
Habe es so gemacht wie du, nur mit dem Android Handy.
TPacketCapture öffnen dann geht alles über ein vpn
Mitschnitt starten
Dyson App öffnen und anmelden mit den benutzerdaten
Ein paar Dinge am Lüfter einstellen (lüfter Drehzahl usw)
Tpacketcapture beenden und die gespeicherte Mitschnittdatei in wireshark öffnen
Nach mqtt filtern und dann stand dort nach dem connect suchen
@Blackcat
Konntest du denn in meinen Links etwas passendes finden? Ich habe leider zu wenig Ahnung, um näher nachzusehen. Würde mich über eine Antwort freuen.
@Shadow3561
ich habe es jetzt hinbekommen!
Letztendlich habe ich ein altes iPhone 5 "modifiziert" OpenSSH und TCPDump installliert und mit remoteshh von Wireshark den Netzwerkverkehr mit geschrieben. Den Dyson auf Werkseinstellungen gesetzt und neu eingerichtet. In der Datei hab ich dann endlich den connect command gefunden!
Danke für die Beispieldateien zum einbinden.
Hast Du zufällig noch die Umweltdaten visualisiert?
Hi!
Ich hab ein C++ Programm zum Auslesen und Steuern vom Dyson Pure Cool 2018 geschrieben.
Vielleicht hilft es ja irgendwen :
https://gitlab.com/Amhehu/klaros
Vielleicht mache ich noch ein YouTube Video in dem ich erkläre wie man die Zugangsdaten ermittelt bzw. wie man an die Syntax kommt.
Bei Fragen stehe ich gern zur Verfügung.
Beste Grüße Silvio
Danke für die Antwort. Vielleicht könntest du ja die Befehle zur Ansteuerung des Lüfters hier zeigen, dann könnte man den ja aus fhem schalten. Vieles geht ja schon. Dein Programm ist ja für fhem nicht geeignet? Es müsste ja dafür zumindest auf dem Raspberry laufen. Ich hab leider zu wenig Ahnung davon.
self._oscillation_angle_low = \
get_field_value(self._state, 'osal')
self._oscillation_angle_high = \
get_field_value(self._state, 'osau')
particulate_matter_25 = get_field_value(data, 'pm25')
self._particulate_matter_25 = 0 \
if particulate_matter_25 in SENSOR_INIT_STATES \
else int(particulate_matter_25)
particulate_matter_10 = get_field_value(data, 'pm10')
self._particulate_matter_10 = 0 \
if particulate_matter_10 in SENSOR_INIT_STATES \
else int(particulate_matter_10)
volatile_organic_compounds = get_field_value(data, 'va10')
self._volatile_organic_compounds = 0 \
if volatile_organic_compounds in SENSOR_INIT_STATES \
else int(volatile_organic_compounds)
nitrogen_dioxide = get_field_value(data, 'noxl')
self._nitrogen_dioxide = 0 if nitrogen_dioxide in SENSOR_INIT_STATES \
else int(nitrogen_dioxide)
ich habe die Parameter gefunden, also jeweils der hintere Wert müsste als reading angelegt werden: get_field_value(data, 'noxl'), Shadow3561 hat das aber in seinen Codeänderungen schon gemacht ;D
Zur Zeit bin ich etwas stark ausgelastet durch Job und den Youtube Kanal den ich angefangen habe. Bald kommen da auch FHEM Videos
Danke. Ich habe die Hoffnung, dass du ja vielleicht doch mal einige Minuten Zeit findest, den Code einzuarbeiten. Ich kann es leider nicht selbst. Bin zu doof.
Hallo zusammen,
ich habe die letzten Tage etwas verbracht, mich in das homebridgeMapping einzuarbeiten, damit ich meinen Dyson auch über den Google Assistant steuern kann.
Falls es jemandem etwas bringt, poste ich hier mal mein Mapping. ("FanSpeed"muss leider wirklich in einer Zeile, ohne Umbrüchte, stehen.)
{
"On": {
"reading": "desired_mode",
"valueOff": "OFF",
"cmdOn": "desired_mode FAN",
"cmdOff": "desired_mode OFF",
"delayAfter": true
},
"FanSpeed":{"reading":"state","speeds":{"S1":{"cmd":"desired_mode FAN;desired_fanspeed 1","value":"s1","synonyms":{"de":["langsam","minimal","minimum","stufe 1"],"en":["slow","speed 1"]}},"S2":{"cmd":"desired_mode FAN;desired_fanspeed 2","value":"s2","synonyms":{"de":["stufe 2"],"en":["speed 2"]}},"S3":{"cmd":"desired_mode FAN;desired_fanspeed 3","value":"s3","synonyms":{"de":["stufe 3"],"en":["speed 3"]}},"S4":{"cmd":"desired_mode FAN;desired_fanspeed 4","value":"s4","synonyms":{"de":["stufe 4"],"en":["speed 4"]}},"S5":{"cmd":"desired_mode FAN;desired_fanspeed 5","value":"s5","synonyms":{"de":["mittel","stufe 5"],"en":["medium","speed 5"]}},"S6":{"cmd":"desired_mode FAN;desired_fanspeed 6","value":"s6","synonyms":{"de":["stufe 6"],"en":["speed 6"]}},"S7":{"cmd":"desired_mode FAN;desired_fanspeed 7","value":"s7","synonyms":{"de":["stufe 7"],"en":["speed 7"]}},"S8":{"cmd":"desired_mode FAN;desired_fanspeed 8","value":"s8","synonyms":{"de":["stufe 8"],"en":["speed 8"]}},"S9":{"cmd":"desired_mode FAN;desired_fanspeed 9","value":"s9","synonyms":{"de":["stufe 9"],"en":["speed 9"]}},"S10":{"cmd":"desired_mode FAN;desired_fanspeed 10","value":"s10","synonyms":{"de":["maximum","maximal","stufe 10"],"en":["maximum","speed 10"]}}},"ordered":true,"reversible":false},
"Modes": [
{
"reading": "state",
"cmds": [
"oscillating:desired_oscillation ON",
"not_oscillating:desired_oscillation OFF"
],
"mode_attributes": {
"name": "oscillation",
"name_values": [
{
"name_synonym": [
"Bewegung"
],
"lang": "de"
}
],
"settings": [
{
"setting_name": "oscillating",
"setting_values": [
{
"setting_synonym": [
"bewegen",
"Bewegung",
"oszillieren",
"oszillierend",
"Oszillation"
],
"lang": "de"
}
]
},
{
"setting_name": "not_oscillating",
"setting_values": [
{
"setting_synonym": [
"still",
"nicht bewegen",
"nicht oszillieren"
],
"lang": "de"
}
]
}
]
}
},
{
"reading": "state",
"cmds": [
"surveil:desired_mode AUTO"
],
"mode_attributes": {
"name": "mode",
"name_values": [
{
"name_synonym": [
"Auto-Modus",
"Überwachung",
"Luftüberwachung",
"Modus"
],
"lang": "de"
}
],
"settings": [
{
"setting_name": "surveil",
"setting_values": [
{
"setting_synonym": [
"Überwachung der Luftqualität",
"Luftqualität",
"überwachen",
"auto",
"ein"
],
"lang": "de"
}
]
}
]
}
}
]
}
Viele Grüße
Hallo zusammen,
Hat irgendjemand Erfahrung mit einem Dyson Typ 455?
Ich kann diesen über WLAN und App steuern. Dieses Plugins habe ich dank der tollen Beschreibung auch bei mir eingebunden. Leider kommt ein Kontakt zum Dyson nicht zustande...
Unabhängig des Plugins, Passwörtern oder sonstigen, kann ich den Dyson nur pingen. Der MQTT Port 1883 ist einfach nicht offen am Dyson.
Hierzu meine Frage:muss irgendwas am Dyson aktiviert werden oder ist die Funktion rausgeflogen irgendwann?
Grüße
Vossi
Einwandfrei. Vielen Dank für die super Arbeit. 8)
Hallo zusammen,
ich habe es mit der Anleitung von @BlackCat und @Shadow3561 jetzt auch geschafft meinen "Purifier Cool Formaldehyde" einzurichten.
Er gibt sich als "438E" zu erkennen.
In den Listings habt ihr immer Icons mit angegeben, wo sind die her?
Andreas
Kann mir jemand helfen? ICh habe mir einen PH04 gegönnt und scheitere schon recht früh :D
xxx@mqtt:/home/xxx/dyson# npm install --save dyson-cloud
npm WARN deprecated axios@0.18.1: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410
added 6 packages, and audited 7 packages in 800ms
1 package is looking for funding
run `npm fund` for details
3 high severity vulnerabilities
Some issues need review, and may require choosing
a different dependency.
Run `npm audit` for details.
xxx@mqtt:/home/xxx/dyson# npm audit
# npm audit report
axios <=0.21.1
Severity: high
Incorrect Comparison in axios - https://github.com/advisories/GHSA-cph5-m8f7-6c5x
Server-Side Request Forgery in Axios - https://github.com/advisories/GHSA-4w2v-q235-vp99
Depends on vulnerable versions of follow-redirects
No fix available
node_modules/axios
dyson-cloud *
Depends on vulnerable versions of axios
node_modules/dyson-cloud
follow-redirects <=1.14.7
Severity: high
Exposure of Sensitive Information to an Unauthorized Actor in follow-redirects - https://github.com/advisories/GHSA-pw2r-vq6v-hr8c
Exposure of sensitive information in follow-redirects - https://github.com/advisories/GHSA-74fj-2j2h-c42q
No fix available
node_modules/follow-redirects
axios <=0.21.1
Depends on vulnerable versions of follow-redirects
node_modules/axios
dyson-cloud *
Depends on vulnerable versions of axios
node_modules/dyson-cloud
3 high severity vulnerabilities
Some issues need review, and may require choosing
a different dependency.
ich glaube die dyson-cloud version ist nicht funktional. durch die 2wege authentifizierung
Hallo zusammen,
ich habe seit ein paar Monaten einen TP02 und möchte diesen nun einbinden.
Zitat2. Password Hash
Password Hash erzeugen. Danke an Skipper für das Windows Powershell Script.
Das mit den PowerShell hat auch geklappt.
Aber wo bekomme ich nun den Benutzernamen her?
Das ist mir nicht ganz klar.
Hallo zusammen,
mir ist es nun gelungen, meinen TP02 einzubinden.
Es kommen alle Readings an und jede Änderung wird in FHEM sichtbar.
Nur leider kann ich den TP02 aus FHEM heraus nicht steuern.
Jegliche Änderung übers DOIF wird nicht berücksichtigt.
Kann mir jemand helfen bzw. wie kann ich den TP02 direkt, ohne DOIF steuern?
Beim MQTT2 device weiß ich nicht wie.
Hallo zusammen,
vielleicht kann mir doch noch jemand helfen.
Ich habe die Anleitung befolgt und konnte den Dyson TP02 einbinden (readings funktionieren,...).
Mit folgendem Befehl ist es mir gelungen, die Lüfterdrehzahl zu ändern:
{fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("fnsp", "10"))}
Soweit so gut.
Leider gelingt es mir noch immer nicht, den Dyson ein- oder auszuschalten.
Eigentlich müsste es doch damit funktionieren (ausschalten):
{fhem("set sz_dyson_device_tp02 publish ".dyson_json_compose("fpwr", "OFF"))}
Woran kann es liegen? Vielleicht hat jemand einen Hinweis für mich.