Hey @fishermans,
welche Version von homegear setzt du ein?
Die aktuelle Funktionsreferenz befindet sich hier: https://ref.homegear.eu/
so long,
p
Hey @fishermans,
welche Version von homegear setzt du ein?
Die aktuelle Funktionsreferenz befindet sich hier: https://ref.homegear.eu/
so long,
p
Hallo @pmayer,
ich verwende die neuste Version 0.6. Aber auch hier (https://ref.homegear.eu/)
ist der erste Parameter kein String. Ich verstehe auch nicht, warum die Rückgabe immer von unterschiedlicher Größe ist, mal werden für ein device 16 items zurückgegeben mal 14 oder 13. Ich habe hier nur MAX! devices. Wie kann ich wissen, wo welches Feld in der Rückgabe steht, wenn die Anzahl der Felder nicht dem der Rückgabestruktur entspricht?
Viele Grüße
Also, ich nutze listDevices
in einem Webinterface und da gibt es mir immer die gleiche Anzahl Geräten zurück - zugegeben über die PHP-Schnittstelle, sollten aber die gleichen Funktionsaufrufe sein.
pi@homegearpi:~$ sudo homegear -e rc 'print_r($hg->listDevices(false, ["FAMILY", "ID", "ADDRESS", "TYPE", "FIRMWARE"]));'
Die Rückgabe ist bei mir auch immer gleich, aber die Struktur entspricht nicht der in der Dokumentation. Die Parent-Devices sint immer korrekt aber die Channel-devices variiren in der Länge der Struktur.
Viele Grüße
Gib mal ein Beispiel…
So habe einmal nur eine Testausgabe gemacht, hier werden 41 Devices (parents plus channels)
gefunden, dann nur die Anzahl der Einträge pro Device:
Starting call: getVersion()
getVersion: Homegear 0.6.17-902
Version: Homegear 0.6.17-902
Starting call: logLevel()
logLevel: Loglevel is set to 5
Loglevel: 5
Starting call: listDevices()
Array length: 41
Count: 16
Count: 13
Count: 14
Count: 14
Count: 16
Count: 13
Count: 15
Count: 14
Count: 14
Count: 16
Count: 13
Count: 15
Count: 14
Count: 14
Count: 16
Count: 13
Count: 15
Count: 14
Count: 14
Count: 16
Count: 13
Count: 15
Count: 14
Count: 14
Count: 16
Count: 13
Count: 15
Count: 14
Count: 14
Count: 16
Count: 13
Count: 13
Count: 13
Count: 16
Count: 13
Count: 13
Count: 13
Count: 16
Count: 13
Count: 13
Count: 13
Hast du ein Beispiel, wie du die RPC-Methode in deinem Programm aufrufst?
Ist allerdings mein Quälcode, es wird die Methode aufgerufen und die Rückgabe protokolliert:
Function TForm1.listDevices(channels : Boolean; fields : TStrings; familyid : Integer) : Integer;
Var
hgDevice : THGDevice;
RpcResult : IRpcResult;
Flags, Rx_Mode,
i, j, k, l : Integer;
s : String;
Begin
FRpcFunction.ObjectMethod := 'listDevices';
FRpcFunction.AddItem(channels);
{
If fields <> NIL Then Begin
For i := 0 To fields.Count-1 Do
FRpcFunction.AddItem(fields[i]);
End Else
FRpcFunction.AddItem('');
FRpcFunction.AddItem(familyid);
}
AddMessage('Starting call: listDevices()');
try
RpcResult := FRpcCaller.Execute(FRpcFunction);
if RpcResult.IsError then
AddMessage(Format('Error: (%d) %s',
[RpcResult.ErrorCode, RpcResult.ErrorMsg]))
else Begin
If RpcResult.DataType = dtArray Then Begin
AddMessage('Array length: '+IntToStr(RpcResult.AsArray.Count));
For i := 0 To RpcResult.AsArray.Count-1 Do Begin
{
if Pos(':', RpcResult.AsArray.Items[i].AsStruct.Items[4].AsString) = 0 Then // Adresse
hgDevice := hgd_Parent
else
hgDevice := hgd_Channel;
}
// AddMessage('-----------------------------------------------------------------');
AddMessage('Count: '+InttoStr(RpcResult.AsArray.Items[i].AsStruct.Count));
//
// Parent Device
//
If hgDevice = hgd_Parent Then Begin
If RpcResult.AsArray.Items[i].DataType = dtStruct Then Begin // Array 0 = Struct lenth = 11
For j := 0 To RpcResult.AsArray.Items[i].AsStruct.Count-1 Do Begin
AddMessage('DataType: '+GetDataTypeStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].DataType));
// if j = 0 then
// AddMessage('Address: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
(*
Case j OF
// FAMILY DeviceFamily The family the device belongs to (e. g. HomeMatic BidCoS)
00 : Begin
AddMessage('Family: '+IntToStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger));
End;
// TYPE String Type of the device
01 : Begin
AddMessage('Type: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
// TYPE_ID Integer The type ID of the device
02 : Begin
AddMessage('Type_Id: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
// ID Integer The id of the device(e. g. 131)
03 : Begin
AddMessage('ID: '+IntToStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger));
End;
// ADDRESS String Serialnumber of the device (e. g. JEQ0123456)
04 : Begin
AddMessage('Adress: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
// CHILDREN Array<String> For compatibility. Addresses of the channels (e. g. JEQ0123456:1)
05 : Begin
For k := 0 To RpcResult.AsArray.Items[i].AsStruct.Items[j].AsStruct.Count-1 Do Begin
AddMessage('Children: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsStruct.Items[k].AsString);
End;
End;
// CHANNELS Array<Integer> Indexes of all available channels
06 : Begin
For k := 0 To RpcResult.AsArray.Items[i].AsStruct.Items[j].AsStruct.Count-1 Do Begin
AddMessage('Channel: '+IntToStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].AsStruct.Items[k].AsInteger));
End;
end;
// PARENT String Empty for parent device
07 : Begin
AddMessage('Patent: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
// PARAMSETS Array<String> Names of the available parameter sets (MASTER, VALUES and/or LINK)
08 : Begin
For k := 0 To RpcResult.AsArray.Items[i].AsStruct.Items[j].AsStruct.Count-1 Do Begin
AddMessage('Paramsets: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsStruct.Items[k].AsString);
End;
End;
// FIRMWARE String Optional. Firmware version (e. g. "2.1"). "?" for teams.
09 : Begin
AddMessage('Firmware: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
// AVAILABLE_FIRMWARE String Optional. Firmware version available for update (e. g. "2.2"). Only set when a newer firmware version is available.
10 : Begin
AddMessage('Aviable Firmware: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
// VERSION Integer Version of the XML file
11 : Begin
AddMessage('Version: '+IntToStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger));
End;
// FLAGS Flags or-linked flags for the GUI
12 : Begin
// 1 Visible: Device should be visible to the user
// 2 Internal: Device is only used internally
// 8 Dontdelete: Device can't (or shouldn't) be deleted
// ThgFlags = (hgf_Visible=1,hgf_Internal=2,hgf_Dontdelete=8);
Flags := RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger;
s := '';
If GetBit(Flags, chgf_Visible-1) Then
s := '-Visible ';
If GetBit(Flags, chgf_Internal-1) Then
s := s + '-Internal ';
If GetBit(Flags, chgf_Dontdelete-1) Then
s := s + '-Dontdelete ';
AddMessage('Flags ('+IntToStr(Flags)+'): '+s);
End;
// RF_ADDRESS Integer For compatability. Physical address of the device.
13 : Begin
AddMessage('RF_Adress: '+IntToStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger));
End;
// PHYSICAL_ADDRESS Integer Physical address of the device
14 : Begin
AddMessage('Physical Adress: '+IntToStr(RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger));
End;
// RX_MODE RXMode The supported RX modes of the device.
15 : Begin
Rx_Mode := RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger;
s := '';
If GetBit(Flags, chgr_RX_ALWAYS-1) Then
s := s + '-RX_ALWAYS ';
If GetBit(Flags, chgr_RX_BURST-1) Then
s := s + '-RX_BURST ';
If GetBit(Flags, chgr_RX_CONFIG-1) Then
s := s + '-RX_CONFIG ';
If GetBit(Flags, chgr_RX_WAKEUP-1) Then
s := s + '-RX_WAKEUP ';
If GetBit(Flags, chgr_RX_LAZY_CONFIG-1) Then
s := s + '-RX_LAZY_CONFIG ';
AddMessage('RX-Mode: ('+IntToStr(Rx_Mode)+'): '+s);
End;
// INTERFACE String Only for compatibility. Serial number of the central.
16 : Begin
AddMessage('Interface: '+RpcResult.AsArray.Items[i].AsStruct.Items[j].AsString);
End;
end;
*)
end; // For i := ...
end; //
end;
//
// Channel Device
//
If hgDevice = hgd_Channel Then Begin
For j := 0 To RpcResult.AsArray.Items[i].AsStruct.Count-1 Do Begin
Case j OF
// FAMILY DeviceFamily The family the device belongs to (e. g. HomeMatic BidCoS)
00 : Begin
// RpcResult.AsArray.Items[i].AsStruct.Items[j].AsInteger;
End;
// ID Integer The id of the device(e. g. 131)
01 : Begin
End;
// CHANNELS Array<Integer> Indexes of all available channels
02 : Begin
End;
// ADDRESS String Serialnumber of the device (e. g. JEQ0123456)
03 : Begin
End;
// PARENT String Empty for parent device
04 : Begin
End;
// PARENT_TYPE String Type of the parent device
05 : Begin
End;
// INDEX Integer Channel number
06 : Begin
End;
// AES_ACTIVE Integer "1" when AES handshakes are enabled for the channel otherwise "0". This variable is of type Integer for compatibility.
07 : Begin
End;
// PARAMSETS Array<String> Names of the available parameter sets (MASTER, VALUES and/or LINK)
08 : Begin
End;
// VERSION Integer Version of the XML file
09 : Begin
End;
// FLAGS Flags or-linked flags for the GUI
10 : Begin
End;
// LINK_SOURCE_ROLES String Source roles defined for this channel in the XML file seperated by space
11 : Begin
End;
// LINK_TARGET_ROLES String Target roles defined for this channel in the XML file seperated by space
12 : Begin
End;
// DIRECTION Direction Direction of the channel (sender or receiver)
13 : Begin
End;
// GROUP String Optional. Only when device has grouped channels. Serial number and index of the grouped channel (e. g. JEQ0123456:3)
14 : Begin
End;
// TEAM String Optional. Only when channel supports teams. Serial number of the team (e. g. *JEQ0123456 - note the "*")
15 : Begin
End;
// TEAM_TAG String Optional. Only when channel supports teams or for teams. Type of the team ("team_tag" attribute of the team's XML file).
16 : Begin
End;
// TEAM_CHANNELS Array<String> Optional. Only for teams. Array of peers (serialnumber and channel) paired to this team (e. g. JEQ0234567:1) end;
17 : Begin
End;
end;
end;
end;
end;
end;
end;
except
on E: Exception do
AddMessage(StringReplace(E.Message, #13#10, ': ', [rfReplaceAll]));
end;
end;
Sorry, da blicke ich nicht durch.
Bau doch mal einen einfachen Aufruf der Methode listDevices
nach.
Ich denke nicht, dass die Funktion in einer Schleife aufgerufen werden sollte. Sie gibt eine Liste der verfügbaren Geräte zurück. Um Info’s für ein einzelnes Gerät zu bekommen wird getDeviceInfo
genutzt: https://ref.homegear.eu/rpc.html#getDeviceInfo
Das mit der Schleife sollte eigentlich korrekt sein, die Funktion liefert ja ein Array zurück
Array listDevices()
Das durchlaufe ich und lese die Daten ein. Die entspricht aber nicht der in der Dokumentation.
Mein Ziel ist, die Geräte (MAX!) zu program.ieren.
Ich kann aber kein VisualBasic (glaube, dass du das da programmierst) und kann nicht sehen welche Methode in der Schleife ausgeführt wird.
Also wäre doch der logische Schritt erst mal listDevices
“alleine” auszuführen und zu debuggen ob denn die Rückgabe dem Erwarteten entspricht.
Das ist Pascal, ich rufe hier die Methode auf:
FRpcFunction.ObjectMethod := ‘listDevices’;
If RpcResult.DataType = dtArray Then Begin…
Falls nun ein Array zurückgegeben wird werte ich die Daten aus.
In der Dokumentation steht
Name Type Description
FAMILY DeviceFamily The family the device belongs to (e. g. HomeMatic BidCoS)
TYPE String Type of the device
d.h. der erste Eintrag sollte ein Integer Wert sein, da ich nur Max! Devices habe also eine 4.
Die finde ich aber an einer späteren Position. An erster Position wird die Adresse zurückgegeben die aber an Position 4 auftauchen sollte…
???
Gibst du eine Liste der gewünschten Parameter mit?
Nein, das sollte ich vielleicht noch versuchen, ansonsten werte ich die einzelnen Geräte händisch
aus, das ist zwar nicht besonderst schön und funktioniert dann nur mit meinen vorhandenene Geräten, aber sollte klappen. Dann kann leider niemand etwas damit anfangen ausser mir. Inspiriert hat mich dieser Beitrag Homegear Script Editor. Ich würde gerne die devices einlesen und per rpc programmieren.
So, wenn ich eine Liste der Parameter angebe, bekomme ich die gewünschten Informationen, allerdings nicht in der Reihnfolge meiner Parameterliste sondern in alphabetischer Reihnfolge:
family: 4
firmware: 1.4
id: 2
type: BC-RT-TRX-CyG
--------------------------------------------
adress: IEQ0184984
family: 4
firmware: 1.4
id: 3
type: BC-RT-TRX-CyG
--------------------------------------------
adress: IEQ0108293
family: 4
firmware: 1.4
id: 4
type: BC-RT-TRX-CyG
--------------------------------------------
adress: IEQ0198096
family: 4
firmware: 1.4
id: 5
type: BC-RT-TRX-CyG
--------------------------------------------
adress: IEQ0196591
family: 4
firmware: 1.4
id: 6
type: BC-RT-TRX-CyG
--------------------------------------------
adress: IEQ0052570
family: 4
firmware: 1.2
id: 7
type: BC-PB-2-WM
--------------------------------------------
adress: IEQ0144688
family: 4
firmware: 1.2
id: 8
type: BC-PB-2-WM
--------------------------------------------
adress: IEQ0144585
family: 4
firmware: 1.2
id: 9
type: BC-PB-2-WM
So komme ich zumindest weiter
Viele Grüße
Hallo @fishermans,
die Reihenfolge der Strukturelemente ist zwar konstant aber sie darf nach XML-RPC-Spezifikation variieren. Du kannst also nicht davon ausgehen, dass die Elemente immer an der gleichen Stelle zu finden sind. Die Unterschiede in der Elementezahl kommen zustande, da einige Elemente optional sind. Greif daher am besten über den Namen auf die Elemente zu. Bei optionalen Elementen ist vorher zu prüfen, ob der Schlüssel existiert. Beantwortet das deine Frage?
Viele Grüße
Sathya
Hallo @sathya,
ja das hat meine Frage beantwortet. Das eigentliche Problem lag in dem Verständnis der Komponente, die ich verwendet habe um die Daten einzulesen. Da gibt es ein Feld “Name” was immer leer war, aber der Name steht in einem Feld mit der Bezeichnung “Key”. Nach dem ich das begriffen hatte ging es ganz leicht :-). Vielen Dank für dieses tolle Programm! Ich werde, wenn ich das Programm soweit fertig habe, das Ganze mal hier vorstellen incl. Quälcode, für die die es interesiert.
Viele Grüße
Elmar
Sehr gerne ;-).