[TRIXI] Implementation Delphi 7

Ich habe die Version 0.12 runtergeladen und dann die dort vorhandene Delphi TRIXI.EXE und DLL in ein Verzeichnis kopiert.
Der Connect will mit nicht gelingen (immer „Fail“). Die IP-Adresse ist definitiv correct gesetzt, die Firewall habe ich testweise mal abgeschaltet, ipconsole läuft ohne Probleme; auch auf dem IPS-Server selbst gibt’s kein connect (mit localhost bzw. 127.0.0.1).
Hmmmmmm, da stehe ich momentan etwas dumm da. Ein Tip zum Start wäre gut. Ich wollte in Delphi7 einen kleinen Raumtemperatur-Regler (bzw. das Bedienteil) Programmieren und dafür die aktuelle IST-Temperatur, letzte Aktualsierung und momentane SOLL-Temperatur (editierbar) anzeigen lassen.

Schau ich mir Montag an. vielleicht ist mir ein Fehler beim packen des Pakets unterlaufen. Hast du mal ne andere Exe aus dem Paket versucht?

Gruß,

Toni

Ich habe eben mal verschiedene EXE aus der ZIP Datei probiert:
-Delphi Prism EXE funktioniert!
-Delphi exe (430080 Bytes) funktioniert nicht (Fail); diese fehlerhafte EXE ist zweimal in der ZIP Datei vorhanden in \demo\ und \demo\delphi

Okay, dann habe ich mal eben die Delphi-Demo selbst kompiliert: Läuft NICHT
???

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

function Connect(Server: PAnsiChar; Port: Integer): Boolean; stdcall external 'TRIXI.DLL';
function Disconnect(): Boolean; stdcall external 'TRIXI.DLL';
function IsOnline(): Boolean; stdcall external 'TRIXI.DLL';
function WriteString(Variable: Integer; Value: PAnsiChar): Integer; stdcall external 'TRIXI.DLL';
function WriteInteger(Variable: Integer; Value: Integer): Integer; stdcall external 'TRIXI.DLL';
function WriteFloat(Variable: Integer; Value: Double): Integer; stdcall external 'TRIXI.DLL';
function WriteBoolean(Variable: Integer; Value: Boolean): Integer; stdcall external 'TRIXI.DLL';
function ReadString(Variable: Integer): PAnsiChar; stdcall external 'TRIXI.DLL';
function ReadInteger(Variable: Integer): Integer; stdcall external 'TRIXI.DLL';
function ReadFloat(Variable: Integer): Double; stdcall external 'TRIXI.DLL';
function ReadBoolean(Variable: Integer): Boolean; stdcall external 'TRIXI.DLL';
function RunScript(Variable: Integer): Integer; stdcall external 'TRIXI.DLL';

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    if Connect('192.168.3.8', 3773) then
    showmessage('Online')
  else
    showmessage('Fail');
end;

end.

Ich habe meine EXE eben noch mal überprüft:
-die Trixi.DLL wird korrekt geladen (sagt auch der Process Explorer)
-mit Wireshark habe ich mal die laufende Kommunikation mit dem IPS-Server mitgeschnitten: Da gehen überhaupt keine Pakete raus!
Vielleicht hilft das zu weiteren Auffindung der Ursache.

Guten Morgen,
ich habe mir zum Vergleich mal PULSE.zip von Tonis Seite heruntergeladen und die darin enthaltene TRIXI.DLL in ein funktionierendes DELPHI-Programm eingebunden. - Ergebnis siehe screenshot- Die "alte " DLL ist in Ordnung.
Toni: Vielleicht ist sie ja wirklich beim zippen verändert worden.
:frowning:

Ich kriege allerdings manchmal(1-2 mal täglich) Zugriffsfehler in meinem Delphi Programm. Ich denke das passiert beim gleichzeitigen Zugriff von IPS und der EXE.
Ich werde den nächsten Fehler mal posten - kommt natürlich jetzt, wo ich ihn bräuchte nicht !!

Aber:
Kompliment - die dll ist klasse!!!

Trixi.PNG

Ich kann keinerlei Probleme nachvollziehen. Das Paket scheint in Ordnung zu sein. Ihr müsst mir schon sagen was genau ihr gemacht habt damit ich den Fehler nachstellen kann.

Recht unwahrscheinlich. Wenn, dann kann das höchstens passieren wenn du selbst in mehreren Threads die selbe dll verwendest. Aber die SOAP Schnittstelle kann das normal ab. Dafür ist sie ja gebaut.

Zeig mir doch mal deine Deklaration für ReadBoolean.

Toni

Hallo,
wie ich heute morgen geschrieben habe : das Programm läuft.
Der Fehler tritt jetzt natürlich nicht auf, dann hätte ich ja die Fehler-Adresse(Murphy)
Ich benutze DELPHI 7 . Unten ein Teil des Codes.
Das Programm läuft auf einem Rechner im Netz, IP-Symcon auf einem 2. Rechner. Das Programm wird nur einmal ausgeführt.
ich habe im IP-Symcon sporadisch Meldungsfehler (siehe Grafik)
ich kann aber leider nicht nachvollziehen, ob die IPS-Meldungen zeitgleich mit den Zugriffsverletzungen auftreten.

Das sind die Zeilen - Das Script läuft alle 30 sec.



//Scriptauszug PHP
Zeile48  PJ_SwitchLED($id_lcd,3,FALSE);
Zeile49   PJ_SwitchLED($id_lcd2,3,FALSE);
Zeile50   IPS_Sleep(50); //Wartenn
Zeile51   PJ_SwitchLED($id_lcd,3,true); // grün
Zeile52   PJ_SwitchLED($id_lcd2,3,true); // grün
Zeile53   PJ_LCDText($id_lcd, 2, $a1.$a2); // Text in Zeile 2 ausgeben
Zeile54   PJ_LCDText($id_lcd2, 2, $a1.$a2); // Text in Zeile 2 ausgeben
ende IPS-Script



//////////////////////////////////////////////////////////////////////
ab hier ist der Delphi-Code

// ich lese die Werte aus einer INI-Datei ein 
// und aktualisiere über einen Timer so alle 20 sec.





procedure TForm1.FormCreate(Sender: TObject);
 var
   CWinfoINI : TIniFile;
begin
  // INI-Datei lesen
 slistbox1.Items.Clear;

   CWINFOINI := TIniFile.Create('.\CWINFO.ini');
   try
[b]pumpe_bo:=CWINFOINI.ReadInteger('CW','pumpe_bo',0);[/b]garage_bo:=CWINFOINI.ReadInteger('CW','garage_bo',0);
brenner_bo:=CWINFOINI.ReadInteger('CW','brenner_bo',0);
Anrufer_st:=CWINFOINI.ReadInteger('CW','anrufer_st',0);
Nummer_st:=CWINFOINI.ReadInteger('CW','nummer_st',0);
usw..........
   finally
     cwinfoINI.Free;
end;
zaehler := 20;
  if not Connect('192.168.0.16', 3773) then
    begin
      ShowMessage('ohne Rechner geht nix!!');
    end;
end;

procedure aktualisieren;
var
z : single;
i: integer;
 alt : String;
Begin
with form1 DO
begin
DownloadJPEGToImage('http://192.168.0.25:8025/snapshot.jpg',image1);

[b]if readboolean(pumpe_bo) THEN[/b]BEGIN
pumpe_blink :=true;
Pumpe.Caption := 'Pumpe läuft';
shape7.Brush.color:=clred;
END
ELSE
BEGIN
pumpe_blink :=false;
Pumpe.Caption := 'Pumpe aus';
shape7.Brush.color:=clgreen;
END;

if readboolean(brenner_bo) THEN
BEGIN
brenner_blink :=true;
brenner.Caption := 'Brenner läuft';
shape3.Brush.color:=clred;
END
ELSE
BEGIN
brenner_blink :=false;
brenner.Caption := 'Brenner aus';
shape3.Brush.color:=clgreen;
END;
///////////////////////////
if readboolean(garage_bo) THEN
BEGIN
garage_blink :=true;
garage.Caption := 'Garage auf';
shape2.Brush.color:=clred;
END
ELSE
BEGIN
garage_blink :=false;
garage.Caption := 'Garage zu';
shape2.Brush.color:=clgreen;
END;
  END;
  
  procedure TForm1.aufClick(Sender: TObject);
begin
runscript(rollo_auf_sc);
end;

procedure TForm1.abClick(Sender: TObject);
begin
runscript(rollo_ab_sc);
end;

procedure TForm1.stopClick(Sender: TObject);
begin
runscript(rollo_stop_sc);
end;
  

Ohne die Deklaration der ReadBoolean Funktion (der teil mit external „TRIXI.dll“) kann ich deine Fehlermeldung aus dem Screeanshot nicht beurteilen. Die Fehlermeldung sagt nämlich sinngemäß: „So wie du die Funktion deklariert hast kann ich sie in der DLL nicht finden“.

Die Fehlermeldung die du gepostet hast ist keine Access Violation. Hast du zwei Fehler?

Was steht denn in deinem Script in Zeile 16, 49, 52 etc? Sind das immer die selben Zeilen? Und was hat deine LCD-Laufschrift mit Trixi zu tun?!? Und warum benutzt du überhaupt die alte TRIXI Version aus dem Pulse-Package?

Gruß,

Toni

Ich seh grad was…

Das ist nicht aus der Demo. Der Server muss als PAnsiChar übergeben werden. Das ist ein Pointer (LPCSTR). Das steht hier und in der Demo auch so drin. Du hingegen übergibts einen String.

Gruß,

Toni

Ja 2 Fehler aber ich bin nicht sicher ob die zusammenhängen.

Der erste Fehler kommt sporadisch im Meldungsfenster von IPS und ist die Zeitüberschreitung. Da läuft ein Script, das mir alle 30 sec. Meldungen auf 2 FD868 schickt Die Zeilen, die da „angemeckert“ werden 16, 49, 52… haben immer denselben Inhalt. So in der Art
IPS_Sleep(50); //Wartenn
PJ_SwitchLED($id_lcd,3,true); // grün
PJ_SwitchLED($id_lcd2,3,true); // grün
PJ_LCDText($id_lcd, 2, $a1.$a2); // Text in Zeile 2 ausgeben
PJ_LCDText($id_lcd2, 2, $a1.$a2); // Text in Zeile 2 ausgeben


Der 2. Fehler ist eine AccessViolation. Es werden im delphi-Programm genau die IPS-Variablen abgefragt, die auch auf den Displays ausgegeben werden.
Deshalb dachte ich an einen evtl. Zusammenhang.
Der Fehler ist übrigens heute noch nicht aufgetreten.
Beim nächsten Auftauchen wird er gepostet.


Die alte TRIXI.DLL habe ich nur heute ausprobiert, weil motions schrieb, daß er Probleme mit einer EXE hat, Du eventuelle Fehler beim Zippen nicht ausgeschlossen hast und Programme bei mir laufen…
Tut mir leid wenn ich mich da unnütz eingemischt habe und Trouble verursache.
:eek:--------------
Bei der Function formcreate übergab ich bis eben ( habs geändert) auch einen String
// if not Connect(pansichar(‚192.168.0.16‘), 3773) then

if not Connect(‚192.168.0.16‘, 3773) then - diese Zeile hat funktioniert

Die Deklarationen
var: Form1: TForm1;
function Connect(Server: PAnsiChar; Port: Integer): Boolean; stdcall external ‚TRIXI.DLL‘;
function Disconnect(): Boolean; stdcall external ‚TRIXI.DLL‘;
function IsOnline(): Boolean; stdcall external ‚TRIXI.DLL‘;
function WriteString(Variable: Integer; Value: PAnsiChar): Integer; stdcall external ‚TRIXI.DLL‘;
function WriteInteger(Variable: Integer; Value: Integer): Integer; stdcall external ‚TRIXI.DLL‘;
function WriteFloat(Variable: Integer; Value: Double): Integer; stdcall external ‚TRIXI.DLL‘;
function WriteBoolean(Variable: Integer; Value: Boolean): Integer; stdcall external ‚TRIXI.DLL‘;
function ReadString(Variable: Integer): PAnsiChar; stdcall external ‚TRIXI.DLL‘;
function ReadInteger(Variable: Integer): Integer; stdcall external ‚TRIXI.DLL‘;
function ReadFloat(Variable: Integer): Double; stdcall external ‚TRIXI.DLL‘;
function ReadBoolean(Variable: Integer): Boolean; stdcall external ‚TRIXI.DLL‘;
function RunScript(Variable: Integer): Integer; stdcall external ‚TRIXI.DLL‘;
implementation

{$R *.dfm}

Mit besten Grüßen aus Saarbrücken

Also die alte Dll kann durchaus mit nem String zufrieden gewesen sein. Das müsst ich jetzt irgendwo nachschauen. Die DLL, die ich hier offiziell vorgestellt hab ist vollkommen neu geschrieben. Die braucht definitiv eine Speicheradresse von der sie die IP lesen kann. Einen Typisierten Pointer halt (PAnsiChar).

Die Deklaration scheint okay. Wenn die DLL auch zu der Demo passt aus der du die Deklaration hast sollte es passen. Wenn du natürlich irgendwelche DLLs und irgendwelche Dokus zusammenwirfst ists halt Glückssache was passiert… Die Dokumentation der 0.12 Schnittstelle passt in erster Linie auch erstmal für das was drauf steht :wink:

Einfach mal Rechtsklick auf die Dll - Eigenschaften - Details - Dateiversion. Das sollte Klarheit schaffen.

Toni

Toni,
ich habe das gerade noch mal überprüft und ein PAnsiChar drum gecastet, aber leider immer noch kein Connect.
Die Deklaration stimmt soweit mit der Demo überein und auch die DLL ist Version 0.1.2.0; die richtige Version sollte ich somit auch erwischt haben.

Ich rätsel immer noch was denn hier wohl klemmt. Zumal wie gesagt die TRIXI.exe aus dem Hauptverzeichnis und dem Delphi Unterverzeichnis den gleichen Fehler zeigt; die EXE aus dem Delphi Prism aber nicht (funktioniert).

Hast mal ein Debug-Log erstellt?

Toni

Ich habe eben mal das Trixipro Beispiel kompiliert (mit D7) und das Ergebnis bleibt mager: Fail
Und das Log-File sagt:
22.10.2010 17:33:32 — DebugFile enabled.
22.10.2010 17:33:32 — Messagesink will be written to logfile too.
22.10.2010 17:33:38 — Server settings: 192.168.3.8:3773
22.10.2010 17:33:39 — Try to connect to IPS -> Offline

Aber die IP-Adresse ist per Ping erreichbar und auch ipsconsole läuft ohne Probs; die Delphi-Prism Demo natürlich auch; laut Wireshark gehen wie gesagt auch keine Pakete raus.

Okay, ich seh schon. Das Debugfile löst das Problem wofür es gemacht war aber dies geht nen Schritt weiter. Ich werd das debugfile mal aufbohren damit wir etwas mehr herausbekommen. Ich schick dir auch eine Vorabversion per PM.

Gruß,

Toni

@motions

Ich hab das Debug etwas aufgebohrt. Magst es mit der 0.13 nochmal versuchen?

Toni

@Tonic1024:
Gerade getestet: Funktioniert!
Nur die neue DLL verwendet und schon läuft alles.
Hier der Debug der Trixipro:

25.10.2010 18:45:33 --- DebugFile enabled.
25.10.2010 18:45:33 --- Messagesink will be written to logfile too.
25.10.2010 18:45:38 --- Server settings: alarm:3773 - Pinging...
25.10.2010 18:45:38 --- Ping is good. Starting portscan...
25.10.2010 18:45:38 --- Port is open and reachable.
25.10.2010 18:45:39 --- Try to connect to IPS -> Okay
25.10.2010 18:45:39 --- Update Variable Callback set.
25.10.2010 18:45:39 --- Change Variable Callback set.
25.10.2010 18:45:39 --- +MsgSink+ -> Variable update notified: 17364, 24,625
25.10.2010 18:45:44 --- +MsgSink+ -> Variable update callback fired.
25.10.2010 18:45:44 --- +MsgSink+ -> Variable update notified: 46771, 14,75
25.10.2010 18:45:45 --- +MsgSink+ -> Variable update callback fired.
25.10.2010 18:45:45 --- +MsgSink+ -> Variable update notified: 52350, 62,125
25.10.2010 18:45:45 --- +MsgSink+ -> Variable update callback fired.
25.10.2010 18:45:46 --- +MsgSink+ -> Variable change callback fired.

Auch meine eigene Applikation mit den ersten Trixi-Aufrufen funktioniert. Also wo auch immer das Problem herkam, nu’ isses wech.
Vielen Dank für Deine Mühe.

Hm… Das freut mich natürlich. Aber seltsam isses schon. Delphi 7 sagtest du, oder? Bin zwar Fan von D7 aber habs leider nicht mehr installiert. Hatte jetzt nicht erwartet, dass es bei so grundlegenden Funktionen so einen Unterschied zwischen BDS2k6 (meine älteste installierte IDE) und D7 gibt. Wird dann wohl am „AutoIT-Patch“ gelegen haben, der auch in der 0.13 neu ist.

Ich verzeichne das mal auf der Haben-Seite. :wink:

Gruß,

Toni

Ja, das sieht momentan wirklich gut aus. Bin schon dabei meine kleine Applikation Raumtemperatur-Anzeige und -Einstellung zu erstellen.
Eine kleine zusätzliche Funktion wäre nett:
Abfrage des letzten Aktualisierungszeitpunktes einer Variablen
Function ReadLastUpdate(Variable:Integer) : TDateTime;
Oder habe ich da was übersehen und so etwas existiert bereits?

Wenn du mit callbacks arbeitest bekommst du die Änderungszeit mit. Für die nächste Version hab ich erweiterte Variablen-Operationen geplant. (siehe ToDo im Vorstellungsthread) da könnt sowas mit rein.

Muss mir noch überlegen ob ich ne Struktur (in pascal record) zurückgeben sollte oder der Einfachheit halber lieber ne art CSV-String. Dann könnt man das schon machen. Ich schreibs mal unverbindlich mit auf.

Toni