| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300 |
- ##############################################
- # $Id: 86_Robonect.pm 17176 2018-08-19 17:20:49Z andi291 $
- # ABU 20160307 First release
- # ABU 20160321 Added first parsing algos
- # ABU 20160311 Migrated to JSON
- # ABU 20160412 Integrated basic set-mechanism, added internals, changed callback-routine
- # ABU 20160413 Renamed to robonect, added status offline
- # ABU 20160414 Changed final two Automower to Robonect
- # ABU 20160414 Renamed private fn "decode"
- # ABU 20160415 Renamed private fn "decode" again, set eventonchangedreading, removed debug, increased interval to 90
- # ABU 20160416 Added logs, removed eventonchangedreading, added debug
- # ABU 20160416 Removed logs, added eventonchangedreading, removed debug, added 1=true for json data
- # ABU 20160426 Fixed decode warning, added error support
- # ABU 20160515 Added splitFn and doku
- # BJOERNAR 20160715 added duration and wlan-signal
- # ABU 20160831 Integrated API-changes for RC9, added attribute timeout for httpData
- # ABU 20160831 added calculations for duration and wlan - show in hours and percent
- # ABU 20160901 rounded duration and wlan
- # ABU 20161120 addaed encode_utf8 at json decode, tuned 0.5b repiar-stuff, added hibernate
- # ABU 20161126 added summary
- # ABU 20161129 fixed hash issues which prevents the module from loading
- # ABU 20170301 fixed hybernate-check in set
- # ABU 20170406 fixed hybernate-check in timer
- # ABU 20170422 fixed doku
- # ABU 20170427 fixed numerich undefs
- # ABU 20170428 do not delete private hash data in undef
- # ABU 20170428 do not define defptr in define
- # ABU 20170428 fixed in define section: removed me and my secret, removed IP-check for DNS-Support
- # ABU 20170428 removed setting attributes in define (eventonchange and pollInterval)
- # ABU 20170428 masked decode_json in eval and added error-path
- # ABU 20170501 added setkey/getkey for username and password
- # ABU 20170501 added eval-error-logging
- # ABU 20170501 changed verbose 3 to verbose 4
- # ABU 20170501 tuned documentation
- # ABU 20170516 removed useless print
- # ABU 20170525 bugfixed winterschlaf again
- # ABU 20171006 added options for Maehauftrag
- # ABU 20171006 added "umlautfilter" for test
- # ABU 20171006 added "health" for test
- # ABU 20171010 finished health for test, added chck for undef at each reading
- # ABU 20180507 replaced "umwelt" with "climate" in readings-section (roughly line 740)
- # ABU 20180509 reading winterschlaf was not decoded correctly - fixed
- # ABU 20180509 always try to decode health details - even without Attribute being set. Line 726-748.
- # ABU 20180819 Added userdefined status. Line 102.
- package main;
- use strict;
- use warnings;
- use HttpUtils;
- use Encode;
- use JSON;
- my $EOD = "feierabend";
- my $HOME = "home";
- my $AUTO = "auto";
- my $MANUAL = "manuell";
- my $JOB = "maehauftrag";
- my $START = "start";
- my $STOP = "stop";
- my $OFFLINE = "offline";
- my $HYBERNATE = "winterschlaf";
- my $USER = "benutzername";
- my $PW = "passwort";
- #available get cmds
- my %gets = (
- "status" => "noArg",
- "health" => "noArg"
- );
- #available set cmds
- my %sets = (
- $EOD => "noArg",
- $HOME => "noArg",
- $AUTO => "noArg",
- $MANUAL => "noArg",
- $JOB => "",
- $START => "noArg",
- $STOP => "noArg",
- $HYBERNATE => "on,off",
- $USER => "",
- $PW => ""
- );
- my %commands = (
- #GET_STATUS => "cmd=status",
- SET_MODE => {$HOME=>"cmd=mode&mode=home", $MANUAL=>"cmd=mode&mode=man", $JOB=>"cmd=mode&mode=job", $AUTO=>"cmd=mode&mode=auto", $EOD=>"cmd=mode&mode=eod", $STOP=>"cmd=stop", $START=>"cmd=start"}
- );
- #set to 1 for debug
- my $debug = 0;
- #elements within group next
- my %elements = (
- # "robonect" =>
- # {
- "successful" => {ALIAS=>"kommunikation", "true"=>"erfolgreich", "false"=>"fehlgeschlagen", 1=>"erfolgreich", 0=>"fehlgeschlagen"},
-
- "status" =>
- {
- ALIAS => "allgemein",
- "status" => {ALIAS=>"status", 0=>"schlafen", 1=>"parken", 2=>"maehen", 3=>"suche-base", 4=>"laden", 5=>"suche", 7=>"fehler", 8=>"schleife-fehlt", 16=>"abgeschaltet", 17=>"schlafen", 18=>"wartezeit-tuere"},
- "mode" => {ALIAS=>"modus", 0=>"automatik", 1=>"manuell", 2=>"home", 3=>"demo"},
- "battery" => {ALIAS=>"batteriezustand"},
- "duration" => {ALIAS=>"dauer"},
- "hours" => {ALIAS=>"betriebsstunden"}
- },
-
- "health" =>
- {
- ALIAS => "erweitert",
- "alarm" =>
- {
- ALIAS => "alarm",
- "voltage3v3extmin" => {ALIAS=>"unterspannung_extern_3V3", "false"=> "bereit", "true"=>"alarm"},
- "voltage3v3extmax" => {ALIAS=>"ueberspannung_extern_3V3", "false"=> "bereit", "true"=>"alarm"},
- "voltage3v3intmin" => {ALIAS=>"unterspannung_intern_3V3", "false"=> "bereit", "true"=>"alarm"},
- "voltage3v3intmax" => {ALIAS=>"ueberspannung_intern_3V3", "false"=> "bereit", "true"=>"alarm"},
- "voltagebattmin" => {ALIAS=>"unterspannung_batterie", "false"=> "bereit", "true"=>"alarm"},
- "voltagebattmax" => {ALIAS=>"ueberspannung_batterie", "false"=> "bereit", "true"=>"alarm"},
- "temperatureMin" => {ALIAS=>"zu_kalt", "false"=> "bereit", "true"=>"alarm"},
- "temperatureMax" => {ALIAS=>"zu_warm", "false"=> "bereit", "true"=>"alarm"},
- "humidityMax" => {ALIAS=>"zu_feucht", "false"=> "bereit", "true"=>"alarm"},
- },
- "voltages" =>
- {
- ALIAS => "spannung",
- "ext3v3" => {ALIAS=>"extern"},
- "int3v3" => {ALIAS=>"intern"},
- "batt" => {ALIAS=>"batterie"},
- },
- "climate" =>
- {
- ALIAS => "umwelt",
- "temperature" => {ALIAS=>"temperatur"},
- "humidity" => {ALIAS=>"feuchte"},
- }
- },
-
- "timer" =>
- {
- ALIAS => "timer",
- "status" => {ALIAS=>"status", 0=>"deaktiviert", 1=>"aktiv", 2=>"standby"},
- "next" =>
- {
- ALIAS => "timer",
- "date" => {ALIAS=>"startdatum"},
- "time" => {ALIAS=>"startzeit"},
- #"date" => {ALIAS=>"start-unix"},
- }
- },
-
- "wlan" =>
- {
- ALIAS => "wlan",
- "signal" => {ALIAS=>"signal"}
- },
-
- "error" =>
- {
- ALIAS => "fehler",
- "error_code" => {ALIAS=>"code"},
- "error_message" => {ALIAS=>"nachricht"},
- "date" => {ALIAS=>"datum"},
- "time" => {ALIAS=>"zeit"}
- }
- # }
- );
- #this table is used to replace special chars
- my %umlaute = ("ä" => "ä", "ü" => "ü", "ö" => "ö","Ä" => "Ä", "Ü" => "Ü", "Ö" => "Ö", "ß" => "ß");
- #Init this device
- #This declares the interface to fhem
- #############################
- sub Robonect_Initialize($) {
- my ($hash) = @_;
- $hash->{DefFn} = 'Robonect_Define';
- $hash->{UndefFn} = 'Robonect_Undef';
- $hash->{SetFn} = 'Robonect_Set';
- $hash->{GetFn} = 'Robonect_Get';
- $hash->{AttrFn} = 'Robonect_Attr';
- $hash->{ShutdownFn} = 'Robonect_Shutdown';
- $hash->{ReadyFn} = 'Robonect_Ready';
- $hash->{DbLog_splitFn} = 'Robonect_DbLog_split';
- $hash->{AttrList} = "do_not_notify:1,0 " . #supress any notification (including log)
- "showtime:1,0 " . #shows time instead of received value in state
- "credentials " . #user/password combination for authentication in mower, stored in a credentials file
- "basicAuth " . #user/password combination for authentication in mower
- "pollInterval " . #interval to poll in seconds
- "timeout " . #http-timeout
- "useHealth " . #if true, poll for health
- "$readingFnAttributes "; #standard attributes
- }
- #Define this device
- #Is called at every define
- #############################
- sub Robonect_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t][ \t]*", $def);
- #device name
- my $name = $a[0];
- #set verbose to 5, if debug enabled
- $attr{$name}{verbose} = 5 if ($debug eq 1);
- my $tempStr = join (", ", @a);
- Log3 ($name, 5, "define $name: enter $hash, attributes: $tempStr");
-
- #too less arguments
- #return "wrong syntax - define <name> Robonect <ip-adress> [<user> <password>]" if (int(@a) < 3);
- return "wrong syntax - define <name> Robonect <ip-adress>" if (int(@a) < 3);
- #check IP
- my $ip = $a[2];
- #remove whitespaces
- $ip =~ s/^\s+|\s+$//g;
- #removed IP-check - can also be a name
- #Syntax ok
- #if ($ip =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)
- #{
- # my @octs = split (".", $ip);
- #
- # foreach my $octet (@octs)
- # {
- # return "wrong syntax - $octet has an invalid range. Allowed is 0..255" if (($octet >= 256) or ($octet <= -1));
- # }
- #}
- #else
- #{
- # return "wrong syntax - IP must be supplied correctly <0..254>.<0..254>.<0..254>.<0..254>";
- #}
-
- #wrong syntax for IP
- #return "wrong syntax - IP must be supplied correctly <0..254>.<0..254>.<0..254>.<000..254>" if (int(@a) < 3);
-
- #assign name and port
- $hash->{NAME} = $name;
- $hash->{IP} = $ip;
- #backup name for a later rename
- $hash->{DEVNAME} = $name;
-
- #get first info and launch timer
- InternalTimer(gettimeofday(), "Robonect_GetUpdate", $hash, 0);
- #finally create decice
- #defptr is needed to supress FHEM input
- #removed according Rudis recommendation
- #$modules{Robonect}{defptr}{$name} = $hash;
- #default event-on-changed-reading for all readings
- #removed according Rudis recommendation
- #$attr{$name}{"event-on-change-reading"} = ".*";
- #default poll-interval
- #removed according Rudis recommendation
- #$attr{$name}{"pollInterval"} = 90;
-
- Log3 ($name, 5, "exit define");
- return undef;
- }
- #Release this device
- #Is called at every delete / shutdown
- #############################
- sub Robonect_Undef($$)
- {
- my ($hash, $name) = @_;
- Log3 ($name, 5, "enter undef $name: hash: $hash name: $name");
-
- #kill interval timer
- RemoveInternalTimer($hash);
- #close port
- Robonect_Shutdown ($hash);
-
- #remove module. Refer to DevName, because module may be renamed
- delete $modules{KNX}{defptr}{$hash->{DEVNAME}};
- #removed according to Rudis recommendation
- #remove name
- #delete $hash->{NAME};
- #remove backuped name
- #delete $hash->{DEVNAME};
-
- Log3 ($name, 5, "exit undef");
- return undef;
- }
- #Release this device
- #Is called at every delete / shutdown
- #############################
- sub Robonect_Shutdown($)
- {
- my ($hash) = @_;
-
- #hash may be de-referenced already
- my $name = "robonect-not_named_any_more";
- $name = $hash->{NAME} if (ref($hash) eq "HASH");
-
- Log3 ($name, 5, "enter shutdown $name: hash: $hash name: $name");
- Log3 ($name, 5, "exit shutdown");
- return undef;
- }
- #This function is called from fhem from rime to time
- #############################
- sub Robonect_Ready($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- Log3 ($name, 5, "enter ready $name: hash: $hash name: $name");
- Log3 ($name, 5, "exit ready");
- return undef;
- }
- #Reads info from the mower
- #############################
- sub Robonect_Get($@)
- {
- my ($hash, @a) = @_;
- my $name = $hash->{NAME};
- my $tempStr = join (", ", @a);
- Log3 ($name, 5, "enter get $name: $name hash: $hash, attributes: $tempStr");
- #backup cmd
- my $cmd = $a[1];
- #lower cmd
- $cmd = lc($cmd);
-
- #create response, if cmd is wrong or gui asks
- my $cmdTemp = Robonect_getCmdList ($hash, $cmd, %gets);
- return $cmdTemp if (defined ($cmdTemp));
-
- my ($userName, $passWord) = Robonect_getCredentials ($hash);
-
- #basic url
- my $url = "http://" . $hash->{IP} . "/json?";
- #append userdata, if given
- $url = $url . "user=" . $userName . "&pass=" . $passWord . "&" if (defined ($userName) and defined ($passWord));
- #append command
- #$url = $url . $commands{GET_STATUS};
- $url = $url . "cmd=" . $cmd;
-
- my $httpData;
- $httpData->{url} = $url;
- $httpData->{loglevel} = AttrVal ($name, "verbose", 2);
- $httpData->{loglevel} = 5;
- $httpData->{hideurl} = 0;
- $httpData->{callback} = \&Robonect_callback;
- $httpData->{hash} = $hash;
- #$httpData->{cmd} = $commands{GET_STATUS};
- $httpData->{cmd} = "cmd=" . $cmd;
- $httpData->{timeout} = AttrVal ($name, "timeout", 4);
-
- HttpUtils_NonblockingGet($httpData);
-
- Log3 ($name, 5, "exit get");
-
- my $err = $httpData->{err};
-
- if (defined ($err) and (length ($err) > 0))
- {
- return $err;
- }
- else
- {
- return "update requested";
- }
- }
- #Sends commands to the mower
- #############################
- sub Robonect_Set($@)
- {
- my ($hash, @a) = @_;
- my $name = $hash->{NAME};
- my $tempStr = join (", ", @a);
- Log3 ($name, 5, "enter set $name: $name hash: $hash, attributes: $tempStr");
-
- #backup cmd
- my $cmd = $a[1];
- #lower cmd
- $cmd = lc($cmd);
-
- #create response, if cmd is wrong or gui asks
- my $cmdTemp = Robonect_getCmdList ($hash, $cmd, %sets);
- return $cmdTemp if (defined ($cmdTemp));
-
- my ($userName, $passWord) = Robonect_getCredentials ($hash);
- my $decodedCmd = $commands{SET_MODE}{$cmd};
- #if command is hybernate, do this
- if ($cmd eq lc($HYBERNATE))
- {
- Log3 ($name, 5, "set - got hybernate for set-command");
-
- my $val = lc($a[2]);
- $val = "off" if (!defined ($val));
-
- if ($val =~ m/on/)
- {
- readingsSingleUpdate($hash, $HYBERNATE, "on", 1);
- Log3 ($name, 5, "set - activated hybernate");
- }
- elsif ($val =~ m/off/)
- {
- readingsSingleUpdate($hash, $HYBERNATE, "off", 1);
- Log3 ($name, 5, "set - deactivated hybernate");
- }
- else
- {
- return "only on or off are supported for $HYBERNATE";
- }
- }
- #if command is user
- elsif ($cmd eq lc($USER))
- {
- setKeyValue("ROBONECT_USER_$name", $a[2]);
- Log3 ($name, 5, "set - wrote username");
- }
- #if command is password
- elsif ($cmd eq lc($PW))
- {
- setKeyValue("ROBONECT_PW_$name", $a[2]);
- Log3 ($name, 5, "set - wrote password");
- }
- #else proceed with communication to mower
- #execute it
- elsif (defined ($decodedCmd))
- {
- my $url = "http://" . $hash->{IP} . "/json?";
- #append userdata, if given
- $url = $url . "user=" . $userName . "&pass=" . $passWord . "&" if (defined ($userName) and defined ($passWord));
- #append command
- $url = $url . $decodedCmd;
- #execute for alle "extra" arguments
- for (my $i = 2; $i < @a; $i++)
- {
- my $cmdAttr = $a[$i];
- my ($key, $val) = split (/=/, $cmdAttr);
-
- if (defined ($key) and defined ($val) and (length ($key) > 0) and (length ($val) > 0))
- {
- $url = $url . "&" . $key . "=" . $val;
- Log3 ($name, 5, "set - found option. Key:$key Value:$val")
- }
- else
- {
- Log3 ($name, 1, "set - found incomplete option. Key:$key Value:$val")
- }
- }
-
- Log3 ($name, 5, "set - complete call-string: $url");
-
- my $httpData;
- $httpData->{url} = $url;
- $httpData->{loglevel} = AttrVal ($name, "verbose", 2);
- $httpData->{loglevel} = 5;
- $httpData->{hideurl} = 0;
- $httpData->{callback} = \&Robonect_callback;
- $httpData->{hash} = $hash;
- $httpData->{cmd} = $decodedCmd;
-
- HttpUtils_NonblockingGet($httpData);
-
- return $httpData->{err};
-
- #BUllshit - never gets called
- #Robonect_GetUpdate($hash);
- }
-
- Log3 ($name, 5, "exit set");
-
- return;
- }
- #called on every mod of the attributes
- #############################
- sub Robonect_Attr(@)
- {
- my ($cmd,$name,$attr_name,$attr_value) = @_;
- Log3 ($name, 5, "enter attr $name: $name, attrName: $attr_name");
-
- #if($cmd eq "set")
- #{
- # if(($attr_name eq "debug") and (($attr_value eq "1") or ($attr_value eq "true")))
- # {
- # #todo
- # }
- #}
-
- Log3 ($name, 5, "exit attr");
-
- return undef;
- }
- #Split reading for DBLOG
- #############################
- sub Robonect_DbLog_split($) {
- my ($event) = @_;
- my ($reading, $value, $unit);
- my $tempStr = join (", ", @_);
- Log (5, "splitFn - enter, attributes: $tempStr");
-
- #detect reading - real reading or state?
- my $isReading = "false";
- $isReading = "true" if ($event =~ m/: /);
-
- #split input-string
- my @strings = split (" ", $event);
-
- my $startIndex = undef;
- $unit = "";
-
- return undef if (not defined ($strings[0]));
- #real reading?
- if ($isReading =~ m/true/)
- {
- #first one is always reading
- $reading = $strings[0];
- $reading =~ s/:?$//;
- $startIndex = 1;
- }
- #plain state
- else
- {
- #for reading state nothing is supplied
- $reading = "state";
- $startIndex = 0;
- }
-
- return undef if (not defined ($strings[$startIndex]));
- #per default join all single pieces
- $value = join(" ", @strings[$startIndex..(int(@strings) - 1)]);
-
- #numeric value?
- #if ($strings[$startIndex] =~ /^[+-]?\d*[.,]?\d+/)
- if ($strings[$startIndex] =~ /^[+-]?\d*[.,]?\d+$/)
- {
- $value = $strings[$startIndex];
- #single numeric value? Assume second par is unit...
- if ((defined ($strings[$startIndex + 1])) && !($strings[$startIndex+1] =~ /^[+-]?\d*[.,]?\d+/))
- {
- $unit = $strings[$startIndex + 1] if (defined ($strings[$startIndex + 1]));
- }
- }
- #numeric value?
- #if ($strings[$startIndex] =~ /^[+-]?\d*[.,]?\d+/)
- #{
- # $value = $strings[$startIndex];
- # $unit = $strings[$startIndex + 1] if (defined ($strings[$startIndex + 1]));
- #}
- #string or raw
- #else
- #{
- # $value = join(" ", @strings[$startIndex..(int(@strings) - 1)]);
- #}
-
- Log (5, "splitFn - READING: $reading, VALUE: $value, UNIT: $unit");
-
- return ($reading, $value, $unit);
- }
- #Called on the interval timer, if enabled
- #############################
- sub Robonect_GetUpdate($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- Log3 ($name, 5, "enter update $name: $name");
- #evaluate reading hybernate
- #my $hybernate = $hash->{READINGS}{$HYBERNATE}{VAL};
- my $hybernate = ReadingsVal($name, $HYBERNATE, undef);
-
- Log3 ($name, 5, "XXX: $hybernate");
-
- #supress sending, if hybernate is set
- if (!defined ($hybernate) or ($hybernate =~ m/(off)|[0]/i))
- {
- #get status
- my @callAttr;
- $callAttr[0] = $name;
- $callAttr[1] = "status";
- Robonect_Get ($hash, @callAttr);
-
- #try to poll health, if desired
- my $useHealth = AttrVal($name,"useHealth",undef);
- if (defined ($useHealth) and ($useHealth =~ m/[1]|([oO][nN])/))
- {
- $callAttr[1] = "health";
- Robonect_Get ($hash, @callAttr);
- }
- }
- my $interval = AttrVal($name,"pollInterval",90);
- #reset timer
- InternalTimer(gettimeofday() + $interval, "Robonect_GetUpdate", $hash, 1) if ($interval > 0);
-
- Log3 ($name, 5, "exit update");
- }
- #Private function which handles http-responses
- #############################
- sub Robonect_callback ($)
- {
- my ($param, $err, $data) = @_;
- my $hash = $param->{hash};
- my $name = $hash->{NAME};
-
- #wenn ein Fehler bei der HTTP Abfrage aufgetreten ist
- if($err ne "")
- {
- Log3 ($name, 4, "callback - error while requesting ".$param->{url}." - $err");
- $hash->{LAST_COMM_STATUS} = $err;
- #set reading with failure - notify only, when state has not changed
- readingsSingleUpdate($hash, "state", $OFFLINE, 1);
- }
- #wenn die Abfrage erfolgreich war ($data enthält die Ergebnisdaten des HTTP Aufrufes)
- elsif($data ne "")
- {
- Log3 ($name, 4, "callback - url ".$param->{url}." returned: $data");
-
- #repair V5.0b
- $data =~ s/:"/,"/g;
- $data = "" if (!defined($data));
-
- #execute in eval to be safe - therefore $answer may be undef
- my $answer = undef;
- eval '$answer = decode_json (encode_utf8($data))';
-
- #try to replaye german special chars
- if (defined ($answer) and (length ($answer) > 0))
- {
- my $umlautkeys = join ("|", keys(%umlaute));
- $answer =~ s/($umlautkeys)/$umlaute{$1}/g;
- }
-
- #backup error from eval
- my $evalErr = $@;
-
- if (not defined($answer))
- {
- my $err = "callback - error while decoding content";
- $err = $err . ": " . $evalErr if (defined ($evalErr));
- Log3 ($name, 2, $err);
- readingsSingleUpdate($hash, "fehler_aktuell", "cannot decode content", 1);
- return undef;
- }
-
- Log3 ($name, 4, "callback - url ".$param->{url}." repaired: $data");
-
- my ($key, $value) = Robonect_decodeContent ($hash, $answer, "successful", undef, undef);
-
- $hash->{LAST_CMD} = $param->{cmd};
- $hash->{LAST_COMM_STATUS} = "success: " . $value;
-
- Log3 ($name, 5, "callback - communication ok");
-
- #my %tmp = %$answer;
- #print "answer: ", %tmp, "\n";
-
- #status-readings
- #answer may be undefined due to eval
- if ($answer->{successful} =~ m/(true)|(1)/)
- {
- Log3 ($name, 5, "callback - update readings");
-
- readingsBeginUpdate($hash);
- #($key, $value) = Robonect_decodeContent ($hash, $answer, "successful", undef);
- #readingsBulkUpdate($hash, $key, $value);
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "status", "status", undef);
- if (defined ($value) and !($value =~ m/undef/))
- {
- readingsBulkUpdate($hash, $key, $value);
- readingsBulkUpdate($hash, "state", $value);
- }
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "status", "mode", undef);
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "status", "battery", undef);
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- $value = 0;
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "status", "duration", undef);
- readingsBulkUpdate($hash, $key, sprintf ("%d", $value/3600)) if (defined($value) and ($value =~ m/(?:\d*\.)?\d+/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "status", "hours", undef);
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "timer", "status", undef);
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
-
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "timer", "next", "date");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "timer", "next", "time");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
-
- $value = -95;
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "wlan", "signal", undef);
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
-
- if (defined($value) and ($value =~ m/(?:\d*\.)?\d+/))
- {
- $value = sprintf ("%d", ($value + 95) / 0.6);
- readingsBulkUpdate($hash, $key . "-prozent", $value);
- }
-
- #try to decode health, if desired
- #my $useHealth = AttrVal($name,"useHealth",undef);
- #if (defined ($useHealth) and ($useHealth =~ m/[1]|([oO][nN])/))
- #{
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "alarm", "voltagebattmin");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
-
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "alarm", "voltagebattmax");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "alarm", "temperatureMin");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "alarm", "temperatureMax");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
-
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "alarm", "humidityMax");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
-
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "voltages", "batt");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "climate", "temperature");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- ($key, $value) = Robonect_decodeContent ($hash, $answer, "health", "climate", "humidity");
- readingsBulkUpdate($hash, $key, $value) if (defined ($value) and !($value =~ m/undef/));
- #}
-
- readingsEndUpdate($hash, 1);
- }
-
- #error?
- #answer may be undefined due to eval
- my $errorOccured = $answer->{status}->{status};
- if (defined ($errorOccured) and ($errorOccured =~ m/7/))
- {
- readingsSingleUpdate($hash, "fehler_aktuell", $answer->{error}->{error_message}, 1);
- }
- #no error
- elsif (defined ($errorOccured))
- {
- my $hashref = $hash->{READINGS};
- my %readings = %$hashref;
-
- #delete readings
- foreach my $key (keys %readings)
- {
- #delete $readings{$key} if ($key =~ m/^fehler.*/);
- delete $hash->{READINGS}{$key} if ($key =~ m/^fehler.*/);
- #delete $hash->{READINGS}{$key} if ($key =~ m/^fehler-aktuell.*/);
- }
- }
- }
- }
- #Private function to get json-content
- #############################
- sub Robonect_decodeContent ($$$$$)
- {
- my ($hash, $msg, $key1, $key2, $key3) = @_;
- my $name = $hash->{NAME};
-
- my $rdName = undef;
- my $rdValue = undef;
-
- my $template = undef;
- if (defined ($key2) && defined ($key3))
- {
- $template = $elements{$key1}{$key2}{$key3};
- $rdName = $elements{$key1}{$key2}{ALIAS} . "-" . $template->{ALIAS};
- $rdValue = $msg->{$key1}->{$key2}->{$key3};
- }
- elsif (defined ($key2))
- {
- $template = $elements{$key1}{$key2};
- $rdName = $elements{$key1}{ALIAS} . "-" . $template->{ALIAS};
- $rdValue = $msg->{$key1}->{$key2};
- }
- else
- {
- $template = $elements{$key1};
- $rdValue = $msg->{$key1};
- $rdName = $template->{ALIAS};
- }
-
- $rdValue = "undef" if (not defined ($rdValue));
- $rdValue = $template->{$rdValue} if (defined ($template->{$rdValue}));
-
- Log3 ($name, 5, "decodeContent - NAME: $rdName, VALUE: $rdValue");
-
- return $rdName, $rdValue;
- }
- #Private function to evaluate credentials
- #############################
- sub Robonect_decodeAnswer ($$$)
- {
- my ($hash, $getCmd, @readings) = @_;
- my $name = $hash->{NAME};
-
- my @list;
-
- foreach my $reading (@readings)
- {
- my $answer = undef;
- my $transval = undef;
- my ($header, $key, $value) = undef;
-
- $header = $reading->{header};
- $key = $reading->{key};
- $value = $reading->{value};
-
- if ($header =~ m/robonect/i)
- {
- $answer->{name} = $getCmd . "-" . $elements{$header}{$key}{ALIAS};
- $transval = $elements{$header}{$key}{$value};
- }
- else
- {
- $answer->{name} = $getCmd . "-" . $elements{"robonect"}{$header}{ALIAS} . "-" . $elements{"robonect"}{$header}{$key}{ALIAS};
- $transval = $elements{"robonect"}{$header}{$key}{$value};
- }
-
- if (defined($transval))
- {
- $answer->{value} = $transval;
- }
- else
- {
- $answer->{value} = $value;
- }
-
- #$answer->{name} = $getCmd . "-" . $answer->{name};
-
- Log3 ($name, 5, "decodeAnswer - NAME: $answer->{name}, VALUE: $answer->{value}");
-
- push (@list, $answer);
- }
-
- return @list;
- }
- #Private function to evaluate credentials
- #############################
- sub Robonect_getCredentials ($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my $userName = undef;
- my $passWord = undef;
- #use username and password previously defined with set and stored in "registry"
- my ($errUsr, $user) = getKeyValue("ROBONECT_USER_$name");
- Log3 ($name, 4, "credentials - Error while getting value USER: " . $errUsr) if (defined ($errUsr));
- my ($errPw, $password) = getKeyValue("ROBONECT_PW_$name");
- Log3 ($name, 4, "credentials - Error while getting value PASSWORD: " . $errPw) if (defined ($errPw));
- if (defined ($user) and defined ($password))
- {
- Log3 ($name, 5, "credentials - found with key-value");
- return $userName, $passWord;
- }
-
- #parse basicAuth - overrules getKeyValue
- my $basicAuth = AttrVal ($name, "basicAuth", undef);
- if (defined ($basicAuth))
- {
- #if the string does NOT contain a ":", assume base64-encoded data
- if (not ($basicAuth =~ m/:/))
- {
- $basicAuth = decode_base64 ($basicAuth);
- Log3 ($name, 5, "credentials - found encrypted data");
- }
- #try to split
- my @plainAuth = split (":", $basicAuth);
-
- #found plain authentication
- if (int(@plainAuth) == 2)
- {
- $userName = $plainAuth[0];
- $passWord = $plainAuth[1];
-
- Log3 ($name, 5, "credentials - found plain or decrypted data");
- }
- else
- {
- Log3 ($name, 0, "credentials - user/pw combination not correct");
- }
- }
-
- #parse credential-File - overrules basicAuth ang getKeyValue
- my $credentials = AttrVal ($name, "credentials", undef);
- if(defined($credentials))
- {
- #cannot open file
- if(!open(CFG, $credentials))
- {
- Log3 ($name, 0, "cannot open credentials file: $credentials") ;
- }
- #read it
- else
- {
- my @cfg = <CFG>;
- close(CFG);
- my %creds;
- eval join("", @cfg);
- #extract it
- $userName =~ $creds{$name}{username};
- $passWord =~ $creds{$name}{password};
-
- Log3 ($name, 5, "credentials - found in file");
- }
- }
-
- return $userName, $passWord;
- }
- #Private function to evaluate command-lists
- #############################
- sub Robonect_getCmdList ($$$)
- {
- my ($hash, $cmd, %cmdArray) = @_;
- my $name = $hash->{NAME};
- #return, if cmd is valid
- return undef if (defined ($cmd) and defined ($cmdArray{$cmd}));
-
- #response for gui or the user, if command is invalid
- my $retVal;
- foreach my $mySet (keys %cmdArray)
- {
- #append set-command
- $retVal = $retVal . " " if (defined ($retVal));
- $retVal = $retVal . $mySet;
- #get options
- my $myOpt = $cmdArray{$mySet};
- #append option, if valid
- $retVal = $retVal . ":" . $myOpt if (defined ($myOpt) and (length ($myOpt) > 0));
- $myOpt = "" if (!defined($myOpt));
- #Logging makes me crazy...
- #Log3 ($name, 5, "parse cmd-table - Set:$mySet, Option:$myOpt, RetVal:$retVal");
- }
-
- if (!defined ($retVal))
- {
- $retVal = "error while parsing set-table" ;
- }
- else
- {
- $retVal = "Unknown argument $cmd, choose one of " . $retVal;
- }
-
-
- return $retVal;
- }
- 1;
- =pod
- =begin html
- <a name="Robonect"></a>
- <h3>Robonect</h3>
- <ul>
- <p>Robonect is a after-market wifi-module for robomowers based on the husky G3-control. It was developed by Fabian H. and can be optained at www.robonect.de. This module gives you access to the basic commands. This module will not work without libjson-perl! Do not forget to install it first!</p>
- <p><a name="RobonectDefine"></a> <b>Define</b></p>
- <ul>
- <code>define <name> Robonect <ip-adress or name></code>
-
- <p>Setting Winterschlaf prevents communicating with the mower.</p>
-
- <p>The authentication can be supplied in the definition as plaine text or in a differen way - see the attributes. Per default the status is polled every 90s.</p>
- <p>Example:</p>
- <pre>
- define myMower Robonect 192.168.13.5
- define myMower Robonect myMowersDNSName
- </pre>
- </ul>
-
- <p><a name="RobonectSet"></a> <b>Set</b></p>
- <ul>
- <b>Set</b>
- <ul>
- <li>auto<br>
- Sets the mower to automatic mode. The mower follows the internal timer, until another mode is chosen. The mower can be stopped with stop at any time. After using stop: be aware, that it continues
- mowing only if the timer supplies an active slot AND start is executed before.
- </li>
- <li>manuell<br>
- This sets the mower to manual mode. The internal timer is ignored. Mowing starts with start and ends with stop.
- </li>
- <li>home<br>
- This sends the mower directly home. Until you switch to auto or manuell, no further mowing work is done.
- </li>
- <li>feierabend<br>
- This sends the mower home for the rest of the actual timeslot. At the next active timeslot mowing is continued automatically.
- </li>
- <li>start<br>
- Start mowing in manual mode or in automatic mode at active timer-slot.
- </li>
- <li>stop<br>
- Stops mowing immediately. The mower does not drive home. It stands there, until battery is empty. Use with care!
- </li>
- <li>maehauftrag<br>
- This command starts a single mowing-task. It can be applied as much parameters as you want. For example you can influence start-/stop-time and duration.<br>
- The parameters have to be named according the robonect-API (no doublechecking!).<br>
- <br>
- Example:<br>
- Lauch at 15:00, Duration 120 minutes, do not use a remote-start-point, do not change mode after finishing task
- <pre>
- set myMower maehauftrag start=15:00 duration=120 remotestart=0 after=4
- </pre>
- </li>
- <li>winterschlaf <on, off><br>
- If set to on, no polling is executet. Please use this during winter.
- </li>
- <li>user <user><br>
- One alternative to store authentication: username for robonect-logon is stored in FhemUtils or database (not encrypted).<br
- If set, the attributes regarding authentication are ignored.
- </li>
- <li>password <password><br>
- One alternative to store authentication: password for robonect-logon is stored in FhemUtils or database (not encrypted).<br
- If set, the attributes regarding authentication are ignored.
- </li>
- </ul>
- </ul>
- <p><a name="RobonectGet"></a> <b>Get</b></p>
- <ul>
- <b>Get</b>
- <ul>
- <li>status<br>
- Gets the actual state of the mower - normally not needed, because the status is polled cyclic.
- </li>
- <li>health<br>
- This one gets more detailed information - like voltages and temperatures. It is NOT SUPPORTED BY ALL MOWERS!!!<br>
- If enabled via attribute, health is polled accordingly status.
- </li>
- </ul>
- </ul>
-
- <p><a name="RobonectAttr"></a> <b>Attributes</b></p>
- <ul><br>
- Common attributes:<br>
- <a href="#DbLogInclude">DbLogInclude</a><br>
- <a href="#DbLogExclude">DbLogExclude</a><br>
- <a href="#IODev">IODev</a><br>
- <a href="#alias">alias</a><br>
- <a href="#comment">comment</a><br>
- <a href="#devStateIcon">devStateIcon</a><br>
- <a href="#devStateStyle">devStateStyle</a><br>
- <a href="#do_not_notify">do_not_notify</a><br>
- <a href="#readingFnAttributes">readingFnAttributes</a><br>
- <a href="#event-aggregator">event-aggregator</a><br>
- <a href="#event-min-interval">event-min-interval</a><br>
- <a href="#event-on-change-reading">event-on-change-reading</a><br>
- <a href="#event-on-update-reading">event-on-update-reading</a><br>
- <a href="#eventMap">eventMap</a><br>
- <a href="#group">group</a><br>
- <a href="#icon">icon</a><br>
- <a href="#room">room</a><br>
- <a href="#showtime">showtime</a><br>
- <a href="#sortby">sortby</a><br>
- <a href="#stateFormat">stateFormat</a><br>
- <a href="#userReadings">userReadings</a><br>
- <a href="#userattr">userattr</a><br>
- <a href="#verbose">verbose</a><br>
- <a href="#webCmd">webCmd</a><br>
- <a href="#widgetOverride">widgetOverride</a><br>
- <br>
- </ul>
- <p><a name="RobonectCredentials"></a> <b>credentials</b></p>
- <ul>
- If you supply a valid path to a credentials file, this combination is used to log in at robonect. This mechism overrules basicAuth.
- </ul>
- <p><a name="RobonectBasicAuth"></a> <b>basicAuth</b></p>
- <ul>
- You can supply username and password plain or base-64-encoded. For a base64-encoder, use google.
- <p>Example:</p>
- <pre>
- define myMower Robonect 192.168.5.1
- attr myMower basicAuth me:mySecret
- </pre>
- <pre>
- define myMower Robonect 192.168.5.1
- attr myMower basicAuth bWU6bXlTZWNyZXQ=
- </pre>
- </ul>
- <p><a name="RobonectPollInterval"></a> <b>pollInterval</b></p>
- <ul>
- Supplies the interval top poll the robonect in seconds. Per default 90s is set.
- </ul>
-
- <p><a name="RobonectTimeout"></a> <b>timeout</b></p>
- <ul>
- Timeout for httpData to recive data. Default is 4s.
- </ul>
-
- <p><a name="RobonectHealth"></a> <b>useHealth</b></p>
- <ul>
- If set to 1, the health-status of the mower will be polled. Be aware NOT ALL MOWERS ARE SUPPORTED!<br>
- Please refer to logfile or LAST_COMM_STATUS if the function does not seem to be working.
- </ul>
- </ul>
- =end html
- =device
- =item summary Communicates to HW-module robonect
- =item summary_DE Kommuniziert mit dem HW-Modul Robonect
- =begin html_DE
- <a name="Robonect"></a>
- <h3>Robonect</h3>
- <ul>
- <p>Robonect ist ein Nachr¨stmodul für automower, die auf der Husky-G3-Steuerung basieren. Es wurde von Fabian H. entwickelt und kann unter www.robonect.de bezogen werden. Dieses Modul gibt Euch Zugriff auf die nötigsten Kommandos. Dieses Modul benötigt libjson-perl. Bitte NICHT VERGESSEN zu installieren!</p>
- <p><a name="RobonectDefine"></a> <b>Define</b></p>
- <ul>
- <code>define <name> Robonect <IP-Adresse oder Name></code>
-
- <p>Mit gesetztem Winterschlaf wird die Kommunikation zum Mäher unterbunden.</p>
-
- <p>Die Zugangsinformationen können im Klartext bei der Definition angegeben werden. Wahlweise auch per Attribut. Standardmäßig wird der Status vom RObonect alle 90s aktualisiert.</p>
- <p>Beispiel:</p>
- <pre>
- define myMower Robonect 192.168.13.5
- define myMower Robonect myMowersDNSName
- </pre>
- </ul>
-
- <p><a name="RobonectSet"></a> <b>Set</b></p>
- <ul>
- <b>Set</b>
- <ul>
- <li>auto<br>
- Dies versetzt den Mäher in den Automatikmodus. Der Mäher reagiert nur auf den internen Timer, bis eine andere Betriebsart gewählt wird. Der Mäher kann mit Stop jederzeit
- angehalten werden. Es wird erst wieder begonnen zu mähen, wenn der Timer (wieder) ein aktives Fenster hat UND Start gesendet wurde.
- </li>
- <li>manuell<br>
- Dies versetzt den Mäher in den manuellen modus. Der interne Timer wird nicht beachtet. Der Mäher reagiert nur auf Start oder Stopp Befehle von FHEM.
- </li>
- <li>home<br>
- Dies schickt den Mäher direkt nach hause. Weiteres mähen wird verhindert, bis auf manuell oder auto umgeschalten wird.
- </li>
- <li>feierabend<br>
- Dies schickt den Mäher für den aktuellen Timerslot direkt nach hause. Beim nächsten aktiven Timerslot wird weitergemäht.
- </li>
- <li>start<br>
- Startet den Mähvorgang im manuellen Modus oder im Automatikmodus bei aktivem Zeitslot.
- </li>
- <li>stop<br>
- Beendet den Mähvorgang. Der Mäher fährt nicht nach Hause und beginnt nicht wieder zu mähen. Er bleibt stehen, bis die Batterie leer ist. Nur mit Bedacht benutzen!
- </li>
- <li>maehauftrag<br>
- Hiermit wird ein (einmaliger) Auftrag an den Mäher abgesetzt. Es können beliebig viele Parameter mitgegeben werden. So kann zum Beispiel der Modus nach dem Auftrag,
- sowie Start- oder Stoppzeit beeinflusst werden.<br>
- Die Parameter müssen wie in der API des Robonect beschrieben lauten. Es erfolgt keine syntaktische Prüfung!<br>
- <br>
- Beispiel:<br>
- Startzeit 15 Uhr, Dauer 120 Minuten, keinen Fernstartpunkt verwenden, keine Betriebsartenumschaltung nach Auftragsende
- <pre>
- set myMower maehauftrag start=15:00 duration=120 remotestart=0 after=4
- </pre>
- </li>
- <li>winterschlaf <on, off><br>
- Wenn aktiviert, wird das Pollen unterbunden. Empfiehlt sich für die Winterpause.
- </li>
- <li>user <user><br>
- Alternativ zur Angabe per Argument kann per Set-Befehl der Benutzername zur Anmeldung am Robonect hier einmalig eingegeben werden. Er wird im Klartext in FhemUtils oder der DB gespeichert.<br>
- Wenn angegeben, werden die Attribute zur Authentisierung ignoriert.
- </li>
- <li>password <password><br>
- Alternativ zur Angabe per Argument kann per Set-Befehl das Passwort zur Anmeldung am Robonect hier einmalig eingegeben werden. Er wird im Klartext in FhemUtils oder der DB gespeichert.<br>
- Wenn angegeben, werden die Attribute zur Authentisierung ignoriert.
- </li>
- </ul>
- </ul>
- <p><a name="RobonectGet"></a> <b>Get</b></p>
- <ul>
- <b>Get</b>
- <ul>
- <li>status<br>
- Holt den aktuellen Status des Mähers. Wird normalerweise nicht benötigt, da automatisch gepolled wird.
- </li>
- <li>health<br>
- Mit diesem Kommando können detailliertere Informationen vom Mäher gelesen werden. Beispielsweise sind einge Spannungen und Umweltbedingungen verfügbar.<br>
- Es werden NICHT ALLE MÄHER UNTERSTÜTZT!!!
- Wenn das entsprechende Attribut gesetzt ist, wird health analog status gepolled.
- This one gets more detailed information - like voltages and temperatures. It is NOT SUPPORTED BY ALL MOWERS!!!<br>
- If enabled via attribute, health is polled accordingly status.
- </li>
- </ul>
- </ul>
-
- <p><a name="RobonectAttr"></a> <b>Attributes</b></p>
- <ul><br>
- Common attributes:<br>
- <a href="#DbLogInclude">DbLogInclude</a><br>
- <a href="#DbLogExclude">DbLogExclude</a><br>
- <a href="#IODev">IODev</a><br>
- <a href="#alias">alias</a><br>
- <a href="#comment">comment</a><br>
- <a href="#devStateIcon">devStateIcon</a><br>
- <a href="#devStateStyle">devStateStyle</a><br>
- <a href="#do_not_notify">do_not_notify</a><br>
- <a href="#readingFnAttributes">readingFnAttributes</a><br>
- <a href="#event-aggregator">event-aggregator</a><br>
- <a href="#event-min-interval">event-min-interval</a><br>
- <a href="#event-on-change-reading">event-on-change-reading</a><br>
- <a href="#event-on-update-reading">event-on-update-reading</a><br>
- <a href="#eventMap">eventMap</a><br>
- <a href="#group">group</a><br>
- <a href="#icon">icon</a><br>
- <a href="#room">room</a><br>
- <a href="#showtime">showtime</a><br>
- <a href="#sortby">sortby</a><br>
- <a href="#stateFormat">stateFormat</a><br>
- <a href="#userReadings">userReadings</a><br>
- <a href="#userattr">userattr</a><br>
- <a href="#verbose">verbose</a><br>
- <a href="#webCmd">webCmd</a><br>
- <a href="#widgetOverride">widgetOverride</a><br>
- <br>
- </ul>
- <p><a name="RobonectCredentials"></a> <b>credentials</b></p>
- <ul>
- Hier kann ein Link auf ein credentials-file angegeben werden. Die Zugansinformationen werden dann aus der Datei geholt. Dieser Mechanismus überschreibt basicAuth.
- </ul>
- <p><a name="RobonectBasicAuth"></a> <b>basicAuth</b></p>
- <ul>
- Hier werden die Zugangsinformationen entweder im Klartext oder base-64-codiert übergeben. Base64-encoder gibts bei google.
- <p>Example:</p>
- <pre>
- define myMower Robonect 192.168.5.1
- attr myMower basicAuth me:mySecret
- </pre>
- <pre>
- define myMower Robonect 192.168.5.1
- attr myMower basicAuth bWU6bXlTZWNyZXQ=
- </pre>
- </ul>
- <p><a name="RobonectPollInterval"></a> <b>pollInterval</b></p>
- <ul>
- Hier kann das polling-interval in Sekunden angegeben werden. Default sind 90s.
- </ul>
-
- <p><a name="RobonectTimeout"></a> <b>timeout</b></p>
- <ul>
- Für das holen der Daten per Wlan kann hier ein Timeout angegeben werden. Default sind 4s.
- </ul>
- <p><a name="RobonectHealth"></a> <b>useHealth</b></p>
- <ul>
- Wenn dieses Attribut auf 1 gesetzt wird, wird der health-status analog dem normalen Status gepolled.<br>
- Bitte beachtet, dass NICHT ALLE MÄHER UNTERSTÜTZT WERDEN!
- Wenn die Funktion nicht gegeben zu sein scheint, bitte den LAST_COMM_STATUS und das Logfile beachten.
- </ul>
- </ul>
- =end html_DE
- =cut
|