Modul für Irobot Roomba 980

Begonnen von kukamee, 22 Februar 2017, 02:34:53

Vorheriges Thema - Nächstes Thema

luetty

Zitat von: Spiff am 17 Juli 2017, 18:15:32
Bei mir kam es glaube ich noch am ersten Tag, spätestens am zweiten nach Inbetriebnahme. - vielleicht dauerte das anfangs beim ersten Ausrollen durch die Vielzahl an Geräten länger.

Gruß
Spiff
ich harre der Dinge, die da kommen werden  ;) Danke, dass macht zumindest schon mal "Mut"  8)

DanHard

Zitat von: luetty am 17 Juli 2017, 18:19:11
ich harre der Dinge, die da kommen werden  ;) Danke, dass macht zumindest schon mal "Mut"  8)

Habe meinen Robi seit 2 Wochen, das Update hat er schon in der zweiten Nacht eingespielt! Ich drück dir die Daumen... [emoji16]
- FHEM auf RaspberryPi B
- RFXTRX 433
- 3x IT-1500
- 3x Thermo-, Hygro-Sensor TS34C

luetty

#92
Zitat von: DanHard am 17 Juli 2017, 22:32:18
Habe meinen Robi seit 2 Wochen, das Update hat er schon in der zweiten Nacht eingespielt! Ich drück dir die Daumen... [emoji16]

Scheint geholfen zu haben, manchmal ist man halt zu ungeduldig  ;)
21:23 fing WhatsApp an zu explodieren und hat mir batteryType-Warnungen vom Roombi geschickt. Ein klares Zeichen dafür, dass dieses Modul hier funktioniert und die FW unseres "neuen" aktualisiert wurde!  ;D ;D
Jetzt kann ich mich damit beschäftigen  8)
Allerdings geht der state laufend von opened auf disconnected, dadurch werden auch die readings jedesmal neu getriggert. Uncool :-( Kennt jemand das Problem?

edit: leider 2x innerhalb 16h fhem komplett lahmgelegt  :-\ Bin weiter am beobachten.

Lasst Ihr Euren Sauger permanent connected?

luetty

#93
Hallo zusammen,

leider heute morgen wieder ein Crash von fhem.  ::)
Folgenden Fehler fand ich bis jetzt diesbzgl. immer in den logs:

2017.07.19 09:11:57 3: Opening Roombi device roombi.xy.z:8883
2017.07.19 09:11:58 3: Roombi device opened
decode_string: insufficient data at FHEM/lib/Net/MQTT/Message/Publish.pm line 36.
2017.07.19 09:12:01 1: BlockingInformParent (BlockingStart): Can't connect to localhost:41736: IO::Socket::INET: connect: Connection refused
2017.07.19 09:12:01 1: BlockingInformParent (PRESENCE_ProcessLocalScan): Can't connect to localhost:41736: IO::Socket::INET: connect: Connection refused
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/opt/yowsup-master/yowsup/demos/cli/cli.py", line 153, in startInputThread
    cmd = self._queuedCmds.pop(0) if len(self._queuedCmds) else input(self.getPrompt()).strip()
EOFError: EOF when reading a line

Traceback (most recent call last):
  File "/opt/yowsup-master/yowsup-cli", line 368, in <module>
    if not parser.process():
  File "/opt/yowsup-master/yowsup-cli", line 268, in process
    self.startCmdline()
  File "/opt/yowsup-master/yowsup-cli", line 297, in startCmdline
    stack.start()
  File "/opt/yowsup-master/yowsup/demos/cli/stack.py", line 26, in start
    self.stack.loop(timeout = 0.5, discrete = 0.5)
  File "/opt/yowsup-master/yowsup/stacks/yowstack.py", line 188, in loop
    asyncore.loop(*args, **kwargs)
  File "/usr/lib/python2.7/asyncore.py", line 216, in loop
    poll_fun(timeout, map)
  File "/usr/lib/python2.7/asyncore.py", line 156, in poll
    read(obj)
  File "/usr/lib/python2.7/asyncore.py", line 87, in read
    obj.handle_error()
  File "/usr/lib/python2.7/asyncore.py", line 83, in read
    obj.handle_read_event()
  File "/usr/lib/python2.7/asyncore.py", line 449, in handle_read_event
    self.handle_read()
  File "/opt/yowsup-master/yowsup/layers/network/layer.py", line 102, in handle_read
    self.receive(data)
  File "/opt/yowsup-master/yowsup/layers/network/layer.py", line 110, in receive
    self.toUpper(data)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/stanzaregulator/layer.py", line 29, in receive
    self.processReceived()
  File "/opt/yowsup-master/yowsup/layers/stanzaregulator/layer.py", line 49, in processReceived
    self.toUpper(oneMessageData)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/auth/layer_crypt.py", line 65, in receive
    self.toUpper(payload)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/coder/layer.py", line 35, in receive
    self.toUpper(node)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/logger/layer.py", line 14, in receive
    self.toUpper(data)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/axolotl/layer_control.py", line 44, in receive
    self.toUpper(protocolTreeNode)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 189, in receive
    s.receive(data)
  File "/opt/yowsup-master/yowsup/layers/axolotl/layer_receive.py", line 44, in receive
    self.toUpper(protocolTreeNode)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 189, in receive
    s.receive(data)
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 121, in receive
    if not self.processIqRegistry(node):
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 156, in processIqRegistry
    successClbk(protocolTreeNode, originalIq)
  File "/opt/yowsup-master/yowsup/layers/protocol_iq/layer.py", line 30, in onPong
    self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(protocolTreeNode))
  File "/opt/yowsup-master/yowsup/layers/__init__.py", line 76, in toUpper
    self.__upper.receive(data)
  File "/opt/yowsup-master/yowsup/layers/interface/interface.py", line 80, in receive
    self.entity_callbacks[entityType](entity)
  File "/opt/yowsup-master/yowsup/demos/cli/layer.py", line 458, in onIq
    print(entity)
IOError: [Errno 32] Broken pipe


Scheint an MQTT zu liegen, was fhem -wegen ungültigen Daten - dann abschießt.

Roomba-FW: v2.2.9-1

luetty

#94
So. verbose=5 und den nächsten Crash abgewartet. Kam schneller als erwartet.

Zitat2017.07.19 17:39:30 5: End notify loop for Roombi
2017.07.19 17:39:30 5: MQTT Roombi message received: Publish/at-most-once wifistat
  20 02 00 00 30 aa 01 00 08 77 69 66 69 73 74 61   ...0....wifista
  74 7b 22 73 74 61 74 65 22 3a 7b 22 72 65 70 6f  t{"state":{"repo
  72 74 65 64 22 3a 7b 22 6e 65 74 69 6e 66 6f 22  rted":{"netinfo"
  3a 7b 22 64 68 63 70 22 3a 74 72 75 65 2c 22 61  :{"dhcp":true,"a
  64 64 72 22 3a 31 36 38 35 35 39 34 33 39 2c 22  ddr":168559439,"
  6d 61 73 6b 22 3a 34 32 39 34 39 36 37 30 34 30  mask":4294967040
  2c 22 67 77 22 3a 31 36 38 35 35 39 33 36 31 2c  ,"gw":168559361,
  22 64 6e 73 31 22 3a 31 36 38 35 35 39 33 37 37  "dns1":168559377
  2c 22 64 6e 73 32 22 3a 30 2c 22 62 73 73 69 64  ,"dns2":0,"bssid
  22 3a 22 39 63 3a 63 37 3a 61 36 3a 62 65 3a 33  ":"9c:c7:xx:xx:x
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 1 (before "\x{2}\x{0}\x{0}0\x{fffd}...") at ./FHEM/42_Roomba980.pm line 376.
2017.07.19 17:39:31 1: BlockingInformParent (BlockingStart): Can't connect to localhost:40046: IO::Socket::INET: connect: Connection refused
2017.07.19 17:39:31 1: BlockingInformParent (PRESENCE_ProcessLocalScan): Can't connect to localhost:40046: IO::Socket::INET: connect: Connection refused

Stellt sich jetzt die Frage, warum der JSON-String nicht vollständig ist und wie man soetwas abfangen kann. Ggfls. liegt es an den laufenden Connect/ Disconnects - aber dass sollte fhem ja nicht zum abkacheln bringen.
Mir ist klar, dass dieses Modul dafür nichts kann - da MQTT hier das Chaos letztlich auslöst, repektive hätte abfangen können. Hat irgendjemand ne Idee dazu?

DANKEEE!


edit: ich hab dass Modul mal schnell angepasst und prüfe jetzt mittels Test::JSON auf einen validen String innerhalb processMessage. Quick & dirty, mal sehen ob ich die Abstürze damit wegbekomme. Schön ist anders, aber dafür brauche ich dann mehr Zeit.

Thorsten Pferdekaemper

Zitat von: luetty am 19 Juli 2017, 17:46:53
edit: ich hab dass Modul mal schnell angepasst und prüfe jetzt mittels Test::JSON auf einen validen String innerhalb processMessage. Quick & dirty, mal sehen ob ich die Abstürze damit wegbekomme. Schön ist anders, aber dafür brauche ich dann mehr Zeit.
Hi,
wenn das funktioniert, dann gib uns auch mal die angepasste Version. Gut wäre auch, wenn Du im Coding irgendwie markieren könntest, wo Du was angepasst hast.
Ich habe zwar zurzeit keine Möglichkeit, bei der Entwicklung des Moduls zu helfen, aber ich kann zumindest mal ein Git-Repo dafür anlegen und das ganze "hosten".
Gruß,
   Thorsten
FUIP

eisler

Hallo Thorsten,

Git Repro ist eine prima Idee, dann kann ich das auch mal mit unserem neuen iRobot Roomba 980 testen und bei der Entwicklung des Moduls helfen.

Grüße
Stephan

luetty

Zitat von: Thorsten Pferdekaemper am 20 Juli 2017, 09:04:38
Hi,
wenn das funktioniert, dann gib uns auch mal die angepasste Version. Gut wäre auch, wenn Du im Coding irgendwie markieren könntest, wo Du was angepasst hast.
Ich habe zwar zurzeit keine Möglichkeit, bei der Entwicklung des Moduls zu helfen, aber ich kann zumindest mal ein Git-Repo dafür anlegen und das ganze "hosten".
Gruß,
   Thorsten
Mache ich die Tage, ich will erst sicher sein dass es funktioniert.

Thorsten Pferdekaemper

Hi,
also das Ding gibt es jetzt hier:

https://github.com/ThorstenPferdekaemper/FHEM-Roomba980/

Wer sich daran beteiligen will, nur zu.
Gruß,
   Thorsten
FUIP

luetty

#99
Hallo zusammen,

leider habe ich dass Problem noch nicht lösen können.  >:(
Die Prüfung auf einen validen JSON-String hatte ich in processMessage eingebaut und ging im Fehlerfall mit return zurück.

Es wurde auch alles schön protokolliert, MQTT/Publish krachte danach aber trotzdem weg.
Also hab ich dass ganze mal in "Read" gepackt und im Fehlerfall mit return undef abzubrechen. Soeben hat sich gezeigt, dass dies auch nicht hilft.  ::) :'(

Ich bin grad ein bisschen hilflos, werde dass Modul wohl erstmal deaktivieren müssen.
MQTT-Check failed: ^B^@^@0ª^A^@^Hwifistat{"state":{"reported":{"netinfo":{"dhcp":true,"addr":168559374,"mask":4294967040,"gw":168559361,"dns1":168559377,"dns2":0,"bssid":"9c:c7:xx:xx:x
decode_string: insufficient data at FHEM/lib/Net/MQTT/Message/Publish.pm line 36.


Im Prinzip gleich der Erkenntnis von Thorsten im Beitrag #20 https://forum.fhem.de/index.php/topic,67632.msg598968.html#msg598968

Hat also 0,nix gebracht - meine tolle Prüfung.  ;) ::)

ct

#100
Hallo Zusammen,

einen Crash konnte ich (glaube ich) beheben, wobei das noch jemand bestätigen müsste:

Zeile 408 ersetzen mit:

my $message_type = -1;
eval {
    $message_type = $mqtt->message_type();

    Log3($name,5,"MQTT $name message received: [$message_type] ".$mqtt->string());
}
or do {
  Log3 ($name, 5, "Error in Read 1: $@" );
};


Die while-Schleife kann wohl auch ausgeführt werden, wenn der Puffer unvollständig ist und dann krachts im message_type()-Aufruf.

Optional:
Evtl. krachts auch schon in der Generierung vom mqtt-Objekt. Daher habe ich zusätzlich auch noch die Bedingung der while-Schleife in die Schleife gezogen und mit eval abgesichert...

Zeile 406 ersetzen mit:

while (1) { 
    my $mqtt = undef;
  eval {
$mqtt = Net::MQTT::Message->new_from_bytes($hash->{buf},1);
        }
        or do {
      Log3 ($name, 5, "Error in Read 0: $@" );
        };
last if ( !defined($mqtt) );


Könnte man sicher eleganter lösen, aber hat seit dem Umbau funktioniert und hatte dann keine Zeit mehr das schön zu machen.

Das Dauer-Disconnect-Verhalten wird damit leider nicht behoben.

Grüße,
Chi-Tai

luetty

Kannst Du bitte mal Deine Version hier anhängen oder ins Git stellen.
Ich habe Deine Änderungen, in die letzte Version von Thorsten, übernommen, lief genau 15 Minuten und dann:

2017.07.26 15:05:08 1: 10.12.3.14:8883 reappeared (Roombi)
, or } expected while parsing object/hash, at character offset 33 (before "w6ADb8uS,"mapUploadA...") at ./FHEM/42_Roomba980.pm line 376.
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/opt/yowsup-master/yowsup/demos/cli/cli.py", line 153, in startInputThread
    cmd = self._queuedCmds.pop(0) if len(self._queuedCmds) else input(self.getPrompt()).strip()
EOFError: EOF when reading a line
  :'( :'(

ct

#102
Hallo luetty,

stimmt, da war auch ein Crash. Versuch mal die processMessage durch diese zu ersetzen:


sub processMessage($$){
    my ($hash, $msgtext) = @_;
# message empty?
if(!$msgtext){
    Log3($hash->{NAME},3, "Received empty message");
return;
};
# decode to Perl
my $msg = 0;
  eval {
    $msg = JSON::XS::decode_json($msgtext);
  if ($@) {
    Log3($hash->{NAME},3, "Could not decode: "); #.$@->what);
  }
if(!$msg){
    Log3($hash->{NAME},3, "Could not decode ".$msgtext);
    return;
};
# all known events start with "state->reported"
if(!defined($msg->{state}{reported})){
Log3($hash->{NAME},3, "state:reported missing ".$msgtext);
return;
};
if(ref($msg->{state}{reported}) ne "HASH"){
Log3($hash->{NAME},3, "No hash in ".$msgtext);
return;
};
# now we should be able to find readings
readingsBeginUpdate($hash);
    messageToReadings($hash,$msg->{state}{reported});
    # TODO: really trigger for all readings?
    readingsEndUpdate($hash,1);

  }
  or do {
  Log3 ($hash->{NAME}, 5, "Error in processMessage: $@" );
  };
};


Im Endeffekt werden damit auch nur die Exceptions abgefangen, damit nicht gleich das ganze fhem lahmgelegt wird. Falls es noch an anderer Stelle crashen sollte, dann gib Bescheid. Allerdings muss ich meine Version erst etwas "saubermachen", bevor ich sie bereitstellen kann.

Ach ja, ich denke nicht, dass das notwendig ist, aber die Funktion davor, also messageToReadings, habe ich auch mit eval abgesichert:

sub messageToReadings($$;$){
    my ($hash,$msgpart,$prefix) = @_;
my $type = ref($msgpart);
  eval {
    if($type eq "HASH") {
    foreach my $key (keys %{$msgpart}) {
    messageToReadings($hash,$msgpart->{$key},$prefix ? $prefix."-".$key : $key);
};
return;
};
if($type eq "ARRAY") {
    # TODO: error handling... my $rv = readings...
readingsBulkUpdate($hash,$prefix,JSON::XS::encode_json($msgpart));
return;
};
    # now it should be a normal "field"
# my $rv = TODO: error handling
readingsBulkUpdate($hash,$prefix,prettyPrintReading($prefix,$msgpart));
}
  or do {
  Log3 ($hash->{NAME}, 5, "Error in messageToReadings: $@" );
  };
};


Grüße,
ct


luetty

#103
Zitat von: ct am 26 Juli 2017, 15:38:22
Hallo luetty,

stimmt, da war auch ein Crash. Versuch mal die processMessage durch diese zu ersetzen:
...

Grüße,
ct

Hallo ct,

vielen Dank, hab beide Funktionen ersetzt!
Bei dem Müll, was da anscheinend ab und an ankommt, kann man auch nur die Ausnahmefehler abfangen.

Seit 6h im Einsatz ohne Crash, werde weiter beobachten....

Allerdings ist jetzt schon zu erkennen, dass einige Readings seit Stunden nicht durchkommen, obwohl mehrfache connect/disconnect - naja schaun wir mal....

...stay tuned  8)

ciao
luetty

ct

#104
Hallo Luetty,

freut mich :-)
Ich schau am Wochenende mal wo ich noch etwas abgefangen habe, aber ich glaube das waren die größten Gefahrenstellen.

Grüße,
ct