[Modul] Husqvarna Automower Connect

danke

prima, so soll’s sein

hardlog ha da ja schon ein script gemacht, das könnte ich ggfs integrieren.

@hardlog: wenn du magst und mir dein script postest würde ich das in das modul einbauen .

Bzgl. weiter Funktionen sieht mau aus. Die API ist nicht dokumentiert und Anfragen, die offen zu legen sind anscheinen bisher gescheitert. Von daher bin ich da leider nicht optimistisch.

Gerne stelle ich meine Lösung vor.

Meine Karte ist allerdings „hingefummel“. Ich hab mir online einen passenden Screenshot bei OpenStreepMaps gemacht, dann die GPS-Koordianten auf die Pixel des Bildes umgerechnet und dann eingezeichnet (html5 / canvas).
Ist also keine so einfach universell integrierbare Lösung. Wenn ich Zeit habe kann ich’s gerne hier nochmal ausführlich darstellen. Besser (oder sauberer) wäre aber ne Lösung über die API von OpenStreetmaps o.ä.

Ich habs so gemacht, weil ich es auf die Schnelle nicht anders hinbekommen habe und weil ich so unabhängig von einer dritten Partei bin.

LG
hardlog

hmm, das stimmt, so macht es wenig Sinn, das so in das Modul zu übernehmen. Ich hab mich mal etwas (ganz oberflächlich) in die GoogleMap-API eingelesen.
Grundsätzlich kann man das damit machen (macht ja die Original-App genauso). Aber jeder Anwender (der die Karte haben möchte) müsste sich einen API-Key holen. OpenStreetMap habe ich noch nicht viel gefunden gefunden, aber auch nicht wirklich nach gesucht.

Hallo zusammen. Super Modul!! Danke schonmal dafür. Läuft auch soweit aber kriege irgendwie den Moser nicht per Anweisung (Skript) gestoppt oder gestartet. Kann jemand Mal ein Beispiel zum Stoppen des Mowers Posten. Wäre echt super. Kriege irgendwie die Funktion nicht aufgerufen bzw weiß nicht wie ich den Befehl absetzte.

Dannyboy

über die Weboberfläche ->

und im Script via

AutomowerDevice_ParkMower(<Instance-ID der Automower-Instanz) und analog StartMower/StopMower.

Ich habe gemerkt, das man nach einem Park u.U. (die Umstände sind mir noch nicht ganz klar) 2x ein Start schicken muss.

gruß
demel

Danke für die schnelle Antwort

Habe in der Oberfläche nur eine Anzeige, keine 3 Buttons. Fehlt dort das Script von mir?

Ist aber ja nicht so schlimm. Wenn ich jetzt die Variable „Aktivität starten“ in IPS von Hand auf den Wert integer 1,2 oder 3 setze passiert auch nicht.

Per Script aufgerufen mit dem Befehl --> AutomowerDevice_ParkMower(29543 /*Automower…). meldet sich IPs zurück mit der Aussage dass es den Befehl nicht kennt.

Das Aufrufen der letzten 50 GPS-Position des Mowers wiederum funktioniert, ich verstehe das irgendwie nicht ganz.

Werde aber heute abend weiter versuchen.

Grüße

Dannyboy

das ist merkwürdig. Dieser Variable MowerAction sollte das Integer-Profil Automower.Action zugewiesenen und hat eine Standardaktion (die ja im Modul gesetzt wird).


ich bin kein Fachmann für die IPS-Visulalisierung, aber es hört sich für mich so an, als wenn die Standardaktion fehlt.

Wenn Du im Script-Editor eingibst Auto und Ctrl+Space, sollte sich das das Fenster öffnen mit den passenden Funktionen, das müsste etwa so aussehen:

Ich würde vorschlagen, das Du das Modul in der Modulverwaltung einfach mal löscht und wieder neu lädst, irgendwie scheint da etwas in Unordnung zu sein.

Wie weit bist du auf der Shell zu hause?

in dem IPS-Scriptverzeichnis gibt es eine Datei namens __generated.inc.php. In der finden sich alle Funktionen aller geladenen Module und somit müsste auch die ganzen AUtomower-Funktionen enthalten sein.

function AutomowerDevice_GetMowerList($InstanceID)
function AutomowerDevice_GetRawData($InstanceID, $name)
function AutomowerDevice_StopMower($InstanceID)
function AutomowerDevice_ParkMower($InstanceID)
function AutomowerDevice_UpdateStatus($InstanceID)
function AutomowerConfig_GetMowerList($InstanceID)
function AutomowerConfig_Doit($InstanceID, $mower_name)
function AutomowerDevice_TestAccount($InstanceID)
function AutomowerDevice_StartMower($InstanceID)

Die Datei wird immer ergänzt, wenn ein Modul geladen oder ein MC_ReloadModule aufgerufen wird (sowie - wenn ich das richtig sehe - auch beim Neustart von IPS)

Welche IPS-Version hast du am Start?

gruß
demel

Hallo demel42,

hat alles geklappt. Nach dem Löschen der Instanz und wiederanlegen funktioniert es.
Reagiert auf alle Befehle und funktioniert super. Danke nochmal für deine schnelle Hilfe und Support.

Habe im noch eine Kuriosität gefunden. Ist das bei euch auch so?

Wenn der Mower in Betriebsart–>Automatik und Status -->PARKED_AUTOTIMER ist, dann kommt aktuelle Aktivität --> Fehler bei Aktivität starten–> starten.

Grüße

Dannyboy

hmm, ich kenne aufgrund der fehlenden API-Doku nicht alle Stati sondern habe die mir zusammengesucht und alles, was ich nicht kenne wird „ERROR“.

Wenn du in der Instanz den Debug einschaltest siehst du dort sowohl die html-Kommunikation also auch ggfs. soetwas

normalize_mowerStatus: unknown value "..."

kannst du das mal aufzeichnen und posten? Und ggfs das schreiben, was die Automower-App zu dem Zeitpunkt anzeigt?

danke
demel

Ja werde Mal gucken wie die Statistik sind. Ich untersuche das Mal. Kann ich aber erst am Samstag machen. Meld mich dann wieder.

Grüẞe

Hallo,

es wurde hier gefragt nach einer Darstellung der GPS-Daten in GoogleMaps.

Ich habe mich in den letzten Tagen mal in die API von GoogleMaps hineingelesen und etwas experimentiert. Da der Abruf der Karten nicht ganz ohne ist und auch für andere Zwecke verwendet werden kann, habe ich das nicht in das AUtomower-Modul integriert sondern ein neues Modul gemacht, das hier zu finden ist: GitHub - demel42/IPSymconGoogleMaps: Interface for GoogleMaps API to create simple Maps

Das Modul ist experimentell, daher habe ich noch keine eigene Module-Seite erstell, es ist noch nicht vollständig (Routen und Verkehrsfluss fehlt z.B. noch) und die Dokumentation lässt noch zu wünschen.

Wenn jemand Interesse hat, kann er das ausprobieren.

Je nachdem, ob welche Art man benutzen will, ist der Weg unterschiedlich

a) StaticMap (was für diese Zwecke eigentlich reicht):

  1. eine Variable vom Typ HTML-Box anlegen

  2. folgendes Script anlegen


<?

$cdata = AutomowerDevice_GetRawData(1234 /*[Rasenmäher\Automower]*/, 'LastLocations');
$jdata = json_decode($cdata, true);

$points = [];
foreach ($jdata as $jpoint) {
    $points[] = [
            'lat' => $jpoint['latitude'],
            'lng' => $jpoint['longitude'],
        ];
}

// allgemeine Angaben zur Karte
$map = [];

// Mittelpunkt der Karte
$map['center'] = $points[0];

$map['zoom'] = 20;
$map['size'] = '640x640';
$map['scale'] = 1;
$map['maptype'] = 'satellite';

$markers = [];

$marker_points = [];
$marker_points[0] = $points[0];

$markers[] = [
        'color'     => 'green',
		'label'		=> 'P',
        'points'    => $marker_points,
    ];

$map['markers'] = $markers;

$paths = [];
$paths[] = [
        'color'     => '0xff0000ff',       // 0xhhhhhhoo oo=opacity
        'weight'    => 2,
        'points'    => $points,
    ];

$map['paths'] = $paths;

$url = GoogleMaps_GenerateStaticMap(4711 /*[GoogleMaps]*/, json_encode($map));

$html = '<img width="500", height="500" src="' . $url . '" />';
SetValueString(8888 /*[GoogleMaps\Karte (static)]*/, $html);

Dieses Script könnte man per Ereignis aufrufen, wenn die Variable ‚letzter Status‘ des Automower sich ändert.

b) DynamicMap

ist etwas komplizierter; da IPS die Webseite nicht direkt darstellen kann, muss man den Umweg über ein WebHook gehen.

  1. Variable vom Typ HTML-Box anlegen und mit einer iframe-Anweisung befüllen, zB mit einem solchen Script.

<?

$url = 'http://<IPS-IP/Name>:3777/hook/GoogleMaps_Automower';

$html = '<iframe width="500", height="500" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' . $url . '"></iframe>';
SetValueString(4711 /*[GoogleMaps\Karte (dynamic)]*/, $html);

  1. Script anlegen

<?

$cdata = AutomowerDevice_GetRawData(1234 /*[Rasenmäher\Automower]*/, 'LastLocations');
$jdata = json_decode($cdata, true);

$points = [];
foreach ($jdata as $jpoint) {
    $points[] = [
            'lat' => $jpoint['latitude'],
            'lng' => $jpoint['longitude'],
        ];
}

// allgemeine Angaben zur Karte
$map = [];

// Zentrum der Karte
$map['center'] = $points[0];

// Optionen für google.maps.Map
$map_options = [
        'zoom'      => 20,              // 1: World, 5: Landmass/continent, 10: City, 15: Streets, 20: Buildings
        'tilt'      => 0,               // 0..45
        'mapTypeId' => 'satellite',     // roadmap, terrain, hybrid, satellite
    ];
$map['map_options'] = $map_options;

// Standard-Optionen für google.maps.InfoWindow
$infowindow_options = [
        'maxWidth'  => 200,				// pixel
    ];
$map['infowindow_options'] = $infowindow_options;



// Karte mit Positionen
$markers = [];

$marker = [];

$marker_points = [];
$marker_points[0] = $points[0];

// Text eines Punktes für google.maps.InfoWindow
$marker_points[0]['info'] = 'akt. Position';

// Optionen eines Punktes für google.maps.Marker
$marker_options = [
        'icon'		=> [
            'url'        => 'http://maps.google.com/mapfiles/kml/paddle/grn-circle.png',
            'scaledSize' => [
            		'width'		=> 32,
            		'height'	=> 32
            	]
            ]
    ];
$marker['marker_options'] = $marker_options;

// GPS-Punkte
$marker['points'] = $marker_points;

$markers[] = $marker;

$map['markers'] = $markers;

// Karte mit verbundenen Punkten
$paths = [];

$path = [];

// GPS-Punkte
$path['points'] = $points;

// Optionen für google.maps.Polyline
$polyline_options = [
        'strokeColor'    => '#FF0000',
        'strokeOpacity'  =>  1.0,		// 0.0 .. 1.0
        'strokeWeight'   =>  2,			// pixel   
    ];

$path['polyline_options'] = $polyline_options;

$paths[] = $path;

$map['paths'] = $paths;

$html = GoogleMaps_GenerateDynamicMap(4711 /*[GoogleMaps]*/, json_encode($map));
echo $html;

  1. WebHook anlegen (unter Kernel-Module), Namen passend zu (1) vergeben und als Script das unter (2) angelegte Script eintragen.

Da die Daten immer aktuell bei Aufruf des WebHook ermittelt werden, ist eine ereignisgesteuerte Aktualisierung nicht erforderlich.

Gruß
demel

Erst einmal vielen Dank für das Modul.
Habe es aber nicht zum Laufen gebracht.
Da gibt es eine Fehlermeldung bei der Generierung der StaticMap.
Zeile 266 … erwarte String nicht Array … blablabla
In der Funktion wird nochmals JSON genutzt, das ist dort aber überflüssig.
Die Zeile habe ich gelöscht und den Funktionsaufruf auf „Array $map“ geändert.
Hey … es funktioniert.

Besten Gruß

sorry, da hatten sich Änderung überschnitten.

Also die Übergabe der ‚map‘ an die Funktion hatte ich auf Anraten von nall-chan von arryauf string geändert (siehe korrekte Typ-Deklaration von Funktionsparametern).
Da Problem(chen) ist, das IPS als Variablentyp ‚array‘ nicht unterstützt (im Gegensatz von PHP).

daher habe ich die Übergabe so geändert, also bei Aufruf ein json_encode($map) bei Aufruf der FUnktion und in der Funktion dann ein json_decode() in der Funktion selbt.

Ja, ist eigentlich (technisch) überflüssig, aber dann wird die fehlende Typdeklaration angemeckert.

Ich hatte leider meine Anleitung in diesem Vorgang nicht angepasst … habe ich nachgeholt.

Hallo,

das sieht ja alles schon super aus.

Was ich noch besonders lohnend fände ist wenn man nicht immer nur die letzten 50 GPS Positionen des Mähers sehen könnte sondern einstellen könnte: die letzten 4 Stunden, den letzten Tag, die letzte Woche. Ich habe eine recht grosse Fläche zu mähen und es wäre für mich interessant zu wissen wie der Mäher sich seine Tage/Wochen einteilt.

Hat da schon mal jemand was implementiert oder drüber nachgedacht?

VG

gros_ibou

Hallo,

nein, habe ich noch nicht nachgedacht. Die 50 Positionen sind einfach das, was mit jedem Status geliefert wird.

Aber warum nicht.
Ich könnte mir folgendes vorstellen:
es gibt optional eine Variable.
in die packe ich bei jeder Statusabfrage die aktuelle Postion. Da die Position ja aus zwei Werten besteht, ist die Variable vom Typ String und enthält json-kodierte Latitude und Longitude.
Die Variable muss natürlich so eingestellt sein, das die Daten gelogged werden. Somit hätte man bei Bedarf Zugriff auf alle Positionen. Für die Darstellung müsste man die Werte per AC_* Funktionen für den gewünschten Zeitraum geholt und für die Visulaisierung aufbereitet werden.

Wäre das in Deinem Sinne?

Ja das wäre sehr in meinem Sinne.

Ich weiss ja nicht in welchem Zeitabstand die 50 Werte die mitkommen genommen werden.
Man könnte auch einfach die nehmen dann immer aneinander reihen. Dann hätte man es noch genauer (mehr Punkte).

Aber so oder so wäre es in meinem Sinne.

Verstehe ich Dich richtig, dass Du mal einen Anlauf machen würdest das zu programmieren? Dann würde ich nämlich erstmal nicht mehr weiter machen (hab gerade angefangen ein bisschen rumzuspielen - aber wenn das sauber integriert wäre wäre es natürlich viel besser).

VG
gros_ibou

den zeitlich Abstand kenne ich auch nicht . Aber wenn ich jede Minute den Status holte und die letzte Poistion speichere, wäre das achon ziemlich eng.

Verstehe ich Dich richtig, dass Du mal einen Anlauf machen würdest das zu programmieren?

ja, werde ich mal in den nächsten Tagen angehen.

Super. Danke :slight_smile:

Bisschen habe ich angefangen drüber nachzudenken.

Ein Problem ist, wenn man das Variablen Logging benutzt, dass ja nur Änderungen geloggt werden. D.h. man hat z.B. 500 Werte für die „lon“ Koordinaten und 505 für die „lat“ Koordinaten. Das muss man dann alles mühsam mit dem Timestamp wieder auseinander fieseln. Geht natürlich ist aber nicht gerade elegant. Kann man dem Variablen logging beibringen, dass es einfach jedesmal (auch bei Update ohne Veränderung) den Wert wegschreibt?

Gruss
gros_ibou

hallo,

ich habe inzwischen was implementiert, muss aber noch ein bisschen testen, da mein mäher nur ein paar stunden am tag läuft, dauert etwas. ich denke übermorgen abend veröffentliche ich eine neue version.

wüsste ich nicht, aber ich sehe nicht das problem. denn wenn er fährt, ändert er ja permanent seine position; ist also immer eine änderung der variablen. und falls (auch) die frage ist, wann er fährt/mäht - das dokumentiere ich ja in einer anderen variablen