AdapterRequests
AdapterRequests copied to clipboard
Hydrawise Bewässerung
Ein Adapter für Hydrawise wäre klasse. https://www.hydrawise.com API bekommt man wohl nur auf Anfrage: https://support.hydrawise.com/hc/en-us/articles/360008965753-Account-API-Information Hier hat jemand bereits etwas für Neo und IP-Symcon gebaut: https://mediola.answerbase.com/2301313/Darstellung-der-Informationen-eines-Bewässerungssystems-in-NEO https://www.symcon.de/forum/threads/37530-Hunter-Hydrawise-einbinden
Ein paar mehr Informationen zu "Hydrawise" wären ebenso klasse :-) Links zum Produkt? Links zu Anleitungen? Links zu verfügbaren APIs? Links zu verfügbaren Bibliotheken zu einer Anbindung?
Hydrawise ist eine Software die zur Bewässerung dient und kommt von Hunter. https://www.hydrawise.com/ Es können damit verschiendenste Bewässerungscontroller angesteuert werden: https://www.hydrawise.com/content/hydrawise-controllers-and-hardware
Es gibt eine python library, die scheinbar auch gepflegt wird. Vielleicht dienen diese Informationen zur Umsetzung in einen Adapter.
Einen API-Key könnte ich testweise zur Verfügung stellen...
hab mit die scripte mal angeschaut das sieht nach ner guten JSON aus die kann man eigentlich ganz leicht umsetzen in states.
Mit API documentation und nem key zu testen könnte wir mal schauen
Würde mich auf freuen, ich habe einen Hydrawise Hunter HC 6 im Einsatz und kann euch gern unterstützen (außer beim Programmieren).
Hi! Leider kann ich keinen Adapter bauen, habe aber ein Skript zusammengewürfelt, dass die Daten aus der Api zieht. Leider gibt API1 nicht viel her - zb nicht die Wassermenge meines Sensors "Wasseruhr". Ich habe Hunter mal angemailt, ob es für API2 eine Doku gibt.
schedule('* * * * *', function(){
var url="https://app.hydrawise.com/api/v1/statusschedule.php?api_key=xxxx-xxxx-xxxx-xxxx"
request({url : url}, function (error, response, body) {
CreateRelays(JSON.parse(body));
});
var url="https://app.hydrawise.com/api/v1/customerdetails.php?api_key=xxxx-xxxx-xxxx-xxxx"
request({url : url}, function (error, response, body) {
CreateCustomer(JSON.parse(body));
});
})
function CreateCustomer(data){
//log(data.controllers);
if (existsState('javascript.0.hydrawise.user_lastcontact')==false)
{
createState('javascript.0.hydrawise.user_lastcontact');
}
setState('javascript.0.hydrawise.user_lastcontact', data.controllers[0].last_contact );
if (existsState('javascript.0.hydrawise.user_status')==false)
{
createState('javascript.0.hydrawise.user_status');
}
setState('javascript.0.hydrawise.user_status', data.controllers[0].status );
}
function CreateRelays(data){
if ("undefined" !== typeof data.relays){
//log(data.relays);
var i;
for (i = 0; i < data.relays.length; i++)
{
if (existsState('javascript.0.hydrawise.relay'+i+'_id')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_id');
}
setState('javascript.0.hydrawise.relay'+i+'_id', data.relays[i].relay_id );
if (existsState('javascript.0.hydrawise.relay'+i+'_time')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_time');
}
setState('javascript.0.hydrawise.relay'+i+'_time', data.relays[i].time );
if (existsState('javascript.0.hydrawise.relay'+i+'_run')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_run');
}
setState('javascript.0.hydrawise.relay'+i+'_run', data.relays[i].run );
if (existsState('javascript.0.hydrawise.relay'+i+'_run_min')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_run_min');
}
setState('javascript.0.hydrawise.relay'+i+'_run_min', Math.round(data.relays[i].run/60) );
if (existsState('javascript.0.hydrawise.relay'+i+'_name')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_name');
}
setState('javascript.0.hydrawise.relay'+i+'_name', data.relays[i].name );
if (existsState('javascript.0.hydrawise.relay'+i+'_period')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_period');
}
setState('javascript.0.hydrawise.relay'+i+'_period', data.relays[i].period );
if (existsState('javascript.0.hydrawise.relay'+i+'_timestr')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_timestr');
}
setState('javascript.0.hydrawise.relay'+i+'_timestr', data.relays[i].timestr );
}
if ("undefined" !== typeof data.sensors){
log (data.sensors);
var i;
for (i = 0; i < data.sensors.length; i++)
{
//log(data.sensors);
}
}
}
else{console.warn('Response in JSON nicht gefunden ! ')}
}
Antwort von Hunter zu API2:
the Graph QL API is designed for commercial application and monitoring more than 1 controller it does not offer any extra functionality than the RestAPI.
Hallo,
ich habe seit ein paar Tagen einen Hunter Hydrawise HC-Pro am Start und verwende ioBroker. Habe mit Interesse dieses Request gelesen und würde gerne mit der Hardware unterstützen.
Hydrawise hat auch eine Seite mit guten Informationen zu den beiden verfügbaren API im Netz (Link war auch schon oben verlinkt): https://support.hydrawise.com/hc/en-us/articles/360008965753-Account-API-Information
Die pdf Datei mit den Informationen zur REST-API ist auf dieser Seite verlinkt: Hydrawise REST API.pdf
Habe gerade mal etwas mit den Informationen "gespielt" und das Abrufen der Informationen und auch einfache Aktionen, wie starten und stoppen einer Bewässerung per API hat problemlos geklappt.
Es wäre toll, wenn ich mit meinem Gerät und Zugang die Basis für eine Adapterentwicklung für ioBroker unterstützen könnte.
Gruß
Michael
Hallo Community, Hat jemand einen aktuellen Status zur ioBroker integration von Hunter Controlern? Gruss,und vielen Dank im Voraus für's update ... Luc
+1 ... ich würde mich auch sehr über einen funktionierenden ioBroker Adapter für meine Hunter Hydrawise freuen - sowohl zur Auswertung, als auch zur Steuerung. Gibt es ev. jemanden, der daran arbeitet? Beim testen kann ich gerne helfen, über eine Spende lässt sich auch reden - für mehr fehlt mir leider die Zeit, tut mir leid. Viele Grüße, Christian
Gibt es hier inzwischen schon etwas? Falls nicht, würde ich mir das mal ansehen.
Mir ist hier noch keine Lösung bekannt. Ich biete mich auch gerne zum Testen an :-)
Hallo Magnus, nicht wirklich viel, außer dem, was hier bei dem Tiket steht. Im deutchen Forum gibt es noch einen Thread zu dem Thema, aber die Überschneidungen zu den Infos hier sind sehr groß. Eine wirkliche Lösung ist mir nicht bekannt. VG, Christian
Hallo, ist mir aktuell auch nicht bekannt. Ich kann mit Hardware und Testzugang (API) unterstützen. Freue mich auf den Kontakt.
Hallo zusammen,
der letzte Eintrag ist zwar schon lange her, aber vlt. ist noch jemand hier aktiv und kann mir den richtigen Input geben. Ich habe das Script installiert und dabei gesehen, dass die Zeitangaben in Unix sind. Meine Java-Fähigkeiten sind allerdings nicht prickelnd und ich habe so meine Probleme aus den Zeitangaben brauchbare Werte zu ermitteln.
Beispiel:
Aus diesem Zeitwert erhalte ich die Uhrzeit
Der Timestamp 1651186939 entspricht dem 29.04.2022 um 01:02:19 Uhr. (gilt für UTC+2)
Eine kurze Überprüfung im Hydravise-Konto ergibt, dass dieser Wert korrekt ist.
Der Wert
javascript.0.hydrawise.relayx_time
sollte dann die tägliche Bewässerungsuhrzeit ergeben. Zumindest sehe ich dort eine Veränderung, wenn ich verschiedene Zeitpläne für Zonen anwende und die Zeiten veränder... Bei der Formel du bin ich dann allerdings ratlos.
Hallo!
Die Relaytime gibt an, in wie vielen Sekunden beregnet wird. Willst Du also wissen, wann das nächste mal das Relay angesteuert wird, musst Du diese RelayTime + AktuelleTime rechnen.
Im ioBroker mache ich das so:
a = new Date().getTime() ; a=a+data.relays[i].time*1000; a = formatDate(a, 'DD.MM. hh:mm'); } setState('javascript.0.hydrawise.relay'+i+'_timeS', a );
Gruß Micha
Hier noch mal mein aktuelles ioBroker-Script in Gänze:
schedule('* * * * *', function(){
//Customer-Daten abfragen
var url="https://app.hydrawise.com/api/v1/customerdetails.php?api_key=xxxx-xxxx-xxxx-xxxx"
request({url : url}, function (error, response, body) {
CreateCustomer(JSON.parse(body));
});
//Daten Current-Controller abfragen
var url="https://app.hydrawise.com/api/v1/statusschedule.php?api_key=xxxx-xxxx-xxxx-xxxx"
request({url : url}, function (error, response, body) {
CreateRelays(JSON.parse(body));
});
})
//*********************************/
function CreateCustomer(data){
//log(data.controllers);
//aktuelle Controller-ID (betrifft wohl die Website der Cloud, welcher aktuell da angewählt ist)
if (existsState('javascript.0.hydrawise.current_controller_id')==false)
{
createState('javascript.0.hydrawise.current_controller_id');
}
setState('javascript.0.hydrawise.current_controller_id', data.controller_id );
//Customer ID
if (existsState('javascript.0.hydrawise.customer_id')==false)
{
createState('javascript.0.hydrawise.customer_id');
}
setState('javascript.0.hydrawise.customer_id', data.customer_id );
//aktueller Controller-Name (betrifft wohl die Website der Cloud, welcher aktuell da angewählt ist)
if (existsState('javascript.0.hydrawise.current_controller_name')==false)
{
createState('javascript.0.hydrawise.current_controller_name');
}
setState('javascript.0.hydrawise.current_controller_name', data.current_controller );
//alle Controller anlegen
var i;
for (i = 0; i < data.controllers.length; i++)
{
//Controller[] Name
if (existsState('javascript.0.hydrawise.controller'+i+'_name')==false)
{
createState('javascript.0.hydrawise.controller'+i+'_name');
}
setState('javascript.0.hydrawise.controller'+i+'_name', data.controllers[i].name );
//Controller[] letzter Kontakt (Denke das ist Hunter, die Daten vom Controller holen)
if (existsState('javascript.0.hydrawise.controller'+i+'_lastcontact')==false)
{
createState('javascript.0.hydrawise.controller'+i+'_lastcontact');
}
setState('javascript.0.hydrawise.controller'+i+'_lastcontact', data.controllers[i].last_contact );
//Controller[] Serial Number
if (existsState('javascript.0.hydrawise.controller'+i+'_serial_number')==false)
{
createState('javascript.0.hydrawise.controller'+i+'_serial_number');
}
setState('javascript.0.hydrawise.controller'+i+'_serial_number', data.controllers[i].serial_number );
//Controller[] ID
if (existsState('javascript.0.hydrawise.controller'+i+'_id')==false)
{
createState('javascript.0.hydrawise.controller'+i+'_id');
}
setState('javascript.0.hydrawise.controller'+i+'_id', data.controllers[i].controller_id );
//Controller[] Status
if (existsState('javascript.0.hydrawise.controller'+i+'_status')==false)
{
createState('javascript.0.hydrawise.controller'+i+'_status');
}
setState('javascript.0.hydrawise.controller'+i+'_status', data.controllers[i].status );
}
}
//*********************************/
function CreateRelays(data){
if ("undefined" !== typeof data.relays){
//log(data.relays);
//aktuellen Controller auslesen (wie schaltet man die Controller per API um, ausser auf der Website)
var i;
// alle Ventile auslesen
for (i = 0; i < data.relays.length; i++)
{
//Ventil ID
if (existsState('javascript.0.hydrawise.relay'+i+'_id')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_id');
}
setState('javascript.0.hydrawise.relay'+i+'_id', data.relays[i].relay_id );
//Ventil nächste Startzeit als Zeitstempel
if (existsState('javascript.0.hydrawise.relay'+i+'_time')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_time');
}
setState('javascript.0.hydrawise.relay'+i+'_time', data.relays[i].time );
//Ventil nächste Startzeit als String
if (existsState('javascript.0.hydrawise.relay'+i+'_timeS')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_timeS');
}
var a="";
if (data.relays[i].time<500000)
{
a = new Date().getTime() ;
a=a+data.relays[i].time*1000;
a = formatDate(a, 'DD.MM. hh:mm');
}
setState('javascript.0.hydrawise.relay'+i+'_timeS', a );
//Ventil Typ (?)
if (existsState('javascript.0.hydrawise.relay'+i+'_type')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_type');
}
setState('javascript.0.hydrawise.relay'+i+'_type', data.relays[i].type );
//Ventil Typ (Erwartete Laufzwit + Restlaufzeit in Sekunden)
if (existsState('javascript.0.hydrawise.relay'+i+'_run')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_run');
}
setState('javascript.0.hydrawise.relay'+i+'_run', data.relays[i].run );
//Ventil Typ (Erwartete Laufzeit + Restlaufzeit in Minuten)
if (existsState('javascript.0.hydrawise.relay'+i+'_run_min')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_run_min');
}
setState('javascript.0.hydrawise.relay'+i+'_run_min', Math.round(data.relays[i].run/60) );
//Ventil Nummer
if (existsState('javascript.0.hydrawise.relay'+i+'_relay')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_relay');
}
setState('javascript.0.hydrawise.relay'+i+'_relay', data.relays[i].relay );
//Ventil Name
if (existsState('javascript.0.hydrawise.relay'+i+'_name')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_name');
}
setState('javascript.0.hydrawise.relay'+i+'_name', data.relays[i].name );
//Ventil Period (???)
if (existsState('javascript.0.hydrawise.relay'+i+'_period')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_period');
}
setState('javascript.0.hydrawise.relay'+i+'_period', data.relays[i].period );
//Ventil nächste Beregnung als String
if (existsState('javascript.0.hydrawise.relay'+i+'_timestr')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_timestr');
}
var a=data.relays[i].timestr;
if (a=="Mon"){a="Montag";}
if (a=="Tue"){a="Dienstag";}
if (a=="Wed"){a="Mittwoch";}
if (a=="Thu"){a="Donnerstag";}
if (a=="Fri"){a="Freitag";}
if (a=="Sat"){a="Samstag";}
if (a=="Sun"){a="Sonntag";}
setState('javascript.0.hydrawise.relay'+i+'_timestr',a );
//Ventil stop (???)
if (existsState('javascript.0.hydrawise.relay'+i+'_stop')==false)
{
createState('javascript.0.hydrawise.relay'+i+'_stop');
}
setState('javascript.0.hydrawise.relay'+i+'_stop', data.relays[i].stop );
}
if ("undefined" !== typeof data.sensors){
//log (data.sensors);
//Sonsoren auslesen
var i;
for (i = 0; i < data.sensors.length; i++)
{
//Sensor Input
if (existsState('javascript.0.hydrawise.sensor'+i+'_input')==false)
{
createState('javascript.0.hydrawise.sensor'+i+'_input');
}
setState('javascript.0.hydrawise.sensor'+i+'_input', data.sensors[i].input );
//Sensor Type
if (existsState('javascript.0.hydrawise.sensor'+i+'_type')==false)
{
createState('javascript.0.hydrawise.sensor'+i+'_type');
}
setState('javascript.0.hydrawise.sensor'+i+'_type', data.sensors[i].type );
//Sensor Mode
if (existsState('javascript.0.hydrawise.sensor'+i+'_mode')==false)
{
createState('javascript.0.hydrawise.sensor'+i+'_mode');
}
setState('javascript.0.hydrawise.sensor'+i+'_mode', data.sensors[i].mode );
//Sensor timer
if (existsState('javascript.0.hydrawise.sensor'+i+'_timer')==false)
{
createState('javascript.0.hydrawise.sensor'+i+'_timer');
}
setState('javascript.0.hydrawise.sensor'+i+'_timer', data.sensors[i].timer );
//Sensor offtimer
if (existsState('javascript.0.hydrawise.sensor'+i+'_offtimer')==false)
{
createState('javascript.0.hydrawise.sensor'+i+'_offtimer');
}
setState('javascript.0.hydrawise.sensor'+i+'_offtimer', data.sensors[i].offtimer );
//Sensor rate
if (existsState('javascript.0.hydrawise.sensor'+i+'_rate')==false)
{
createState('javascript.0.hydrawise.sensor'+i+'_rate');
}
setState('javascript.0.hydrawise.sensor'+i+'_rate', data.sensors[i].rate );
}
}
}
else{console.warn('Response in JSON nicht gefunden ! ')}
}
Gibt es mittlerweile schon einen Adapter? Da ich mich mit der API vor kurzem beschäftigt habe, würde ich mich gerne mal daran probieren einen zu schreiben, fall es noch keinen gibt.
Da dieser Issue noch auf "Requested" steht gehe icch davon aus, dass es keinen Adapter gibt - zumindest keinen "offiziellen".
Ev. frag nochmal im Forum nach, z.B. in dem Thread: https://forum.iobroker.net/topic/6564/hydrawise-bew%C3%A4sserungsseuerung/16
Weiters liefert Google einen Adapter (https://github.com/Andreili1000/ioBroker.hydrawise) der aber auf den ersten Blick nicht finalisiert wirkt bzw. keine eleases aufzuweisen scheint. Ev. kannst du mit dem Entwickler Kontakt aufnehmen.
ICh setz den Adapter mal auf planned und assigne ihn dir. Bitte lass uns wissen, wenn du mit einer Enticklung ernsthaft beginnst und/oder wenn du das Projekt einstellst.
Falls du Fragen hast, kannst du gerne im Forum und im Telegramm Channel Support bekommen.
Danke im Voraus für deinen Einsatz
@DutchmanNL Grad erst gesehen, dass du dir den Request vor einiger Zeit assigned hast. Bist du da aktiv dran? Ansonsten assign ihn ev. an @aDabbelju
Gibt es mittlerweile schon einen Adapter? Da ich mich mit der API vor kurzem beschäftigt habe, würde ich mich gerne mal daran probieren einen zu schreiben, fall es noch keinen gibt.
Soweit mir bekannt noch nicht, wen du dich dem annehmen willst sehr gerne bei fragen und bissl Hilfe Stellung stehe ich gerne zur Verfügung und würde das issue dan auch an dich assignen ☺️
@DutchmanNL Dann versuche ich mich einmal daran und melde mich bei Fragen einfach :-)
@DutchmanNL Dann versuche ich mich einmal daran und melde mich bei Fragen einfach :-)
Cool viel Erfolg! Können uns auch gerne mal im Discord treffen bei Interesse oder fragen ☺️
Hi, super, dass es aufgenommen wird. Habe einen HC und Account. Stehe als Tester und mit Hardware / Zugang zur Verfügung. Einfach melden.
Würde mich auch gern als Tester anbieten. Grüße
@aDabbelju kann ich dich beim Adapter unterstützen? Mein Hydrawise Controller ist heute eingetroffen. Melde dich gern :)
Ich hatte die letzten Abende etwas Langeweile. Falls jemand testen möchte: https://github.com/SentiQ/ioBroker.hydrawise Aktuell nur auf einen Controller ausgelegt, da ich selbst nur einen besitze.
Die Installation und das Abrufen der Daten hat bisher funktioniert. Werde ich die Tage noch einmal genauer Testen. Schon mal vielen Dank.
@SentiQ @aDabbelju
Hi Zunächst DANKE für deine / eure Arbeot. ABER könntet ihr mich bitte aufklären ob es da nun 2 Adapter gibt oder einen.
Es gibt die Repos:
https://github.com/aDabbelju/ioBroker.hydrawise https://github.com/SentiQ/ioBroker.hydrawise
Und es gibt npmjs
https://www.npmjs.com/package/iobroker.hydrawise
Das npmjs Verzeichnis verweist auf das aDabbelju Repository - enthält aber die Releasenotes von SentiQ.
Irgendwie ist das für mich (und wahrscheinlich auch User verwirrend). Welcher Code ist nun auf npm hochgeladen? @SentiQ hast du das Repo und Npm übernommen? Oder seid ihr eine Person???
Bitte um Info / Klarstellung bzw. was npm betrifft um Bereinigung soweit möglich.
Bezüglich Test: Bitte mach doch eien Therad im Forum auf (https://forum.iobroker.net/category/91/tester). Dort erreichst du mehr Testwillige als hier.
Und wenn der Adapter so halbwegs für User brauchbar ist, fordere bitte die Aufnahme in die Repos an. Wenn du dazu irgendweölche HIfle bracuchst, bite heri auder auf Telegramm melden.
McM1957