Modul-Fingerübung: Spritpreis

Begonnen von pjakobs, 11 Januar 2017, 11:07:36

Vorheriges Thema - Nächstes Thema

CoolTux

Zitat von: pjakobs am 13 Januar 2017, 13:34:50
Ernsthaft? Es return geht nicht mit string literals? :o

Ich hab übrigens mal die Sache mit der Tankstellenauswahl gebaut, das funktioniert ganz gut, aber wenn ich eine html Form zurückgebe, dann kann ich offenbar keinen submit Button einbauen bzw. der wird nicht angezeigt. Hast Du da ne Idee?


Grüße

pj

Sicherlich geht es auch als String. Aber das müsste ich mir auch erstmal selber ansehen. So aus dem Kopf heraus will ich mich da nicht festlegen, dafür gebe ich zu selten Werte zurück.
Am besten Du überprüfst erstmal martins Aussage.


Zum Button. Du kannst doch einen Link anlegen lassen


my $aHref="<a href=\"http://".$headerHost[0]."/fhem?cmd=get+".$name."+AreaID+".$value->{'latitude'}.",".$value->{'longitude'}."\">Get AreaID</a>";


Stat dem get Befehl als Link machst Du einfach ein modify Befehl oder das setzen eines Attributes.



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

pjakobs

Zitat von: CoolTux am 13 Januar 2017, 14:40:07
Zum Button. Du kannst doch einen Link anlegen lassen


my $aHref="<a href=\"http://".$headerHost[0]."/fhem?cmd=get+".$name."+AreaID+".$value->{'latitude'}.",".$value->{'longitude'}."\">Get AreaID</a>";


klar, aber mein erster Gedanke war: hey klasse, da mach ich ein Form mit Mehrfachauswahl. Geht wohl nicht so einfach.

pj

CoolTux

Wenn Deine Funktion in der Abfrage als Antwort mehrere Datensätze zurück gibt dann funktioniert es. Anders wüsste ich auch nicht.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

pjakobs

Zitat von: CoolTux am 13 Januar 2017, 15:12:13
Wenn Deine Funktion in der Abfrage als Antwort mehrere Datensätze zurück gibt dann funktioniert es. Anders wüsste ich auch nicht.

             my ($stations) = $result->{stations};
             my $ret="<html><p><h3>Stations for Address</h3></p><p><h2>$formattedAddress</h2></p><form action='fhem/cmd?set ".$hash-  >{NAME}." station' method='get'><select multiple name='id'>";
             foreach (@{$stations}){
                 (my $station)=$_;

                 Log3($hash, 2, "Name: $station->{name}, id: $station->{id}");
                 $ret=$ret."<option value=".$station->{id}.">".$station->{name}." ".$station->{place}." ".$station->{street}." ".     $station->{houseNumber}."</option>";
             }
             $ret=$ret."<button type='submit'>submit</button></form></html>";
             Log3($hash,2,"$hash->{NAME}: ############# ret: $ret");
             return $ret;


der fhem popup hat einen eigenen "ok" button, der submit button wird, laut DOM, wegoptimiert.
Vermutlich sind einzelne Links doch der beste Weg.

pj

gent

Zitat von: pjakobs am 11 Januar 2017, 21:12:59
so, ich hab's mal auf github geschoben, vielleicht interessiert's wen

alles noch Stückwerk und mir ist auch noch nicht ganz klar, wie ich damit umgehen will...

Eine Möglichkeit:
Ich implementiere eine "add location" Funktion, die eine Adresse übernimmt, die geokoordinaten bestimmt und die Tankstellen im Umkreis zur Liste hinzufügt. Damit könnte ein Gerät dann Tankstellen an mehreren Orten beinhalten.
Das Preisupdate würde dann immer nur die Liste der Tankstellen-IDs durchlaufen und für die schon bekannten neue Preise anfragen, egal, wo die sich befinden.
Tankstellen löschen ginge vermutlich genauso: Adresse oder geolokation und Radius übergeben, alle IDs die sich daraus ergeben werden aus den Readings geworfen.

Andere Möglichkeit:
die Lokation wird immer in den Attributen lat/lon gespeichert und die geolokations-Routine dient einfach nur dazu, die herauszufinden. Update wie oben. Wird keine Lokation angegeben, verwende ich die von $global, wird eine Adresse angegeben wird die aufgelöst und verwendet, aber nicht im Attribut gespeichert. Das heißt halt dann, dass zusätzlich zur Preisabfrage bei jedem Durchlauf (ich denke irgendwo zwischen alle 5 und 15 Minuten ist sinnvoll) eine Anfrage an Google Maps geschickt wird.

Was ich gerade noch nicht verstehe: wenn ich fhem neu starten muss (und das kommt ja leider manchmal vor, wenn man dicke Finger hat), dann sind alle Readings weg. Ich nehme an, ich muss die bei der Initialisierung irgendwoher lesen...?

pj

Schau mal bei Tankerkönig nach, da gibt es einen Konfigurator

https://creativecommons.tankerkoenig.de/configurator/index.html

Das finde ich eigentlich ziemlich genial, da man als Ergebnis ein json Objekt bekommt, welches man dann in der api verwenden abfragen kann. Ich glaube, dass der "normale" Homeautomation User die Tankstellen, die er abfragen will auch kennt. Mit dem Konfigurator kann man dann alle Tankstellen (Wohnort, Arbeitsort, Entlang einer Route etc... ) übernehmen. Hier mal ein Beispiel

{
  "8d66b8be-5037-4822-8ab4-1aa7b3b8a657": {
    "label": "ESSO | Esso Tankstelle",
    "coords": {
      "lat": 48.659946,
      "lng": 9.221958
    },
    "address": [
      "BONLAENDER HAUPTSTR. 132",
      "70794 FILDERSTADT"
    ],
    "openingTimes": {
      "Mo - Sa": [
        "06:00 - 22:00"
      ],
      "So": [
        "08:00 - 22:00"
      ]
    }
  },
  "de20bca5-64e2-4a4a-71f8-40a562277e6d": {
    "label": "BFT Filderstadt | BFT Station Filderstadt",
    "coords": {
      "lat": 48.658139,
      "lng": 9.195942
    },
    "address": [
      "Schillerstrasse 55",
      "70794 Filderstadt"
    ],
    "openingTimes": {
      "Mo - Sa": [
        "06:30 - 21:30"
      ],
      "So": [
        "08:00 - 21:30"
      ]
    }
  }
}


Vielleicht wäre das etwas, was alle Bedürfnisse befriedigen könnte?

Viele Grüße vom Gent
fhem auf rPi3 mit USB boot und M2, cul866 (hm), homebridge, FlowerSens, Shelly, Harmony, WemosD1, Sonoff/Tasmota, grafana, mqtt/mosquitto

Papaloewe

Vielleicht ist das ja nur bei mir so, aber ein:
update all https://github.com/pljakobs/fhem_spritpreis_module/blob/master/controls_spritpreis.txt
funktioniert nicht und es erscheint nur:
2017.01.16 21:22:00 1 : PERL WARNING: Use of uninitialized value $r[0] in string eq at /opt/fhem/FHEM/98_update.pm line 308.
2017.01.16 21:22:00 1 : PERL WARNING: Use of uninitialized value $r[0] in string ne at /opt/fhem/FHEM/98_update.pm line 318.
2017.01.16 21:22:00 1 : nothing to do...


Hat jemand eine Idee?
Danke & Gruß
Thomas

pjakobs

Zitat von: gent am 16 Januar 2017, 20:24:11
Schau mal bei Tankerkönig nach, da gibt es einen Konfigurator

https://creativecommons.tankerkoenig.de/configurator/index.html

Das finde ich eigentlich ziemlich genial, da man als Ergebnis ein json Objekt bekommt, welches man dann in der api verwenden abfragen kann. Ich glaube, dass der "normale" Homeautomation User die Tankstellen, die er abfragen will auch kennt. Mit dem Konfigurator kann man dann alle Tankstellen (Wohnort, Arbeitsort, Entlang einer Route etc... ) übernehmen. Hier mal ein Beispiel


Vielleicht wäre das etwas, was alle Bedürfnisse befriedigen könnte?

Viele Grüße vom Gent

das ist sehr geil, hatte ich noch nicht gesehen und könnte perfekt passen! Danke!

pj

mrfloppy

Hallo

Könnte man da ev. auch die österreichischen Spritpreise einpflegen.

In Österreich gibt es diese Seite: http://www.spritpreisrechner.at

Für eine Abfrage habe ich diese Seiten dazu gefunden:

https://blog.muehlburger.at/2011/08/spritpreisrechner-at-apps-entwickeln und
http://gregor-horvath.com/spritpreis.html

Ich muss sagen ich habe von dem null Ahnung.

Könnte sich das mal jemand anschauen ob und wie man das in fhem umsetzen kann?

Danke und LG Thomas

RaspiMatic, RFXtrx433 E USB, Div. Thermostate, CUL433, Fhemduino, Signalduino, Temp/luftfeuchesensoren,Fensterkontakte,Intertechno Schalter,....... HM-IP

gent

Hi mrfloppy,

ich denke, das könnte man mit dem HTTPMOD Modul machen. Ich habe in der commandref gelesen, dass man auch post requests machen kann. Das ist in deinem zweiten Link ja auch als "problem" erkannt. Normalerweise sind solche "apis" per http-get Methode aufgebaut. D.h. man kann einfach eine URL schicken z.B.:

http://www.spritpreisrechner.at/espritmap-app/GasStationServlet?parameter1=value&parameter2=value...

das hat aber Gregor Horvath geschrieben geht mit dem spritpreisrechner.at nicht. Deswegen hat er einen "Übersetzer-Server" gebaut, der dann aus eine get-request den für den spritpreisrechner erforderlichen post-request erstellt und die Antwort dann aufbereitet zurückschickt.

Also kurz, was Du tun könntest:

1. Du liest Dich in die Benutzung des HTTPMOD Moduls ein und schickst post-requests an den spritpreisrechner.at... (das habe ich auf die Schnelle nicht richtig hinbekommen)
oder
2. Du gehst auf die Seite von  Gregor Horvath, schickst ihm die nötigen Infos (und evtl. eine kleine Spende) und erhältst einen parametrierten Link. Diesen wiederum kannst Du dann recht einfach mit httpmod auslesen und Dir so wie wir das hier mit unserem tankerkönig.de auch machen die nötigen Readings anlegen.

Viele Grüße vom gent



fhem auf rPi3 mit USB boot und M2, cul866 (hm), homebridge, FlowerSens, Shelly, Harmony, WemosD1, Sonoff/Tasmota, grafana, mqtt/mosquitto

pjakobs

kurzes Update - auch wenn es immer noch nur eine Sammlung von Routinen ist, nimmt es langsam eine fassbare Form an.

Heute habe ich allerdings scheinbar mal kurzfristig den API Server von Tankerkönig getötet, weil ich in einer Schleife ohne funktionierende Abbruchbedingung Requests geschickt hab. So ein $i++ zu vergessen kann schon blöd sein :o

pj

pjakobs

so, ich hab gerade mal eine neue Version in den develop Zweig eingecheckt.

Was funktioniert:


define tanke Spritpreis <api-key>
attr tanke IDs <comma separated list of tankerkoenig station ids>


Beim Start des Moduls wird, wenn das IDs Attribut gesetzt ist, die Funktion

Spritpreis_Tankerkoenig_populateStationsFromAttr($hash);

aufgerufen, diese liest das IDs Attr und erstellt Reading Set mit den Details der einzelnen angegebenen Stationen (es ist noch wenig Error Handling eingebaut)

In der aktuellen Version läuft noch kein Timer, aber mit

set tanke update all

(wobei "tanke" natürlich mein device name ist) werden alle aktuell in den Readings angelegten IDs mit frischen Preisen und Öffnungsstatus upgedatet.

Was auch geht:

set tanke add id <tankerkoenig id>

damit wird eine neue Tankstelle zu den Readings hinzugefügt, sie wird allerdings (noch) nicht in das IDs Attr geschrieben.


set tanke update id <tankerkoenig id>

macht ein update der Werte für die angegebene ID - wenn sie schon angelegt ist.

Es ist auch noch ein haufen anderer Code drin, der zum großen Teil (noch ) nicht genutzt wird, irgendwann muss ich aufräumen :D

pj

jkriegl

#26
Es funktioniert - Die attr Ids alleine haben nicht ausgereicht. Nach einem set tanke add id <> wurden die readings erzeugt.
Aber woher bekommt man Station-IDs? (Habe noch die bisherigen)
Könnte man sich nicht bei update das all sparen, denn entweder alle oder mit einem id.
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

pjakobs

Zitat von: jkriegl am 22 Januar 2017, 20:48:23
Es funktioniert - Die attr Ids alleine haben nicht ausgereicht. Nach einem set tanke add id <> wurden die readings erzeugt.
Aber woher bekommt man Station-IDs? (Habe noch die bisherigen)
Könnte man sich nicht bei update das all sparen, denn entweder alle oder mit einem id.

Das ist ja alles noch am wachsen :-)

Dass die IDs im Attribut nicht ausgereicht haben wundert mich, ansich sollten die readings beim define angelegt werden - vielleicht ist der Aufruf aber auch zu früh, ich hab mal gelesen, dass es noch einen Hook nach dem define gibt. Muss ich mal nachsehen.

Die IDs liefert das Tankerkönig api, Die Routinen für eine Umkreissuche sind schon drin, nur noch nicht "verdrahtet" (also: suche um eine Adresse mit Radius 5km).
Die andere Möglichkeit ist der Tankerkönig Konfigurator, der sogar entlang einer Strecke suchen kann. Der liefert dann ein json file zurück, dass das Modul parsen kann.

Übrigens aufpassen: die Preise werden aktuell noch nicht automatisch aktualisiert! auch das kommt noch ;-)

pj

martins

Also ich weis nicht, ich bekomme es garnicht zum laufen.
Hab per attr eine ID gesetzt und auch per add. Readings werden garkeine erzeugt. Im Log bekomme ich folgendes:
tanke3: get tanke3 add all
tanke3 add: args[0]=all

pjakobs

Zitat von: martins am 23 Januar 2017, 22:46:03
Also ich weis nicht, ich bekomme es garnicht zum laufen.
Hab per attr eine ID gesetzt und auch per add. Readings werden garkeine erzeugt. Im Log bekomme ich folgendes:
tanke3: get tanke3 add all
tanke3 add: args[0]=all


ist das alles an Long was kommt? Das ist seltsam. Ich gestehe, ich hab es nie mit nur einer einzigen ID getestet...

pj