Autor Thema: Modul-Fingerübung: Spritpreis  (Gelesen 2666 mal)

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Modul-Fingerübung: Spritpreis
« am: 11 Januar 2017, 11:07:36 »
Ich dachte mir, ich versuche mich mal an einem eigenen Modul und mach damit auch gleich was nützliches....

Es gibt ja schon ein paar Ansätze, um die vielen unterschiedlichen Benzinportale abzufragen, und mit tankerkoenig.de gibt es sogar ein Portal, das eine recht hübsche json API zur Verfügung stellt. Warum also nicht mal ein Modul schreiben, dass diese Schnittstelle nutzt und mir die Preise in meiner Gegend gibt.

Aktuell ist es auf das Tankerkoenig API zugeschnitten, aber ich denke, wenn ich die entsprechenden Funktionen um deine API ID erweitere, dann lassen sich leicht andere Quellen hinzufügen.

Takerkönig bietet die Preisabfrage entweder über Lokation und Radius oder über die IDs bestimmter Tankstellen.

Nachem ich hier nur schnell ein paar Zeilen zusammengeklöppelt habe (mir ging es mehr darum, zu verstehen, wie ein Modul from scratch entsteht), füllt es jetzt erstmal Readings mit den Werten nach Lokation/Radius. Der nächste Schritt ist dann aber die Funktion, die einfach nur für die Lokation und den Radius die IDs befüllt und danach nur noch per ID abfragt (die Last auf dem API ist, laut der Tankerkönig Doku) dann geringer.

Noch ist das hier sicher weit weg von tatsächlich nutzbar, aber vielleicht interessiert es ja den einen oder anderen und vielleicht gibt es auch noch ein paar Ideen, wie ich Dinge anders oder besser machen könnte. btw: mir ist bewusst, dass es gut dokumentierte Lösungen rund um den html Parser gibt, aber ich wollte es eben als Fingerübung für ein Modul nutzen.

72_Spritpreis.pm (ich habe die 72 gewählt, weil ein paar andere (fossile) Energie-Monitoring-Module da sind
##############################################
# $Id: 72_Spritpreis.pm 0 2017-01-10 12:00:00Z pjakobs $

package main;
 
use strict;
use warnings;

use Time::HiRes;
use Time::HiRes qw(usleep nanosleep);
use Time::HiRes qw(time);
use JSON::XS;
use Data::Dumper;
require "HttpUtils.pm";

$Data::Dumper::Indent = 1;
$Data::Dumper::Sortkeys = 1;

#####################################
#
# fhem skeleton functions
#
#####################################

sub
Spritpreis_Initialize(@) {
    my ($hash) = @_;

    $hash->{DefFn}          = 'Spritpreis_Define';
    $hash->{UndefFn}        = 'Spritpreis_Undef';
    $hash->{ShutdownFn}     = 'Spritpreis_Undef';
    $hash->{SetFn}          = 'Spritpreis_Set';
    $hash->{GetFn}          = 'Spritpreis_Get';
    $hash->{AttrFn}         = 'Spritpreis_Attr';
    $hash->{NotifyFn}       = 'Spritpreis_Notify';
    $hash->{ReadFn}         = 'Spritpreis_Read';
    $hash->{AttrList}       = "lat lon rad type sortby apikey"." $readingFnAttributes";
    return undef;
}

sub
Spritpreis_Define($$) {

    my ($hash, $def)=@_;
    my @parts=split("[ \t][ \t]*", $def);
    my $name=$parts[0];
    return undef;
}

sub
Spritpreis_Undef(@){
    return undef;
}

sub
Spritpreis_Set(@) {
    return undef;
}

sub
Spritpreis_Get(@) {
    my ($hash, $name, $cmd, @args) = @_;
    Spritpreis_Tankerkoenig_GetPricesForLocation($hash);
    # add price trigger here
    return $_;
}

sub
Spritpreis_Attr(@) {
    return undef;
}

sub
Spritpreis_Notify(@) {
    return undef;
}

sub
Spritpreis_Read(@) {
    return undef;
}

#####################################
#
# functions to create requests
#
#####################################

sub
Spritpreis_Tankerkoenig_GetIDsForLocation(@){
    my ($hash) = @_;
    my $lat=AttrVal($hash->{'NAME'}, "lat",0);
    my $lng=AttrVal($hash->{'NAME'}, "lon",0);
    my $rad=AttrVal($hash->{'NAME'}, "rad",5);
    my $type=AttrVal($hash->{'NAME'}, "type","diesel");
    my $sort=AttrVal($hash->{'NAME'}, "sortby","price");
    my $apikey=AttrVal($hash->{'NAME'}, "apikey","");

    if($apikey eq "") {
        Log3($hash,3,"$hash->{'NAME'}: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it");
        return "err no APIKEY";
    }

    my $url="https://creativecommons.tankerkoenig.de/json/list.php?lat=$lat&lng=$lng&rad=$rad&type=$type&sort=$sort&apikey=$apikey";
    my $param = {
        url      => $url,
        timeout  => 2,
        hash     => $hash,
        method   => "GET",
        header   => "User-Agent: fhem\r\nAccept: application/json",
        parser   => \&Spritpreis_ParseIDsForLocation,
        callback => \&Spritpreis_callback
    };
    HttpUtils_NonblockingGet($param);

    return undef;
}

sub
Spritpreis_Tankerkoenig_GetPricesForIDs(@){
    my ($hash) = @_;

    return undef;
}

sub
Spritpreis_Tankerkoenig_GetPricesForLocation(@){
    my ($hash) = @_;

    my $lat=AttrVal($hash->{'NAME'}, "lat",0);
    my $lng=AttrVal($hash->{'NAME'}, "lon",0);
    my $rad=AttrVal($hash->{'NAME'}, "rad",5);
    my $type=AttrVal($hash->{'NAME'}, "type","diesel");
    my $sort=AttrVal($hash->{'NAME'}, "sortby","price");
    my $apikey=AttrVal($hash->{'NAME'}, "apikey","");

    if($apikey eq "") {
        Log3($hash,3,"$hash->{'NAME'}: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it");
        return "err no APIKEY";
    }
    my $url="https://creativecommons.tankerkoenig.de/json/list.php?lat=$lat&lng=$lng&rad=$rad&type=$type&sort=$sort&apikey=$apikey";

    Log3($hash, 4,"$hash->{NAME}: sending request with url $url");
   
    my $param= {
        url      => $url,
        hash     => $hash,
        timeout  => 30,
        method   => "GET",
        header   => "User-Agent: fhem\r\nAccept: application/json",
        parser   => \&Spritpreis_ParsePricesForLocation,
        callback => \&Spritpreis_callback
     };
     HttpUtils_NonblockingGet($param);
     return undef;
}

#####################################
#
# functions to handle responses
#
#####################################

sub
Spritpreis_callback(@) {
     my ($param, $err, $data) = @_;
     my ($hash) = $param->{hash};
 
     # TODO generic error handling
     #Log3($hash, 5, "$hash->{NAME}: received callback with $data");
     # do the result-parser callback
     my $parser = $param->{parser};
     #Log3($hash, 4, "$hash->{NAME}: calling parser $parser with err $err and data $data");
     &$parser($hash, $err, $data);
 
     # Do readings update
 
     if( $err || $err ne ""){
         Log3 ($hash, 3, "$hash->{NAME} Readings NOT updated, received Error: ".$err);
     }
   return undef;
 }

sub
Spritpreis_ParseIDsForLocation(@){
    return undef;
}

sub
Spritpreis_ParsePricesForLocation(@){
    my ($hash, $err, $data)=@_;
    my $result;

    Log3($hash,5,"$hash->{NAME}: ParsePricesForLocation has been called with err $err and data $data");

    if($err){
        Log3($hash, 4, "$hash->{NAME}: error fetching nformation");
    } elsif($data){
        Log3($hash, 4, "$hash->{NAME}: got PricesForLocation reply");
        Log3($hash, 5, "$hash->{NAME}: got data $data\n\n\n");

        eval {
            $result = JSON->new->utf8(1)->decode($data);
        };
        if ($@) {
            Log3 ($hash, 4, "$hash->{NAME}: error decoding response $@");
        } else {
            my ($stations) = $result->{stations};
            #Log3($hash, 5, "$hash->{NAME}: stations:".Dumper($stations));
            readingsBeginUpdate($hash);
            foreach (@{$stations}){
                (my $station)=$_;

                #Log3($hash, 5, "$hash->{NAME}: Station hash:".Dumper($station));
                Log3($hash, 2, "Name: $station->{name}, id: $station->{id}\n");
                my $number=0;
               
                # make sure we update a record with an existign id or create a new one for a new id
                while(ReadingsVal($hash->{NAME},$number."_id",$station->{id}) ne $station->{id})
                {
                    $number++;
                }
                readingsBulkUpdate($hash,$number."_name",$station->{name});
                readingsBulkUpdate($hash,$number."_price",$station->{price});
                readingsBulkUpdate($hash,$number."_place",$station->{place});
                readingsBulkUpdate($hash,$number."_street",$station->{street}." ".$station->{houseNumber});
                readingsBulkUpdate($hash,$number."_distance",$station->{dist});
                readingsBulkUpdate($hash,$number."_brand",$station->{brand});
                readingsBulkUpdate($hash,$number."_lat",$station->{lat});
                readingsBulkUpdate($hash,$number."_lon",$station->{lng});
                readingsBulkUpdate($hash,$number."_id",$station->{id});
                readingsBulkUpdate($hash,$number."_isOpen",$station->{isOpen});
            }
            readingsEndUpdate($hash,1);
        }         
    }else {
        Log3 ($hash, 4, "$hash->{NAME}: something's very odd");
    }
    return $data;
}

sub
Spritpreis_ParsePricesForIDs(@){
}

1;

die Moduldefinition braucht im Moment folgendes:
define tanke Spritpreis
attr tanke apikey <bitte eigenen key generieren>
attr tanke lat <latitude - siehe twilight>
attr tanke lon <longitude - siehe twilight>
attr tanke rad 5
attr tanke sortby price
attr tanke type e5
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html
Gefällt mir Gefällt mir x 4 Liste anzeigen

Offline reibuehl

  • Full Member
  • ***
  • Beiträge: 364
Antw:Modul-Fingerübung: Spritpreis
« Antwort #1 am: 11 Januar 2017, 14:28:23 »
Tolle Idee! Wegen der Location: Würde es nicht Sinn machen, die "latitude" und "longitude" Werte aus dem "global" Device dafür zu nutzen?
Reiner.

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #2 am: 11 Januar 2017, 14:39:13 »
Tolle Idee! Wegen der Location: Würde es nicht Sinn machen, die "latitude" und "longitude" Werte aus dem "global" Device dafür zu nutzen?

als eine Option allemal, aber ich halte es auch für sinnvoll, ggf. mehrere Devices für unterschiedliche Lokationen zu haben (z.B. zuhause / Büro). Aber als Default, wenn nichts anderes angegeben ist, jap, das bau ich ein.

Danke

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #3 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

---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #4 am: 12 Januar 2017, 09:08:31 »
Sehr gute Idee mit dem Modul. Ich ringe seit Monaten damit ein Modul für Tankerkönig zuschreiben, bin aber aus Zeitmangeln nicht dazu gekommen. Umso besser das du es jetzt gemacht hast. :) Werde dies heute Abend testen.

Als weitere Idee: Die Tankstellen nicht nach Geokoordianten suchen, sondern die ID's direkt in einem Attribut übergeben.

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #5 am: 12 Januar 2017, 12:28:21 »
Sehr gute Idee mit dem Modul. Ich ringe seit Monaten damit ein Modul für Tankerkönig zuschreiben, bin aber aus Zeitmangeln nicht dazu gekommen. Umso besser das du es jetzt gemacht hast. :) Werde dies heute Abend testen.
erwarte bitte nix poliertes, es ist ziemlich "rough"
Als weitere Idee: Die Tankstellen nicht nach Geokoordianten suchen, sondern die ID's direkt in einem Attribut übergeben.
Ich bin noch am überlegen, wie ich das vom Bedienungsablauf machen.

Irgendwie muss der Anwender ja die IDs der Tankstellen bekommen und idealerweise sollte er das über das Modul können.
Dazu kann er entweder die Geookoordinaten nutzen, oder, jetzt neu, auch die Adresse.
Dann sollte er die interessanten Tankstellen auswählen können und danach werden nur noch die angefragt.

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline Hollo

  • Hero Member
  • *****
  • Beiträge: 1009
Antw:Modul-Fingerübung: Spritpreis
« Antwort #6 am: 12 Januar 2017, 12:34:16 »
Tankstellen in einem Radius sind mM. vermutlich zu viele (wohne auf dem Dorf, also dicht dran 0 und bei größerem Radius sehr viele).

Interessant fände ich Tankstellen zwischen 2 Koordinaten und dann Auswahlmöglichkeit, welche man davon möchte.
Dann könnte man z.B. die sehen, die auf dem täglichen "Arbeitsweg" (Wohnung<->Arbeit oder so) liegen.
FHEM 5.8 auf BananaPro Jessie
Protokolle: Homematic, Z-Wave, 433Mhz-Sender
Temp/Feuchte: JeeLink-Clone mit LaCrosse/IT
sonstiges: Linux-Server, dBox2, Dreambox, "RSS-Tablet"

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7445
  • fhem.cfg befreite Zone!
Antw:Modul-Fingerübung: Spritpreis
« Antwort #7 am: 12 Januar 2017, 12:47:29 »
erwarte bitte nix poliertes, es ist ziemlich "rough"Ich bin noch am überlegen, wie ich das vom Bedienungsablauf machen.

Irgendwie muss der Anwender ja die IDs der Tankstellen bekommen und idealerweise sollte er das über das Modul können.
Dazu kann er entweder die Geookoordinaten nutzen, oder, jetzt neu, auch die Adresse.
Dann sollte er die interessanten Tankstellen auswählen können und danach werden nur noch die angefragt.

pj

Schau Dir hierfür mal das UWZ Modul an. Interessant für Dich sollten UWZSearch* sein. Sind zwei Funktionen welche über einen Get Befehl aufgerufen werden. In der Antwort enthalten sind gleich Links um automatisch den korrekten Wert an zu legen.



Grüße
Leon
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier

Offline suppenesser

  • New Member
  • *
  • Beiträge: 28
Antw:Modul-Fingerübung: Spritpreis
« Antwort #8 am: 12 Januar 2017, 12:53:54 »
Die idee mit der Strecke von A nach B finde ich recht interessant, zusammen mit zb. der Standort Funktion in Telegram würde ich das als genial empfinden.

Strecke von A nach B im interval aktualisieren und, wenn von Telegram ein Standort kommt, davon im Umkreis von x km ermitteln. Das könnte man dann wiederum an Telegram schicken, wenn Bedarf!

Gesendet von meinem HUAWEI GRA-L09 mit Tapatalk

Raspberry PI B+ | HM-LAN-CFG | HM-LC-Sw1PBU-FM | HM-TC-WM-W-EU | DECT 200 | DHT22 | 1 Wire Temp.Sensoren

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #9 am: 12 Januar 2017, 13:32:37 »
Tankstellen in einem Radius sind mM. vermutlich zu viele (wohne auf dem Dorf, also dicht dran 0 und bei größerem Radius sehr viele).

Interessant fände ich Tankstellen zwischen 2 Koordinaten und dann Auswahlmöglichkeit, welche man davon möchte.
Dann könnte man z.B. die sehen, die auf dem täglichen "Arbeitsweg" (Wohnung<->Arbeit oder so) liegen.
Jetzt wird's aber anspruchsvoll ;-)
Ich denke, das lässt sich in erster Näherung mal mit mehreren Suchen im Radius um Punkte auf der Strecke machen (ich würde jetzt ungern auch noch mit Routenwahl anfangen) und Du suchst Dir dann die aus, die sinnvoll liegen. Das Modul klappert dann die eingegebenen Tankstellen an.

Für die Navigation unterwegs gibt's doch genug Navis mit Tankstellenfinder.

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #10 am: 12 Januar 2017, 13:50:06 »
Schau Dir hierfür mal das UWZ Modul an. Interessant für Dich sollten UWZSearch* sein. Sind zwei Funktionen welche über einen Get Befehl aufgerufen werden. In der Antwort enthalten sind gleich Links um automatisch den korrekten Wert an zu legen.



Grüße
Leon

Ah, ich sehe, das generiert eine html Tablelle aus der ich dann eine Zeile aussuchen kann.
d.h. ich kann, auf ähnliche Art, ein html Multiselect Form generieren und der Nutzer kann die gewünschten Tankstellen aussuchen. Cool! Danke :-) (vorausgesetzt, ich kann mit /fhem?cmd= " jedes beliebige fhem Kommando aufrufen. Was mich ja dann so Securitymäßig nervös macht. Aber das UI ist hier eh nicht abgesichert. Argh! Internet of Things und Security! Ich brauch'n Schnaps! ;-) )

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #11 am: 12 Januar 2017, 22:49:13 »
Also erster Test sieht soweit mal gut aus und Ergebnisse werden angezeigt. Aber wie du schon selbst sagtes, es muss noch weiterentwickelt werden.

Die Return Werte return "err no APIKEY"; musste ich ändern in return undef; sonst ist mir FHEM jedesmal abgestürzt.

Das Update würde ich persönlich über ein set update machen.

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #12 am: 13 Januar 2017, 09:31:50 »
Also erster Test sieht soweit mal gut aus und Ergebnisse werden angezeigt. Aber wie du schon selbst sagtes, es muss noch weiterentwickelt werden.

Die Return Werte return "err no APIKEY"; musste ich ändern in return undef; sonst ist mir FHEM jedesmal abgestürzt.

hmm... dann frag ich mich, wo darf ich eigentlich Strings zurückgeben und wo nicht.
Na ja, wie gesagt: mir ging es hier ja primär darum, zu lernen, wie Module from scratch gebaut werden müssen.

Das Update würde ich persönlich über ein set update machen.

Sicher, ich hab erstmal eine Routine geschireben, die überhaupt das API bedient und sie irgendwo eingebunden.
Gerade bin ich dabei, die Auswahl der Tankstellen zu ermöglichen, danach sehen wir weiter :-)

Danke für's Feedback

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7445
  • fhem.cfg befreite Zone!
Antw:Modul-Fingerübung: Spritpreis
« Antwort #13 am: 13 Januar 2017, 10:05:52 »
Packe Deinen String in eine Variable und gebe diese zurück.
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #14 am: 13 Januar 2017, 13:34:50 »
Packe Deinen String in eine Variable und gebe diese zurück.
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7445
  • fhem.cfg befreite Zone!
Antw:Modul-Fingerübung: Spritpreis
« Antwort #15 am: 13 Januar 2017, 14:40:07 »
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #16 am: 13 Januar 2017, 14:51:23 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7445
  • fhem.cfg befreite Zone!
Antw:Modul-Fingerübung: Spritpreis
« Antwort #17 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.
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.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #18 am: 13 Januar 2017, 17:01:18 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline gent

  • Full Member
  • ***
  • Beiträge: 130
Antw:Modul-Fingerübung: Spritpreis
« Antwort #19 am: 16 Januar 2017, 20:24:11 »
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

Offline Papaloewe

  • Full Member
  • ***
  • Beiträge: 259
Antw:Modul-Fingerübung: Spritpreis
« Antwort #20 am: 16 Januar 2017, 21:23:06 »
Vielleicht ist das ja nur bei mir so, aber ein:
update all https://github.com/pljakobs/fhem_spritpreis_module/blob/master/controls_spritpreis.txtfunktioniert 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

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #21 am: 17 Januar 2017, 09:20:33 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline mrfloppy

  • Jr. Member
  • **
  • Beiträge: 75
Antw:Modul-Fingerübung: Spritpreis
« Antwort #22 am: 17 Januar 2017, 09:39:59 »
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

Cubietruck, Fhem 5.8, CCU2, RFXtrx433 E USB, KeyMatic, Div. Thermostate, CUL433, Fhemduino, Temp/luftfeuchesensoren,Fensterkontakte,Intertechno Schalter,.......

Offline gent

  • Full Member
  • ***
  • Beiträge: 130
Antw:Modul-Fingerübung: Spritpreis
« Antwort #23 am: 17 Januar 2017, 18:29:48 »
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




Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #24 am: 21 Januar 2017, 17:41:52 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #25 am: 22 Januar 2017, 12:16:52 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline jkriegl

  • Full Member
  • ***
  • Beiträge: 103
Antw:Modul-Fingerübung: Spritpreis
« Antwort #26 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.
« Letzte Änderung: 22 Januar 2017, 20:51:14 von jkriegl »
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #27 am: 22 Januar 2017, 23:33:31 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #28 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

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #29 am: 24 Januar 2017, 09:22:08 »
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
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline jkriegl

  • Full Member
  • ***
  • Beiträge: 103
Antw:Modul-Fingerübung: Spritpreis
« Antwort #30 am: 24 Januar 2017, 13:55:19 »
@martins Du musst
set tanke add id <tankerkoenig id>
eingeben (wie beschrieben), ev. neu starten dann gibt es readings.
setz mal dasverbose hoch, damit es log gibt.

Danke @pjakobs, läuft wunderbar. Polle mit einem at bzw. einem dummy Taster. Die suche nach weiteren Stationen ist sehr simpel (Konfigurator).
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #31 am: 24 Januar 2017, 15:56:17 »
Verbose hatte ich schon auf 5, das ist alle was kam nach einem add

@jkriegl, ich glaube ich hab add id vergessen, ich testet es heute abend noch einmal

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #32 am: 25 Januar 2017, 00:01:44 »
Also läuft bei mir jetzt auch, lag aber daran das bei mir der apiKey nicht aus $hash->{helper}->{apiKey} gelesen werden kann, warum auch immer.

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #33 am: 25 Januar 2017, 19:43:30 »
Also läuft bei mir jetzt auch, lag aber daran das bei mir der apiKey nicht aus $hash->{helper}->{apiKey} gelesen werden kann, warum auch immer.
das ist strange - hast Du da ne Fehlermeldung für mich?

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #34 am: 25 Januar 2017, 22:44:19 »
Also ich hab nochmal etwas Debug betrieben.
Zeile 84 habe ich geändert in:
Log3 ($hash, 2, "$hash->{NAME}: error: " . Dumper($result));Output wäre:
2017.01.25 22:36:20 2: tanke3: error: $VAR1 = {
  'data' => 'MTS-K',
  'license' => 'CC BY 4.0 -  https://creativecommons.tankerkoenig.de',
  'ok' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
  'prices' => {
    '12121212-1212-1212-1212-121212121212' => {
      'status' => 'no prices'
    }
  }
};

Hier gibt es kein $result->{ok} = "true" ...und deswegen wird der define abgebrochen

Unabhängig davon müsstest du Zeile 84 abändern, da dort Syntaxfehler enthalten sind in:
Log3 ($hash, 2, "$hash->{NAME}: error: $result->{message}");

vg
martin

Offline unimatrix

  • Developer
  • Full Member
  • ****
  • Beiträge: 410
Antw:Modul-Fingerübung: Spritpreis
« Antwort #35 am: 29 Januar 2017, 22:02:04 »
Kann es sein dass es bei Tankerkoenig nicht mehr den Meldungsknopf gibt um die IDs zu finden? Oder geht das jetzt irgendwie anders?

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #36 am: 04 Februar 2017, 14:02:50 »
Moin zusammen,

ich hab endlich mal wieder Zeit gehabt, ein bisschen was hieran zu machen. Im Wesentlichen hab ein ein bisschen dokumentiert und ein auto-refresh eingebaut. Alles im "develop" Zweig.

Die ganzen Routinen sind zwar jetzt auf Tankerkoenig "gebranded" (d.h. sie haben alle Tankerkoenig im Namen), weshalb auch andere Anbieter-Routinen eingebaut werden können, aber die Grundstruktur des Moduls (also das Define, die set und get commands) sind noch nicht darauf eingerichtet, mit anderen APIs umgehen zu können.

Grüße

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #37 am: 07 Februar 2017, 08:36:05 »
kleine Änderung, große Wirkung: jetzt funktioniert auch das "set <tanke> search <Adresse>" wobei <Adresse eine gültige "Ort, Straße Hausnummer" Adresse sein muss, sonst findet die Google API allerhand, nur nicht die gesuchten Tankstellen.
Das Kommando führt zu einem Dialogfenster, in dem man die gewünschten Tankstellen per klick der internen Liste hinzufügen kann.
Als Umkreis für die Suche wird aktuell das Attribut rad genutzt, oder, alternativ, 5km.
Schaut Euch mal an, ob das Modul in der Form langsam nützlich wird, dann würde ich als nächstes wohl die Funktion für den Österreichischen Anbieter einbauen.

Grüße

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline mrfloppy

  • Jr. Member
  • **
  • Beiträge: 75
Antw:Modul-Fingerübung: Spritpreis
« Antwort #38 am: 07 Februar 2017, 15:36:42 »
..... dann würde ich als nächstes wohl die Funktion für den Österreichischen Anbieter einbauen.

Ja bitte das wäre sehr toll

LG
Cubietruck, Fhem 5.8, CCU2, RFXtrx433 E USB, KeyMatic, Div. Thermostate, CUL433, Fhemduino, Temp/luftfeuchesensoren,Fensterkontakte,Intertechno Schalter,.......

Offline jkriegl

  • Full Member
  • ***
  • Beiträge: 103
Antw:Modul-Fingerübung: Spritpreis
« Antwort #39 am: 07 Februar 2017, 18:27:57 »
klappt bei mir nicht
2017.02.07 18:00:12 3: Tanke2: get Tanke2 search München,
2017.02.07 18:00:12 3: Tanke2: request URL: https://maps.google.com/maps/api/geocode/json?address=+Kreilerstrasse+220+
2017.02.07 18:00:13 3: Tanke2: got coordinates for address as lat: 48.12126, lon: 11.66407
2017.02.07 18:00:13 3: Tanke2: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it
mit set Tanke2 add id <TK Id> kann ich welche hinzufügen.
Am wheezy-raspi klappt dies leider nicht, bekomme nur eine leeres 0_street reading.
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #40 am: 07 Februar 2017, 18:33:39 »
klappt bei mir nicht
2017.02.07 18:00:12 3: Tanke2: get Tanke2 search München,
2017.02.07 18:00:12 3: Tanke2: request URL: https://maps.google.com/maps/api/geocode/json?address=+Kreilerstrasse+220+
2017.02.07 18:00:13 3: Tanke2: got coordinates for address as lat: 48.12126, lon: 11.66407
2017.02.07 18:00:13 3: Tanke2: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it
mit set Tanke2 add id <TK Id> kann ich welche hinzufügen.
Am wheezy-raspi klappt dies leider nicht, bekomme nur eine leeres 0_street reading.

sorry, da hab ich die Syntax geändert, die ID gehört jetzt in's define
define <name> Spritpreis <api-key>

und die nächste Änderung kommt da dann auch bald, nämlich dann, wenn ich weitere Quellen einbaue, ich denke, dann wird es
define <name> Spritpreis <anbieter> <api-key>
Grüße

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline jkriegl

  • Full Member
  • ***
  • Beiträge: 103
Antw:Modul-Fingerübung: Spritpreis
« Antwort #41 am: 07 Februar 2017, 18:57:03 »
Hatte schon ein
define Tanke2 Spritpreis <api-key>
bei "set Tanke2 search München, Kreillerstraße 220" in cmd-Zeile passiert nichts.
bei "get" ..."search" München, Kreillerstrasse 220 -> log wie oben
« Letzte Änderung: 07 Februar 2017, 19:00:34 von jkriegl »
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram

Offline martins

  • Developer
  • Jr. Member
  • ****
  • Beiträge: 78
Antw:Modul-Fingerübung: Spritpreis
« Antwort #42 am: 07 Februar 2017, 23:10:39 »
Ich habe immer noch das Problem das ich die Logmeldung mit dem apikey bekomme, obwohl der define richtig durchgeführt wird
please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it

Offline Intruder1956

  • Full Member
  • ***
  • Beiträge: 351
  • Auch wenn man Älter wird, kann man besser werden
Antw:Modul-Fingerübung: Spritpreis
« Antwort #43 am: 07 Februar 2017, 23:27:40 »
bei mir ist das Fhem völlig abgestürzt bei der "define Tanke Spritpreis", so wie es im ersten Beitrag beschrieben
hatte als erstes dann das attr apikey eingetragen, dann ging nichts mehr
Ich konnte es erst wiederbeleben nachdem ich über WinSCP den Eintrag aus der fhem.cfg gelöscht hatte

das folgende habe ich in meinem Logfile gefunden
2017.02.07 08:58:09 1: PERL WARNING: Prototype mismatch: sub main::to_json ($@) vs ($) at /usr/share/perl/5.20/Exporter.pm line 66.
2017.02.07 08:58:09 1: PERL WARNING: Prototype mismatch: sub main::from_json ($@) vs ($) at /usr/share/perl/5.20/Exporter.pm line 66.
2017.02.07 08:58:09 3: Tanken: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it
2017.02.07 08:58:09 3: Tanken: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it
2017.02.07 08:58:09 3: Tanken: please provide a valid apikey, you can get it from https://creativecommons.tankerkoenig.de/#register. This function can't work without it
Undefined subroutine &main::err no APIKEY called at fhem.pl line 2902.
2017.02.07 08:58:40 1: BlockingInformParent (BlockingStart): Can't connect to localhost:7072: IO::Socket::INET: connect: Verbindungsaufbau abgelehnt
2017.02.07 08:58:40 1: BlockingInformParent (PRESENCE_ProcessLocalScan): Can't connect to localhost:7072: IO::Socket::INET: connect: Verbindungsaufbau abgelehnt
« Letzte Änderung: 07 Februar 2017, 23:29:57 von Intruder1956 »
Raspi 3 SD16GB+USB-Stick 32MB Jessie, Cul 868Mhz;Cul 433Mhz = Busware, JeeLink, HM-CFG-USB-2, FHEM 5.7, Uniroll, IT YCR-100 TMT2100,ITR-1500, LD382 mit Wifilight, ESA 2000 + SENSOR WZ SET,FS20 TFK, HM-Sec-SC, HM-CC-RT-DN, RPI B+, RPI2 und FB 7390 steht noch rum, keine Ahnung wofür einsetzen

Offline pjakobs

  • Full Member
  • ***
  • Beiträge: 305
Antw:Modul-Fingerübung: Spritpreis
« Antwort #44 am: 09 Februar 2017, 10:17:21 »
ok, mal sehen.

Zum APIKey, ja, den habe ich aus einem attr in die define Zeile verschoben, was deshalb sinnvoll ist, weil es für andere Anbieter andere Formate geben wird, und weil ein "Spritpreis" Device nur für einen Anbieter gültig sein kann.

In der Define Routine wird überprüft, das a) ein APIKey angegeben ist und b) der auch gültig ist.

a)
     if(defined $parts[2]){
         $apiKey=$parts[2];
     }else{
         Log3 ($hash, 2, "$hash->{NAME} Module $parts[1] requires a valid apikey");
         return undef;
     }
Damit wird das Modul mit der angegebenen Fehlermeldung im Log beendet. FHEM sollte problemlos weiter laufen.

b)
     my $result;
     my $url="https://creativecommons.tankerkoenig.de/json/prices.php?ids=12121212-1212-1212-12
 
     my $param= {
     url      => $url,
     timeout  => 1,
     method   => "GET",
     header   => "User-Agent: fhem\r\nAccept: application/json",
     };
 
     my ($err, $data)=HttpUtils_BlockingGet($param);
 
     if ($err){
         Log3($hash,2,"$hash->{NAME}: Error verifying APIKey: $err");
         return undef;
     }else{
         eval {
             $result = JSON->new->utf8(1)->decode($data);
         };
         if ($@) {
             Log3 ($hash, 4, "$hash->{NAME}: error decoding response $@");
         } else {
             if ($result->{ok} ne "true"){
                 Log3 ($hash, 2, "$hash->{name}: error: $result-{message}");
                 return undef;
             }
         }
         $hash->{helper}->{apiKey}=$apiKey;
     }
Hier verwende ich eine der Beispiel-Tankstellen-IDs (121212-....), um eine Dummy Anfrage an Tankerkönig zu senden. Nur, wenn darauf eine gültige ($result->{ok}) Antwort kommt, wird der APIKey übernommen, sonst gibt es eine Fehlermeldung und das Modul wird beendet.

@jkriegl, ich denke, in Deinem Fall ist es irgendeine der Zwischenversionen. Der Fehler, den Du bekommst tritt nur auf, wenn innerhalb einer der GetDetail oder UpdateForID Funktionen kein APIKey in $hash->{helper}->{apikey} liegt. Mein Vorschlag: installier mal die neueste Version (reload 72_Spritpreis.pm nicht vegessen), lösch das Device und mach den define neu.

@intruder1956 ich bin mir nicht sicher, was bei Dir da passiert. Auf alle Fälle fehlt auch bei Dir der APIKey.
Der define sollte lauten
define Tanke Spritpreis <apikey>

Auch in Deinem Fall würde ich vorschlagen, dass Du das Gerät löschst (wenn Du es aus der fhem.cfg gelöscht hast, dann solltest Du ein "shutdown restart" von der fhem Kommandozeile ausführen).
Ich kann es nicht mit absoluter Sicherheit sagen, aber ich glaube, dass der Absturz von fhem nicht von diesem Modul herrührt, denn
2017.02.07 08:58:40 1: BlockingInformParent (BlockingStart): Can't connect to localhost:7072: IO::Socket::INET: connect: Verbindungsaufbau abgelehnt
2017.02.07 08:58:40 1: BlockingInformParent (PRESENCE_ProcessLocalScan): Can't connect to localhost:7072: IO::Socket::INET: connect: Verbindungsaufbau abgelehnt
kommt eine halbe Minute nach der Fehlermeldung von Spritpreis.pm, allerdings finde ich
Undefined subroutine &main::err no APIKEY called at fhem.pl line 2902
ausgesprochen seltsam.
Der String "err no APIKEY" kommt ein paar mal im Modul vor, immer als
return "err no APIKEY"
und ich verstehe nicht, warum fhem versuchen sollte, die Funktion "err no APIKEY" aufzurufen, wenn ich einen String Literal zurückgebe.

Aber grundsätzlich auch in Deinem Fall: bitte mal die neueste Version (aus dem develop Zweig) installieren und den define entsprechend ändern. Das Ding ist zwar noch nicht bug-free, läuft bei mir aber einwandfrei.

Ach so: ja, wenn eine Funktion aufgerufen wird, die nicht existiert, dann stirbt fhem. Ich übernehme keine Garantie, dass das hier nicht ab und an passiert - es ist, wie ich schrieb a) eine Fingerübung und b) work in progress ;-) Not for the faint at heart.

Nochwas: Gerät löschen geht am einfachsten, wenn Ihr das Gerät in der fhem UI anklickt und dann ganz unten auf "delete this device" klickt. Dann ist es sofort aus der laufenden Instanz gelöscht. Aber Achtung: aus dem Config File wird es erst gelöscht, wenn Ihr oben links auf "save config" klickt.

@intruder1956: weil Du schreibst, dass Du winscp benutzt hast: Du kannst die config-files (zumindest das fhem.cfg) auch aus dem fhem-UI heraus bearbeiten - unten links, edit files.

Grüße

pj
---------

RGBWWCW Controller Modul: https://forum.fhem.de/index.php/topic,55065.0.html

Offline pc1246

  • Sr. Member
  • ****
  • Beiträge: 866
  • tempus fugit
Antw:Modul-Fingerübung: Spritpreis
« Antwort #45 am: 20 März 2017, 21:32:55 »
Hallo pj
Ich habe gestern Dein Modul in Betrieb genommen. Soweit alles gut, wenn auch das mit den id's sehr doof war. Auf Tankerkoenig konnte ich bei mir in der NAehe nichts erzeugen, habs dann etwas anders gemacht. Dein get hat bei mir nicht funktioniert, es kam immer die Meldung missing key!
Jetz wuerde ich gern ein Plot erzeugen, aber irgendwie scheinen die Werte nicht Plottauglich zu sein. Hast Du da noch einen Tipp?
Danke und Gruss Christoph
RasPi2
Jeelink mit 1 ETH200comfort; Onkyo_AVR;3 Enigma2; SB_Server ; SB_Player; netatmo; HM-USB mit 14 HM-CC-RT-DN, 3 HM_WDS10_TH_O; PhilipsTV; add-on board mit 6 IT-Steckdosen;3 harmony hub; Jeelink mit 6 PCA301; Somfy;
S7-300; 2 LGW; KS300

Offline pc1246

  • Sr. Member
  • ****
  • Beiträge: 866
  • tempus fugit
Antw:Modul-Fingerübung: Spritpreis
« Antwort #46 am: 22 März 2017, 21:20:46 »
Hallo zusammen
Ja, der Herr Christoph ist mal wieder zu bloed gewesen! Aus irgendeinem Grund war beim Plot Spalte 3 statt Spalte 4 ausgewaehlt. Das laesst sich natuerlich schlecht darstellen. Mit 4 laeuft es aber wie Butter, da kann ich dann schon mal erkennen, wann ich definitiv nicht tanken werde!
Gruss, und Danke nochmals
Christoph
RasPi2
Jeelink mit 1 ETH200comfort; Onkyo_AVR;3 Enigma2; SB_Server ; SB_Player; netatmo; HM-USB mit 14 HM-CC-RT-DN, 3 HM_WDS10_TH_O; PhilipsTV; add-on board mit 6 IT-Steckdosen;3 harmony hub; Jeelink mit 6 PCA301; Somfy;
S7-300; 2 LGW; KS300

 

decade-submarginal