mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-09 20:57:11 +00:00
00_DFPlayerMini: improved requestAck handling
git-svn-id: https://svn.fhem.de/fhem/trunk@14229 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
182a62d8c3
commit
5b54a84c60
@ -1,5 +1,6 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- feature: 00_DFPlayerMini: improved requestAck handling
|
||||
- change: 49_SSCam: new version 2.1.3, change of internal processes, new
|
||||
get scanVirgin command
|
||||
- bugfix: 73_ElectricityCalculator: SiPrefix multiplier instead divider
|
||||
|
@ -287,6 +287,7 @@ DFPlayerMini_Define($$)
|
||||
$ret = DevIo_OpenDev($hash, 0, "DFPlayerMini_DoInit", 'DFPlayerMini_Connect');
|
||||
|
||||
} else {
|
||||
DFPlayerMini_DoInit($hash);
|
||||
$hash->{DevState} = 'initialized';
|
||||
readingsSingleUpdate($hash, "state", "opened", 1);
|
||||
}
|
||||
@ -361,7 +362,7 @@ DFPlayerMini_createCmd($$;$$)
|
||||
$par2 = 0 if !defined $par2;
|
||||
|
||||
my $requestAck = AttrVal($hash->{NAME}, "requestAck", 0) || $cmd == DFP_C_Acknowledge;
|
||||
|
||||
|
||||
my $checksum = -(DFP_Version_Byte+DFP_Command_Length+$cmd+$requestAck+$par1+$par2);
|
||||
return pack('CCCCCCCnC', DFP_Start_Byte,DFP_Version_Byte, DFP_Command_Length, $cmd, $requestAck, $par1, $par2, $checksum, DFP_End_Byte);
|
||||
|
||||
@ -1046,6 +1047,7 @@ DFPlayerMini_DoInit($)
|
||||
|
||||
@{$hash->{PLAYQUEUE}} = ();
|
||||
@{$hash->{TTSQUEUE}} = ();
|
||||
$hash->{waitForAck} = 0;
|
||||
|
||||
return;
|
||||
#return undef;
|
||||
@ -1138,7 +1140,7 @@ sub DFPlayerMini_AddSendQueue($$)
|
||||
|
||||
#Log3 $hash, 3,"$name: AddSendQueue: " . $hash->{NAME} . ": $msg";
|
||||
|
||||
if (gettimeofday() - $hash->{LAST_SEND_TS} > DFP_MIN_WAITTIME) {
|
||||
if (!$hash->{waitForAck} && gettimeofday() - $hash->{LAST_SEND_TS} > DFP_MIN_WAITTIME) {
|
||||
# minimal wait time before next command exceeded, can write immediately
|
||||
DFPlayerMini_SimpleWrite($hash, $msg);
|
||||
} else {
|
||||
@ -1146,32 +1148,16 @@ sub DFPlayerMini_AddSendQueue($$)
|
||||
push(@{$hash->{QUEUE}}, $msg);
|
||||
|
||||
#Log3 $hash , 5, Dumper($hash->{QUEUE});
|
||||
|
||||
InternalTimer(gettimeofday() + DFP_MIN_WAITTIME, "DFPlayerMini_HandleWriteQueue", "HandleWriteQueue:$name", 1);
|
||||
if ($hash->{waitForAck} == 0) {
|
||||
# if we don't have to wait for an acknowledge from dfp we have at least to wait 20ms
|
||||
InternalTimer(gettimeofday() + DFP_MIN_WAITTIME, "DFPlayerMini_HandleWriteQueue", "HandleWriteQueue:$name", 1);
|
||||
} else {
|
||||
Log3 $hash, 5, "delayed send, waiting for ack";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub
|
||||
DFPlayerMini_SendFromQueue($$)
|
||||
{
|
||||
my ($hash, $msg) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if($msg ne "") {
|
||||
#DevIo_SimpleWrite($hash, $msg,2);
|
||||
|
||||
DFPlayerMini_SimpleWrite($hash,$msg);
|
||||
|
||||
}
|
||||
|
||||
##############
|
||||
if (AttrVal($name, "requestAck", 0) == 0) {
|
||||
# Write the next buffer not earlier than 20ms, which is the fastest time the DFP can process commands
|
||||
InternalTimer(gettimeofday() + DFP_MIN_WAITTIME, "DFPlayerMini_HandleWriteQueue", "HandleWriteQueue:$name", 1);
|
||||
}
|
||||
}
|
||||
|
||||
####################################
|
||||
sub
|
||||
DFPlayerMini_HandleWriteQueue($)
|
||||
@ -1183,12 +1169,13 @@ DFPlayerMini_HandleWriteQueue($)
|
||||
#my @arr = @{$hash->{QUEUE}};
|
||||
|
||||
if(@{$hash->{QUEUE}}) {
|
||||
my $msg= shift(@{$hash->{QUEUE}});
|
||||
my $msg = shift(@{$hash->{QUEUE}});
|
||||
|
||||
if($msg eq "") {
|
||||
DFPlayerMini_HandleWriteQueue("x:$name");
|
||||
} else {
|
||||
DFPlayerMini_SendFromQueue($hash, $msg);
|
||||
|
||||
DFPlayerMini_SimpleWrite($hash,$msg);
|
||||
}
|
||||
} else {
|
||||
Log3 $name, 4, "$name/HandleWriteQueue: nothing to send, stopping timer";
|
||||
@ -1213,11 +1200,11 @@ DFPlayerMini_Read($)
|
||||
|
||||
#Log3 $name, 5, "$name: DFPlayerMini_Read ($name) - received data: " . $hash->{PARTIAL};
|
||||
|
||||
# Daten an den Puffer anhängen
|
||||
# Daten an den Puffer anhängen
|
||||
$hash->{helper}{BUFFER} .= $buf;
|
||||
#Log3 $name, 5, "$name: DFPlayerMini_Read ($name) - current buffer content: " . unpack('H*', $hash->{helper}{BUFFER});
|
||||
|
||||
# prüfen, ob im Buffer ein vollständiger Frame mit 10 Bytes zur Verarbeitung vorhanden ist.
|
||||
# prufen, ob im Buffer ein vollstä;ndiger Frame mit 10 Bytes zur Verarbeitung vorhanden ist.
|
||||
while (length($hash->{helper}{BUFFER}) >= DFP_FrameLength)
|
||||
{
|
||||
if (unpack("C",substr($hash->{helper}{BUFFER},0,1)) == DFP_Start_Byte && unpack("C", substr($hash->{helper}{BUFFER},9,1)) == DFP_End_Byte) {
|
||||
@ -1305,10 +1292,9 @@ DFPlayerMini_Parse($$)
|
||||
# ToDo: Special case: DFP_C_GetNoTracksFolder will return DFP_E_TrackNotFound if the folder is empty
|
||||
readingsSingleUpdate($hash, "state", $error, 1);
|
||||
} elsif ($cmd == DFP_C_Acknowledge) {
|
||||
if (AttrVal($name, "requestAck", 0)) {
|
||||
# send next command
|
||||
DFPlayerMini_HandleWriteQueue("x:$name");
|
||||
}
|
||||
# send next command if one is in the queue
|
||||
$hash->{waitForAck} = 0;
|
||||
DFPlayerMini_HandleWriteQueue("x:$name");
|
||||
} elsif ($cmd == DFP_C_GetStorage) {
|
||||
if ($par2 & 0x01) {
|
||||
push @storage, "USB";
|
||||
@ -1410,6 +1396,7 @@ DFPlayerMini_SimpleWrite(@)
|
||||
my $hexMsg = unpack ('H*', $msg);
|
||||
Log3 $name, 5, "$name SW: $hexMsg";
|
||||
|
||||
|
||||
my $sendCmd = AttrVal($name, "sendCmd", undef);
|
||||
if (defined $sendCmd) {
|
||||
$sendCmd =~ s/\$msg/${hexMsg}/;
|
||||
@ -1428,7 +1415,13 @@ DFPlayerMini_SimpleWrite(@)
|
||||
|
||||
# remember time the command was sent
|
||||
$hash->{LAST_SEND_TS} = gettimeofday();
|
||||
|
||||
# evaluate requestAck byte in command
|
||||
# if it is set an acknowledge must be received before
|
||||
# sending the next command from the queue
|
||||
$hash->{waitForAck} = unpack('C', substr($msg,4,1));
|
||||
Log3 $name, 5, "current cmd waitForAck " . $hash->{waitForAck};
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub
|
||||
@ -1597,7 +1590,8 @@ sub DFPlayerMini_Notify($$)
|
||||
</li>
|
||||
<li>requestAck<br>
|
||||
The DFPlayer can send a response to any command sent to it to acknowledge that is has received the command. As this increases the communication
|
||||
overhead it can be switched off if the communication integrity is ensured by other means.
|
||||
overhead it can be switched off if the communication integrity is ensured by other means. If set the next command is only sent if the last one was
|
||||
acknowledged by the DFPlayer. This ensures that no command is lost if the the DFPlayer is busy/sleeping.
|
||||
</li>
|
||||
<li>sendCmd<br>
|
||||
A fhem command that is used to send the command data generated by this module to the DFPlayer hardware. If this is set, no other way of communication with the DFP is used.
|
||||
@ -1821,7 +1815,8 @@ sub DFPlayerMini_Notify($$)
|
||||
</li>
|
||||
<li>requestAck<br>
|
||||
Der DFPlayer kann fü jedes Kommando eine Bestätigung senden. Da das zu erhöhter Kommunikation führt kann es über dieses
|
||||
Attribut abgeschaltet werden.
|
||||
Attribut abgeschaltet werden. Wenn es eingeschaltet ist wird das nächste Kommando erst dann zum DFPlayer wenn das vorherige bestätigt wurde.
|
||||
Das stellt sicher, dass kein Kommando verloren geht selbst wenn der DFPlayer ausgelastet oder im Schlafzustand ist.
|
||||
</li>
|
||||
<li>sendCmd<br>
|
||||
Ein fhem Kommando das verwendet wird um ein durch diese Modul erzeugtes DFPlayer Kommando an die DFPlayer Hardware zu senden.
|
||||
|
Loading…
x
Reference in New Issue
Block a user