2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

58_RPI_1Wire: added on-for-timer and validated DS2408

git-svn-id: https://svn.fhem.de/fhem/trunk@28208 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Adimarantis 2023-11-25 18:57:45 +00:00
parent 56bc125eb6
commit 40a326bb08
2 changed files with 51 additions and 24 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # 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. # Do not insert empty lines here, update check depends on it.
- feature: 58_RPI_1Wire: added on-for-timer and validated DS2408
- change: 10_KNX.pm: minor changes, see Forum #122582 - change: 10_KNX.pm: minor changes, see Forum #122582
- change: 00_KNXIO.pm: minor changes, see Forum #127792 - change: 00_KNXIO.pm: minor changes, see Forum #127792
- feature: 76_SolarForecast: graphicHeaderOwnspec: show readings of other devs - feature: 76_SolarForecast: graphicHeaderOwnspec: show readings of other devs

View File

@ -124,6 +124,7 @@ sub RPI_1Wire_Init { #
$family="DHT".$1; $family="DHT".$1;
$device=$family; $device=$family;
} else { } else {
#testing - comment next line to create devices without HW check
return "Device $arg does not exist" if (! -e "$w1_path/$arg" and $check==1 and $force==0); #Only quit if coming from interactive define return "Device $arg does not exist" if (! -e "$w1_path/$arg" and $check==1 and $force==0); #Only quit if coming from interactive define
($family, $id) = split('-',$arg); ($family, $id) = split('-',$arg);
return "Unknown device family $family" if !defined $RPI_1Wire_Devices{$family}; return "Unknown device family $family" if !defined $RPI_1Wire_Devices{$family};
@ -143,6 +144,11 @@ sub RPI_1Wire_Init { #
$hash->{helper}{write}.="resolution "; $hash->{helper}{write}.="resolution ";
} }
} }
if ($type eq "switch") {
if (-e "$w1_path/$arg/output" && !-w "$w1_path/$arg/output") {
$hash->{helper}{write}.="output ";
}
}
if ($device eq "BUSMASTER") { if ($device eq "BUSMASTER") {
if (-e "$w1_path/$arg/therm_bulk_read") { if (-e "$w1_path/$arg/therm_bulk_read") {
$hash->{helper}{write}.="therm_bulk_read " if (!-w "$w1_path/$arg/therm_bulk_read"); $hash->{helper}{write}.="therm_bulk_read " if (!-w "$w1_path/$arg/therm_bulk_read");
@ -289,10 +295,12 @@ sub RPI_1Wire_SetConversion {
} }
sub RPI_1Wire_Switch { sub RPI_1Wire_Switch {
my ($hash,$switch)= @_; my ($hash,$switch,$pio,$cmd,$duration)= @_;
Log3 $hash->{NAME}, 3, $hash->{NAME}.": Switching $hash->{DEF} to $switch"; Log3 $hash->{NAME}, 3, $hash->{NAME}.": Switching $hash->{DEF} to $switch ($pio $cmd) for ($duration)";
my $fh; my $fh;
my $path="$w1_path/$hash->{DEF}/output"; my $path="$w1_path/$hash->{DEF}/output";
#testing - uncomment to test with a normal file
#my $path="/home/pi/state";
if (open($fh, ">", $path)) { if (open($fh, ">", $path)) {
print $fh pack("C",$switch); print $fh pack("C",$switch);
close($fh); close($fh);
@ -302,6 +310,12 @@ sub RPI_1Wire_Switch {
#After setting switch, read back to set readings correctly #After setting switch, read back to set readings correctly
my $ret=RPI_1Wire_Poll($hash); my $ret=RPI_1Wire_Poll($hash);
RPI_1Wire_FinishFn($ret); RPI_1Wire_FinishFn($ret);
if ($cmd =~ /-for-timer$/) {
$cmd=( $cmd =~ /^on/?"off":"on"); #Revert condition to be executed after timer
return "Invalid duration $duration" if (!looks_like_number($duration));
Log3 $hash->{NAME}, 4, $hash->{NAME}.": Setting time for switching $hash->{DEF} $pio to $cmd in $duration s";
InternalTimer(gettimeofday()+$duration, sub { RPI_1Wire_Set($hash, $hash->{NAME},($pio,$cmd)); },0);
}
return; return;
} }
@ -328,11 +342,11 @@ sub RPI_1Wire_Set {
} }
} }
if ($type eq "switch" or $type eq "2p-switch") { if ($type eq "switch" or $type eq "2p-switch") {
$sets.="pioa:on,off piob:on,off "; $sets.="pioa:widgetList,5,select,on,off,on-for-timer,off-for-timer,1,textField piob:widgetList,5,select,on,off,on-for-timer,off-for-timer,1,textField ";
} }
if ($type eq "8p-switch") { if ($type eq "8p-switch") {
for my $i ((0..7)) { for my $i ((0..7)) {
$sets.="pio".$i.":on,off "; $sets.="pio".$i.":widgetList,5,select,on,off,on-for-timer,off-for-timer,1,textField ";
} }
} }
if ($device =~ /(BUSMASTER)(-\d)?$/) { if ($device =~ /(BUSMASTER)(-\d)?$/) {
@ -349,34 +363,40 @@ sub RPI_1Wire_Set {
if ( $cmd eq "?" ) { if ( $cmd eq "?" ) {
return "RPI_1Wire_Set: Unknown argument $cmd, choose one of " . $sets; return "RPI_1Wire_Set: Unknown argument $cmd, choose one of " . $sets;
} }
if ($cmd =~ /^pio(a|b)/ and @args==1) { my @cm;
my $val=shift @args; if (@args>0) {
Log3 $name, 3, $name." set pio $1 $val\n"; @cm=split(",",$args[0]);
push @cm,$args[1] if (@args>1);
push @cm,"-" if (@cm==1);
}
if ($cmd =~ /^pio(a|b)/ and @cm>0) {
Log3 $name, 3, $name." set pio $1 $cm[0] $cm[1]\n";
my $set=0; my $set=0;
if ($cmd eq "pioa") { if ($cmd eq "pioa") {
$set=ReadingsVal($name,"piob","0")*2+($val eq "on"?1:0); $set=ReadingsVal($name,"piob","0")*2+($cm[0] =~ /^on/?1:0);
} else { } else {
$set=ReadingsVal($name,"pioa","0")+($val eq "on"?1:0)*2; $set=ReadingsVal($name,"pioa","0")+($cm[0] =~ /^on/?1:0)*2;
} }
if ($type eq "2p-switch") { if ($type eq "2p-switch") {
$set=($set^3); #bits are inverted on DS2413 $set=($set^3); #bits are inverted on DS2413
} }
return RPI_1Wire_Switch($hash,$set); return RPI_1Wire_Switch($hash,$set,$cmd, $cm[0],$cm[1]);
} }
if ($cmd =~ /^pio(\d)/ and @args==1) { if ($cmd =~ /^pio(\d)/ and @cm>0) {
my $val=shift @args; my $pio=$1;
Log3 $name, 3, $name." set pio $1 $val\n"; Log3 $name, 3, $name." set pio $pio $cm[0] $cm[1]\n";
my $id=$1; my $id=$1;
my $set=0; my $set=0;
for my $i (0..7) { for my $i (0..7) {
my $bit=2**$i; my $bit=2**$i;
if ($i==$id) { if ($i==$id) {
$set+=($val eq "on"?1:0)*$bit; $set+=($cm[0] =~ /^on/?1:0)*$bit;
} else { } else {
$set+=ReadingsVal($name,"pio".$i,"0")*$bit; $set+=ReadingsVal($name,"pio".$i,"0")*$bit;
} }
} }
return RPI_1Wire_Switch($hash,$set); $set=($set^255); # invert bits
return RPI_1Wire_Switch($hash,$set,$cmd, $cm[0],$cm[1]);
} }
if ($cmd eq "precision" and @args==1) { if ($cmd eq "precision" and @args==1) {
@ -433,6 +453,7 @@ sub RPI_1Wire_Get {
$script .= "chmod g+w /sys/devices/w1_bus_master*/therm_bulk_read;\\\n"; $script .= "chmod g+w /sys/devices/w1_bus_master*/therm_bulk_read;\\\n";
$script .= "chmod g+w /sys/devices/w1_bus_master*/*/resolution;\\\n"; $script .= "chmod g+w /sys/devices/w1_bus_master*/*/resolution;\\\n";
$script .= "chmod g+w /sys/devices/w1_bus_master*/*/conv_time;\\ \'\"\n"; $script .= "chmod g+w /sys/devices/w1_bus_master*/*/conv_time;\\ \'\"\n";
$script .= "chmod g+w /sys/devices/w1_bus_master*/*/output;\\ \'\"\n";
return $ret.$script; return $ret.$script;
} }
@ -485,9 +506,11 @@ sub RPI_1Wire_Poll {
my @data; my @data;
foreach (@path) { foreach (@path) {
$file="$w1_path/$device/$_"; $file="$w1_path/$device/$_";
#testing - uncomment to test with a normal file
#if ($type =~ /switch/) { #if ($type =~ /switch/) {
# $file="/home/pi/state"; # $file="/home/pi/state";
#} #}
#testing
if ($family =~ /DHT(11|22)/) { if ($family =~ /DHT(11|22)/) {
my $env = RPi::DHT->new($id,$1,1); my $env = RPi::DHT->new($id,$1,1);
Log3 $name, 4 , $name.": Using RPi::DHT for $id DHT-$1"; Log3 $name, 4 , $name.": Using RPi::DHT for $id DHT-$1";
@ -576,7 +599,7 @@ sub RPI_1Wire_Poll {
if ($type eq "8p-switch") { if ($type eq "8p-switch") {
my $pin=0; my $pin=0;
foreach (@pio) { foreach (@pio) {
$retval.=" pio".$pin++."=".$_; $retval.=" pio".$pin++."=".($_^1);
} }
} else { } else {
if ($type eq "2p-switch") { if ($type eq "2p-switch") {
@ -718,7 +741,7 @@ For German documentation see <a href="https://wiki.fhem.de/wiki/RPI_1Wire">Wiki<
<li>Family 0x1d (DS2423) dual counter</li> <li>Family 0x1d (DS2423) dual counter</li>
<li>Family 0x26 (DS2438) a/d converter with temperature support</li> <li>Family 0x26 (DS2438) a/d converter with temperature support</li>
<li>Family 0x28 (DS18B20) temperature</li> <li>Family 0x28 (DS18B20) temperature</li>
<li>Family 0x29 (DS2408) 8 port switch (untested)</li> <li>Family 0x29 (DS2408) 8 port switch</li>
<li>Family 0x3a (DS2413) adressable 2 port switch</li> <li>Family 0x3a (DS2413) adressable 2 port switch</li>
<li>Family 0x3b (DS1825) temperature</li> <li>Family 0x3b (DS1825) temperature</li>
<li>Family 0x42 (DS28EA00) temperature</li> <li>Family 0x42 (DS28EA00) temperature</li>
@ -777,17 +800,20 @@ For German documentation see <a href="https://wiki.fhem.de/wiki/RPI_1Wire">Wiki<
<a id="RPI_1Wire-set-clear"></a> <a id="RPI_1Wire-set-clear"></a>
Clears the failures counter. Clears the failures counter.
</li> </li>
<li><b>set pioa on|off</b><br> <li><b>set pioa on|off &ltduration&gt</b><br>
<a id="RPI_1Wire-set-pioa"></a> <a id="RPI_1Wire-set-pioa"></a>
Sets the pioa of a 2 port switch to on or off. Sets the pioa of a 2 port switch to on or off.<br>
The optional duration switches the pio back after a given number of seconds. The alternative options "on-for-timer" and "off-for-timer" work identically and are only provided to find this functionality more easily.
</li> </li>
<li><b>set piob on|off</b><br> <li><b>set piob on|off &ltduration&gt</b><br>
<a id="RPI_1Wire-set-piob"></a> <a id="RPI_1Wire-set-piob"></a>
Sets the piob of a 2 port switch to on or off. Sets the piob of a 2 port switch to on or off.<br>
The optional duration switches the pio back after a given number of seconds. The alternative options "on-for-timer" and "off-for-timer" work identically and are only provided to find this functionality more easily.
</li> </li>
<li><b>set pio(0-7) on|off</b><br> <li><b>set pio(0-7) on|off &ltduration&gt</b><br>
<a id="RPI_1Wire-set-pio0"></a> <a id="RPI_1Wire-set-pio0"></a>
Sets the according pio of a 8 port switch (0-7) to on or off. (untested) Sets the according pio of a 8 port switch (0-7) to on or off.<br>
The optional duration switches the pio back after a given number of seconds. The alternative options "on-for-timer" and "off-for-timer" work identically and are only provided to find this functionality more easily.
</li> </li>
</ul> </ul>