Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Thingspeak - Datenabruf (https://www.delphipraxis.net/212985-thingspeak-datenabruf.html)

Rollo62 3. Mai 2023 07:32

AW: Thingspeak - Datenabruf
 
Könnte es bei der SSL Fehlermeldung nicht einfach an fehlenden SSL DLL-Libraries oder Konfiguration liegen ?

Uwe Raabe 3. Mai 2023 08:30

AW: Thingspeak - Datenabruf
 
Zitat:

Zitat von Schleifchen (Beitrag 1521939)
@Uwe: die Werte sollen in einem Array gespeichert werden

Wie verhält sich diese Aussage zu dieser?
Zitat:

Zitat von Schleifchen (Beitrag 1521933)
Ziel ist es die abgerufenen Werte in eine SQlite-Datenbank einzutragen.


rabatscher 3. Mai 2023 10:00

AW: Thingspeak - Datenabruf
 
Dein Problem ist SSL. In deinem Code wird kein SSL handler konfiguriert - ein kleiner Check per Browser zeigt,
dass TLS1.2 dort zumindest verwendet wird. Du müsstest die SSL handler in diese Richtung konfigurieren:

function CreateCon : TIdHTTP;
begin
Result := TIdHTTP.Create(nil);
sslIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Result);
sslIOHandler.SSLOptions.Method := sslvTLSv1_2;

Result.IOHandler := sslIOHandler;
Result.ConnectTimeout := 6000;
Result.ReadTimeout := 6000;
end;


Einfacher:
Ich würde im url mal statt HTTPS:// nur HTTP:// verwenden.
Der Server unterstützt http auch ;)

himitsu 3. Mai 2023 10:28

AW: Thingspeak - Datenabruf
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1521946)
Wie verhält sich diese Aussage zu dieser?
Zitat:

Zitat von Schleifchen (Beitrag 1521933)
Ziel ist es die abgerufenen Werte in eine SQlite-Datenbank einzutragen.


Joar, nahezu für jedes DBMS gibt es Import-Funktionen für CSV,
nur leider oft über die Konsole. (selten, indem man die CSV-Daten als einen VARCHAR/TEXT übergibt)

Gut, man könnte im SQL auch den Text selber über Funktionen zerlegen und den Feldern für's INSERT übergeben,
aber die SQlite-DB liegt auch vermutlich eh auf dem selben System, wie der Client, was das Problem einfacher lösen lassen könnte.

Ja, natürlich kann man die CSV auch im Delphi-Code zerlegen und manuell Feld für Feld und Record (Zeile) für Record einzeln posten. :stupid:
OK, es wäre so bissl langsamer, da viele DB-Aufrufe, aber es würde wohl auch bissl RAM/Cache sparen, wenn man es nicht im SQL löst.

Schleifchen 3. Mai 2023 11:22

AW: Thingspeak - Datenabruf
 
Hallo, der Hinweis von rabatscher:
Zitat:

Ich würde im url mal statt HTTPS:// nur HTTP:// verwenden.
ist vorerst die einfachste Lösung und funzt auch. DANKE, hätte ich auch selber drauf kommen können :-), bin ich aber nicht :-(
Mein weiterer Plan wäre jetzt aus
Code:
resultStr
die Anweisung für die Datenbank zu erstellen.

Jetzt möchte ich bei allen Bedanken und mangels Wissen mORMot für später aufheben.

Danke
Stefan

mytbo 3. Mai 2023 16:00

AW: Thingspeak - Datenabruf
 
Zitat:

Zitat von Schleifchen (Beitrag 1521957)
Jetzt möchte ich bei allen Bedanken und mangels Wissen mORMot für später aufheben.

Ich finde, die Umsetzung mit mORMot ist einfach. Die CSV-Datei enthält Zeichen an Stellen, an dem diese bestimmt nicht hingehören. Ohne diese Überraschung wäre es ein No-Brainer. Daher folgende praktische (mit kleinen Umwegen) Lösung:
Delphi-Quellcode:
uses
  mormot.core.base,
  mormot.core.data,
  mormot.core.text,
  mormot.core.perf,
  mormot.core.search,
  mormot.core.unicode,
  mormot.core.variants,
  mormot.core.datetime,
  mormot.core.os,
  mormot.net.client,
  mormot.orm.base,
  mormot.orm.core,
  mormot.orm.sqlite3,
  mormot.rest.core,
  mormot.rest.sqlite3,
  mormot.db.raw.sqlite3,
  mormot.db.raw.sqlite3.static;
 
type
  TCsvItem = packed record
    created_at: String;
    entry_id: Integer;
    field1: Double;
    field2: Double;
    field3: Double;
    field4: String;
  end;
  TCsvItems = array of TCsvItem;

  TOrmCsvItem = class(TOrm)
  private
    FCreatedAt: TDateTime;
    FField1: Double;
    FField2: Double;
    FField3: Double;
    FField4: Integer;
  published
    property CreatedAt: TDateTime
      read FCreatedAt write FCreatedAt;
    property Field1: Double
      read FField1 write FField1;
    property Field2: Double
      read FField2 write FField2;
    property Field3: Double
      read FField3 write FField3;
    property Field4: Integer
      read FField4 write FField4;
  end;

function UpdateCsvItems(const pmcDBFileName: TFileName): Integer;
const
  BASE_URL = 'https://api.thingspeak.com/channels/1671193/feeds.csv?start=';
var
  csvItems: TCsvItems;
begin
  Result := -1;
  var restClient: TRestClientDB := TRestClientDB.Create(TOrmModel.Create([TOrmCsvItem]), Nil, pmcDBFileName, TRestServerDB, {HandleUserAuthentication=}False);
  try
    restClient.Model.Owner := restClient;
    restClient.DB.Synchronous := smOff;
    restClient.DB.LockingMode := lmExclusive;
    restClient.Server.CreateMissingTables(0, [itoNoAutoCreateGroups, itoNoAutoCreateUsers]);

    var ormItem: TOrmCsvItem := TOrmCsvItem.Create;
    try
      var startTime: TDateTime := IncYear(Now, -100);
      var maxID: TID := restClient.TableMaxID(TOrmCsvItem);
      if (maxID >= 0) and restClient.Retrieve(maxID, ormItem) then
        startTime := ormItem.CreatedAt;

      var url: RawUtf8 := BASE_URL + DateTimeToIso8601(startTime, {Expanded=}True, 'T', {WithMS=}False, '"');
      if DynArrayLoadCsv(csvItems, HttpGet(url), TypeInfo(TCsvItems)) then
      begin
        if Length(csvItems) = 0 then Exit; //=>

        restClient.BatchStart(TOrmCsvItem);
        for var i: Integer := 0 to High(csvItems) do
        begin
          if csvItems[i].entry_id <= maxID then Continue;

          with csvItems[i] do
          begin
            ormItem.IDValue := entry_id;
            ormItem.CreatedAt := Iso8601ToDateTime(StringToUtf8(created_at));
            ormItem.Field1 := field1;
            ormItem.Field2 := field2;
            ormItem.Field3 := field3;
            ormItem.Field4 := field4.Trim.ToInteger;
          end;
          restClient.BatchAdd(ormItem, True, True);
        end;

        var insRowIDs: TIDDynArray;
        if restClient.BatchSend(insRowIDs) = HTTP_SUCCESS then
          Result := Length(insRowIDs);
      end;
    finally
      ormItem.Free;
    end;
  finally
    restClient.Free;
  end;
end;
Damit sind alle Daten in der SQLite Datenbank. Auch die SQLite DB-Engine ist mit im Programm. Aufrufen kannst du die Funktion wie folgt:
Delphi-Quellcode:
var
  timer: TPrecisionTimer;
begin
  timer.Start;
  ShowMessage(Format('New insert: %d, Time: %s', [UpdateCsvItems(MakePath([Executable.ProgramFilePath, 'daten.db3'])), timer.Stop]));
Bis bald...
Thomas

Schleifchen 3. Mai 2023 17:53

AW: Thingspeak - Datenabruf
 
Hallo Thomas, ich bekomme mORMot nicht zum Laufen.
  1. habe unter GitHub die gesamte Datei curl-master.zip geladen und in den Order D:\Programme\RAD-Studio\mORMot2 entpackt.
  2. im RAD-Studio unter Tools->Sprache->Bibliotheken-> Bibliothekspfad und Suchpfad um
    Code:
    D:\Programme\RAD-Studio\mORMot2\src;D:\Programme\RAD-Studio\mORMot2\src\app;D:\Programme\RAD-Studio\mORMot2\src\core;D:\Programme\RAD-Studio\mORMot2\src\crypt;D:\Programme\RAD-Studio\mORMot2\src\db;D:\Programme\RAD-Studio\mORMot2\src\lib;D:\Programme\RAD-Studio\mORMot2\src\misc;D:\Programme\RAD-Studio\mORMot2\src\net;D:\Programme\RAD-Studio\mORMot2\src\orm;D:\Programme\RAD-Studio\mORMot2\src\rest;D:\Programme\RAD-Studio\mORMot2\src\script;D:\Programme\RAD-Studio\mORMot2\src\soa;D:\Programme\RAD-Studio\mORMot2\src\tools\ecc;D:\Programme\RAD-Studio\mORMot2\src\ui;[*]
    ergänzt.

Während des Compilierens erscheint die Fehlermeldung:
Code:
[dcc32 Fehler] mormot.lib.z.pas(603): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibdeflate.obj'
[dcc32 Fehler] mormot.lib.z.pas(604): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibtrees.obj'
[dcc32 Fehler] mormot.lib.z.pas(605): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibinflate.obj'
[dcc32 Fehler] mormot.lib.z.pas(606): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibinftrees.obj'
[dcc32 Fehler] mormot.lib.z.pas(607): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibadler32.obj'
[dcc32 Fehler] mormot.lib.z.pas(608): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibcrc32.obj'
[dcc32 Fehler] mormot.lib.z.pas(609): E1026 Datei nicht gefunden: '..\..\static\delphi\zlibinffast.obj'
[dcc32 Fehler] mormot.lib.z.pas(178): E2065 Ungenügende Forward- oder External-Deklaration: 'crc32'
[dcc32 Fehler] mormot.lib.z.pas(185): E2065 Ungenügende Forward- oder External-Deklaration: 'adler32'
[dcc32 Fehler] mormot.lib.z.pas(642): E2065 Ungenügende Forward- oder External-Deklaration: 'deflate'
[dcc32 Fehler] mormot.lib.z.pas(643): E2065 Ungenügende Forward- oder External-Deklaration: 'deflateEnd'
[dcc32 Fehler] mormot.lib.z.pas(644): E2065 Ungenügende Forward- oder External-Deklaration: 'inflate'
[dcc32 Fehler] mormot.lib.z.pas(645): E2065 Ungenügende Forward- oder External-Deklaration: 'inflateEnd'
[dcc32 Fehler] mormot.lib.z.pas(647): E2065 Ungenügende Forward- oder External-Deklaration: 'deflateInit_'
[dcc32 Fehler] mormot.lib.z.pas(649): E2065 Ungenügende Forward- oder External-Deklaration: 'inflateInit_'
[dcc32 Fehler] mormot.lib.z.pas(652): E2065 Ungenügende Forward- oder External-Deklaration: 'deflateInit2_'
[dcc32 Fehler] mormot.lib.z.pas(654): E2065 Ungenügende Forward- oder External-Deklaration: 'inflateInit2_'
[dcc32 Fehler] mormot.lib.z.pas(655): E2065 Ungenügende Forward- oder External-Deklaration: 'get_crc_table'
[dcc32 Fataler Fehler] mormot.core.zip.pas(797): F2063 Verwendete Unit 'mormot.lib.z.pas' kann nicht compiliert werden
??? sicherlich weist Du auf Anhieb was ich wiedermal vergessen habe....?:?

mytbo 3. Mai 2023 18:16

AW: Thingspeak - Datenabruf
 
Zitat:

Zitat von Schleifchen (Beitrag 1521975)
Hallo Thomas, ich bekomme mORMot nicht zum Laufen.

Lade dir mORMot2 Master herunter. Dann die Static-Binaries mORMot2Static.7z aus dem letzten Tag herunterladen. Entpacke den mORMot2 Master in dein gewünschtes Verzeichnis. Entpacke die Static-Binaries in das static Verzeichnis des mORMot2 Ordners. Dann die Bibliotheks- und Suchpfade in Delphi eintragen.

Bis bald...
Thomas

Schleifchen 3. Mai 2023 18:39

AW: Thingspeak - Datenabruf
 
Oh danke, das läuft jetzt.
Aber noch immer nicht fehlerfrei:
Code:
[dcc32 Fehler] Project1.dpr(58): E2003 Undeklarierter Bezeichner: 'TFileName'
[dcc32 Fehler] Project1.dpr(65): E2250 Es gibt keine überladene Version von 'Create', die man mit diesen Argumenten aufrufen kann
[dcc32 Fehler] Project1.dpr(74): E2003 Undeklarierter Bezeichner: 'IncYear'
[dcc32 Fehler] Project1.dpr(96): E2018 Record, Objekt oder Klassentyp erforderlich
[dcc32 Fehler] Project1.dpr(96): E2035 Nicht genügend wirkliche Parameter
[dcc32 Fehler] Project1.dpr(114): E2029 Deklaration erwartet, aber Dateiende gefunden
Misslungen
:cry:

mytbo 3. Mai 2023 18:45

AW: Thingspeak - Datenabruf
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Schleifchen (Beitrag 1521979)
Oh danke, das läuft jetzt.
Aber noch immer nicht fehlerfrei:

Hast du diese Delphi Units vergessen?
Delphi-Quellcode:
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, System.DateUtils,
Und auch Interface und Implementation Abschnitt schön getrennt.

Nachtrag: Habe besser gleich ein Beispiel Projekt (siehe Anhang) erstellt.

Bis bald...
Thomas


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:28 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz