MQTT2 für Xiaomi Vacuum Sauger

Begonnen von Otto123, 12 Mai 2021, 12:53:37

Vorheriges Thema - Nächstes Thema

sherwood

#120
@MadMax-FHEM bei einem Xiaomi V1/V2 und roborock, ja, da auf dem robot abgelegt. Bei einem dreame l10pro laut valetudo Entwickler, tracked die cloud und erstellt diese Werte und werden nicht auf dem robot abgelegt. Ohne cloud auch keine Historie auf dem robot.

total_cleans ist in den MQTT topics bei einem dreame nicht vorhanden, siehe meine readings list.


@Otto123
Dein l10pro ist also nicht mit FHEM verbunden und es werden auch keine Aktionen getriggered? Hast du den zumindest in valetudo einen Status einer Reinigung (erfolgreich, qm, Zeit)? Bei mir bleibt z.B. bei einem Zone-Cleaning die Current Statistics auf '0' und ändern sich nicht, ebenso über MQTT.

Auf 'error' kann man nicht setzen, da der Status nicht sagt, was passiert ist.
Das einzige was mir einfällt, wäre den Status zu verfolgen 'docked -> cleaning -> returning -> docked'
oder zumindest 'cleaning -> ... -> docked' und dann ein neues Readings (z.B. last_clean) zu erstellen/setzten.

Hier fängt es an wie man das gelöst bekommt.
Das mit dem userReadings funktioniert nicht, da die Readings des State und CurrentStatistics allein nicht ausreichen.

TomLee

Zitat von: Otto123 am 16 Januar 2022, 17:51:37

Da habe ich mittlerweile eine kleine Umwandlung geschrieben -> zones sub valetudo_r {
my $setter = shift;
my $payload = shift;
my $ret = 'error';
my %t;
if ($setter eq 'presets') {
  my $decoded = decode_json($payload);
  for (keys %$decoded) { $t{$decoded->{$_}->{'name'}} = $_ } # build a new hash only with zone id and zone name
  $ret = encode_json(\%t)
  }
return $ret
}
und die Readingslist so gemacht:
$DEVICETOPIC/ZoneCleaningCapability/presets:.* { $TOPIC =~ m,$DEVICETOPIC\/.*\/([a-zA-Z\-_]+),; {"zones"=>valetudo_r($1,$EVENT)} }

Da musst du nochmal ran das passt so nicht, der Hash der zurückgegeben wird ist unsortiert, darum gibts dann in dem Reading alle 30 Sekunden ein Event, weil er ja eigentlich immer anders und nur zufällig mal so aufgebaut sein kann wie zuvor.

Ich hab mal versucht in der Schleife nach dem Schlüssel zu sortieren, bringt aber nix weil (denk ich) später die Referenz die an encode_json übergeben wird wieder unsortiert ist ? 




Otto123

#122
@sherwood Doch mein L10pro ist über mqtt mit FHEM verbunden. Aber ich bin noch am entwickeln und testen :)
ich bin erstmal noch am kämpfen weil das Ding nicht in mein "normales" Wlan will :o

@TomLee Ja ist mir gestern auch aufgefallen, irgendwie klemmt es bei mir das Ding zu sortieren. Ich bin da ziemlich blind was die Verarbeitung der hashes angeht  :'(
Ich glaube wenn man es sortiert haben will, darf man nicht encode_json nehmen. Irgendwo habe ich gelesen das json erstmal "nicht sortiert sein darf oder soll"? und die sortier Beispiele in der Art
$json->canonical->encode($perl_scalar)
versteh ich nicht :(
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

sherwood

Ok, dann bin ich mal gespannt wenn er bei dir läuft.
(Wlan hat bei mir gut funktioniert und er hat die settings von der vorherigen Xiaomi App übernommen. Es wird so weit ich weiß, von config editing abgeraten. Am besten über die GUI, über die valetudo Android App, geht das auch.)

Ich kämpfe mich dann mal weiter durch und berichte.


Otto123

#124
@TomLee Das ist jetzt encode json zu Fuß - sicher noch stark verbesserungswürdig :)
sub valetudo_r {
my $setter = shift;
my $payload = shift;
my $ret = 'error';
my %t;
if ($setter eq 'presets') {
  my $decoded = decode_json($payload);
  for (keys %$decoded) { $t{$decoded->{$_}->{'name'}} = $_ } # build a new hash only with zone id and zone name
  }
my @arr;
for (sort keys %t) { push @arr, "\"$_\":\"$t{$_}\"" }
$ret = join ',', @arr;
$ret="{$ret}";
return $ret
}

Edit: toJSON sortiert es offenbar  ;)
sub valetudo_r {
my $setter = shift;
my $payload = shift;
my $ret = 'error';
my %t;
if ($setter eq 'presets') {
  my $decoded = decode_json($payload);
  for (keys %$decoded) { $t{$decoded->{$_}->{'name'}} = $_ } # build a new hash only with zone id and zone name
  $ret = toJSON(\%t);
  }
return $ret
}
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TomLee

Zitat von: Otto123 am 17 Januar 2022, 13:52:42
Edit: toJSON sortiert es offenbar  ;)
sub valetudo_r {
my $setter = shift;
my $payload = shift;
my $ret = 'error';
my %t;
if ($setter eq 'presets') {
  my $decoded = decode_json($payload);
  for (keys %$decoded) { $t{$decoded->{$_}->{'name'}} = $_ } # build a new hash only with zone id and zone name
  $ret = toJSON(\%t);
  }
return $ret
}


Cool, hab ich mich eben kurz mit beschäftigt und alles wieder ein Stück mehr verinnerlicht.

Sortiert nach den Schlüsseln wird wie ich es meine zu verstehen in Zeile 5256 in fhem.pl, oder ?

5253   } elsif (ref $val eq 'HASH') {
5254       return '{' . join(',',
5255                    map { toJSON($_).":".toJSON($val->{$_}) }
5256                    sort keys %$val) . '}';

TomLee

Und vlt. noch eine Frage/Ergänzung/Steigerung von:

ZitatDa habe ich mittlerweile eine kleine Umwandlung geschrieben -> zones

Hab ich bisher mein ich in noch keinem Template gesehen das Readings versteckt werden, aber was hältst du davon das Reading erst gar nicht anzuzeigen?

$DEVICETOPIC/ZoneCleaningCapability/presets:.* { $TOPIC =~ m,$DEVICETOPIC\/.*\/([a-zA-Z\-_]+),; {".zones"=>valetudo_r($1,$EVENT)} }


sherwood

#127
Der erste Teil für wäre schon mal geschafft.
Was der Dreame nicht kann, muss dann halt fhem erledigen ;)

Attributes:

oldreadings stateDetail,last_cleaning-area,last_cleaning-mode,last_cleaning-time,last_cleaning-timestamp
event-on-change-reading .*


userReadings state:docked {
  use Time::Piece;

  my $timestamp = strftime('%F %X', localtime);
  my $cleaningTimeMin = ReadingsVal($NAME,'time',0)/60;
  my $cleaningAreaM2 = ReadingsVal($NAME,'area',0)/10000;
  my $cleaningMode = OldReadingsVal($NAME,'stateDetail','none');

  fhem"
    sleep 0.1;
    setreading Valetudo last_cleaning-timestamp $timestamp;
    setreading Valetudo last_cleaning-area $cleaningAreaM2;
    setreading Valetudo last_cleaning-time $cleaningTimeMin;
    setreading Valetudo last_cleaning-mode $cleaningMode;
  ";
},

Otto123

Zitat von: sherwood am 17 Januar 2022, 11:26:01
Bei mir bleibt z.B. bei einem Zone-Cleaning die Current Statistics auf '0' und ändern sich nicht, ebenso über MQTT.
Das ist bei mir nicht so, gerade eine Zone gereinigt
2022-01-17_23:42:30 MQTT2_valetudo_ClumsyQuirkyCattle set_clean_zone
2022-01-17_23:42:30 MQTT2_valetudo_ClumsyQuirkyCattle start: 4f8b7ebe-ad5f-4c2b-850b-90172fc47dba
2022-01-17_23:42:32 MQTT2_valetudo_ClumsyQuirkyCattle cleaning
2022-01-17_23:42:32 MQTT2_valetudo_ClumsyQuirkyCattle stateDetail: zone
2022-01-17_23:43:03 MQTT2_valetudo_ClumsyQuirkyCattle signal: -50
2022-01-17_23:43:34 MQTT2_valetudo_ClumsyQuirkyCattle signal: -54
2022-01-17_23:44:02 MQTT2_valetudo_ClumsyQuirkyCattle batteryPercent: 99
2022-01-17_23:44:02 MQTT2_valetudo_ClumsyQuirkyCattle signal: -55
2022-01-17_23:44:03 MQTT2_valetudo_ClumsyQuirkyCattle time: 60
2022-01-17_23:44:04 MQTT2_valetudo_ClumsyQuirkyCattle area: 20000
2022-01-17_23:44:32 MQTT2_valetudo_ClumsyQuirkyCattle signal: -54
2022-01-17_23:45:03 MQTT2_valetudo_ClumsyQuirkyCattle signal: -56
2022-01-17_23:45:03 MQTT2_valetudo_ClumsyQuirkyCattle time: 120
2022-01-17_23:45:03 MQTT2_valetudo_ClumsyQuirkyCattle area: 30000
2022-01-17_23:45:11 MQTT2_valetudo_ClumsyQuirkyCattle batteryPercent: 98
2022-01-17_23:45:22 MQTT2_valetudo_ClumsyQuirkyCattle returning
2022-01-17_23:45:22 MQTT2_valetudo_ClumsyQuirkyCattle stateDetail: none
2022-01-17_23:46:03 MQTT2_valetudo_ClumsyQuirkyCattle signal: -62
2022-01-17_23:46:07 MQTT2_valetudo_ClumsyQuirkyCattle sensor-all: 93600
2022-01-17_23:46:09 MQTT2_valetudo_ClumsyQuirkyCattle docked
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

sherwood

Zone-Cleaning Statistik funktioniert bei mir jetzt auch. Meine Testfläche war zu klein, da die Genauigkeit nur bei 1 m2 und 1 Min. liegt.

Otto123

Zitat von: TomLee am 17 Januar 2022, 16:11:26
Hab ich bisher mein ich in noch keinem Template gesehen das Readings versteckt werden, aber was hältst du davon das Reading erst gar nicht anzuzeigen?
Ich habe das mal realisiert / umgebaut, bin aber noch ein bisschen am überlegen/testen - vor dem einchecken.
Wenn Du gucken willst :) https://github.com/heinz-otto/scripts/tree/master/fhem

Habe auch goto location eingebaut, das kann ja der Gen1 - der L10pro kann es nicht. Man müsste also noch die Features abfragen und bestimmte Dinge ein und ausblenden. ???
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TomLee

ZitatHabe auch goto location eingebaut, ...

Funzt. :)

ZitatMan müsste also noch die Features abfragen ...

Versteh ich nicht wie das gemeint ist, du willst das get der Features in einem Reading ?

Im clean_zone-setter des Templates hast du "vorne" vergessen presets in zones umzubennen und (kannst ja machen wie du willst) ich hab mir angewöhnt (bzw. bin ich noch dabei) wenn ich eh nur "Text" mit Quotes schreibe immer nur einfache zu verwenden, ich find das übersichtlicher/ruhiger  ::) ;D:
Zitatclean_zone:{valetudo_w($name,'zones')} { valetudo_c($NAME,$EVENT) }
clean_segment:{'multiple-strict,'.valetudo_w($name,'segments')} { valetudo_c($NAME,$EVENT) }
goto:{valetudo_w($name,'locations')} { valetudo_c($NAME,$EVENT) }



TomLee

Achso und noch was .

Wenn du (schon) mit den Templates event-on-change-reading .* verteilst, wäre es nicht auch dann angebracht mindestens timestamp-on-change-reading .* zu setzen ?

Otto123

Zu den Features: ich meine man könnte irgendwo irgendwann (beim Template anwenden oder dann im Device) den Typ (die Features) abfragen und die Dinge entsprechend ein- und ausblenden.
timestamp könnte man machen, ich finde es manchmal gut, da sehe ich es arbeitet noch :)
Das mit zones und den ' ' habe ich gemacht ;) Ich habe aber eh noch eine Idee etwas umzubauen...
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Otto123

Hab nochmal etwas umgebaut, ich fand es doof alle 30 sec die json readings durch mehrere convert / hash Schleifen zu schubsen. Dank der Idee mit den versteckten Readings schreib ich jetzt einfach die json in Readings und werte die in der Util komplett aus. timestamp-on-change-reading .*  hab ich auch eingebaut.
Also nochmal ne vorab Version https://github.com/heinz-otto/scripts/tree/master/fhem
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz