Hallo Demel42,
erst mal: ein dickes Kompliment für das Projekt! Ich besitze seit 1 Woche einen Husqvarna Automower 315x und habe ihn auch gleich mit deinem Modul eingebunden. Vorher hatte ich einen Robomow RC312, der zwar das bessere Mähwerk und einen Kantenmodus hat, aber die Elektronik hinkt 10 Jahre hinterher.
Mich stört nur, dass Dein Modul erst ab IPS 5.3 installierbar ist, Ich tue mich mit dem Update etwas schwer, da IPS bei mir 3.2 GB groß ist und in meinem Augen nichts auf der System-Partition verloren hat. So habe ich nur Testweise ein Update gemacht möchte aber eigentlich auf IPS 5.2 bleiben.
Dann fiel mir beim Recherchieren auf, dass Husqvarna eine API bereitstellt, die auch halbwegs vernünftig dokumentiert ist:
https://developer.1689.cloud/apis
Nun meine Frage: benutzt Du tatsächlich IPS 5.3-spezifische Funktionen ? Beim überfliegen hatte ich zumindest nichts auf Anhieb entdeckt. Könntest Du also die Freigabe schon ab IPS 5.2 ändern ?
Oder noch besser: Könnten wir uns eventuell zusammen tun, auf die API mit Zugang unter :
https://api.amc.husqvarna.dev/v1
umstellen ? Vorteil wäre, dass mehr Funktionen verfügbar sind.
Anbei mal ein „wildes“ Test-Script zur Abfrage des Status und Senden von Befehlen:
<?
/*//////////////////////////////////////////////////////////////////////////////
Test Husqvarna API -Forum 2020 by André Liebmann
2020-04-29
--------------------------------------------------------------------------------
Links: https://developer.1689.cloud/apis/Automower+Connect+API
API: https://api.amc.husqvarna.dev/v1
Swagger: https://developer.1689.cloud/apis/Automower+Connect+API#/swagger
Application key: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Application secret: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/*//////////////////////////////////////////////////////////////////////////////
$Username = "Mail-Adresse";
$Password = "XXXX";
$Application_Key = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
$Application_Secret = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
$URl_Access = "https://api.amc.husqvarna.dev/v1";
$URL_Token = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/token";
$Mower_ID = "XXXXXXXXX-XXXXXXXX";
/*//////////////////////////////////////////////////////////////////////////////
function Automower_Get_Token($Application_Key, $Username, $Password, $URL_Token)
--------------------------------------------------------------------------------
CURL-Abfrage zur Ermittlung des Token
/*//////////////////////////////////////////////////////////////////////////////
function Automower_Get_Token($Application_Key, $Username, $Password, $URL_Token)
{
$curl = curl_init();
$auth_data = "grant_type=password&";
$auth_data .= "client_id=".$Application_Key."&";
$auth_data .= "username=".$Username."&";
$auth_data .= "password=".$Password;
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $auth_data);
curl_setopt($curl, CURLOPT_URL, $URL_Token);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$Result = curl_exec($curl);
if(!$Result)
{
die("Connection Failure");
}
curl_close($curl);
$ResultArray = json_decode($Result, true); //print_r($ResultArray);
$Token = $ResultArray["access_token"]; echo("
Token: $Token
");
return $Token;
}
$Token = Automower_Get_Token($Application_Key, $Username, $Password, $URL_Token);
/*//////////////////////////////////////////////////////////////////////////////
Alle Mower abfragen
/*//////////////////////////////////////////////////////////////////////////////
$URL = "https://api.amc.husqvarna.dev/v1/mowers";
if($Token)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"accept: application/vnd.api+json",
"X-Api-Key: ".$Application_Key,
"Authorization: Bearer ".$Token,
"Authorization-Provider: husqvarna",
));
curl_setopt($curl, CURLOPT_URL, $URL);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$Result = curl_exec($curl);
if(!$Result)
{
die("Connection Failure 2");
}
curl_close($curl);
$ResultArray = json_decode($Result, true); //print_r($ResultArray);
}
/*//////////////////////////////////////////////////////////////////////////////
Ersten Mower abfragen
/*//////////////////////////////////////////////////////////////////////////////
$Mower_ID = $ResultArray["data"][0]["id"]; //echo($Mower_ID);
$URL = "https://api.amc.husqvarna.dev/v1/mowers/".$Mower_ID;
if($Token)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"accept: application/vnd.api+json",
"X-Api-Key: ".$Application_Key,
"Authorization: Bearer ".$Token,
"Authorization-Provider: husqvarna",
));
curl_setopt($curl, CURLOPT_URL, $URL);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$Result = curl_exec($curl);
if(!$Result)
{
die("Connection Failure 2");
}
curl_close($curl);
$ResultArray = json_decode($Result, true); //print_r($ResultArray);
}
//echo(Automower_Request($Mower_ID, $Application_Key, $Token, $Method, $Action, $Attributes));
/*//////////////////////////////////////////////////////////////////////////////
function Automower_Send_Action
JSON-Strukturen:
Pause mower:
data: {
type: 'Pause'
}
Park mower until next scheduled run:
data: {
type: 'ParkUntilNextSchedule'
}
Park mower until further notice, overriding schedule:
data: {
type: 'ParkUntilFurtherNotice'
}
Park mower for a duration of time, overriding schedule:
data: {
type: 'Park',
attributes: {
duration: 24
}
}
Resume mower according to schedule:
data: {
type: 'ResumeSchedule'
}
Start mower and cut for a duration of time, overriding schedule:
data: {
type: 'Start',
attributes: {
duration: 24
}
}
/*//////////////////////////////////////////////////////////////////////////////
// Husqvarna API - URL
$URL = "https://api.amc.husqvarna.dev/v1/mowers/".$Mower_ID."/actions";
$Action = "Start";
$Attributes = '"attributes": { "duration":10 }';
$Message = '
{
"data": {
"type": "'.$Action.'",
'.$Attributes.'
}
}
';
$Method = "POST";
echo(Automower_Request($URL, $Mower_ID, $Application_Key, $Token, $Method, $Message));
function Automower_Request($URL, $Mower_ID, $Application_Key, $Token, $Method, $Message)
{
$URL = "https://api.amc.husqvarna.dev/v1/mowers/".$Mower_ID."/actions";
// prepare CURL
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Accept: */*",
"Content-Type: application/vnd.api+json",
"X-Api-Key: ".$Application_Key,
"Authorization: Bearer ".$Token,
"Authorization-Provider: husqvarna",
));
curl_setopt($curl, CURLOPT_URL, $URL);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $Method);
// set POSTFIELDS for "POST"
if($Method == "POST")
{
curl_setopt($curl, CURLOPT_POSTFIELDS, $Message);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$Result = curl_exec($curl); print_r($Result);
curl_close($curl);
// proof response
if(preg_match("/errors/i", $Result))
{
$Detail = json_decode($Result, true);
print_r($Detail);
$Notification = 'ERROR: '.$Detail["errors"][0]["title"].' | '.$Detail["errors"][0]["detail"];
}
else
{
$Notification = "OK";
}
// return response
return $Notification;
}
Sowie Status- und Error-Arrays:
<?php
/*//////////////////////////////////////////////////////////////////////////////
Husqvarna States and Errors 2020 by André Liebmann
2020-04-29
/*//////////////////////////////////////////////////////////////////////////////
$Mode = array(
'MAIN_AREA' => 'Mower will mow until low battery. Go home and charge. Leave and continue mowing. Week schedule is used. Schedule can be overridden with forced park or forced mowing.',
'DEMO' => 'Same as main area, but shorter times. No blade operation. ',
'SECONDARY_AREA' => 'Mower is in secondary area. Schedule is overridden with forced park or forced mowing. Mower will mow for request time or untill the battery runs out. ',
'HOME' => 'Mower goes home and parks forever. Week schedule is not used. Cannot be overridden with forced mowing. ',
'UNKNOWN' => 'Unknown mode',
);
$Activity = array(
'UNKNOWN' => 'Unknown activity. ',
'NOT_APPLICABLE' => 'Manual start required in mower. ',
'MOWING' => 'Mower is mowing lawn. If in demo mode the blades are not in operation. ',
'GOING_HOME' => 'Mower is going home to the charging station. ',
'CHARGING' => 'Mower is charging in station due to low battery. ',
'LEAVING' => 'Mower is leaving the charging station. ',
'PARKED_IN_CS' => 'Mower is parked in charging station. ',
'STOPPED_IN_GARDEN' => 'Mower has stopped. Needs manual action to resume. ',
);
$State = array(
'UNKNOWN' => 'Unknown state. ',
'NOT_APPLICABLE' => '',
'PAUSED' => 'Mower has been paused by user. ',
'IN_OPERATION' => 'See value in activity for status. ',
'WAIT_UPDATING' => 'Mower is downloading new firmware. ',
'WAIT_POWER_UP' => 'Mower is performing power up tests. ',
'RESTRICTED' => 'Mower can currently not mow due to week calender, or override park. ',
'OFF' => 'Mower is turned off. ',
'STOPPED' => 'Mower is stopped requires manual action. ',
'ERROR' => 'An error has occurred. Check errorCode. Mower requires manual action. ',
'FATAL_ERROR' => 'An error has occurred. Check errorCode. Mower requires manual action. ',
'ERROR_AT_POWER_UP' => 'An error has occurred. Check errorCode. Mower requires manual action. ',
);
$Error_Codes = array(
'0' => 'Unexpected error',
'1' => 'Outside working area',
'2' => 'No loop signal',
'3' => 'Wrong loop signal',
'4' => 'Loop sensor problem, front',
'5' => 'Loop sensor problem, rear',
'6' => 'Loop sensor problem, left',
'7' => 'Loop sensor problem, right',
'8' => 'Wrong PIN code',
'9' => 'Trapped',
'10' => 'Upside down',
'11' => 'Low battery',
'12' => 'Empty battery',
'13' => 'No drive',
'14' => 'Mower lifted',
'15' => 'Lifted',
'16' => 'Stuck in charging station',
'17' => 'Charging station blocked',
'18' => 'Collision sensor problem, rear',
'19' => 'Collision sensor problem, front',
'20' => 'Wheel motor blocked, right',
'21' => 'Wheel motor blocked, left',
'22' => 'Wheel drive problem, right',
'23' => 'Wheel drive problem, left',
'24' => 'Cutting system blocked',
'25' => 'Cutting system blocked',
'26' => 'Invalid sub-device combination',
'27' => 'Settings restored',
'28' => 'Memory circuit problem',
'29' => 'Slope too steep',
'30' => 'Charging system problem',
'31' => 'STOP button problem',
'32' => 'Tilt sensor problem',
'33' => 'Mower tilted',
'34' => 'Cutting stopped - slope too steep',
'35' => 'Wheel motor overloaded, right',
'36' => 'Wheel motor overloaded, left',
'37' => 'Charging current too high',
'38' => 'Electronic problem',
'39' => 'Cutting motor problem',
'40' => 'Limited cutting height range',
'41' => 'Unexpected cutting height adj',
'42' => 'Limited cutting height range',
'43' => 'Cutting height problem, drive',
'44' => 'Cutting height problem, curr',
'45' => 'Cutting height problem, dir',
'46' => 'Cutting height blocked',
'47' => 'Cutting height problem',
'48' => 'No response from charger',
'49' => 'Ultrasonic problem',
'50' => 'Guide 1 not found',
'51' => 'Guide 2 not found',
'52' => 'Guide 3 not found',
'53' => 'GPS navigation problem',
'54' => 'Weak GPS signal',
'55' => 'Difficult finding home',
'56' => 'Guide calibration accomplished',
'57' => 'Guide calibration failed',
'58' => 'Temporary battery problem',
'59' => 'Temporary battery problem',
'60' => 'Temporary battery problem',
'61' => 'Temporary battery problem',
'62' => 'Temporary battery problem',
'63' => 'Temporary battery problem',
'64' => 'Temporary battery problem',
'65' => 'Temporary battery problem',
'66' => 'Battery problem',
'67' => 'Battery problem',
'68' => 'Temporary battery problem',
'69' => 'Alarm! Mower switched off',
'70' => 'Alarm! Mower stopped',
'71' => 'Alarm! Mower lifted',
'72' => 'Alarm! Mower tilted',
'73' => 'Alarm! Mower in motion',
'74' => 'Alarm! Outside geofence',
'75' => 'Connection changed',
'76' => 'Connection NOT changed',
'77' => 'Com board not available',
'78' => 'Slipped - Mower has Slipped.Situation not solved with moving pattern',
'79' => 'Invalid battery combination - Invalid combination of different battery types.',
'80' => 'Cutting system imbalance Warning',
'81' => 'Safety function faulty',
'82' => 'Wheel motor blocked, rear right',
'83' => 'Wheel motor blocked, rear left',
'84' => 'Wheel drive problem, rear right',
'85' => 'Wheel drive problem, rear left',
'86' => 'Wheel motor overloaded, rear right',
'87' => 'Wheel motor overloaded, rear left',
'88' => 'Angular sensor problem',
'89' => 'Invalid system configuration',
'90' => 'No power in charging station',
);
?>
Wenn ich die Struktur Deiner Scripte sehe bist Du mir da allerdings Meilenweit voraus. Mit Modulen habe ich Null-Erfahrung :rolleyes:
Besten Gruß
André
PS: gern auch über PN