[HM-Wired] HM485 erkennt ACK nicht

Begonnen von Thorsten Pferdekaemper, 17 Juli 2015, 00:48:22

Vorheriges Thema - Nächstes Thema

hglaser

#15
Zitat2. Jede empfangene Nachricht kann als ACK gelten. Die ACK-Verarbeitung wird schon in der Protokollschicht verarbeitet.
   (Wenn eine empfangende Nachricht nur ein ACK ist, dann muss das Modul selbst davon eigentlich gar nichts mitbekommen.)
Wenn ich nun einmal z.B Configurations daten sende

2015.07.18 15:28:04 4: HM485_LAN1: TX: (229) I[1](0,F,B)(1A) 00000001 -> 0000E1DD [7] 57(W) 00070122
2015.07.18 15:28:04 4: ACK: (229)
2015.07.18 15:28:04 4: Response: (229)
2015.07.18 15:28:04 4: HM485_LAN1: TX: (230) I[2](0,F,B)(1C) 00000001 -> 0000E1DD [7] 57(W) 000A010A
2015.07.18 15:28:04 4: ACK: (230)
2015.07.18 15:28:04 4: Response: (230)
2015.07.18 15:28:04 4: HM485_LAN1: TX: (231) I[3](0,F,B)(1E) 00000001 -> 0000E1DD [7] 57(W) 000901FE
2015.07.18 15:28:04 4: ACK: (231)
2015.07.18 15:28:04 4: Response: (231)
2015.07.18 15:28:04 4: HM485_LAN1: TX: (232) I[0](0,F,B)(18) 00000001 -> 0000E1DD [3] 43(C)
2015.07.18 15:28:04 4: ACK: (232)
2015.07.18 15:28:04 4: Response: (232)

würde man doch eigentlich ein ACK brauchen, um das "Configuration" FW_detailFn zu aktualisieren (was es zur Zeit nicht tut) oder sehe ich das falsch? Irgend eine Rückmeldung müsste man dann dennoch brauchen oder?

Derzeit wird ja wenn ein Befehl geschickt wird zuerst im xmlDevice.pm nachgesen
Zitat"state" => {
                        "control" => "switch.state",
                        "conversion" => {
                           "false" => 0,
                           "threshold" => 1,
                           "true" => 200,
                           "type" => "boolean_integer"
                        },
                        "logical" => {
                           "default" => false,
                           "type" => "boolean"
                        },
                        "operations" => "read,write,event",
                        "physical" => {
                           "event" => {
                              "frame" => "info_level"
                           },
                           "get" => {
                              "request" => "level_get",
                              "response" => "info_level"
                           },
                           "interface" => "command",
                           "set" => {
                              "request" => "level_set"
                           },
                           "type" => "integer",
                           "value_id" => "state"
                        }
                     },
z.B bei "state" wäre das "info_level". und das wird in HM485_DoSendCommand mit den den beiden Arrays @validRequestTypes und @waitForAckTypes verglichen. je nachdem kommts dann entweder in den .waitForResponse hash oder in den .waitForAck hash im IODev. bei einer Antwort vom Device wirds dann aus dem jeweiligen hash gelöscht (eigentlich aus beiden) und ist somit abgearbeitet. Es kommt also darauf an was im xmlDevice.pm steht. Willst Du das alles ändern? So wäre es zur Zeit implementiert.

Ich habe irgend wan mal nachträglich ein $onlyAck bit ins HM485_SendCommand eingebaut (wird wohl noch in gevoos Version drin sein), sollte das Device nur mit einem Ack antworten. Ein Mischen (mal ein ACK, und mal ein 0x69) ist derzeit nicht möglich und ich weiß auch eigentlich nicht warum auch.

lg Harald

Thorsten Pferdekaemper

Zitat von: honk am 18 Juli 2015, 16:15:30würde man doch eigentlich ein ACK brauchen, um das "Configuration" FW_detailFn zu aktualisieren (was es zur Zeit nicht tut) oder sehe ich das falsch? Irgend eine Rückmeldung müsste man dann dennoch brauchen oder?
Da hast Du Recht. Wenn man im Device ein Reading oder ähnliches hat, welches das erfolgreiche Abarbeiten von irgendwas anzeigen soll, dann muss man das ACK ins Modul hochgeben. Dann reicht es nicht, wenn es nur die Protokollschicht erledigt.

ZitatDerzeit wird ja wenn ein Befehl geschickt wird zuerst im Device.pm nachgesenz.B bei "state" wäre das "info_level". und das wird in HM485_DoSendCommand mit den den beiden Arrays @validRequestTypes und @waitForAckTypes verglichen. je nachdem kommts dann entweder in den .waitForResponse hash oder in den .waitForAck hash im IODev. bei einer Antwort vom Device wirds dann aus dem jeweiligen hash gelöscht und ist somit abgearbeitet. Es kommt also darauf an was im xmlDevice.pm steht. Willst Du das alles ändern? So wäre es zur Zeit implementiert.
Nein, ich will nicht wirklich alles ändern. Ich dachte aber, man könnte es vereinfachen: Im Prinzip kann jede Nachricht als ACK gelten. ...aber anscheinend wird das auch schon so verarbeitet, ich hab's ja ausprobiert.
Von der Funktionalität her will ich eigentlich nur eine Sache ändern: Auch wenn ein Befehl eigentlich in .waitForResponse landet, sollte trotzdem nicht wiederholt werden, wenn "nur" ein ACK kommt. In dem Fall ist ja offenbar irgendwo logisch was faul und nicht in der Übertragung.
FUIP

hglaser

#17
ja ich verstehe, Wird es das denn ?
Es werden nämlich in gevoos Version beide hashes am ende von HM485_ProcessResponse gelöscht.
Ansonsten wäre es wohl das einfachste auch das  $onlyAck bit zu verwenden. Dann brauchts aber irgendein Unterscheidungs-Merkmal, so wie beim IO-12 SW14. da ist es "digital_analog_output.frequency"

lg Harald

Ralf9

Ich habe es mir nochmals in der HM485_Protocol.pm angeschaut.
Das Handling der Ack oder Response geschieht in der Protokollschicht zwischen dem HM485d und dem Modul. In dem  HM485d oder dem HMW-Lan-Gateway wird auf ein Response mit einem Ack geantwortet.

In der HM485_Protocol.pm steht:

} else {
if (grep $_ eq $cmd, @validRequestTypes) {
$self->{sendQueue}{$queueId}{STATE} = STATE_WAIT_RESPONSE;
} else {
$self->{sendQueue}{$queueId}{STATE} = STATE_WAIT_ACK;
}
}


Erfolgt auf ein gesendetes Kommando keine Antwort, wird das Kommando noch 2 mal wiederholt und dann an fhem eine Fehlermeldung zurückgeschickt. 

if ($self->{sendQueue}{$currentQueueId}{SEND_COUNT} >= MAX_SEND_RETRY) {
### NACK ###
$self->sendError($self->{sendQueue}{$currentQueueId}{MSG_ID}, 1);
$self->deleteCurrentItemFromQueue();
}



In der 00_HM485_LAN.pm wird dann dies aufgerufen:

sub HM485_LAN_DispatchNack($$) {
my ($hash, $currentQueueId) = @_;
my $name = $hash->{NAME};

$hash->{Last_Sent_RAW_CMD_State} = 'NACK';

if ($currentQueueId) {
my $msgId = $hash->{sendQueue}{$currentQueueId}{msgId};
if ($msgId) {
my $hmwId = $hash->{sendQueue}{$currentQueueId}{hmwId};
if ($hmwId) {
if ($modules{HM485}{defptr}{$hmwId}) {
# We use CMD_ALIVE and second byte for signalize NACK messages internaly
# The last 4 bytes identify the HMW-ID which was not acked
my $message = pack('H*',
sprintf(
'%02X%02X%02X%02X%02X%s',
HM485::FRAME_START_LONG, 3, $msgId, HM485::CMD_ALIVE, 1, $hmwId
)
);
Dispatch($hash, $message, '');
} else {
HM485::Util::logger($name, 3, 'NACK: (' . $msgId . ') ' . $hmwId);
}
}
}
HM485_LAN_DeleteCurrentItemFromQueue($hash, $currentQueueId);
}
}


Wisst ihr zufällig in welcher Datei die Routine "Dispatch($hash, $message, '');" ist?

Gruß Ralf
FHEM auf Cubietruck mit Igor-Image, SSD und  hmland + HM-CFG-USB-2,  HMUARTLGW Lan,   HM-LC-Bl1PBU-FM, HM-CC-RT-DN, HM-SEC-SC-2, HM-MOD-Re-8, HM-MOD-Em-8
HM-Wired:  HMW_IO_12_FM, HMW_Sen_SC_12_DR, Selbstbau IO-Module HBW_IO_SW
Maple-SIGNALduino, WH3080,  Hideki, Id 7

Thorsten Pferdekaemper

Zitat von: Ralf9 am 18 Juli 2015, 18:43:45
Erfolgt auf ein gesendetes Kommando keine Antwort, wird das Kommando noch 2 mal wiederholt und dann an fhem eine Fehlermeldung zurückgeschickt. 
Das ist ja ok. Was meiner Meinung nach aber nicht ok ist, ist folgendes: Wenn in HM485_Protocol.pm eine Response erwartet wird und nicht nur ein ACK, aber das Device trotzdem nur ein ACK schickt, dann wird auch wiederholt. Das ist meiner Meinung nach mindestens überflüssig. In dem Fall handelt es sich höchstwahrscheinlich um einen logischen Fehler und es ist sehr unwahrscheinlich, dass beim nächsten Versuch plötzlich nicht nur ein ACK kommt.

Zitat
Wisst ihr zufällig in welcher Datei die Routine "Dispatch($hash, $message, '');" ist?
Ich glaube, dass das im Wesentlichen einen Aufruf von HM485_Parse bewirkt.
Definiert ist das in fhem.pl.

Gruß,
   Thorsten
FUIP

Thorsten Pferdekaemper

Zitat von: honk am 18 Juli 2015, 16:15:30würde man doch eigentlich ein ACK brauchen, um das "Configuration" FW_detailFn zu aktualisieren (was es zur Zeit nicht tut)
Ich habe das gerade mal ausprobiert. Ich habe in HM485_FhemwebShowConfig den Log-Eintrag aktiviert und dann eine 0x73 an mein Device geschickt. Darauf hat es mit ACK geantwortet. Im Log steht das:

2015.07.18 21:59:51 3: HM485_FhemwebShowConfig: fwName = WEB name = HBW_TEST_HBW7296276_01 roomName =
2015.07.18 21:59:54 3: HM485_FhemwebShowConfig: fwName = WEB name = HBW_TEST_HBW7296276_01 roomName =

Das funktioniert derzeit also.
FUIP

Thorsten Pferdekaemper

Zitat von: honk am 18 Juli 2015, 17:00:09
ja ich verstehe, Wird es das denn ?
Ich nehme an, dass sich das auf die Wiederholungen bezieht, wenn FHEM eine Response erwartet, aber nur ein ACK bekommt.
Ja, das ist so. Sonst hätte ich das Problem mit dem 0x73 ja nicht gehabt.
FUIP

hglaser

#22
ZitatIch habe das gerade mal ausprobiert. Ich habe in HM485_FhemwebShowConfig den Log-Eintrag aktiviert und dann eine 0x73 an mein Device geschickt. Darauf hat es mit ACK geantwortet.
Ja das meinte ich eigentlich nicht. Ich meinte, daß sich im Webbrowser das Detail-Fenster nicht aktualisiert wenn man einen Wert ändert, und um sowas wie einen Refresh machen zu können, müssten man das ACK auswerten. Für solche Fälle fand ich, wäre es gut das ACK nicht schon in der Protokollschicht abzufangen.
ZitatIch nehme an, dass sich das auf die Wiederholungen bezieht, wenn FHEM eine Response erwartet, aber nur ein ACK bekommt.
Ja, das ist so. Sonst hätte ich das Problem mit dem 0x73 ja nicht gehabt.
ok habs kapiert, danke

Ein HM485_ProcessChannelState im ACK zweig von HM485_ProcessResponse sollte eigentlich keine Nebenwirkungen haben. Versuche es doch bitte einmal.

Dann wird aus

if($hash->{'DEF'} eq $hmwId) {
if ($requestType eq '57') {                                     # W (ACK written Eeprom Data)
# ACK for write EEprom data
my $devHash = HM485_GetHashByHmwid(substr($hmwId, 0,8));
HM485::Device::internalUpdateEEpromData($devHash, $requestData);
}
}

halt ein


if($hash->{'DEF'} eq $hmwId) {
if ($requestType eq '57') {                                     # W (ACK written Eeprom Data)
# ACK for write EEprom data
my $devHash = HM485_GetHashByHmwid(substr($hmwId, 0,8));
HM485::Device::internalUpdateEEpromData($devHash, $requestData);
} else {
HM485_ProcessChannelState($hash, $hmwId, $msgData, 'response');
}
}



lg Harald