GOOGLE WETTER XML API DLL

Dieser Bereich ist für den Austausch FERTIGER Makros und allgemein nützlicher Schaltungen vorgesehen.
Antworten
ExpertProfi
Beiträge: 43
Registriert: Freitag 30. Januar 2009, 11:36

GOOGLE WETTER XML API DLL

Beitrag von ExpertProfi » Freitag 22. Juni 2012, 13:33

Hallo Kollegen,
nach längerer Abstinenz melde ich mich heute zurück mit einem neuen Projekt, das vielleicht Euren Geschmack trifft...

Abfrage der Google-Stadtwetter-Info aus dem Internet, wie z.B.
http://www.google.com/ig/api?weather=Kiel&hl=DE
für sehr viele Städte und in diversen Sprachen

Um die Daten in PL verfügbar zu machen, habe ich eine DLL geschrieben,
die die Daten abruft und die XML-Info parst. Google hat die Schnittstelle zwar nicht
dokumentiert, aber sie funktioniert z.Zt. prima. (Natürlich weiss ich nicht ob der
Service für immer lizenzfrei, offen und unverändert weiter besteht.)

Für alle die wissen möchten was die DLL macht, füge ich unten die Source an.

Hier nun das Ergebnis... Viel Spass mit der 0-cost-Wetterstation ... Freue mich auf Rückmeldungen...

DOWNLOAD:
http://www.expertprofi.wg.am/Google_Wetter_API_DLL.zip
Wetter.jpg
Wetter.jpg (99.76 KiB) 13933 mal betrachtet

ExpertProfi
Beiträge: 43
Registriert: Freitag 30. Januar 2009, 11:36

Re: GOOGLE WETTER XML API DLL

Beitrag von ExpertProfi » Freitag 22. Juni 2012, 13:34

... und hier die DLL-Source ...

Code: Alles auswählen

library Wetter;

// Google Wetter XML API
// Beispiel: http://www.google.com/ig/api?weather=Berlin';

uses
  SysUtils,
  Windows,
  Classes,
  VCL.controls, VCL.Forms,
  idHttp, Xml.xmldom, Xml.XMLIntf, Xml.Win.msxmldom, Xml.XMLDoc,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;


{$R *.RES}

Const  Server = 'http://www.google.com/ig/api?weather=';

       Inputs = 3;  // number of inputs
       Outputs = 12; // number of outputs

       {INPUTS}
       LocationInPin   = 0;   // $PLZ oder ORT
       LanguageInPin   = 1;   // DE, UK, ...
       CLKPin   = 2;   // Clock
       {USER}
       DLLIndex = 100;       // DLL No. set by ProfiLab

Type TDLLParams = array[0..100] of extended;   // Type of ProfiLab DLL parameters
     PDLLParams = ^TDLLParams;                 // Pointer to ProfiLab DLL parameters

     TStringParams = array[0..100] of PAnsiChar;   // Additional string parameters for CalculateEx
     PStringParams = ^TStringParams;               // Pointer to string parameters


var XMLDoc: TXMLDocument;
    DataList: array[0..100] of TStringList;
    Location: String;
    Language: String;

function NumInputs: Byte;
begin
  result:=Inputs; //Define number of component input pins
end;

function NumOutputs: Byte;
begin
  result:=Outputs; //Define number of component output pins
end;

Function InputName(Channel: Byte): ShortString; // Return name for each component input pin
begin
   // string inputs must be named with leading '$' character
   case Channel of
   LocationInPin:  result:='$LOC';   //  Location: PLZ oder Ort
   LanguageInPin:  result:='$LAN';   //  Language de, uk, ...
   ClkPin:         result:='CLK';    //  Update Clk
   end;
end;

Function OutputName(Channel: Byte): ShortString; // Return name for each component output pin
begin
   // string outputs must be named with leading '$' character!
   case Channel of
   0: result:='$LOC'; // Ort
   1: result:='$ZIP'; // PLZ
   2: result:='$DTE'; // Datum
   3: result:='$CDN'; // aktuelle Wetterbdingung
   4: result:='$ °F'; // Aktuelle Temperatur F
   5: result:='$ °C'; // Aktuelle Temperatur C
   6: result:='$HUM'; // Luftfeuchtigkeit %
   7: result:='$WND'; // Wind
   8: result:='$FC1'; // Vorhersage heute + 1 Tag
   9: result:='$FC2'; // Vorhersage heute + 2 Tag
   10: result:='$FC3'; // Vorhersage heute + 3 Tag
   11: result:='$FC4'; // Vorhersage heute + 4 Tag
   end;
end;

// ###########################  XML PARSING #########################

function GetNodeData(aNode: IXMLNode): String;
begin
   result:='';
   if aNode=nil then exit;
   result:=aNode.LocalName;
   try
      result:=aNode.Attributes['data'];
   except
   end;
end;

procedure GetNodeChildren(aNode: IXMLNode);
var i: Integer;
    ChildNode: IXMLNode;
    aString: String;
begin
   if aNode=nil then exit;
   for i:=0 to aNode.ChildNodes.Count-1 do
   begin
      ChildNode:=aNode.ChildNodes[i];
      DataList[0].add(GetNodeData(ChildNode));
      GetNodeChildren(ChildNode);
   end;
end;

function NodeByLocalName(aNode: IXMLNode; aLocalName: String; var Appear: Integer): IXMLNode;
var ChildNode: IXMLNode;
   i: Integer;
begin
   result:=nil;
   if aNode=nil then exit;
   if aNode.LocalName=aLocalName then
   begin
      dec(Appear);
      if appear<=0 then
      begin
         result:=aNode;
         exit;
      end;
   end;
   for i:=0 to aNode.ChildNodes.Count-1 do
   begin
      ChildNode:=aNode.ChildNodes[i];
      result:=NodeByLocalName(ChildNode, aLocalName, Appear);
      if result<>nil then exit;
   end;
end;

function StreamToString(Stream : TStream) : String;
var ms : TMemoryStream;
begin
  Result := '';
  ms := TMemoryStream.Create;
  try
    ms.LoadFromStream(Stream);
    SetString(Result,PAnsiChar(ms.memory),ms.Size);
  finally
    ms.free;
  end;
end;

function ReadSite(URI: string): String; // Request mit Indy 10 componenten
 var
   idClient: TIdHTTP;
   msData: TMemoryStream;
   ResultString: String;
begin
     ResultString:='';
     idClient := TIdHTTP.Create(Application);
     idClient.Request.AcceptLanguage:=Language;
     msData := TMemoryStream.Create;
     try
       idClient.Get(URI, msData);
       msData.Seek(0, soFromBeginning);
       ResultString := StreamToString(msData);
     finally
        idClient.Free;
        msData.Free;
     end;

   result := ResultString;
end;

procedure GetDataList; // XML PARSER
var InfoNode: IXMLNode;
    ConditionsNode: IXMLNode;
    ForecastNode: IXMLNode;
    aNode: IXMLNode;
    ForeCastString, UnitSystem: String;
    Appear,i: Integer;
begin
   xmldoc.XML.Add(ReadSite('http://www.google.com/ig/api?weather='+Location));

   xmldoc.Active:=true;

   //General Info
   Appear:=1;
   InfoNode:=NodeByLocalName(xmldoc.DocumentElement, 'forecast_information', Appear);
   Appear:=1;
   aNode:=NodeByLocalName(InfoNode, 'city', Appear);
   DataList[0].Add(GetNodeData(aNode));
   Appear:=1;
   aNode:=NodeByLocalName(InfoNode, 'postal_code', Appear);
   DataList[0].Add(GetNodeData(aNode));
   Appear:=1;
   aNode:=NodeByLocalName(InfoNode, 'forecast_date', Appear);
   DataList[0].Add(GetNodeData(aNode));
   Appear:=1;
   aNode:=NodeByLocalName(InfoNode, 'unit_system', Appear);
   UnitSystem:=GetNodeData(aNode);

   // Current condition
   Appear:=1;
   ConditionsNode:=NodeByLocalName(xmldoc.DocumentElement, 'current_conditions', Appear);
   Appear:=1;
   aNode:=NodeByLocalName(ConditionsNode, 'condition', Appear);
   DataList[0].Add(GetNodeData(aNode));
   Appear:=1;
   aNode:=NodeByLocalName(ConditionsNode, 'temp_f', Appear);
   DataList[0].Add(GetNodeData(aNode)+' °F');
   Appear:=1;
   aNode:=NodeByLocalName(ConditionsNode, 'temp_c', Appear);
   Appear:=1;
   DataList[0].Add(GetNodeData(aNode)+' °C');
   Appear:=1;
   aNode:=NodeByLocalName(ConditionsNode, 'humidity', Appear);
   DataList[0].Add(GetNodeData(aNode));
   Appear:=1;
   aNode:=NodeByLocalName(ConditionsNode, 'wind_condition', Appear);
   DataList[0].Add(GetNodeData(aNode));

   //4x Forcast
   for i:=1 to 4 do
   begin
      Appear:=i;
      ForeCastNode:=NodeByLocalName(xmldoc.DocumentElement, 'forecast_conditions', Appear);
      Appear:=1;
      aNode:=NodeByLocalName(ForecastNode, 'day_of_week', Appear);
      ForeCastString:=GetNodeData(aNode)+';';
      Appear:=1;
      aNode:=NodeByLocalName(ForecastNode, 'condition', Appear);
      ForeCastString:=ForeCastString+GetNodeData(aNode)+';';
      Appear:=1;
      aNode:=NodeByLocalName(ForecastNode, 'low', Appear);
      ForeCastString:=ForeCastString+GetNodeData(aNode)+';';
      Appear:=1;
      aNode:=NodeByLocalName(ForecastNode, 'high', Appear);
      ForeCastString:=ForeCastString+GetNodeData(aNode)+';'+UnitSystem;
      DataList[0].Add(ForeCastString);
   end;

   xmldoc.Active:=false;
end;


// ##################

// New CalculateEx method now allows string parameters...
Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams); //called regularly from ProfiLab
var aString: AnsiString;
    aWord: Word;
    aChar: AnsiChar;
    aExtended: extended;
    Hour, Min, Sec, MSec: Word;
    i: integer;
    DLLNo: Integer;
begin
   DLLNo:=round(PUser^[DLLIndex]); // Die ProfiLab DLL Nummer
   if Datalist[0]=nil then DataList[0]:=TStringlist.Create; // Templiste zum Daten holen
   if Datalist[DllNo]=nil then DataList[DllNo]:=TStringlist.Create; // Listen für bis zu 100 DLL-Import (Wetter für 100 Orte)

   if (PInput^[ClkPin]<2.5) and (PUser^[ClkPin]>=2.5) then // Abfrage Taktsignal
   begin
      Location:=strPas(PStrings[LocationInPin]);  // Der Ort
      while pos('  ',location)>0 do location:=StringReplace(Location,'  ',' ',[rfReplaceAll]);
      location:=StringReplace(Location,' ','+',[rfReplaceAll]);
      Language:=strPas(PStrings[LanguageInPin]);  // Die Sprache

      Datalist[0].Clear; // Templiste leeren
      XMLDoc:=TXMLDocument.Create(Application); // XML vorbereiten
      GetDataList; // Daten holen und XML parsen => Ergebnis in Datalist[0]
      DataList[DLLno].Assign(Datalist[0]); // Tempdaten der passenden DLL zuordnen
      XMLDoc.Free; // Daten fertig
   end;

   PUser^[ClkPin]:=PInput^[ClkPin]; // Alten Clock merken

   // Ausgangswerte (aus passender Datenliste) ausgeben
   for i:=0 to 11 do
   begin
      if DataList[DllNo].count>i then strPCopy(PStrings[i], DataList[DLLNo][i])
                          else strPCopy(PStrings[i], '');
   end;
end;


//export methods for ProfiLab
exports NumInputs,
        NumOutputs,
        CalculateEx,
        InputName,
        OutputName;

begin

end.

HCS
Beiträge: 189
Registriert: Montag 3. November 2008, 16:11
Kontaktdaten:

Re: GOOGLE WETTER XML API DLL

Beitrag von HCS » Freitag 22. Juni 2012, 19:54

Ein wahrhaftiger EXPERTPROFI!! Respekt!!

Werde versuchen, eine intelligente Brenner - Solarverknüpfung daraus zu machen.
So könnte man vorausschauend den Boiler laden und morgens wenn Sonne zu erwarten ist, den Brenner sperren.

Hast du dann vor, wenn Google das Protokoll etwas ändert, deine DLL wieder anzupassen?

Gruß
Bernd

ExpertProfi
Beiträge: 43
Registriert: Freitag 30. Januar 2009, 11:36

Re: GOOGLE WETTER XML API DLL

Beitrag von ExpertProfi » Montag 25. Juni 2012, 08:01

Danke, die Idee stammt aus einem Artikel, auf den ich zufällig gestossen bin...
http://www.keepaneye.de/wetterdaten-aus ... verwenden/
Dank fertiger Komponenten für XML und INDY10 für Netzprotokolle war die Sache nicht
allzu schwierig. Ich habe versucht das Parsen so zu gestalten, das die XML-Tags
auch dann noch funktionieren müssten, wenn Google den Service erweitern sollte,
solange die derzeitigen Tags erhalten bleiben. Ich wollte nur darauf hinweisen,
dass die Komponente von einem Google-Dienst abhängig ist, d.h. man weiss nicht
was die Zukunft bringt.

P.S. Ich habe gerade noch festgestellt, dass im ersten Upload noch ein Bug war.
(Schutzverletzung bei fehlender Netzwerkverbindung)
Ich habe jetzt eine neue Version hochgeladen. Bitte obigen Download ggf. nochmasl durchführen.
Die Source der neuen Version ist im Download enthalten.
25. Juni 2012 - 10.15 Uhr MESZ

abacom
Site Admin
Beiträge: 3917
Registriert: Dienstag 23. September 2008, 10:54
Kontaktdaten:

Re: GOOGLE WETTER XML API DLL

Beitrag von abacom » Dienstag 26. Juni 2012, 08:11

Wir freuen uns über dieses gelungene Projekt von ExpertProfi, welches vor längerer Zeit auch schon einmal angeregt wurde.
Wir selbst hatten etwas Ähnliches auch schon einmal ins Auge gefasst, aber mangels einer verlässlichen Dokumentation
seitens Google wieder verwerfen müssen. Gute Arbeit und vielen Dank!
ABACOM support

KAKTUS
Beiträge: 651
Registriert: Samstag 18. Oktober 2008, 21:12

Re: GOOGLE WETTER XML API DLL

Beitrag von KAKTUS » Dienstag 26. Juni 2012, 11:24

Tolles Projekt.

Kaktus sagt DANKE !

PS: mit welcher Software hast du die DLL erstellt?
stachlige Grüße, Kaktus

ExpertProfi
Beiträge: 43
Registriert: Freitag 30. Januar 2009, 11:36

Re: GOOGLE WETTER XML API DLL

Beitrag von ExpertProfi » Mittwoch 27. Juni 2012, 07:16

Hallo Kaktus,
die DLL ist mit Delphi XE2 erstellt. In älteren Delphi-Versionen
wird man die verwendeten Komponenten
(INDY10 und XML) vermutlich vergeblich suchen.
Es gibt auch eine kostenlose 30-Tage Trial-Version...
http://www.embarcadero.com/de/products/delphi

KAKTUS
Beiträge: 651
Registriert: Samstag 18. Oktober 2008, 21:12

Re: GOOGLE WETTER XML API DLL

Beitrag von KAKTUS » Mittwoch 27. Juni 2012, 15:53

Danke
stachlige Grüße, Kaktus

tom_g
Beiträge: 215
Registriert: Freitag 31. Oktober 2008, 14:59

Re: GOOGLE WETTER XML API DLL

Beitrag von tom_g » Freitag 29. Juni 2012, 12:56

Hi ExpertProfi,

gelungene DLL ! Das Forum lebt von solchen "Perlen" wie Deiner Wetter-DLL !

Ich habe die Daten mal geloggt "messen übers Web"
Blau: Feuchte, rot: Temp, grün: Windspeed
Anbei das Beispiel des Klimas an meinem Wohnort über vergangene 2 Tage.

Wieso jittern die Signale so ?

Ich habe die Strings von Temp, Feuchtigkeit und Windspeed nur mit "value" in einen Wert konvertiert, und nicht weiter untersucht, ob die Konversion in allen Fällen gut funktioniert.

Beste Grüsse von Thomas
Dateianhänge
Profi_wetter.jpg
Profi_wetter.jpg (13.61 KiB) 13494 mal betrachtet
Curiousity makes us progress !

abacom
Site Admin
Beiträge: 3917
Registriert: Dienstag 23. September 2008, 10:54
Kontaktdaten:

Re: GOOGLE WETTER XML API DLL

Beitrag von abacom » Montag 2. Juli 2012, 08:07

Das müsste man dann wohl Google fragen. Der Dienst ist vermutlich für die Google Wetter-Gadgets.
http://www.google.com/ig/directory?type ... eather.xml
ABACOM support

HCS
Beiträge: 189
Registriert: Montag 3. November 2008, 16:11
Kontaktdaten:

Re: GOOGLE WETTER XML API DLL

Beitrag von HCS » Sonntag 2. September 2012, 09:18

... leider geht die Google-Funktion scheinbar nicht mehr!
Sehr schade.

Bernd

Bernie
Beiträge: 8
Registriert: Montag 16. Mai 2011, 09:10

Re: GOOGLE WETTER XML API DLL

Beitrag von Bernie » Donnerstag 4. Oktober 2012, 17:58

Hallo zusammen,

ich bekomme folgende Meldung:

Hat jemand eine Idee ?

Viele Grüße
Bernd
Dateianhänge
Bild2.jpg
Bild2.jpg (58.41 KiB) 11728 mal betrachtet

KAKTUS
Beiträge: 651
Registriert: Samstag 18. Oktober 2008, 21:12

Re: GOOGLE WETTER XML API DLL

Beitrag von KAKTUS » Donnerstag 4. Oktober 2012, 19:46

stachlige Grüße, Kaktus

Bernie
Beiträge: 8
Registriert: Montag 16. Mai 2011, 09:10

Re: GOOGLE WETTER XML API DLL

Beitrag von Bernie » Dienstag 9. Oktober 2012, 12:38

Danke Kaktus für die schnelle Antwort. Da hätte ich ja auch selbst drauf kommen können :roll:

Viele Grüße
Bernd

Antworten

Zurück zu „Makros & Schaltungen“