| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935 |
- ###############################################################################
- #
- # (c) 2018 Copyright: Dr. Dennis Krannich (blog at krannich dot de)
- # All rights reserved
- #
- # This script is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # any later version.
- #
- # The GNU General Public License can be found at
- # http://www.gnu.org/copyleft/gpl.html.
- # A copy is found in the textfile GPL.txt and important notices to the license
- # from the author is found in LICENSE.txt distributed with these scripts.
- #
- # This script is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- #
- # $Id: 74_HusqvarnaAutomower.pm 16888 2018-06-19 21:07:42Z krannich $
- #
- ################################################################################
- package main;
- my $missingModul = "";
- use strict;
- use warnings;
- use Time::Local;
- use JSON;
- use HttpUtils;
- use Blocking;
- eval "use JSON;1" or $missingModul .= "JSON ";
- my $version = "0.1";
- use constant AUTHURL => "https://iam-api.dss.husqvarnagroup.net/api/v3/";
- use constant APIURL => "https://amc-api.dss.husqvarnagroup.net/app/v1/";
- ##############################################################
- #
- # Declare functions
- #
- ##############################################################
- sub HusqvarnaAutomower_Initialize($);
- sub HusqvarnaAutomower_Define($$);
- sub HusqvarnaAutomower_Notify($$);
- sub HusqvarnaAutomower_Attr(@);
- sub HusqvarnaAutomower_Set($@);
- sub HusqvarnaAutomower_Undef($$);
- sub HusqvarnaAutomower_CONNECTED($@);
- sub HusqvarnaAutomower_CMD($$);
- ##############################################################
- sub HusqvarnaAutomower_Initialize($) {
- my ($hash) = @_;
-
- $hash->{SetFn} = "HusqvarnaAutomower_Set";
- $hash->{DefFn} = "HusqvarnaAutomower_Define";
- $hash->{UndefFn} = "HusqvarnaAutomower_Undef";
- $hash->{NotifyFn} = "HusqvarnaAutomower_Notify";
- $hash->{AttrFn} = "HusqvarnaAutomower_Attr";
- $hash->{AttrList} = "username " .
- "password " .
- "mower " .
- "language " .
- "interval " .
- $readingFnAttributes;
- foreach my $d(sort keys %{$modules{HusqvarnaAutomower}{defptr}}) {
- my $hash = $modules{HusqvarnaAutomower}{defptr}{$d};
- $hash->{HusqvarnaAutomower}{version} = $version;
- }
- }
- sub HusqvarnaAutomower_Define($$){
- my ( $hash, $def ) = @_;
- my @a = split( "[ \t]+", $def );
- my $name = $a[0];
- return "too few parameters: define <NAME> HusqvarnaAutomower" if( @a < 1 ) ;
- return "Cannot define HusqvarnaAutomower device. Perl modul $missingModul is missing." if ( $missingModul );
- %$hash = (%$hash,
- NOTIFYDEV => "global,$name",
- HusqvarnaAutomower => {
- CONNECTED => 0,
- version => $version,
- token => '',
- provider => '',
- user_id => '',
- mower_id => '',
- mower_name => '',
- mower_model => '',
- mower_battery => 0,
- mower_status => '',
- mower_mode => '',
- mower_cuttingMode => '',
- mower_lastLatitude => 0,
- mower_lastLongitude => 0,
- mower_nextStart => 0,
- mower_nextStartSource => '',
- mower_restrictedReason => '',
- mower => 0,
- username => '',
- language => 'DE',
- password => '',
- interval => 300,
- expires => time(),
- },
- );
-
- $attr{$name}{room} = "HusqvarnaAutomower" if( !defined( $attr{$name}{room} ) );
-
- HusqvarnaAutomower_CONNECTED($hash,'initialized');
- return undef;
- }
- sub HusqvarnaAutomower_Notify($$) {
-
- my ($hash,$dev) = @_;
- my ($name) = ($hash->{NAME});
-
- if (AttrVal($name, "disable", 0)) {
- Log3 $name, 5, "Device '$name' is disabled, do nothing...";
- HusqvarnaAutomower_CONNECTED($hash,'disabled');
- return undef;
- }
- my $devname = $dev->{NAME};
- my $devtype = $dev->{TYPE};
- my $events = deviceEvents($dev,1);
- return if (!$events);
-
- $hash->{HusqvarnaAutomower}->{updateStartTime} = time();
-
- if ( $devtype eq 'Global') {
- if (
- grep /^INITIALIZED$/,@{$events}
- or grep /^REREADCFG$/,@{$events}
- or grep /^DEFINED.$name$/,@{$events}
- or grep /^MODIFIED.$name$/,@{$events}
- ) {
- HusqvarnaAutomower_APIAuth($hash);
- }
- }
-
- if ( $devtype eq 'HusqvarnaAutomower') {
- if ( grep(/^state:.authenticated$/, @{$events}) ) {
- HusqvarnaAutomower_getMower($hash);
- }
-
- if ( grep(/^state:.connected$/, @{$events}) ) {
- HusqvarnaAutomower_DoUpdate($hash);
- }
-
- if ( grep(/^state:.disconnected$/, @{$events}) ) {
- Log3 $name, 3, "Reconnecting...";
- HusqvarnaAutomower_APIAuth($hash);
- }
- }
-
- return undef;
- }
- sub HusqvarnaAutomower_Attr(@) {
-
- my ( $cmd, $name, $attrName, $attrVal ) = @_;
- my $hash = $defs{$name};
-
- if( $attrName eq "disable" ) {
- if( $cmd eq "set" and $attrVal eq "1" ) {
- RemoveInternalTimer($hash);
- readingsSingleUpdate ( $hash, "state", "disable", 1 );
- Log3 $name, 5, "$name - disabled";
- }
- elsif( $cmd eq "del" ) {
- readingsSingleUpdate ( $hash, "state", "active", 1 );
- Log3 $name, 5, "$name - enabled";
- }
- }
-
- elsif( $attrName eq "username" ) {
- if( $cmd eq "set" ) {
- $hash->{HusqvarnaAutomower}->{username} = $attrVal;
- Log3 $name, 5, "$name - username set to " . $hash->{HusqvarnaAutomower}->{username};
- }
- }
- elsif( $attrName eq "password" ) {
- if( $cmd eq "set" ) {
- $hash->{HusqvarnaAutomower}->{password} = $attrVal;
- Log3 $name, 5, "$name - password set to " . $hash->{HusqvarnaAutomower}->{password};
- }
- }
- elsif( $attrName eq "language" ) {
- if( $cmd eq "set" ) {
- $hash->{HusqvarnaAutomower}->{language} = $attrVal;
- Log3 $name, 5, "$name - language set to " . $hash->{HusqvarnaAutomower}->{language};
- }
- }
-
- elsif( $attrName eq "mower" ) {
- if( $cmd eq "set" ) {
- $hash->{HusqvarnaAutomower}->{mower} = $attrVal;
- Log3 $name, 5, "$name - mower set to " . $hash->{HusqvarnaAutomower}->{mower};
- }
- elsif( $cmd eq "del" ) {
- $hash->{HusqvarnaAutomower}->{mower} = 0;
- Log3 $name, 5, "$name - deleted mower and set to default: 0";
- }
- }
- elsif( $attrName eq "interval" ) {
- if( $cmd eq "set" ) {
- return "Interval must be greater than 0"
- unless($attrVal > 0);
- $hash->{HusqvarnaAutomower}->{interval} = $attrVal;
- RemoveInternalTimer($hash);
- InternalTimer( time() + $hash->{HusqvarnaAutomower}->{interval}, "HusqvarnaAutomower_DoUpdate", $hash, 0 );
- Log3 $name, 5, "$name - set interval: $attrVal";
- }
- elsif( $cmd eq "del" ) {
- $hash->{HusqvarnaAutomower}->{interval} = 300;
- RemoveInternalTimer($hash);
- InternalTimer( time() + $hash->{HusqvarnaAutomower}->{interval}, "HusqvarnaAutomower_DoUpdate", $hash, 0 );
- Log3 $name, 5, "$name - deleted interval and set to default: 300";
- }
- }
- return undef;
- }
- sub HusqvarnaAutomower_Undef($$){
- my ( $hash, $arg ) = @_;
- my $name = $hash->{NAME};
- my $deviceId = $hash->{DEVICEID};
- delete $modules{HusqvarnaAutomower}{defptr}{$deviceId};
- RemoveInternalTimer($hash);
- return undef;
- }
- sub HusqvarnaAutomower_Set($@){
- my ($hash,@a) = @_;
- return "\"set $hash->{NAME}\" needs at least an argument" if ( @a < 2 );
- my ($name,$setName,$setVal,$setVal2,$setVal3) = @a;
- Log3 $name, 3, "$name: set called with $setName " . ($setVal ? $setVal : "") if ($setName ne "?");
- if (HusqvarnaAutomower_CONNECTED($hash) eq 'disabled' && $setName !~ /clear/) {
- return "Unknown argument $setName, choose one of clear:all,readings";
- Log3 $name, 3, "$name: set called with $setName but device is disabled!" if ($setName ne "?");
- return undef;
- }
- if ($setName !~ /start|stop|park|update/) {
- return "Unknown argument $setName, choose one of start stop park update";
- }
-
- if ($setName eq 'update') {
- RemoveInternalTimer($hash);
- HusqvarnaAutomower_DoUpdate($hash);
- }
-
- if (HusqvarnaAutomower_CONNECTED($hash)) {
- if ($setName eq 'start') {
- HusqvarnaAutomower_CMD($hash,'START');
-
- } elsif ($setName eq 'stop') {
- HusqvarnaAutomower_CMD($hash,'STOP');
-
- } elsif ($setName eq 'park') {
- HusqvarnaAutomower_CMD($hash,'PARK');
-
- }
- }
-
- return undef;
- }
- ##############################################################
- #
- # API AUTHENTICATION
- #
- ##############################################################
- sub HusqvarnaAutomower_APIAuth($) {
- my ($hash, $def) = @_;
- my $name = $hash->{NAME};
-
- my $username = $hash->{HusqvarnaAutomower}->{username};
- my $password = $hash->{HusqvarnaAutomower}->{password};
-
- my $header = "Content-Type: application/json\r\nAccept: application/json";
- my $json = ' {
- "data" : {
- "type" : "token",
- "attributes" : {
- "username" : "' . $username. '",
- "password" : "' . $password. '"
- }
- }
- }';
- HttpUtils_NonblockingGet({
- url => AUTHURL . "token",
- timeout => 5,
- hash => $hash,
- method => "POST",
- header => $header,
- data => $json,
- callback => \&HusqvarnaAutomower_APIAuthResponse,
- });
-
- }
- sub HusqvarnaAutomower_APIAuthResponse($) {
- my ($param, $err, $data) = @_;
- my $hash = $param->{hash};
- my $name = $hash->{NAME};
- if($err ne "") {
- HusqvarnaAutomower_CONNECTED($hash,'error');
- Log3 $name, 5, "error while requesting ".$param->{url}." - $err";
-
- } elsif($data ne "") {
-
- my $result = decode_json($data);
- if ($result->{errors}) {
- HusqvarnaAutomower_CONNECTED($hash,'error');
- Log3 $name, 5, "Error: " . $result->{errors}[0]->{detail};
-
- } else {
- Log3 $name, 5, "$data";
- $hash->{HusqvarnaAutomower}->{token} = $result->{data}{id};
- $hash->{HusqvarnaAutomower}->{provider} = $result->{data}{attributes}{provider};
- $hash->{HusqvarnaAutomower}->{user_id} = $result->{data}{attributes}{user_id};
- $hash->{HusqvarnaAutomower}->{expires} = time() + $result->{data}{attributes}{expires_in};
-
- # set Readings
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,'token',$hash->{HusqvarnaAutomower}->{token} );
- readingsBulkUpdate($hash,'provider',$hash->{HusqvarnaAutomower}->{provider} );
- readingsBulkUpdate($hash,'user_id',$hash->{HusqvarnaAutomower}->{user_id} );
-
- my $expire_date = strftime("%Y-%m-%d %H:%M:%S", localtime($hash->{HusqvarnaAutomower}->{expires}));
- readingsBulkUpdate($hash,'expires',$expire_date );
- readingsEndUpdate($hash, 1);
-
- HusqvarnaAutomower_CONNECTED($hash,'authenticated');
- }
-
- }
- }
- sub HusqvarnaAutomower_CONNECTED($@) {
- my ($hash,$set) = @_;
- if ($set) {
- $hash->{HusqvarnaAutomower}->{CONNECTED} = $set;
- RemoveInternalTimer($hash);
- %{$hash->{updateDispatch}} = ();
- if (!defined($hash->{READINGS}->{state}->{VAL}) || $hash->{READINGS}->{state}->{VAL} ne $set) {
- readingsSingleUpdate($hash,"state",$set,1);
- }
- return undef;
- } else {
- if ($hash->{HusqvarnaAutomower}->{CONNECTED} eq 'disabled') {
- return 'disabled';
- }
- elsif ($hash->{HusqvarnaAutomower}->{CONNECTED} eq 'connected') {
- return 1;
- } else {
- return 0;
- }
- }
- }
- ##############################################################
- #
- # UPDATE FUNCTIONS
- #
- ##############################################################
- sub HusqvarnaAutomower_DoUpdate($) {
- my ($hash) = @_;
- my ($name,$self) = ($hash->{NAME},HusqvarnaAutomower_Whoami());
- Log3 $name, 3, "doUpdate() called.";
- if (HusqvarnaAutomower_CONNECTED($hash) eq "disabled") {
- Log3 $name, 3, "$name - Device is disabled.";
- return undef;
- }
- if (time() >= $hash->{HusqvarnaAutomower}->{expires} ) {
- Log3 $name, 3, "LOGIN TOKEN MISSING OR EXPIRED";
- HusqvarnaAutomower_CONNECTED($hash,'disconnected');
- } elsif ($hash->{HusqvarnaAutomower}->{CONNECTED} eq 'connected') {
- Log3 $name, 3, "Update with device: " . $hash->{HusqvarnaAutomower}->{mower_id};
- HusqvarnaAutomower_getMowerStatus($hash);
- InternalTimer( time() + $hash->{HusqvarnaAutomower}->{interval}, $self, $hash, 0 );
- }
- }
- ##############################################################
- #
- # GET MOWERS
- #
- ##############################################################
- sub HusqvarnaAutomower_getMower($) {
- my ($hash) = @_;
- my ($name) = $hash->{NAME};
- my $token = $hash->{HusqvarnaAutomower}->{token};
- my $provider = $hash->{HusqvarnaAutomower}->{provider};
- my $header = "Content-Type: application/json\r\nAccept: application/json\r\nAuthorization: Bearer " . $token . "\r\nAuthorization-Provider: " . $provider;
- HttpUtils_NonblockingGet({
- url => APIURL . "mowers",
- timeout => 5,
- hash => $hash,
- method => "GET",
- header => $header,
- callback => \&HusqvarnaAutomower_getMowerResponse,
- });
-
- return undef;
- }
- sub HusqvarnaAutomower_getMowerResponse($) {
-
- my ($param, $err, $data) = @_;
- my $hash = $param->{hash};
- my $name = $hash->{NAME};
- if($err ne "") {
- Log3 $name, 5, "error while requesting ".$param->{url}." - $err";
-
- } elsif($data ne "") {
-
- if ($data eq "[]") {
- Log3 $name, 3, "Please register an automower first";
- $hash->{HusqvarnaAutomower}->{mower_id} = "none";
- # STATUS LOGGEDIN MUST BE REMOVED
- HusqvarnaAutomower_CONNECTED($hash,'connected');
- } else {
- Log3 $name, 5, "Automower(s) found";
- Log3 $name, 5, $data;
-
- my $result = decode_json($data);
- my $mower = $hash->{HusqvarnaAutomower}->{mower};
- Log3 $name, 5, $result->[$mower]->{'name'};
-
- # MOWER DATA
- my $mymower = $result->[$mower];
- $hash->{HusqvarnaAutomower}->{mower_id} = $mymower->{'id'};
- $hash->{HusqvarnaAutomower}->{mower_name} = $mymower->{'name'};
- $hash->{HusqvarnaAutomower}->{mower_model} = $mymower->{'model'};
- # MOWER STATUS
- my $mymowerStatus = $mymower->{'status'};
- $hash->{HusqvarnaAutomower}->{mower_battery} = $mymowerStatus->{'batteryPercent'};
- $hash->{HusqvarnaAutomower}->{mower_status} = $mymowerStatus->{'mowerStatus'}->{'activity'};
- $hash->{HusqvarnaAutomower}->{mower_mode} = $mymowerStatus->{'operatingMode'};
-
- $hash->{HusqvarnaAutomower}->{mower_nextStart} = HusqvarnaAutomower_Correct_Localtime( $mymowerStatus->{'nextStartTimestamp'} );
-
- HusqvarnaAutomower_CONNECTED($hash,'connected');
- }
-
- readingsBeginUpdate($hash);
- #readingsBulkUpdate($hash,$reading,$value);
- readingsBulkUpdate($hash, "mower_id", $hash->{HusqvarnaAutomower}->{mower_id} );
- readingsBulkUpdate($hash, "mower_name", $hash->{HusqvarnaAutomower}->{mower_name} );
- readingsBulkUpdate($hash, "mower_battery", chop($hash->{HusqvarnaAutomower}->{mower_battery}) );
- readingsBulkUpdate($hash, "mower_status", $hash->{HusqvarnaAutomower}->{mower_status} );
- readingsBulkUpdate($hash, "mower_mode", HusqvarnaAutomower_ToGerman($hash, $hash->{HusqvarnaAutomower}->{mower_mode} ));
- my $nextStartTimestamp = strftime("%Y-%m-%d %H:%M:%S", localtime($hash->{HusqvarnaAutomower}->{mower_nextStart}) );
- readingsBulkUpdate($hash, "mower_nextStart", $nextStartTimestamp );
-
- readingsEndUpdate($hash, 1);
-
- }
-
- return undef;
- }
- sub HusqvarnaAutomower_getMowerStatus($) {
- my ($hash) = @_;
- my ($name) = $hash->{NAME};
- my $token = $hash->{HusqvarnaAutomower}->{token};
- my $provider = $hash->{HusqvarnaAutomower}->{provider};
- my $header = "Content-Type: application/json\r\nAccept: application/json\r\nAuthorization: Bearer " . $token . "\r\nAuthorization-Provider: " . $provider;
- my $mymower_id = $hash->{HusqvarnaAutomower}->{mower_id};
- HttpUtils_NonblockingGet({
- url => APIURL . "mowers/" . $mymower_id . "/status",
- timeout => 5,
- hash => $hash,
- method => "GET",
- header => $header,
- callback => \&HusqvarnaAutomower_getMowerStatusResponse,
- });
-
- return undef;
- }
- sub HusqvarnaAutomower_getMowerStatusResponse($) {
-
- my ($param, $err, $data) = @_;
- my $hash = $param->{hash};
- my $name = $hash->{NAME};
- if($err ne "") {
- Log3 $name, 5, "error while requesting ".$param->{url}." - $err";
-
- } elsif($data ne "") {
-
- Log3 $name, 5, $data;
- my $result = decode_json($data);
-
- $hash->{HusqvarnaAutomower}->{mower_battery} = $result->{'batteryPercent'};
- $hash->{HusqvarnaAutomower}->{mower_status} = HusqvarnaAutomower_ToGerman($hash, $result->{'mowerStatus'}->{'activity'});
- $hash->{HusqvarnaAutomower}->{mower_mode} = HusqvarnaAutomower_ToGerman($hash, $result->{'operatingMode'});
- $hash->{HusqvarnaAutomower}->{mower_nextStart} = HusqvarnaAutomower_Correct_Localtime( $result->{'nextStartTimestamp'} );
-
- $hash->{HusqvarnaAutomower}->{mower_nextStartSource} = HusqvarnaAutomower_ToGerman($hash, $result->{'nextStartSource'});
- $hash->{HusqvarnaAutomower}->{mower_restrictedReason} = HusqvarnaAutomower_ToGerman($hash, $result->{'mowerStatus'}->{'restrictedReason'});
-
- $hash->{HusqvarnaAutomower}->{mower_cuttingMode} = HusqvarnaAutomower_ToGerman($hash, $result->{'mowerStatus'}->{'mode'});
-
- $hash->{HusqvarnaAutomower}->{mower_lastLatitude} = $result->{'lastLocations'}->[0]->{'latitude'};
- $hash->{HusqvarnaAutomower}->{mower_lastLongitude} = $result->{'lastLocations'}->[0]->{'longitude'};
- readingsBeginUpdate($hash);
-
- readingsBulkUpdate($hash, "mower_battery", $hash->{HusqvarnaAutomower}->{mower_battery} );
- readingsBulkUpdate($hash, "mower_status", $hash->{HusqvarnaAutomower}->{mower_status} );
- readingsBulkUpdate($hash, "mower_mode", $hash->{HusqvarnaAutomower}->{mower_mode} );
- my $nextStartTimestamp = strftime("%Y-%m-%d %H:%M", localtime($hash->{HusqvarnaAutomower}->{mower_nextStart}));
- if ($nextStartTimestamp eq "1969-12-31 23:00") { $nextStartTimestamp = "-"; }
-
- if (
- strftime("%Y-%m-%d", localtime($hash->{HusqvarnaAutomower}->{mower_nextStart}) )
- eq
- strftime("%Y-%m-%d", localtime() )
- ) {
- $nextStartTimestamp = HusqvarnaAutomower_ToGerman($hash, "Today at") . " " . strftime("%H:%M", localtime($hash->{HusqvarnaAutomower}->{mower_nextStart}));
- } elsif (
- strftime("%Y-%m-%d", localtime($hash->{HusqvarnaAutomower}->{mower_nextStart}) )
- eq
- strftime("%Y-%m-%d", localtime(time + 86400) )
- ) {
- $nextStartTimestamp = HusqvarnaAutomower_ToGerman($hash, "Tomorrow at") . " " . strftime("%H:%M", localtime($hash->{HusqvarnaAutomower}->{mower_nextStart}));
- } elsif ($nextStartTimestamp ne "-") {
- my @c_time = split(" ", $nextStartTimestamp);
- my $c_date = join("." => reverse split('-', (split(' ',$nextStartTimestamp))[0]));
- $nextStartTimestamp = $c_date . " " . HusqvarnaAutomower_ToGerman($hash, "at") . " " . $c_time[1];
-
- }
- readingsBulkUpdate($hash, "mower_nextStart", $nextStartTimestamp );
-
- readingsBulkUpdate($hash, "mower_nextStartSource", $hash->{HusqvarnaAutomower}->{mower_nextStartSource} );
- readingsBulkUpdate($hash, "mower_restrictedReason", $hash->{HusqvarnaAutomower}->{mower_restrictedReason} );
- readingsBulkUpdate($hash, "mower_cuttingMode", $hash->{HusqvarnaAutomower}->{mower_cuttingMode} );
- readingsBulkUpdate($hash, "mower_lastLatitude", $hash->{HusqvarnaAutomower}->{mower_lastLatitude} );
- readingsBulkUpdate($hash, "mower_lastLongitude", $hash->{HusqvarnaAutomower}->{mower_lastLongitude} );
-
- readingsEndUpdate($hash, 1);
-
- }
-
- return undef;
- }
- ##############################################################
- #
- # SEND COMMAND
- #
- ##############################################################
- sub HusqvarnaAutomower_CMD($$) {
- my ($hash,$cmd) = @_;
- my $name = $hash->{NAME};
-
- # valid commands ['PARK', 'STOP', 'START']
- my $token = $hash->{HusqvarnaAutomower}->{token};
- my $provider = $hash->{HusqvarnaAutomower}->{provider};
- my $mower_id = $hash->{HusqvarnaAutomower}->{mower_id};
- my $header = "Content-Type: application/json\r\nAccept: application/json\r\nAuthorization: Bearer " . $token . "\r\nAuthorization-Provider: " . $provider;
-
- Log3 $name, 5, "cmd: " . $cmd;
- my $json = '{"action": "' . $cmd . '"}';
- HttpUtils_NonblockingGet({
- url => APIURL . "mowers/". $mower_id . "/control",
- timeout => 5,
- hash => $hash,
- method => "POST",
- header => $header,
- data => $json,
- callback => \&HusqvarnaAutomower_CMDResponse,
- });
-
- }
- sub HusqvarnaAutomower_CMDResponse($) {
- my ($param, $err, $data) = @_;
- my $hash = $param->{hash};
- my $name = $hash->{NAME};
- if($err ne "") {
- HusqvarnaAutomower_CONNECTED($hash,'error');
- Log3 $name, 5, "error while requesting ".$param->{url}." - $err";
-
- } elsif($data ne "") {
-
- my $result = decode_json($data);
- if ($result->{errors}) {
- HusqvarnaAutomower_CONNECTED($hash,'error');
- Log3 $name, 5, "Error: " . $result->{errors}[0]->{detail};
-
- } else {
- Log3 $name, 5, $data;
-
- }
-
- }
- }
- ###############################################################################
- sub HusqvarnaAutomower_Correct_Localtime($) {
-
- my ($time) = @_;
- my ($dst) = (localtime)[8]; # fetch daylight savings time flag
- if ($dst) {
- return $time - ( 2 * 3600 );
- } else {
- return $time - ( 1 * 3600 );
- }
-
- }
- sub HusqvarnaAutomower_ToGerman($$) {
- my ($hash,$readingValue) = @_;
- my $name = $hash->{NAME};
-
- my %langGermanMapping = (
- #'initialized' => 'initialisiert',
- #'authenticated' => 'authentifiziert',
- #'disabled' => 'deaktiviert',
- #'connected' => 'verbunden',
- 'Today at' => 'Heute um',
- 'Tomorrow at' => 'Morgen um',
- 'at' => 'um',
- 'NO_SOURCE' => 'keine Quelle',
- 'NOT_APPLICABLE' => 'nicht zutreffend',
-
- 'AUTO' => 'Automatisch',
- 'MAIN_AREA' => 'Hauptbereich',
-
- 'MOWING' => 'mäht',
- 'CHARGING' => 'lädt',
-
- 'LEAVING' => 'verlässt Ladestation',
- 'GOING_HOME' => 'auf dem Weg zur Ladestation',
- 'WEEK_TIMER' => 'Wochen-Zeitplan',
- 'WEEK_SCHEDULE' => 'Wochen-Zeitplan',
-
- 'PARKED_IN_CS' => 'In der Ladestation geparkt',
- 'COMPLETED_CUTTING_TODAY_AUTO' => 'Fertig für heute',
- 'PAUSED' => 'pausiert',
- 'SENSOR' => 'Sensor',
- 'OFF_DISABLED' => 'ausgeschaltet',
- 'OFF_HATCH_OPEN' => 'Abdeckung ist offen',
- 'OFF_HATCH_CLOSED' => 'Ausgeschaltet, manueller Start erforderlich',
-
- 'PARKED_TIMER' => 'geparkt nach Zeitplan',
- 'PARKED_PARK_SELECTED' => 'geparkt',
- 'MOWER_CHARGING' => 'Automower lädt',
- 'OK_SEARCHING' => 'sucht Ladestation',
- 'OK_LEAVING' => 'verlässt Ladestation',
- 'OK_CHARGING' => 'lädt',
- 'OK_CUTTING' => 'mäht',
- 'OK_CUTTING_TIMER_OVERRIDDEN' => 'manuelles Mähen',
- 'OK' => 'OK'
- );
-
- if( defined($langGermanMapping{$readingValue}) and HusqvarnaAutomower_isSetGerman($hash) ) {
- return $langGermanMapping{$readingValue};
- } else {
- return $readingValue;
- }
- }
- sub HusqvarnaAutomower_isSetGerman($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- if ( AttrVal('global','language','EN') eq 'DE' or $hash->{HusqvarnaAutomower}->{language} eq 'DE') {
- return 1;
- } else {
- return 0;
- }
- }
- sub HusqvarnaAutomower_Whoami() { return (split('::',(caller(1))[3]))[1] || ''; }
- sub HusqvarnaAutomower_Whowasi() { return (split('::',(caller(2))[3]))[1] || ''; }
- ##############################################################
- 1;
- =pod
- =item device
- =item summary Modul to control Husqvarna Automower with Connect Module (SIM)
- =item summary_DE Modul zur Steuerung von Husqvarna Automower mit Connect Modul (SIM)
- =begin html
- <a name="HusqvarnaAutomower"></a>
- <h3>Husqvarna Automower with Connect Module (SIM)</h3>
- <ul>
- <u><b>Requirements</b></u>
- <br><br>
- <ul>
- <li>This module allows the communication between the Husqvarna Cloud and FHEM.</li>
- <li>You can control any Automower that is equipped with the original Husqvarna Connect Module (SIM).</li>
- <li>The Automower must be registered in the Husqvarna App beforehand.</li>
- </ul>
- <br>
-
- <a name="HusqvarnaAutomowerdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> HusqvarnaAutomower</code>
- <br><br>
- Beispiel:
- <ul><br>
- <code>define myMower HusqvarnaAutomower<br>
- attr myMower username YOUR_USERNAME<br>
- attr myMower password YOUR_PASSWORD
- </code><br>
- </ul>
- <br><br>
- You must set both attributes <b>username</b> and <b>password</b>. These are the same that you use to login via the Husqvarna App.
- </ul>
- <br>
-
- <a name="HusqvarnaAutomowerattributes"></a>
- <b>Attributes</b>
- <ul>
- <li>username - Email that is used in Husqvarna App</li>
- <li>password - Password that is used in Husqvarna App</li>
- </ul>
- <br>
-
- <b>Optional attributes</b>
- <ul>
- <li>mower - ID of Automower, if more that one is registered. Default: 0</li>
- <li>interval - Time in seconds that is used to get new data from Husqvarna Cloud. Default: 300</li>
- <li>language - language setting, EN = original messages, DE = german translation. Default: DE</li>
- </ul>
- <br>
-
- <a name="HusqvarnaAutomowerreadings"></a>
- <b>Readings</b>
- <ul>
- <li>expires - date when session of Husqvarna Cloud expires</li>
- <li>mower_id - ID of the mower</li>
- <li>mower_lastLatitude - last known position (latitude)</li>
- <li>mower_lastLongitude - last known position (longitude)</li>
- <li>mower_mode - current working mode (e. g. AUTO)</li>
- <li>mower_name - name of the mower</li>
- <li>mower_nextStart - next start time</li>
- <li>mower_status - current status (e. g. OFF_HATCH_CLOSED_DISABLED, PARKED_IN_CS)</li>
- <li>mower_cuttingMode - mode of cutting area (e. g. MAIN_AREA)</li>
- <li>mower_nextStartSource - detailed status (e. g. COMPLETED_CUTTING_TODAY_AUTO)</li>
- <li>mower_restrictedReason - reason for parking (e. g. SENSOR)</li>
- <li>provider - should be Husqvarna</li>
- <li>state - status of connection to Husqvarna Cloud (e. g. connected)</li>
- <li>token - current session token of Husqvarna Cloud</li>
- <li>user_id - your user ID in Husqvarna Cloud</li>
- </ul>
- </ul>
- =end html
- =begin html_DE
- <a name="HusqvarnaAutomower"></a>
- <h3>Husqvarna Automower mit Connect Modul</h3>
- <ul>
- <u><b>Voraussetzungen</b></u>
- <br><br>
- <ul>
- <li>Dieses Modul ermöglicht die Kommunikation zwischen der Husqvarna Cloud und FHEM.</li>
- <li>Es kann damit jeder Automower, der über ein original Husqvarna Connect Modul (SIM) verfügt, überwacht und gesteuert werden.</li>
- <li>Der Automower muss vorab in der Husqvarna App eingerichtet sein.</li>
- </ul>
- <br>
-
- <a name="HusqvarnaAutomowerdefine"></a>
- <b>Define</b>
- <ul>
- <br>
- <code>define <name> HusqvarnaAutomower</code>
- <br><br>
- Beispiel:
- <ul><br>
- <code>define myMower HusqvarnaAutomower<br>
- attr myMower username YOUR_USERNAME<br>
- attr myMower password YOUR_PASSWORD
- </code><br>
- </ul>
- <br><br>
- Es müssen die beiden Attribute <b>username</b> und <b>password</b> gesetzt werden. Diese sind identisch mit den Logindaten der Husqvarna App.
- </ul>
- <br>
-
- <a name="HusqvarnaAutomowerattributes"></a>
- <b>Attributes</b>
- <ul>
- <li>username - Email, die in der Husqvarna App verwendet wird</li>
- <li>password - Passwort, das in der Husqvarna App verwendet wird</li>
- </ul>
- <br>
-
- <b>Optionale Attribute</b>
- <ul>
- <li>mower - ID des Automowers, sofern mehrere registriert sind. Standard: 0</li>
- <li>interval - Zeit in Sekunden nach denen neue Daten aus der Husqvarna Cloud abgerufen werden. Standard: 300</li>
- <li>language - Spracheinstellungen, EN = original Meldungen, DE = deutsche Übersetzung. Standard: DE</li>
- </ul>
- <br>
-
- <a name="HusqvarnaAutomowerreadings"></a>
- <b>Readings</b>
- <ul>
- <li>expires - Datum wann die Session der Husqvarna Cloud abläuft</li>
- <li>mower_id - ID des Automowers</li>
- <li>mower_lastLatitude - letzte bekannte Position (Breitengrad)</li>
- <li>mower_lastLongitude - letzte bekannte Position (Längengrad)</li>
- <li>mower_mode - aktueller Arbeitsmodus (e. g. AUTO)</li>
- <li>mower_name - Name des Automowers</li>
- <li>mower_nextStart - nächste Startzeit</li>
- <li>mower_status - aktueller Status (e. g. OFF_HATCH_CLOSED_DISABLED, PARKED_IN_CS)</li>
- <li>mower_cuttingMode - Angabe welcher Bereich gemäht wird (e. g. MAIN_AREA)</li>
- <li>mower_nextStartSource - detaillierter Status (e. g. COMPLETED_CUTTING_TODAY_AUTO)</li>
- <li>mower_restrictedReason - Grund für Parken (e. g. SENSOR)</li>
- <li>provider - Sollte immer Husqvarna sein</li>
- <li>state - Status der Verbindung zur Husqvarna Cloud (e. g. connected)</li>
- <li>token - aktueller Sitzungstoken für die Husqvarna Cloud</li>
- <li>user_id - Nutzer-ID in der Husqvarna Cloud</li>
- </ul>
- </ul>
- =end html_DE
|