2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-05-05 14:29:35 +00:00

git-svn-id: https://svn.fhem.de/fhem/trunk@2433 2b470e98-0d58-463d-a4d8-8e2adae1ed80

This commit is contained in:
pahenning 2013-01-04 12:12:41 +00:00
parent 2cac0b8811
commit 5a898baf40
6 changed files with 1154 additions and 1193 deletions

View File

@ -2,23 +2,13 @@
# #
# OWAD.pm # OWAD.pm
# #
# WIESO UNINITIALIZED in 623FF
#
# FHEM module to commmunicate with 1-Wire A/D converters DS2450 # FHEM module to commmunicate with 1-Wire A/D converters DS2450
# #
# Attention: This module may communicate with the OWX module,
# but currently not with the 1-Wire File System OWFS
#
# Prefixes for subroutines of this module:
# OW = General 1-Wire routines Peter Henning)
# OWX = 1-Wire bus master interface (Peter Henning)
# OWFS = 1-Wire file system (??)
#
# Prof. Dr. Peter A. Henning, 2012 # Prof. Dr. Peter A. Henning, 2012
# #
# Version 2.25 - October, 2012 # $Id$
# #
# Setup bus device in fhem.cfg as ########################################################################################
# #
# define <name> OWAD [<model>] <ROM_ID> [interval] # define <name> OWAD [<model>] <ROM_ID> [interval]
# #
@ -42,20 +32,19 @@
# Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B,C,D # Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B,C,D
# Note: attributes are read only during initialization procedure - later changes are not used. # Note: attributes are read only during initialization procedure - later changes are not used.
# #
# attr <name> event on-change/on-update = when to write an event (default= on-update) # attr <name> stateAL0 "<string>" = character string for denoting low normal condition, default is empty
# # attr <name> stateAH0 "<string>" = character string for denoting high normal condition, default is empty
# attr <name> stateAL0 "<string>" = character string for denoting low normal condition, default is empty, # attr <name> stateAL1 "<string>" = character string for denoting low alarm condition, default is down triangle
# overwritten by attribute setting green down triangle # attr <name> stateAH1 "<string>" = character string for denoting high alarm condition, default is up triangle
# attr <name> stateAH0 "<string>" = character string for denoting high normal condition, default is empty,
# overwritten by attribute setting green up triangle
# attr <name> stateAL1 "<string>" = character string for denoting low alarm condition, default is l,
# overwritten by attributre setting red down triangle
# attr <name> stateAH1 "<string>" = character string for denoting high alarm condition, default is h,
# overwritten by attributre setting red up triangle
# attr <name> <channel>Name <string>|<string> = name for the channel | a type description for the measured value # attr <name> <channel>Name <string>|<string> = name for the channel | a type description for the measured value
# attr <name> <channel>Unit <string>|<string> = unit of measurement for this channel | its abbreviation # attr <name> <channel>Unit <string>|<string> = unit of measurement for this channel | its abbreviation
#
# ATTENTION: Usage of Offset/Factor is deprecated, replace by Function attribute
# attr <name> <channel>Offset <float> = offset added to the reading in this channel # attr <name> <channel>Offset <float> = offset added to the reading in this channel
# attr <name> <channel>Factor <float> = factor multiplied to (reading+offset) in this channel # attr <name> <channel>Factor <float> = factor multiplied to (reading+offset) in this channel
# attr <name> <channel>Function <string> = arbitrary functional expression involving the values V<channel>=VA,VB,VC,VD
# VA is replaced by the measured voltage in channel A, etc.
#
# attr <name> <channel>Alarm <string> = alarm setting in this channel, either both, low, high or none (default) # attr <name> <channel>Alarm <string> = alarm setting in this channel, either both, low, high or none (default)
# attr <name> <channel>Low <float> = measurement value (on the scale determined by offset and factor) for low alarm # attr <name> <channel>Low <float> = measurement value (on the scale determined by offset and factor) for low alarm
# attr <name> <channel>High <float> = measurement value (on the scale determined by offset and factor) for high alarm # attr <name> <channel>High <float> = measurement value (on the scale determined by offset and factor) for high alarm
@ -80,7 +69,6 @@
######################################################################################## ########################################################################################
package main; package main;
#-- Prototypes to make komodo happy
use vars qw{%attr %defs}; use vars qw{%attr %defs};
use strict; use strict;
use warnings; use warnings;
@ -93,7 +81,7 @@ my $owg_state;
my @owg_fixed = ("A","B","C","D"); my @owg_fixed = ("A","B","C","D");
my @owg_channel; my @owg_channel;
#-- channel values - always the raw values from the device #-- channel values - always the raw values from the device
my @owg_val; my @owg_val=("","","","");
#-- channel mode - fixed for now #-- channel mode - fixed for now
my @owg_mode = ("input","input","input","input"); my @owg_mode = ("input","input","input","input");
#-- resolution in bit - fixed for now #-- resolution in bit - fixed for now
@ -101,8 +89,8 @@ my @owg_resoln = (16,16,16,16);
#-- raw range in mV - fixed for now #-- raw range in mV - fixed for now
my @owg_range = (5100,5100,5100,5100); my @owg_range = (5100,5100,5100,5100);
#-- alarm status 0 = disabled, 1 = enabled, but not alarmed, 2 = alarmed #-- alarm status 0 = disabled, 1 = enabled, but not alarmed, 2 = alarmed
my @owg_slow; my @owg_slow=(0,0,0,0);
my @owg_shigh; my @owg_shigh=(0,0,0,0);
#-- alarm values - always the raw values committed to the device #-- alarm values - always the raw values committed to the device
my @owg_vlow; my @owg_vlow;
my @owg_vhigh; my @owg_vhigh;
@ -154,12 +142,14 @@ sub OWAD_Initialize ($) {
#Factor = a v(oltage) factor multiplied with (reading+offset) #Factor = a v(oltage) factor multiplied with (reading+offset)
#Unit = a unit of measure #Unit = a unit of measure
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2450 loglevel:0,1,2,3,4,5 ". my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2450 loglevel:0,1,2,3,4,5 ".
"stateAL0 stateAL1 stateAH0 stateAH1 event:on-update,on-change "; "event-on-update-reading event-on-change-reading ".
"stateAL0 stateAL1 stateAH0 stateAH1";
for( my $i=0;$i<4;$i++ ){ for( my $i=0;$i<4;$i++ ){
$attlist .= " ".$owg_fixed[$i]."Name"; $attlist .= " ".$owg_fixed[$i]."Name";
$attlist .= " ".$owg_fixed[$i]."Offset"; $attlist .= " ".$owg_fixed[$i]."Offset";
$attlist .= " ".$owg_fixed[$i]."Factor"; $attlist .= " ".$owg_fixed[$i]."Factor";
$attlist .= " ".$owg_fixed[$i]."Function";
$attlist .= " ".$owg_fixed[$i]."Unit"; $attlist .= " ".$owg_fixed[$i]."Unit";
$attlist .= " ".$owg_fixed[$i]."Alarm"; $attlist .= " ".$owg_fixed[$i]."Alarm";
$attlist .= " ".$owg_fixed[$i]."Low"; $attlist .= " ".$owg_fixed[$i]."Low";
@ -225,10 +215,12 @@ sub OWAD_Define ($$) {
#-- Couple to I/O device #-- Couple to I/O device
AssignIoPort($hash); AssignIoPort($hash);
Log 3, "OWAD: Warning, no 1-Wire I/O device found for $name." if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | ($hash->{IODev}->{PRESENT} != 1) ){
if(!defined($hash->{IODev}->{NAME})); return "OWAD: Warning, no 1-Wire I/O device found for $name.";
}
$modules{OWAD}{defptr}{$id} = $hash; $modules{OWAD}{defptr}{$id} = $hash;
$hash->{STATE} = "Defined"; #--
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWAD: Device $name defined."; Log 3, "OWAD: Device $name defined.";
#-- Initialization reading according to interface type #-- Initialization reading according to interface type
@ -256,20 +248,10 @@ sub OWAD_InitializeDevice($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
#-- more colorful alarm signatures
CommandAttr (undef,"$name stateAL1 <span style=\"color:red\">&#x25BE;</span>")
if( !defined($attr{$name}{"stateAL1"} ));
CommandAttr (undef,"$name stateAH1 <span style=\"color:red\">&#x25B4;</span>")
if( !defined($attr{$name}{"stateAH1"} ));
CommandAttr (undef,"$name stateAL0 <span style=\"color:green\">&#x25BE;</span>")
if( !defined($attr{$name}{"stateAL0"} ));
CommandAttr (undef,"$name stateAH0 <span style=\"color:green\">&#x25B4;</span>")
if( !defined($attr{$name}{"stateAH0"} ));
#-- Initial readings #-- Initial readings
@owg_val = (0.0,0.0,0.0,0.0); @owg_val = (""."".""."");
@owg_slow = (0,0,0,0); @owg_slow = (""."".""."");
@owg_shigh = (0,0,0,0); @owg_shigh = (""."".""."");
#-- Set channel names, channel units and alarm values #-- Set channel names, channel units and alarm values
for( my $i=0;$i<int(@owg_fixed);$i++) { for( my $i=0;$i<int(@owg_fixed);$i++) {
@ -289,18 +271,13 @@ sub OWAD_InitializeDevice($) {
push(@unarr,""); push(@unarr,"");
} }
#-- offset and scale factor
my $offset = defined($attr{$name}{$owg_fixed[$i]."Offset"}) ? $attr{$name}{$owg_fixed[$i]."Offset"} : 0.0;
my $factor = defined($attr{$name}{$owg_fixed[$i]."Factor"}) ? $attr{$name}{$owg_fixed[$i]."Factor"} : 1.0;
#-- put into readings #-- put into readings
$owg_channel[$i] = $cnama[0]; $owg_channel[$i] = $cnama[0];
$hash->{READINGS}{"$owg_channel[$i]"}{TYPE} = $cnama[1]; $hash->{READINGS}{"$owg_channel[$i]"}{TYPE} = $cnama[1];
$hash->{READINGS}{"$owg_channel[$i]"}{UNIT} = $unarr[0]; $hash->{READINGS}{"$owg_channel[$i]"}{UNIT} = $unarr[0];
$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR} = $unarr[1]; $hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR} = $unarr[1];
$hash->{READINGS}{"$owg_channel[$i]"}{OFFSET} = $offset;
$hash->{READINGS}{"$owg_channel[$i]"}{FACTOR} = $factor;
#-- alarm #-- Initial readings
my $alarm = defined($attr{$name}{$owg_fixed[$i]."Alarm"}) ? $attr{$name}{$owg_fixed[$i]."Alarm"} : "none"; my $alarm = defined($attr{$name}{$owg_fixed[$i]."Alarm"}) ? $attr{$name}{$owg_fixed[$i]."Alarm"} : "none";
my $vlow = defined($attr{$name}{$owg_fixed[$i]."Low"}) ? $attr{$name}{$owg_fixed[$i]."Low"} : 0.0; my $vlow = defined($attr{$name}{$owg_fixed[$i]."Low"}) ? $attr{$name}{$owg_fixed[$i]."Low"} : 0.0;
my $vhigh = defined($attr{$name}{$owg_fixed[$i]."High"}) ? $attr{$name}{$owg_fixed[$i]."High"} : 5.0; my $vhigh = defined($attr{$name}{$owg_fixed[$i]."High"}) ? $attr{$name}{$owg_fixed[$i]."High"} : 5.0;
@ -310,10 +287,13 @@ sub OWAD_InitializeDevice($) {
if( $alarm eq "high" || $alarm eq "both" ){ if( $alarm eq "high" || $alarm eq "both" ){
$owg_shigh[$i]=1; $owg_shigh[$i]=1;
}; };
$owg_vlow[$i] = ($vlow/$factor - $offset); $owg_vlow[$i] = $vlow;
$owg_vhigh[$i] = ($vhigh/$factor - $offset); $owg_vhigh[$i] = $vhigh;
} }
#-- Initialize all the display stuff
OWAD_FormatValues($hash);
#-- set status according to interface type #-- set status according to interface type
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
@ -331,8 +311,6 @@ sub OWAD_InitializeDevice($) {
return "OWAD: InitializeDevice with wrong IODev type $interface"; return "OWAD: InitializeDevice with wrong IODev type $interface";
} }
#-- Initialize all the display stuff
OWAD_FormatValues($hash);
} }
######################################################################################## ########################################################################################
@ -347,94 +325,131 @@ sub OWAD_FormatValues($) {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ($offset,$factor,$vval,$vlow,$vhigh); my ($offset,$factor,$vval,$vlow,$vhigh,$vfunc);
my ($value1,$value2,$value3) = ("","",""); my $vfuncall = "";
my $svalue = "";
#-- insert initial values
for( my $k=0;$k<int(@owg_fixed);$k++ ){
$vfuncall .= "\$owg_val[$k]=$owg_val[$k];";
}
my $galarm = 0; my $galarm = 0;
my $tn = TimeNow();
#-- alarm signatures #-- alarm signatures
my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "l"; my $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : "&#x25BE;";
my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "h"; my $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : "&#x25B4;";
my $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : ""; my $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : "";
my $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : ""; my $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : "";
#-- put into READINGS
readingsBeginUpdate($hash);
#-- formats for output #-- formats for output
for (my $i=0;$i<int(@owg_fixed);$i++){ for (my $i=0;$i<int(@owg_fixed);$i++){
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|voltage"; my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|voltage";
my @cnama = split(/\|/,$cname); my @cnama = split(/\|/,$cname);
$owg_channel[$i]=$cnama[0]; $owg_channel[$i]=$cnama[0];
$offset = $hash->{READINGS}{"$owg_channel[$i]"}{OFFSET};
$factor = $hash->{READINGS}{"$owg_channel[$i]"}{FACTOR}; #-- skip a few things when the values are undefined or zero
#-- correct values for proper offset, factor if( !defined($owg_val[$i]) ){
$vval = int(($owg_val[$i] + $offset)*$factor*1000)/1000;; $svalue .= "$owg_channel[$i]: ???"
#-- put into READINGS }else{
$hash->{READINGS}{"$owg_channel[$i]"}{VAL} = $vval; if( $owg_val[$i] eq "" ){
$hash->{READINGS}{"$owg_channel[$i]"}{TIME} = $tn; $svalue .= "$owg_channel[$i]: ???"
}else{
#-- when offset and scale factor are defined, we cannot have a function and vice versa
if( defined($attr{$name}{$owg_fixed[$i]."Offset"}) & defined($attr{$name}{$owg_fixed[$i]."Factor"}) ){
my $offset = $attr{$name}{$owg_fixed[$i]."Offset"};
my $factor = $attr{$name}{$owg_fixed[$i]."Factor"};
$vfunc = "$factor*(V$owg_fixed[$i] + $offset)";
#-- attribute VFunction defined
} elsif (defined($attr{$name}{$owg_fixed[$i]."Function"})){
$vfunc = $attr{$name}{$owg_fixed[$i]."Function"};
} else {
$vfunc = "V$owg_fixed[$i]";
}
$hash->{tempf}{"$owg_fixed[$i]"}{function} = $vfunc;
#-- replace by proper values (VA -> $owg_val[0] etc.)
for( my $k=0;$k<int(@owg_fixed);$k++ ){
my $sstr = "V$owg_fixed[$k]";
$vfunc =~ s/$sstr/\$owg_val[$k]/g;
}
#-- correct alarm values for proper offset, factor #-- correct alarm values for proper offset, factor
$vlow = int(($owg_vlow[$i] + $offset)*$factor*1000)/1000; #$vlow = int(($owg_vlow[$i] + $offset)*$factor*1000)/1000;
$vhigh = int(($owg_vhigh[$i] + $offset)*$factor*1000)/1000; #$vhigh = int(($owg_vhigh[$i] + $offset)*$factor*1000)/1000;
#-- put into READINGS #-- determine the measured value from the function
$hash->{READINGS}{$owg_channel[$i]."Low"}{VAL} = $vlow; $vfunc = $vfuncall.$vfunc;
$hash->{READINGS}{$owg_channel[$i]."Low"}{TIME} = $tn; #Log 1, "After completion vfunc= ".$vfunc;
$hash->{READINGS}{$owg_channel[$i]."High"}{VAL} = $vhigh; $vfunc = eval($vfunc);
$hash->{READINGS}{$owg_channel[$i]."High"}{TIME} = $tn; if( !$vfunc ){
$vval = 0.0;
} elsif( $vfunc ne "" ){
$vval = int( $vfunc*1000 )/1000;
}
#Log 1," And finally after evaluation $vfunc";
#-- string buildup for return value, STATE and alarm #-- string buildup for return value, STATE and alarm
$value1 .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR}); $svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR});
$value2 .= sprintf( "%s: %5.2f %s ", $owg_channel[$i], $vval,$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR});
$value3 .= sprintf( "%s: " , $owg_channel[$i]); #-- alarm
my $alarm = defined($attr{$name}{$owg_fixed[$i]."Alarm"}) ? $attr{$name}{$owg_fixed[$i]."Alarm"} : "none";
my $vlow = defined($attr{$name}{$owg_fixed[$i]."Low"}) ? $attr{$name}{$owg_fixed[$i]."Low"} : 0.0;
my $vhigh = defined($attr{$name}{$owg_fixed[$i]."High"}) ? $attr{$name}{$owg_fixed[$i]."High"} : 5.0;
if( $alarm eq "low" || $alarm eq "both" ){
$owg_slow[$i]=1;
}
if( $alarm eq "high" || $alarm eq "both" ){
$owg_shigh[$i]=1;
};
#-- this needs to be fixed => HOW ???
$owg_vlow[$i] = $vlow;
$owg_vhigh[$i] = $vhigh;
#-- Test for alarm condition #-- Test for alarm condition
#-- alarm signature low #-- alarm signature low
if( $owg_slow[$i] == 0 ) { if( $owg_slow[$i] == 0 ) {
#$value2 .= " ";
$value3 .= "-";
} else { } else {
if( $vval > $vlow ){ if( $vval > $vlow ){
$owg_slow[$i] = 1; $owg_slow[$i] = 1;
$value2 .= $stateal0; $svalue .= $stateal0;
$value3 .= $stateal0;
} else { } else {
$galarm = 1; $galarm = 1;
$owg_slow[$i] = 2; $owg_slow[$i] = 2;
$value2 .= $stateal1; $svalue .= $stateal1;
$value3 .= $stateal1;
} }
} }
#-- alarm signature high #-- alarm signature high
if( $owg_shigh[$i] == 0 ) { if( $owg_shigh[$i] == 0 ) {
#$value2 .= " ";
$value3 .= "-";
} else { } else {
if( $vval < $vhigh ){ if( $vval < $vhigh ){
$owg_shigh[$i] = 1; $owg_shigh[$i] = 1;
$value2 .= $stateah0; $svalue .= $stateah0;
$value3 .= $stateah0;
} else { } else {
$galarm = 1; $galarm = 1;
$owg_shigh[$i] = 2; $owg_shigh[$i] = 2;
$value2 .= $stateah1; $svalue .= $stateah1;
$value3 .= $stateah1;
} }
} }
#-- insert comma #-- put into READINGS
readingsBulkUpdate($hash,"$owg_channel[$i]",$vval);
readingsBulkUpdate($hash,"$owg_channel[$i]Low",$vlow);
readingsBulkUpdate($hash,"$owg_channel[$i]High",$vhigh);
}
}
#-- insert space
if( $i<int(@owg_fixed)-1 ){ if( $i<int(@owg_fixed)-1 ){
$value1 .= " "; $svalue .= " ";
$value2 .= ", ";
$value3 .= ", ";
} }
} }
#-- STATE #-- STATE
$hash->{STATE} = $value2; readingsBulkUpdate($hash,"state",$svalue);
#-- alarm readingsEndUpdate($hash,1);
$hash->{ALARM} = $galarm;
$hash->{READINGS}{alarms}{VAL} = $value3; return $svalue;
$hash->{READINGS}{alarms}{TIME} = $tn;
return $value1;
} }
######################################################################################## ########################################################################################
@ -451,6 +466,7 @@ sub OWAD_Get($@) {
my $reading = $a[1]; my $reading = $a[1];
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL}; my $model = $hash->{OW_MODEL};
my $interface= $hash->{IODev}->{TYPE};
my ($value,$value2,$value3) = (undef,undef,undef); my ($value,$value2,$value3) = (undef,undef,undef);
my $ret = ""; my $ret = "";
my $offset; my $offset;
@ -489,7 +505,6 @@ sub OWAD_Get($@) {
$hash->{PRESENT} = 0; $hash->{PRESENT} = 0;
#-- get reading according to interface type #-- get reading according to interface type
my $interface= $hash->{IODev}->{TYPE};
if($a[1] eq "reading") { if($a[1] eq "reading") {
#-- OWX interface #-- OWX interface
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
@ -507,7 +522,7 @@ sub OWAD_Get($@) {
return "OWAD: Could not get values from device $name"; return "OWAD: Could not get values from device $name";
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
return "OWAD: $name.$reading => ".OWAD_FormatValues($hash); return "OWAD: $name.reading => ".OWAD_FormatValues($hash);
} }
#-- get alarm values according to interface type #-- get alarm values according to interface type
@ -530,14 +545,14 @@ sub OWAD_Get($@) {
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
OWAD_FormatValues($hash); OWAD_FormatValues($hash);
#-- output string looks differently here #-- assemble ouput string
$value = ""; $value = "";
for (my $i=0;$i<int(@owg_fixed);$i++){ for (my $i=0;$i<int(@owg_fixed);$i++){
$value .= sprintf "%s:[%4.2f,%4.2f] ",$owg_channel[$i], $value .= sprintf "%s:[%4.2f,%4.2f] ",$owg_channel[$i],
$hash->{READINGS}{$owg_channel[$i]."Low"}{VAL}, $hash->{READINGS}{$owg_channel[$i]."Low"}{VAL},
$hash->{READINGS}{$owg_channel[$i]."High"}{VAL}; $hash->{READINGS}{$owg_channel[$i]."High"}{VAL};
} }
return "OWAD: $name.$reading => $value"; return "OWAD: $name.alarm => $value";
} }
#-- get status values according to interface type #-- get status values according to interface type
@ -559,9 +574,36 @@ sub OWAD_Get($@) {
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
OWAD_FormatValues($hash); OWAD_FormatValues($hash);
return "OWAD: $name.$reading => ".$hash->{READINGS}{alarms}{VAL};
#-- assemble output string
$value = "";
for (my $i=0;$i<int(@owg_fixed);$i++){
$value .= $owg_channel[$i].": ".$owg_mode[$i].", ";
#$value .= "disabled ,"
# if ( !($sb2 && 128) );
$value .= sprintf "raw range %3.1f V, ",$owg_range[$i]/1000;
$value .= sprintf "resolution %d bit, ",$owg_resoln[$i];
$value .= sprintf "low alarm disabled, "
if( $owg_slow[$i]==0 );
$value .= sprintf "low alarm enabled, "
if( $owg_slow[$i]==1 );
$value .= sprintf "alarmed low, "
if( $owg_slow[$i]==2 );
$value .= sprintf "high alarm disabled"
if( $owg_shigh[$i]==0 );
$value .= sprintf "high alarm enabled"
if( $owg_shigh[$i]==1 );
$value .= sprintf "alarmed high"
if( $owg_shigh[$i]==2 );
#-- insert space
if( $i<int(@owg_fixed)-1 ){
$value .= "\n";
} }
} }
return "OWAD: $name.status => ".$value;
}
}
####################################################################################### #######################################################################################
# #
@ -576,6 +618,7 @@ sub OWAD_GetValues($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL}; my $model = $hash->{OW_MODEL};
my $interface= $hash->{IODev}->{TYPE};
my $value = ""; my $value = "";
my $ret = ""; my $ret = "";
my $offset; my $offset;
@ -593,7 +636,6 @@ sub OWAD_GetValues($) {
$hash->{PRESENT} = 0; $hash->{PRESENT} = 0;
#-- Get readings, alarms and stati according to interface type #-- Get readings, alarms and stati according to interface type
my $interface= $hash->{IODev}->{TYPE};
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
$ret = OWXAD_GetPage($hash,"reading"); $ret = OWXAD_GetPage($hash,"reading");
$ret = OWXAD_GetPage($hash,"alarm"); $ret = OWXAD_GetPage($hash,"alarm");
@ -606,21 +648,12 @@ sub OWAD_GetValues($) {
#-- process results #-- process results
if( defined($ret) ){ if( defined($ret) ){
return "OWAD: Could not get values from device $name"; return "OWAD: Could not get values from device $name, reason $ret";
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
#-- old state, new state
my $oldval = $hash->{STATE};
$value=OWAD_FormatValues($hash); $value=OWAD_FormatValues($hash);
my $newval = $hash->{STATE};
#--logging depends on setting of the event-attribute
Log 5, $value; Log 5, $value;
my $ev = defined($attr{$name}{"event"}) ? $attr{$name}{"event"} : "on-update";
if( ($ev eq "on-update") || (($ev eq "on-change") && ($newval ne $oldval)) ){
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef);
}
return undef; return undef;
} }
@ -728,24 +761,24 @@ sub OWAD_Set($@) {
return "OWAD: Set with wrong IODev type $interface"; return "OWAD: Set with wrong IODev type $interface";
} }
}elsif( $key =~ m/(.*)(Low|High)/ ) { }elsif( $key =~ m/(.*)(Low|High)/ ) {
$offset = $attr{$name}{$owg_fixed[$channo]."Offset"}; #$offset = $attr{$name}{$owg_fixed[$channo]."Offset"};
$factor = $attr{$name}{$owg_fixed[$channo]."Factor"}; #$factor = $attr{$name}{$owg_fixed[$channo]."Factor"};
#-- find upper and lower boundaries for given offset/factor #-- find upper and lower boundaries for given offset/factor
my $mmin = 0.0; my $mmin = 0.0;
$mmin += $offset if ( $offset ); #$mmin += $offset if ( $offset );
$mmin *= $factor if ( $factor ); #$mmin *= $factor if ( $factor );
my $mmax = $owg_range[$channo]/1000; my $mmax = $owg_range[$channo]/1000;
$mmax += $offset if ( $offset ); #$mmax += $offset if ( $offset );
$mmax *= $factor if ( $factor ); #$mmax *= $factor if ( $factor );
return sprintf("OWAD: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax) return sprintf("OWAD: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax)
if($value < $mmin || $value > $mmax); if($value < $mmin || $value > $mmax);
$value /= $factor if ( $factor ); #$value /= $factor if ( $factor );
$value -= $offset if ( $offset ); #$value -= $offset if ( $offset );
#-- round to those numbers understood by the device #-- round to those numbers understood by the device
my $value2 = int($value*255000/$owg_range[$channo])*$owg_range[$channo]/255000; my $value2 = int($value*255000/$owg_range[$channo])*$owg_range[$channo]/255000;
@ -842,7 +875,7 @@ sub OWXAD_GetPage($$) {
#-- issue the match ROM command \x55 and the start conversion command #-- issue the match ROM command \x55 and the start conversion command
$res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0); $res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0);
if( $res eq 0 ){ if( $res eq 0 ){
return "OWXAD: Device $owx_dev not accessible for conversion"; return "not accessible for conversion";
} }
#-- conversion needs some 5 ms per channel #-- conversion needs some 5 ms per channel
select(undef,undef,undef,0.02); select(undef,undef,undef,0.02);
@ -862,47 +895,46 @@ sub OWXAD_GetPage($$) {
$select="\xAA\x08\x00"; $select="\xAA\x08\x00";
#=============== wrong value requested =============================== #=============== wrong value requested ===============================
} else { } else {
return "OWXAD: Wrong memory page requested"; return "wrong memory page requested";
} }
#-- reset the bus #-- reset the bus
OWX_Reset($master); OWX_Reset($master);
#-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes #-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes
$res=OWX_Complex($master,$owx_dev,$select,10); $res=OWX_Complex($master,$owx_dev,$select,10);
#Log 1, "OWXAD: Device $owx_dev returns data of length ".length($res);
if( $res eq 0 ){ if( $res eq 0 ){
return "OWXAD: Device $owx_dev not accessible in reading $page page"; return "not accessible in reading $page page";
} }
#-- reset the bus #-- reset the bus
OWX_Reset($master); OWX_Reset($master);
#-- process results #-- process results
@data=split(//,$res); @data=split(//,substr($res,9));
return "OWXAD: invalid data length, ".int(@data)." bytes" return "invalid data length, ".int(@data)." instead of 13 bytes"
if (@data != 22); if (@data != 13);
#return "invalid data" #return "invalid data"
# if (ord($data[17])<=0); # if (ord($data[17])<=0);
#return "invalid CRC" return "invalid CRC"
# if (OWX_CRC8(substr($res,10,8),$data[18])==0); if (OWX_CRC16(substr($res,9,11),$data[11],$data[12])==0);
#=============== get the voltage reading =============================== #=============== get the voltage reading ===============================
if( $page eq "reading"){ if( $page eq "reading"){
for( $i=0;$i<int(@owg_fixed);$i++){ for( $i=0;$i<int(@owg_fixed);$i++){
$owg_val[$i]= int((ord($data[12+2*$i])+256*ord($data[13+2*$i]))/((1<<$owg_resoln[$i])-1) * $owg_range[$i])/1000; $owg_val[$i]= int((ord($data[3+2*$i])+256*ord($data[4+2*$i]))/((1<<$owg_resoln[$i])-1) * $owg_range[$i])/1000;
} }
#=============== get the alarm reading =============================== #=============== get the alarm reading ===============================
} elsif ( $page eq "alarm" ) { } elsif ( $page eq "alarm" ) {
for( $i=0;$i<int(@owg_fixed);$i++){ for( $i=0;$i<int(@owg_fixed);$i++){
$owg_vlow[$i] = int(ord($data[12+2*$i])/255 * $owg_range[$i])/1000; $owg_vlow[$i] = int(ord($data[3+2*$i])/255 * $owg_range[$i])/1000;
$owg_vhigh[$i] = int(ord($data[13+2*$i])/255 * $owg_range[$i])/1000; $owg_vhigh[$i] = int(ord($data[4+2*$i])/255 * $owg_range[$i])/1000;
} }
#=============== get the status reading =============================== #=============== get the status reading ===============================
} elsif ( $page eq "status" ) { } elsif ( $page eq "status" ) {
my ($sb1,$sb2); my ($sb1,$sb2);
for( $i=0;$i<int(@owg_fixed);$i++){ for( $i=0;$i<int(@owg_fixed);$i++){
$sb1 = ord($data[12+2*$i]); $sb1 = ord($data[3+2*$i]);
$sb2 = ord($data[12+2*$i+1]); $sb2 = ord($data[3+2*$i+1]);
#-- normal operation #-- normal operation
if( $sb1 && 128) { if( $sb1 && 128) {
@ -934,26 +966,7 @@ sub OWXAD_GetPage($$) {
$owg_shigh[$i] = 2; $owg_shigh[$i] = 2;
} }
} }
#-- output operation
#-- assemble status string
$owg_status[$i] = $owg_mode[$i].", ";
$owg_status[$i] .= "disabled ,"
if ( !($sb2 && 128) );
$owg_status[$i] .= sprintf "raw range %3.1f V, ",$owg_range[$i]/1000;
$owg_status[$i] .= sprintf "resolution %d bit, ",$owg_resoln[$i];
$owg_status[$i] .= sprintf "low alarm disabled, "
if( $owg_slow[$i]==0 );
$owg_status[$i] .= sprintf "low alarm enabled, "
if( $owg_slow[$i]==1 );
$owg_status[$i] .= sprintf "alarmed low, "
if( $owg_slow[$i]==2 );
$owg_status[$i] .= sprintf "high alarm disabled"
if( $owg_shigh[$i]==0 );
$owg_status[$i] .= sprintf "high alarm enabled"
if( $owg_shigh[$i]==1 );
$owg_status[$i] .= sprintf "alarmed high"
if( $owg_shigh[$i]==2 );
} else { } else {
$owg_mode[$i] = "output"; $owg_mode[$i] = "output";
#-- assemble status string #-- assemble status string
@ -991,13 +1004,13 @@ sub OWXAD_SetPage($$) {
#-- issue the match ROM command \x55 and the set alarm page command #-- issue the match ROM command \x55 and the set alarm page command
# \x55\x10\x00 reading 8 data bytes and 2 CRC bytes # \x55\x10\x00 reading 8 data bytes and 2 CRC bytes
$select="\x55\x10\x00"; $select="\x55\x10\x00";
for( $i=0;$i<4;$i++){ for( $i=0;$i<int(@owg_fixed);$i++){
$select .= sprintf "%c\xFF\xFF\xFF",int($owg_vlow[$i]*255000/$owg_range[$i]); $select .= sprintf "%c\xFF\xFF\xFF",int($owg_vlow[$i]*255000/$owg_range[$i]);
$select .= sprintf "%c\xFF\xFF\xFF",int($owg_vhigh[$i]*255000/$owg_range[$i]); $select .= sprintf "%c\xFF\xFF\xFF",int($owg_vhigh[$i]*255000/$owg_range[$i]);
} }
#=============== set the status =============================== #=============== set the status ===============================
} elsif ( $page eq "status" ) { } elsif ( $page eq "status" ) {
my ($sb1,$sb2); my ($sb1,$sb2)=(0,0);
#-- issue the match ROM command \x55 and the set status memory page command #-- issue the match ROM command \x55 and the set status memory page command
# \x55\x08\x00 reading 8 data bytes and 2 CRC bytes # \x55\x08\x00 reading 8 data bytes and 2 CRC bytes
$select="\x55\x08\x00"; $select="\x55\x08\x00";
@ -1006,8 +1019,12 @@ sub OWXAD_SetPage($$) {
#-- resolution (TODO: check !) #-- resolution (TODO: check !)
$sb1 = $owg_resoln[$i]-1; $sb1 = $owg_resoln[$i]-1;
#-- alarm enabled #-- alarm enabled
$sb2 = ( $owg_slow[$i] > 0 ) ? 4 : 0; if( defined($owg_slow[$i]) ){
$sb2 += ( $owg_shigh[$i] > 0 ) ? 8 : 0; $sb2 = ( $owg_slow[$i] ne 0 ) ? 4 : 0;
}
if( defined($owg_shigh[$i]) ){
$sb2 += ( $owg_shigh[$i] ne 0 ) ? 8 : 0;
}
#-- range #-- range
$sb2 |= 1 $sb2 |= 1
if( $owg_range[$i] > 2550 ); if( $owg_range[$i] > 2550 );
@ -1038,14 +1055,12 @@ sub OWXAD_SetPage($$) {
=pod =pod
=begin html =begin html
<a name="OWAD"></a>
<h3>OWAD</h3> <h3>OWAD</h3>
<ul>FHEM module to commmunicate with 1-Wire A/D converters<br /><br /> Note:<br /> This <p>FHEM module to commmunicate with 1-Wire A/D converters<br /><br /> Note:<br /> This
1-Wire module so far works only with the OWX interface module. Please define an <a 1-Wire module so far works only with the OWX interface module. Please define an <a
href="#OWX">OWX</a> device first. <br /> href="#OWX">OWX</a> device first. <br /></p>
<br /><b>Example</b><br /> <br /><h4>Example</h4>
<ul> <p>
<code>define OWX_AD OWAD 724610000000 45</code> <code>define OWX_AD OWAD 724610000000 45</code>
<br /> <br />
<code>attr OWX_AD DAlarm high</code> <code>attr OWX_AD DAlarm high</code>
@ -1054,45 +1069,45 @@ sub OWXAD_SetPage($$) {
<br /> <br />
<code>attr OWX_AD DHigh 50.0</code> <code>attr OWX_AD DHigh 50.0</code>
<br /> <br />
<code>attr OWX_AD DName relHumidity|humidity</code> <code>attr OWX_AD DName RelHumidity|humidity</code>
<br /> <br />
<code>attr OWX_AD DOffset -0.8088</code> <code>attr OWX_AD DOffset -0.8088</code>
<br /> <br />
<code>attr OWX_AD DUnit percent|%</code> <code>attr OWX_AD DUnit percent|%</code>
<br /> <br />
</ul><br /> </p><br />
<a name="OWADdefine"></a> <a name="OWADdefine"></a>
<b>Define</b> <h4>Define</h4>
<ul> <p>
<code>define &lt;name&gt; OWAD [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> <code>define &lt;name&gt; OWAD [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire A/D converter.<br /><br /> <br /><br /> Define a 1-Wire A/D converter.<br /><br /></p>
<ul>
<li> <li>
<code>[&lt;model&gt;]</code><br /> Defines the A/D converter model (and thus <code>[&lt;model&gt;]</code><br /> Defines the A/D converter model (and thus 1-Wire
1-Wire family id), currently the following values are permitted: <ul> family id), currently the following values are permitted: <ul>
<li>model DS2450 with family id 20 (default if the model parameter is <li>model DS2450 with family id 20 (default if the model parameter is
omitted)</li> omitted)</li>
</ul> </ul>
</li> </li>
<li> <li>
<code>&lt;id&gt;</code> <code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and <br />12-character unique ROM id of the converter device without family id and CRC
CRC code </li> code </li>
<li> <li>
<code>&lt;interval&gt;</code> <code>&lt;interval&gt;</code>
<br />Measurement interval in seconds. The default is 300 seconds. </li> <br />Measurement interval in seconds. The default is 300 seconds. </li>
<br />
</ul> </ul>
<br /> <br />
<a name="OWADset"> <a name="OWADset"></a>
<b>Set</b></a> <h4>Set</h4>
<ul> <ul>
<li><a name="owad_interval"> <li><a name="owad_interval">
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement <code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement
interval in seconds. The default is 300 seconds. </li> interval in seconds. The default is 300 seconds. </li>
</ul> </ul>
<br /> <br />
<a name="OWADget"> <a name="OWADget"></a>
<b>Get</b></a> <h4>Get</h4>
<ul> <ul>
<li><a name="owad_id"> <li><a name="owad_id">
<code>get &lt;name&gt; id</code></a> <code>get &lt;name&gt; id</code></a>
@ -1102,8 +1117,8 @@ sub OWXAD_SetPage($$) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owad_interval2"> <li><a name="owad_interval2">
<code>get &lt;name&gt; interval</code></a><br />Returns measurement interval <code>get &lt;name&gt; interval</code></a><br />Returns measurement interval in
in seconds. </li> seconds. </li>
<li><a name="owad_reading"> <li><a name="owad_reading">
<code>get &lt;name&gt; reading</code></a><br />Obtain the measuement values. </li> <code>get &lt;name&gt; reading</code></a><br />Obtain the measuement values. </li>
<li><a name="owad_alarm"> <li><a name="owad_alarm">
@ -1113,48 +1128,37 @@ sub OWXAD_SetPage($$) {
</li> </li>
</ul> </ul>
<br /> <br />
<a name="OWADattr"> <a name="OWADattr"></a>
<b>Attributes</b></a> <h4>Attributes</h4>
<ul> <ul>
<li><a name="owad_stateAL0"><code>attr &lt;name&gt; stateAL0 <li><a name="owad_stateAL0"><code>attr &lt;name&gt; stateAL0 &lt;string&gt;</code></a>
&lt;string&gt;</code></a> <br />character string for denoting low normal condition, default is empty </li>
<br />character string for denoting low normal condition, default is green down <li><a name="owad_stateAH0"><code>attr &lt;name&gt; stateAH0 &lt;string&gt;</code></a>
triangle, e.g. the code &lt;span <br />character string for denoting high normal condition, default is empty </li>
style="color:green"&gt;&amp;#x25BE;&lt;/span&gt; leading to the sign <span <li><a name="owad_stateAL1"><code>attr &lt;name&gt; stateAL1 &lt;string&gt;</code></a>
style="color:green">&#x25BE;</span> <br />character string for denoting low alarm condition, default is down triangle,
</li> e.g. the code &amp;#x25BE; leading to the sign &#x25BE;</li>
<li><a name="owad_stateAH0"><code>attr &lt;name&gt; stateAH0 <li><a name="owad_stateAH1"><code>attr &lt;name&gt; stateAH1 &lt;string&gt;</code></a>
&lt;string&gt;</code></a> <br />character string for denoting high alarm condition, default is upward
<br />character string for denoting high alarm condition, default is green triangle, e.g. the code &amp;#x25B4; leading to the sign &#x25B4; </li>
upward triangle, e.g. the code &lt;span </ul> For each of the following attributes, the channel identification A,B,C,D may be used. <ul>
style="color:green"&gt;&amp;#x25B4;&lt;/span&gt; leading to the sign <span
style="color:green">&#x25B4;</span>
</li>
<li><a name="owad_stateAL1"><code>attr &lt;name&gt; stateAL1
&lt;string&gt;</code></a>
<br />character string for denoting low alarm condition, default is red down
triangle, e.g. the code &lt;span style="color:red"&gt;&amp;#x25BE;&lt;/span&gt;
leading to the sign <span style="color:red">&#x25BE;</span></li>
<li><a name="owad_stateAH1"><code>attr &lt;name&gt; stateAH1
&lt;string&gt;</code></a>
<br />character string for denoting high alarm condition, default is red upward
triangle, e.g. the code &lt;span style="color:red"&gt;&amp;#x25B4;&lt;/span&gt;
leading to the sign <span style="color:red">&#x25B4;</span>
</li>
</ul> For each of the following attributes, the channel identification A,B,C,D may be
used. <ul>
<li><a name="owad_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name <li><a name="owad_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name
&lt;string&gt;|&lt;string&gt;</code></a> &lt;string&gt;|&lt;string&gt;</code></a>
<br />name for the channel | a type description for the measured value. </li> <br />name for the channel | a type description for the measured value. </li>
<li><a name="owad_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit <li><a name="owad_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit
&lt;string&gt;|&lt;string&gt;</code></a> &lt;string&gt;|&lt;string&gt;</code></a>
<br />unit of measurement for this channel | its abbreviation. </li> <br />unit of measurement for this channel | its abbreviation. </li>
<li><a name="owad_coffset"><code>attr &lt;name&gt; &lt;channel&gt;Offset <li><a name="owad_coffset"><b>deprecated</b>: <code>attr &lt;name&gt; &lt;channel&gt;Offset
&lt;float&gt;</code></a> &lt;float&gt;</code></a>
<br />offset added to the reading in this channel. </li> <br />offset added to the reading in this channel. </li>
<li><a name="owad_cfactor"><code>attr &lt;name&gt; &lt;channel&gt;Factor <li><a name="owad_cfactor"><b>deprecated</b>: <code>attr &lt;name&gt; &lt;channel&gt;Factor
&lt;float&gt;</code></a> &lt;float&gt;</code></a>
<br />factor multiplied to (reading+offset) in this channel. </li> <br />factor multiplied to (reading+offset) in this channel. </li>
<li><a name="owad_cfunction"> <code>attr &lt;name&gt; &lt;channel&gt;Function
&lt;string&gt;</code></a>
<br />arbitrary functional expression involving the values VA,VB,VC,VD. VA is replaced by
the measured voltage in channel A, etc. This attribute allows linearization of measurement
curves as well as the mixing of various channels. <b>Replacement for Offset/Factor !</b>
<li><a name="owad_calarm"><code>attr &lt;name&gt; &lt;channel&gt;Alarm <li><a name="owad_calarm"><code>attr &lt;name&gt; &lt;channel&gt;Alarm
&lt;string&gt;</code></a> &lt;string&gt;</code></a>
<br />alarm setting in this channel, either both, low, high or none (default). </li> <br />alarm setting in this channel, either both, low, high or none (default). </li>
@ -1166,15 +1170,11 @@ sub OWXAD_SetPage($$) {
&lt;float&gt;</code></a> &lt;float&gt;</code></a>
<br />measurement value (on the scale determined by offset and factor) for high <br />measurement value (on the scale determined by offset and factor) for high
alarm. </li> alarm. </li>
<li><a name="owad_event"><code>attr &lt;name&gt; event on-change|on-update <li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
</code></a>This attribte work similarly, but not identically to the standard event-on-update-change/event-on-update-reading attribute. href="#event-on-update-reading">event-on-update-reading</a>, <a
<ul><li><code>event on-update</code> (default) will write a notify/FileLog event any time a measurement is received.</li> href="#event-on-change-reading">event-on-change-reading</a>, <a href="#room"
<li><code>event on-change</code> will write a notify/FileLog event only when a measurement is different from the previous one.</li> >room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
</li>
<li>Standard attributes alias, comment, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>, <a href="#webCmd">webCmd</a></li>
</ul>
</ul>
=end html =end html
=cut =cut

View File

@ -4,17 +4,11 @@
# #
# FHEM module to commmunicate with general 1-Wire ID-ROMS # FHEM module to commmunicate with general 1-Wire ID-ROMS
# #
# Attention: This module may communicate with the OWX module, # Prof. Dr. Peter A. Henning
# but currently not with the 1-Wire File System OWFS
# #
# Prefixes for subroutines of this module: # $Id$
# OW = General 1-Wire routines Peter Henning)
# #
# Prof. Dr. Peter A. Henning, 2012 ########################################################################################
#
# Version 2.24 - October, 2012
#
# Setup bus device in fhem.cfg as
# #
# define <name> OWID <FAM_ID> <ROM_ID> # define <name> OWID <FAM_ID> <ROM_ID>
# #
@ -49,7 +43,6 @@
######################################################################################## ########################################################################################
package main; package main;
#-- Prototypes to make komodo happy
use vars qw{%attr %defs}; use vars qw{%attr %defs};
use strict; use strict;
use warnings; use warnings;
@ -136,18 +129,18 @@ sub OWID_Define ($$) {
#-- Couple to I/O device #-- Couple to I/O device
AssignIoPort($hash); AssignIoPort($hash);
Log 3, "OWID: Warning, no 1-Wire I/O device found for $name." if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | ($hash->{IODev}->{PRESENT} != 1) ){
if(!defined($hash->{IODev}->{NAME})); return "OWID: Warning, no 1-Wire I/O device found for $name.";
}
$modules{OWID}{defptr}{$id} = $hash; $modules{OWID}{defptr}{$id} = $hash;
#--
$hash->{STATE} = "Defined"; readingsSingleUpdate($hash,"state","Defined",1);
Log 3, "OWID: Device $name defined."; Log 3, "OWTHERM: Device $name defined.";
#-- Initialization reading according to interface type #-- Initialization reading according to interface type
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
#--
$hash->{STATE} = "Initialized"; readingsSingleUpdate($hash,"state","Initialized",1);
return undef; return undef;
} }
@ -213,30 +206,31 @@ sub OWID_Undef ($) {
=pod =pod
=begin html =begin html
<a name="OWID"></a> <a name="OWID"></a>
<h3>OWID</h3> <h3>OWID</h3>
<ul>FHEM module for 1-Wire devices that know only their unique ROM ID<br /> <p>FHEM module for 1-Wire devices that know only their unique ROM ID<br />
<br />Note:<br /> This 1-Wire module so far works only with the OWX interface module. <br />Note:<br /> This 1-Wire module so far works only with the OWX interface module.
Please define an <a href="#OWX">OWX</a> device first. <br /> Please define an <a href="#OWX">OWX</a> device first. <br /></p>
<br /><b>Example</b><br /> <br /><h4>Example</h4><br />
<ul> <p>
<code>define ROM1 OWX_ID OWCOUNT CE780F000000</code> <code>define ROM1 OWX_ID OWCOUNT CE780F000000</code>
<br /> <br />
</ul><br /> </p><br />
<a name="OWIDdefine"></a> <a name="OWIDdefine"></a>
<b>Define</b> <h4>Define</h4>
<ul> <p>
<code>define &lt;name&gt; OWID &lt;id&gt; </code> <code>define &lt;name&gt; OWID &lt;id&gt; </code>
<br /><br /> Define a 1-Wire device.<br /><br /> <br /><br /> Define a 1-Wire device.<br /><br />
</p>
<ul>
<li> <li>
<code>&lt;id&gt;</code> <code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and <br />12-character unique ROM id of the converter device without family id and CRC
CRC code </li> code </li>
</ul> </ul>
<br /> <br />
<a name="OWIDget"> <a name="OWIDget"></a>
<b>Get</b></a> <h4>Get</h4>
<ul> <ul>
<li><a name="owid_id"> <li><a name="owid_id">
<code>get &lt;name&gt; id</code></a> <code>get &lt;name&gt; id</code></a>
@ -246,8 +240,5 @@ sub OWID_Undef ($) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
</ul> </ul>
<br />
</ul>
=end html =end html
=cut =cut

View File

@ -4,17 +4,11 @@
# #
# FHEM module to commmunicate with the 1-Wire LCD hardware # FHEM module to commmunicate with the 1-Wire LCD hardware
# #
# Attention: This module may communicate with the OWX module, # Prof. Dr. Peter A. Henning
# but currently not with the 1-Wire File System OWFS
# #
# Prefixes for subroutines of this module: # $Id$
# OW = General 1-Wire routines Peter Henning
# #
# Prof. Dr. Peter A. Henning, 2012 ########################################################################################
#
# Version 2.24 - October, 2012
#
# Setup bus device in fhem.cfg as
# #
# define <name> OWLCD <ROM_ID> # define <name> OWLCD <ROM_ID>
# #
@ -62,7 +56,6 @@
######################################################################################## ########################################################################################
package main; package main;
#-- Prototypes to make komodo happy
use vars qw{%attr %defs}; use vars qw{%attr %defs};
use strict; use strict;
use warnings; use warnings;
@ -171,9 +164,9 @@ sub OWLCD_Define ($$) {
#-- Couple to I/O device #-- Couple to I/O device
AssignIoPort($hash); AssignIoPort($hash);
Log 3, "OWLCD: Warning, no 1-Wire I/O device found for $name." if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | ($hash->{IODev}->{PRESENT} != 1) ){
if(!defined($hash->{IODev}->{NAME})); return "OWLCD: Warning, no 1-Wire I/O device found for $name.";
}
$modules{OWLCD}{defptr}{$id} = $hash; $modules{OWLCD}{defptr}{$id} = $hash;
$hash->{STATE} = "Defined"; $hash->{STATE} = "Defined";
@ -419,9 +412,10 @@ sub OWLCD_Set($@) {
#-- set a single LCD line #-- set a single LCD line
if($key eq "line") { if($key eq "line") {
$value = OWXLCD_Trans($value);
return "OWLCD: Wrong line number, choose 0..".$lcdlines return "OWLCD: Wrong line number, choose 0..".$lcdlines
if( ( 0 > $line ) || ($line > ($lcdlines-1)) ); if( ( 0 > $line ) || ($line > ($lcdlines-1)) );
return "OWLCD: Wrong line length, must be < ".$lcdchars return "OWLCD: Wrong line length, must be <= ".$lcdchars
if( length($value) > $lcdchars ); if( length($value) > $lcdchars );
#-- check value and write to device #-- check value and write to device
OWXLCD_SetLine($hash,$line,$value); OWXLCD_SetLine($hash,$line,$value);
@ -907,20 +901,9 @@ sub OWXLCD_SetLine($$$) {
$res2 = ""; $res2 = "";
$line = int($line); $line = int($line);
$msg = defined($msg) ? $msg : ""; $msg = defined($msg) ? $msg : "";
#-- replace umlaut chars for special codepage
$msg =~ s/ä/\x7B/g;
$msg =~ s/ö/\x7C/g;
$msg =~ s/ü/\x7E/g;
$msg =~ s/Ä/\x5B/g;
$msg =~ s/Ö/\x5C/g;
$msg =~ s/Ü/\x5E/g;
$msg =~ s/ß/\xBE/g;
#--take out degree sign $msg = OWXLCD_Trans($msg);
if( $msg =~ m/.*\&deg\;.*/ ) {
my @ma = split(/\&deg\;/,$msg);
$msg = $ma[0]."\x80".$ma[1];
}
#-- ID of the device, hash of the busmaster #-- ID of the device, hash of the busmaster
my $owx_dev = $hash->{ROM_ID}; my $owx_dev = $hash->{ROM_ID};
my $master = $hash->{IODev}; my $master = $hash->{IODev};
@ -986,6 +969,34 @@ sub OWXLCD_SetLine($$$) {
} }
########################################################################################
#
# OWXLCD_Trans - String translation helper
#
# Parameter msg = data string to be written
#
########################################################################################
sub OWXLCD_Trans($) {
my ($msg) = @_;
#-- replace umlaut chars for special codepage
$msg =~ s/ä/\x7B/g;
$msg =~ s/ö/\x7C/g;
$msg =~ s/ü/\x7E/g;
$msg =~ s/Ä/\x5B/g;
$msg =~ s/Ö/\x5C/g;
$msg =~ s/Ü/\x5E/g;
$msg =~ s/ß/\xBE/g;
#--take out degree sign
if( $msg =~ m/.*\&deg\;.*/ ) {
my @ma = split(/\&deg\;/,$msg);
$msg = $ma[0]."\x80".$ma[1];
}
return $msg;
}
######################################################################################## ########################################################################################
# #
# OWXLCD_SetMemory - set internal nonvolatile memory # OWXLCD_SetMemory - set internal nonvolatile memory
@ -1038,55 +1049,55 @@ sub OWXLCD_SetMemory($$$) {
=pod =pod
=begin html =begin html
<a name="OWLCD"></a> <a name="OWLCD"></a>
<h3>OWLCD</h3> <h3>OWLCD</h3>
<ul>FHEM module to commmunicate with the <a <p>FHEM module to commmunicate with the <a
href="http://www.louisswart.co.za/1-Wire_Overview.html">1-Wire LCD controller</a> href="http://www.louisswart.co.za/1-Wire_Overview.html">1-Wire LCD controller</a>
from Louis Swart (1-Wire family id FF). See also the corresponding <a from Louis Swart (1-Wire family id FF). See also the corresponding <a
href="http://fhemwiki.de/wiki/1-Wire_Textdisplay">Wiki page.</a><br /><br /> href="http://fhemwiki.de/wiki/1-Wire_Textdisplay">Wiki page.</a><br /><br />
Note:<br /> This 1-Wire module so far works only with the OWX interface module. Please Note:<br /> This 1-Wire module so far works only with the OWX interface module. Please
define an <a href="#OWX">OWX</a> device first. <br /> define an <a href="#OWX">OWX</a> device first. <br /></p>
<br /><b>Example</b><br /> <br /><h4>Example</h4>
<ul> <p>
<code>define OWX_LCD OWLCD 9F0700000100</code> <code>define OWX_LCD OWLCD 9F0700000100</code>
<br /> <br />
</ul> </p>
<br /> <br />
<a name="OWLCDdefine"></a> <a name="OWLCDdefine"></a>
<b>Define</b> <h4>Define</h4>
<ul> <p>
<code>define &lt;name&gt; OWLCD &lt;id&gt;</code> <code>define &lt;name&gt; OWLCD &lt;id&gt;</code>
<br /><br /> Define a 1-Wire LCD device.<br /><br /> <br /><br /> Define a 1-Wire LCD device.<br /><br /></p>
<ul>
<li> <li>
<code>&lt;id&gt;</code> <code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and <br />12-character unique ROM id of the converter device without family id and CRC
CRC code </li> code </li>
</ul> </ul>
<br /> <br />
<a name="OWLCDset"> <a name="OWLCDset"></a>
<b>Set</b></a> <h4>Set</h4>
<ul> <ul>
<li><a name="owlcd_icon"> <li><a name="owlcd_icon">
<code>set &lt;name&gt; icon &lt;int&gt; on|off|blink</code></a><br /> Set <code>set &lt;name&gt; icon &lt;int&gt; on|off|blink</code></a><br /> Set one of
one of the icons 0..14 on, off or blinking</li> the icons 0..14 on, off or blinking</li>
<li><a name="owlcd_icon2"> <li><a name="owlcd_icon2">
<code>set &lt;name&gt; icon 15 0..6</code></a><br /> Set icon 15 to one of <code>set &lt;name&gt; icon 15 0..6</code></a><br /> Set icon 15 to one of its
its values</li> values</li>
<li><a name="owlcd_icon3"> <li><a name="owlcd_icon3">
<code>set &lt;name&gt; icon none</code></a><br /> Set all icons off</li> <code>set &lt;name&gt; icon none</code></a><br /> Set all icons off</li>
<li><a name="owlcd_line"> <li><a name="owlcd_line">
<code>set &lt;name&gt; line &lt;int&gt; &lt;string&gt;</code></a><br /> <code>set &lt;name&gt; line &lt;int&gt; &lt;string&gt;</code></a><br /> Write
Write LCD line 0..3 with some content </li> LCD line 0..3 with some content </li>
<li><a name="owlcd_memory"> <li><a name="owlcd_memory">
<code>set &lt;name&gt; memory &lt;page&gt; <code>set &lt;name&gt; memory &lt;page&gt; &lt;string&gt;</code></a><br />Write
&lt;string&gt;</code></a><br />Write memory page 0..6</li> memory page 0..6</li>
<li><a name="owlcd_gpio"> <li><a name="owlcd_gpio">
<code>set &lt;name&gt; gpio &lt;value&gt;</code></a><br />Write state for <code>set &lt;name&gt; gpio &lt;value&gt;</code></a><br />Write state for all
all three gpio pins (value = 0..7, for each bit 0=ON, 1=OFF)</li> three gpio pins (value = 0..7, for each bit 0=ON, 1=OFF)</li>
<li><a name="owlcd_bl"> <li><a name="owlcd_bl">
<code>set &lt;name&gt; backlight ON|OFF</code></a><br />Switch backlight on <code>set &lt;name&gt; backlight ON|OFF</code></a><br />Switch backlight on or
or off</li> off</li>
<li><a name="owlcd_lcd"> <li><a name="owlcd_lcd">
<code>set &lt;name&gt; lcd ON|OFF</code></a><br />Switch LCD power on or <code>set &lt;name&gt; lcd ON|OFF</code></a><br />Switch LCD power on or
off</li> off</li>
@ -1096,8 +1107,8 @@ sub OWXLCD_SetMemory($$$) {
<code>set &lt;name&gt; test</code></a><br />Test the display</li> <code>set &lt;name&gt; test</code></a><br />Test the display</li>
</ul> </ul>
<br /> <br />
<a name="owlcdget"> <a name="owlcdget"></a>
<b>Get</b></a> <h4>Get</h4>
<ul> <ul>
<li><a name="owlcd_id"> <li><a name="owlcd_id">
<code>get &lt;name&gt; id</code></a> <code>get &lt;name&gt; id</code></a>
@ -1107,8 +1118,7 @@ sub OWXLCD_SetMemory($$$) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owlcd_memory2"> <li><a name="owlcd_memory2">
<code>get &lt;name&gt; memory &lt;page&gt;</code></a><br />Read memory page <code>get &lt;name&gt; memory &lt;page&gt;</code></a><br />Read memory page 0..6 </li>
0..6 </li>
<li><a name="owlcd_gpio"> <li><a name="owlcd_gpio">
<code>get &lt;name&gt; gpio</code></a><br />Obtain state of all four input <code>get &lt;name&gt; gpio</code></a><br />Obtain state of all four input
channels (15 = all off, 0 = all on)</li> channels (15 = all off, 0 = all on)</li>
@ -1116,16 +1126,16 @@ sub OWXLCD_SetMemory($$$) {
<code>get &lt;name&gt; gpio</code></a><br />Obtain state of all four input <code>get &lt;name&gt; gpio</code></a><br />Obtain state of all four input
counters (4 x 16 Bit)</li> counters (4 x 16 Bit)</li>
<li><a name="owlcd_version"> <li><a name="owlcd_version">
<code>get &lt;name&gt; version</code></a><br />Obtain firmware version of <code>get &lt;name&gt; version</code></a><br />Obtain firmware version of the
the controller</li> controller</li>
</ul> </ul>
<br /> <br />
<a name="owlcdattr"> <a name="owlcdattr"></a>
<b>Attributes</b></a> <h4>Attributes</h4>
<ul> <ul>
<li>Standard attributes alias, comment, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>, <a href="#webCmd">webCmd</a></li> <li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
href="#room">room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel"
>loglevel</a>, <a href="#webCmd">webCmd</a></li>
</ul> </ul>
</ul>
=end html =end html
=cut =cut

View File

@ -4,15 +4,11 @@
# #
# FHEM module to commmunicate with 1-Wire chip DS2438Z - Smart Battery Monitor # FHEM module to commmunicate with 1-Wire chip DS2438Z - Smart Battery Monitor
# #
# Prefixes for subroutines of this module: # Prof. Dr. Peter A. Henning
# OW = General 1-Wire routines (Martin Fischer, Peter Henning)
# OWX = 1-Wire bus master interface (Peter Henning)
# #
# Prof. Dr. Peter A. Henning, 2012 # $Id$
# #
# Version 2.24 - October, 2012 ########################################################################################
#
# Setup bus device in fhem.cfg as
# #
# define <name> OWMULTI [<model>] <ROM_ID> [interval] # define <name> OWMULTI [<model>] <ROM_ID> [interval]
# #
@ -38,8 +34,6 @@
# Additional attributes are defined in fhem.cfg # Additional attributes are defined in fhem.cfg
# Note: attributes "tempXXXX" are read during every update operation. # Note: attributes "tempXXXX" are read during every update operation.
# #
# attr <name> event on-change/on-update = when to write an event (default= on-update)
#
# attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading # attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius # attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius
# attr <name> VName <string>|<string> = name for the channel | a type description for the measured value # attr <name> VName <string>|<string> = name for the channel | a type description for the measured value
@ -69,7 +63,6 @@
######################################################################################## ########################################################################################
package main; package main;
#-- Prototypes to make komodo happy
use vars qw{%attr %defs}; use vars qw{%attr %defs};
use strict; use strict;
use warnings; use warnings;
@ -125,7 +118,7 @@ sub OWMULTI_Initialize ($) {
#tempOffset = a temperature offset added to the temperature reading for correction #tempOffset = a temperature offset added to the temperature reading for correction
#tempUnit = a unit of measure: C/F/K #tempUnit = a unit of measure: C/F/K
$hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ". $hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ".
"event:on-update,on-change ". "event-on-update-reading event-on-change-reading ".
"tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ". "tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ".
"VName VUnit VFunction"; "VName VUnit VFunction";
} }
@ -198,10 +191,12 @@ sub OWMULTI_Define ($$) {
#-- Couple to I/O device #-- Couple to I/O device
AssignIoPort($hash); AssignIoPort($hash);
Log 3, "OWMULTI: Warning, no 1-Wire I/O device found for $name." if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | ($hash->{IODev}->{PRESENT} != 1) ){
if(!defined($hash->{IODev}->{NAME})); return "OWMULTI: Warning, no 1-Wire I/O device found for $name.";
}
$modules{OWMULTI}{defptr}{$id} = $hash; $modules{OWMULTI}{defptr}{$id} = $hash;
$hash->{STATE} = "Defined"; #--
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWMULTI: Device $name defined."; Log 3, "OWMULTI: Device $name defined.";
#-- Start timer for initialization in a few seconds #-- Start timer for initialization in a few seconds
@ -231,10 +226,10 @@ sub OWMULTI_InitializeDevice($) {
$hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius"; $hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
$hash->{READINGS}{"temperature"}{TYPE} = "temperature"; $hash->{READINGS}{"temperature"}{TYPE} = "temperature";
#-- Initial readings temperature sensor #-- Initial readings
$owg_temp = 0.0; $owg_temp = "";
$owg_volt = 0.0; $owg_volt = "";
$owg_vdd = 5.0; $owg_vdd = "";
#-- Set channel name, channel unit for voltage channel #-- Set channel name, channel unit for voltage channel
my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage"; my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage";
my @cnama = split(/\|/,$cname); my @cnama = split(/\|/,$cname);
@ -275,9 +270,7 @@ sub OWMULTI_FormatValues($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ($tunit,$toffset,$tfactor,$tabbr,$tval,$vfunc,$vval); my ($tunit,$toffset,$tfactor,$tabbr,$tval,$vfunc,$vval);
my ($value1,$value2) = ("",""); my $svalue = "";
my $tn = TimeNow();
#-- attributes defined ? #-- attributes defined ?
$tunit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT}; $tunit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT};
@ -297,19 +290,18 @@ sub OWMULTI_FormatValues($) {
$tabbr="?"; $tabbr="?";
Log 1, "OWMULTI_FormatValues: unknown unit $tunit"; Log 1, "OWMULTI_FormatValues: unknown unit $tunit";
} }
#-- these values are rather coplex to obtain, therefore save them in the hash #-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{UNIT} = $tunit; $hash->{READINGS}{"temperature"}{UNIT} = $tunit;
$hash->{READINGS}{"temperature"}{UNITABBR} = $tabbr; $hash->{READINGS}{"temperature"}{UNITABBR} = $tabbr;
$hash->{tempf}{offset} = $toffset; $hash->{tempf}{offset} = $toffset;
$hash->{tempf}{factor} = $tfactor; $hash->{tempf}{factor} = $tfactor;
#-- no change in any value if invalid reading
return if( $owg_temp eq "");
#-- correct values for proper offset, factor #-- correct values for proper offset, factor
$tval = ($owg_temp + $toffset)*$tfactor; $tval = ($owg_temp + $toffset)*$tfactor;
#-- put into READINGS
$hash->{READINGS}{"temperature"}{VAL} = $tval;
$hash->{READINGS}{"temperature"}{TIME} = $tn;
my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage"; my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage";
my @cnama = split(/\|/,$cname); my @cnama = split(/\|/,$cname);
$owg_channel=$cnama[0]; $owg_channel=$cnama[0];
@ -324,27 +316,30 @@ sub OWMULTI_FormatValues($) {
#-- determine the measured value from the function #-- determine the measured value from the function
$vfunc = "\$owg_vdd = $owg_vdd; \$owg_volt = $owg_volt; \$tval = $tval; ".$vfunc; $vfunc = "\$owg_vdd = $owg_vdd; \$owg_volt = $owg_volt; \$tval = $tval; ".$vfunc;
#Log 1, "vfunc= ".$vfunc;
$vfunc = eval($vfunc); $vfunc = eval($vfunc);
if( $vfunc ne "" ){ if( !$vfunc ){
$vval = 0.0;
} elsif( $vfunc ne "" ){
$vval = int( $vfunc*1000 )/1000; $vval = int( $vfunc*1000 )/1000;
} else { } else {
$vval = 0.0;
} }
#-- put into READINGS
$hash->{READINGS}{"$owg_channel"}{VAL} = $vval;
$hash->{READINGS}{"$owg_channel"}{TIME} = $tn;
$hash->{READINGS}{"VDD"}{VAL} = $owg_vdd;
$hash->{READINGS}{"VDD"}{TIME} = $tn;
#-- string buildup for return value, STATE #-- string buildup for return value, STATE
$value1 .= sprintf( "%s: %5.3f %s temperature %5.3f %s VDD %5.2f V", $owg_channel, $vval,$hash->{READINGS}{"$owg_channel"}{UNITABBR},$tval,$tabbr,$owg_vdd); $svalue .= sprintf( "%s: %5.2f %s (T: %5.2f %s)", $owg_channel, $vval,$hash->{READINGS}{"$owg_channel"}{UNITABBR},$tval,$tabbr);
$value2 .= sprintf( "%s: %5.2f %s (T: %5.2f %s)", $owg_channel, $vval,$hash->{READINGS}{"$owg_channel"}{UNITABBR},$tval,$tabbr);
#-- put into READINGS
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"$owg_channel",$vval);
readingsBulkUpdate($hash,"VDD",$owg_vdd);
readingsBulkUpdate($hash,"temperature",$tval);
#-- STATE #-- STATE
$hash->{STATE} = $value2; readingsBulkUpdate($hash,"state",$svalue);
readingsEndUpdate($hash,1);
return $value1; return $svalue;
} }
######################################################################################## ########################################################################################
@ -418,7 +413,7 @@ sub OWMULTI_Get($@) {
#-- process results #-- process results
if( defined($ret) ){ if( defined($ret) ){
return "OWMULTI: Could not get values from device $name, return was $ret"; return "OWMULTI: Could not get values from device $name, reason $ret";
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
OWMULTI_FormatValues($hash); OWMULTI_FormatValues($hash);
@ -475,7 +470,7 @@ sub OWMULTI_GetValues($@) {
if( !defined($ret) ); if( !defined($ret) );
} }
#}elsif( $interface eq "OWFS" ){ #}elsif( $interface eq "OWFS" ){
# $ret = OWFSTHERM_GetValues($hash); # $ret = OWFSMULTI_GetValues($hash);
}else{ }else{
Log 3, "OWMULTI: GetValues with wrong IODev type $interface"; Log 3, "OWMULTI: GetValues with wrong IODev type $interface";
return 1; return 1;
@ -488,17 +483,8 @@ sub OWMULTI_GetValues($@) {
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
#-- old state, new state
my $oldval = $hash->{STATE};
$value=OWMULTI_FormatValues($hash); $value=OWMULTI_FormatValues($hash);
my $newval = $hash->{STATE};
#--logging depends on setting of the event-attribute
Log 5, $value; Log 5, $value;
my $ev = defined($attr{$name}{"event"}) ? $attr{$name}{"event"} : "on-update";
if( ($ev eq "on-update") || (($ev eq "on-change") && ($newval ne $oldval)) ){
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef);
}
return undef; return undef;
} }
@ -562,7 +548,7 @@ sub OWMULTI_Set($@) {
$ret = OWXMULTI_SetValues($hash,@a); $ret = OWXMULTI_SetValues($hash,@a);
#-- OWFS interface not yet implemented #-- OWFS interface not yet implemented
#}elsif( $interface eq "OWFS" ){ #}elsif( $interface eq "OWFS" ){
# $ret = OWFSTHERM_SetValues($hash,@a); # $ret = OWFSMULTI_SetValues($hash,@a);
# return $ret # return $ret
# if(defined($ret)); # if(defined($ret));
} else { } else {
@ -672,30 +658,22 @@ sub OWXMULTI_GetValues($) {
return "$owx_dev not accessible in 2nd step"; return "$owx_dev not accessible in 2nd step";
} }
# $res2 = "====> OWXMULTI Received ";
# for(my $i=0;$i<length($res);$i++){
# my $j=int(ord(substr($res,$i,1))/16);
# my $k=ord(substr($res,$i,1))%16;
# $res2.=sprintf "0x%1x%1x ",$j,$k;
# }
# Log 1, $res2;
#-- process results #-- process results
my @data=split(//,$res); my @data=split(//,substr($res,9));
return "invalid data length, ".int(@data)." bytes" return "invalid data length, ".int(@data)." instead of 11 bytes"
if (@data != 20); if (@data != 11);
return "conversion not complete or data invalid" return "conversion not complete or data invalid"
if ((ord($data[11]) & 112)!=0); if ((ord($data[2]) & 112)!=0);
#return "invalid CRC" return "invalid CRC"
# if (OWX_CRC8(substr($res,10,8),$data[18])==0); if (OWX_CRC8(substr($res,11,8),$data[10])==0);
#-- this must be different for the different device types #-- this must be different for the different device types
# family = 26 => DS2438 # family = 26 => DS2438
#-- temperature #-- temperature
my $lsb = ord($data[12]); my $lsb = ord($data[3]);
my $msb = ord($data[13]) & 127; my $msb = ord($data[4]) & 127;
my $sign = ord($data[13]) & 128; my $sign = ord($data[4]) & 128;
#-- test with -55 degrees #-- test with -55 degrees
#$lsb = 0; #$lsb = 0;
@ -709,8 +687,8 @@ sub OWXMULTI_GetValues($) {
} }
#-- voltage #-- voltage
$lsb = ord($data[14]); $lsb = ord($data[5]);
$msb = ord($data[15]) & 3; $msb = ord($data[6]) & 3;
#-- test with 5V #-- test with 5V
#$lsb = 244; #$lsb = 244;
@ -756,35 +734,25 @@ sub OWXMULTI_GetValues($) {
#-- issue the match ROM command \x55 and the read scratchpad command \xBE #-- issue the match ROM command \x55 and the read scratchpad command \xBE
#-- reading 9 + 2 + 9 data bytes = 20 bytes #-- reading 9 + 2 + 9 data bytes = 20 bytes
$res=OWX_Complex($master,$owx_dev,"\xBE\x00",9); $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9);
#Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes";
#-- process results #-- process results
if( $res eq 0 ){ if( $res eq 0 ){
return "$owx_dev not accessible in 2nd step"; return "$owx_dev not accessible in 2nd step";
} }
# $res2 = "====> OWXMULTI Received ";
# for(my $i=0;$i<length($res);$i++){
# my $j=int(ord(substr($res,$i,1))/16);
# my $k=ord(substr($res,$i,1))%16;
# $res2.=sprintf "0x%1x%1x ",$j,$k;
# }
# Log 1, $res2;
#-- process results #-- process results
@data=split(//,$res); @data=split(//,substr($res,9));
return "invalid data length, ".int(@data)." bytes" return "invalid data length, ".int(@data)." instead of 11 bytes"
if (@data != 20); if (@data != 11);
return "conversion not complete or data invalid" return "conversion not complete or data invalid"
if ((ord($data[11]) & 112)!=0); if ((ord($data[2]) & 112)!=0);
#return "invalid CRC" return "invalid CRC"
# if (OWX_CRC8(substr($res,10,8),$data[18])==0); if (OWX_CRC8(substr($res,11,8),$data[10])==0);
#-- this must be different for the different device types #-- this must be different for the different device types
# family = 26 => DS2438 # family = 26 => DS2438
#-- voltage #-- voltage
$lsb = ord($data[14]); $lsb = ord($data[5]);
$msb = ord($data[15]) & 3; $msb = ord($data[6]) & 3;
#-- test with 7.2 V #-- test with 7.2 V
#$lsb = 208; #$lsb = 208;
@ -845,20 +813,17 @@ sub OWXMULTI_SetValues($@) {
return undef; return undef;
} }
1; 1;
=pod =pod
=begin html =begin html
<a name="OWMULTI"></a> <a name="OWMULTI"></a>
<h3>OWMULTI</h3> <h3>OWMULTI</h3>
<ul>FHEM module to commmunicate with 1-Wire multi-sensors, currently the DS2438 smart battery monitor<br /><br /> Note:<br /> This <p>FHEM module to commmunicate with 1-Wire multi-sensors, currently the DS2438 smart battery
1-Wire module so far works only with the OWX interface module. Please define an <a monitor<br /><br /> Note:<br /> This 1-Wire module so far works only with the OWX
href="#OWX">OWX</a> device first. <br /> interface module. Please define an <a href="#OWX">OWX</a> device first. <br /></p>
<br /><b>Example</b><br /> <br /><h4>Example</h4>
<ul> <p>
<code>define OWX_M OWMULTI 7C5034010000 45</code> <code>define OWX_M OWMULTI 7C5034010000 45</code>
<br /> <br />
<code>attr OWX_M VName relHumidity|humidity</code> <code>attr OWX_M VName relHumidity|humidity</code>
@ -867,39 +832,40 @@ sub OWXMULTI_SetValues($@) {
<br /> <br />
<code>attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T)</code> <code>attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T)</code>
<br /> <br />
</ul><br /> </p><br />
<a name="OWMULTIdefine"></a> <a name="OWMULTIdefine"></a>
<b>Define</b> <h4>Define</h4>
<ul> <p>
<code>define &lt;name&gt; OWMULTI [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> <code>define &lt;name&gt; OWMULTI [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire multi-sensor<br /><br /> <br /><br /> Define a 1-Wire multi-sensor<br /><br /></p>
<ul>
<li> <li>
<code>[&lt;model&gt;]</code><br /> Defines the sensor model (and thus <code>[&lt;model&gt;]</code><br /> Defines the sensor model (and thus 1-Wire family
1-Wire family id), currently the following values are permitted: <ul> id), currently the following values are permitted: <ul>
<li>model DS2438 with family id 26 (default if the model parameter is <li>model DS2438 with family id 26 (default if the model parameter is omitted).
omitted). Measured is a temperature value, an external voltage and the current supply voltage</li> Measured is a temperature value, an external voltage and the current supply
voltage</li>
</ul> </ul>
</li> </li>
<li> <li>
<code>&lt;id&gt;</code> <code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and <br />12-character unique ROM id of the converter device without family id and CRC
CRC code </li> code </li>
<li> <li>
<code>&lt;interval&gt;</code> <code>&lt;interval&gt;</code>
<br />Measurement interval in seconds. The default is 300 seconds. </li> <br />Measurement interval in seconds. The default is 300 seconds. </li>
<br />
</ul> </ul>
<br /> <br />
<a name="OWMULTIset"> <a name="OWMULTIset"></a>
<b>Set</b></a> <h4>Set</h4>
<ul> <ul>
<li><a name="owmulti_interval"> <li><a name="owmulti_interval">
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement <code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement
interval in seconds. The default is 300 seconds. </li> interval in seconds. The default is 300 seconds. </li>
</ul> </ul>
<br /> <br />
<a name="OWMULTIget"> <a name="OWMULTIget"></a>
<b>Get</b></a> <h4>Get</h4>
<ul> <ul>
<li><a name="owmulti_id"> <li><a name="owmulti_id">
<code>get &lt;name&gt; id</code></a> <code>get &lt;name&gt; id</code></a>
@ -909,22 +875,22 @@ sub OWXMULTI_SetValues($@) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owmulti_interval2"> <li><a name="owmulti_interval2">
<code>get &lt;name&gt; interval</code></a><br />Returns measurement interval <code>get &lt;name&gt; interval</code></a><br />Returns measurement interval in
in seconds. </li> seconds. </li>
<li><a name="owmulti_reading"> <li><a name="owmulti_reading">
<code>get &lt;name&gt; reading</code></a><br />Obtain the measurement value from VFunction. </li> <code>get &lt;name&gt; reading</code></a><br />Obtain the measurement value from
VFunction. </li>
<li><a name="owmulti_temperature"> <li><a name="owmulti_temperature">
<code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature value. </li> <code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature value. </li>
<li><a name="owmulti_vdd"> <li><a name="owmulti_vdd">
<code>get &lt;name&gt; VDD</code></a><br />Obtain the current supply voltage. <code>get &lt;name&gt; VDD</code></a><br />Obtain the current supply voltage. </li>
</li>
<li><a name="owmulti_raw"> <li><a name="owmulti_raw">
<code>get &lt;name&gt; V</code> or <code>get &lt;name&gt; raw</code></a><br />Obtain the raw external voltage measurement. <code>get &lt;name&gt; V</code> or <code>get &lt;name&gt;
</li> raw</code></a><br />Obtain the raw external voltage measurement. </li>
</ul> </ul>
<br /> <br />
<a name="OWMULTIattr"> <a name="OWMULTIattr"></a>
<b>Attributes</b></a> <h4>Attributes</h4>
<ul> <ul>
<li><a name="owmulti_vname"><code>attr &lt;name&gt; VName <li><a name="owmulti_vname"><code>attr &lt;name&gt; VName
&lt;string&gt;|&lt;string&gt;</code></a> &lt;string&gt;|&lt;string&gt;</code></a>
@ -934,29 +900,25 @@ sub OWXMULTI_SetValues($@) {
<br />unit of measurement for this channel | its abbreviation. </li> <br />unit of measurement for this channel | its abbreviation. </li>
<li><a name="owmulti_vfunction"><code>attr &lt;name&gt; VFunction <li><a name="owmulti_vfunction"><code>attr &lt;name&gt; VFunction
&lt;string&gt;</code></a> &lt;string&gt;</code></a>
<br />arbitrary functional expression involving the values VDD, V, T. Example see above. <br />arbitrary functional expression involving the values VDD, V, T. Example see
<ul> above. <ul>
<li>VDD is replaced by the measured supply voltage in Volt,</li> <li>VDD is replaced by the measured supply voltage in Volt,</li>
<li> V by the measured external voltage,</li> <li> V by the measured external voltage,</li>
<li>T by the measured and corrected temperature in its unit</li> <li>T by the measured and corrected temperature in its unit</li>
</ul></li> </ul></li>
<li><a name="owmulti_tempOffset"><code>attr &lt;name&gt; tempOffset <li><a name="owmulti_tempOffset"><code>attr &lt;name&gt; tempOffset &lt;float&gt;</code>
&lt;float&gt;</code>
</a> </a>
<br />temperature offset in &deg;C added to the raw temperature reading. </li> <br />temperature offset in &deg;C added to the raw temperature reading. </li>
<li><a name="owmulti_tempUnit"><code>attr &lt;name&gt; tempUnit <li><a name="owmulti_tempUnit"><code>attr &lt;name&gt; tempUnit
Celsius|Kelvin|Fahrenheit|C|K|F</code> Celsius|Kelvin|Fahrenheit|C|K|F</code>
</a> </a>
<br />unit of measurement (temperature scale), default is Celsius = &deg;C </li> <br />unit of measurement (temperature scale), default is Celsius = &deg;C </li>
<li><a name="owmulti_event"><code>attr &lt;name&gt; event on-change|on-update <li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
</code></a>This attribte work similarly, but not identically to the standard event-on-update-change/event-on-update-reading attribute. href="#event-on-update-reading">event-on-update-reading</a>, <a
<ul><li><code>event on-update</code> (default) will write a notify/FileLog event any time a measurement is received.</li> href="#event-on-change-reading">event-on-change-reading</a>, <a href="#room"
<li><code>event on-change</code> will write a notify/FileLog event only when a measurement is different from the previous one.</li> >room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
</ul> <a href="#webCmd">webCmd</a></li>
</li>
<li>Standard attributes alias, comment, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>, <a href="#webCmd">webCmd</a></li>
</ul>
</ul>
</ul>
=end html =end html
=cut =cut

View File

@ -4,22 +4,11 @@
# #
# FHEM module to commmunicate with 1-Wire adressable switches DS2413, DS206, DS2408 # FHEM module to commmunicate with 1-Wire adressable switches DS2413, DS206, DS2408
# #
# Attention: This module may communicate with the OWX module, # Prof. Dr. Peter A. Henning
# but currently not with the 1-Wire File System OWFS
# #
# TODO: Kanalattribute ändern zur Laufzeit. # $Id$
# #
# ########################################################################################
# Prefixes for subroutines of this module:
# OW = General 1-Wire routines Peter Henning)
# OWX = 1-Wire bus master interface (Peter Henning)
# OWFS = 1-Wire file system (??)
#
# Prof. Dr. Peter A. Henning, 2012
#
# Version 2.25 - October, 2012
#
# Setup bus device in fhem.cfg as
# #
# define <name> OWSWITCH [<model>] <ROM_ID> [interval] # define <name> OWSWITCH [<model>] <ROM_ID> [interval]
# #
@ -42,16 +31,17 @@
# get <name> gpio => values for channels # get <name> gpio => values for channels
# #
# set <name> interval => set period for measurement # set <name> interval => set period for measurement
# set <name> output <channel-name> ON|OFF => set value for channel (name A, B or defined channel name) # set <name> output <channel-name> on|off|on-for-timer <int>|on-for-timer <int>
# => set value for channel (name A, B or defined channel name)
# note: 1 = OFF, 0 = ON in normal usage. See also the note above # note: 1 = OFF, 0 = ON in normal usage. See also the note above
# ON-for-timer/OFF-for-timer will set the desired value only for <int> seconds
# and then will return to the opposite value.
# set <name> gpio value => set values for channels (3 = both OFF, 1 = B ON 2 = A ON 0 = both ON) # set <name> gpio value => set values for channels (3 = both OFF, 1 = B ON 2 = A ON 0 = both ON)
# set <name> init yes => re-initialize device # set <name> init yes => re-initialize device
# #
# Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B # Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B
# Note: attributes are read only during initialization procedure - later changes are not used. # Note: attributes are read only during initialization procedure - later changes are not used.
# #
# attr <name> event on-change/on-update = when to write an event (default= on-update)
#
# attr <name> stateS <string> = character string denoting external shortening condition, default is (ext) # attr <name> stateS <string> = character string denoting external shortening condition, default is (ext)
# overwritten by an attribute setting "red angled arrow downwward" # overwritten by an attribute setting "red angled arrow downwward"
# #
@ -78,7 +68,6 @@
######################################################################################## ########################################################################################
package main; package main;
#-- Prototypes to make komodo happy
use vars qw{%attr %defs}; use vars qw{%attr %defs};
use strict; use strict;
use warnings; use warnings;
@ -140,7 +129,8 @@ sub OWSWITCH_Initialize ($) {
$hash->{SetFn} = "OWSWITCH_Set"; $hash->{SetFn} = "OWSWITCH_Set";
my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2413,DS2406,DS2408 loglevel:0,1,2,3,4,5 ". my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2413,DS2406,DS2408 loglevel:0,1,2,3,4,5 ".
"event:on-update,on-change stateS "; "event-on-update-reading event-on-change-reading ".
"stateS ";
#TODO: correct number of channels #TODO: correct number of channels
@ -221,17 +211,19 @@ sub OWSWITCH_Define ($$) {
#-- Couple to I/O device #-- Couple to I/O device
AssignIoPort($hash); AssignIoPort($hash);
Log 3, "OWSWITCH: Warning, no 1-Wire I/O device found for $name." if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | ($hash->{IODev}->{PRESENT} != 1) ){
if(!defined($hash->{IODev}->{NAME})); return "OWSWITCH: Warning, no 1-Wire I/O device found for $name.";
}
$modules{OWSWITCH}{defptr}{$id} = $hash; $modules{OWSWITCH}{defptr}{$id} = $hash;
$hash->{STATE} = "Defined"; #--
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWSWITCH: Device $name defined."; Log 3, "OWSWITCH: Device $name defined.";
#-- Initialization reading according to interface type #-- Initialization reading according to interface type
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
#-- Start timer for initialization in a few seconds #-- Start timer for initialization in a few seconds
InternalTimer(time()+1, "OWSWITCH_InitializeDevice", $hash, 0); InternalTimer(time()+10, "OWSWITCH_InitializeDevice", $hash, 0);
#-- Start timer for updates #-- Start timer for updates
InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0); InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
@ -252,15 +244,11 @@ sub OWSWITCH_InitializeDevice($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
#-- more colorful shortening signature
CommandAttr (undef,"$name stateS <span style=\"color:red\">&#x2607;</span>")
if( !defined($attr{$name}{"stateS"} ));
#-- Set channel names, channel units #-- Set channel names, channel units
for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) { for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) {
#-- Initial readings OFF #-- Initial readings ERR
$owg_val[$i] = 1; $owg_val[$i] = 1;
$owg_vax[$i] = 1; $owg_vax[$i] = 0;
#-- name #-- name
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|onoff"; my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|onoff";
my @cnama = split(/\|/,$cname); my @cnama = split(/\|/,$cname);
@ -315,13 +303,14 @@ sub OWSWITCH_FormatValues($) {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ($offset,$factor,$vval,$vvax,$vstr,$cname,@cnama,@unarr); my ($offset,$factor,$vval,$vvax,$vstr,$cname,@cnama,@unarr,$valid);
my ($value1,$value2,$value3) = ("","",""); my $svalue = "";
my $tn = TimeNow();
#-- external shortening signature #-- external shortening signature
my $sname = defined($attr{$name}{"stateS"}) ? $attr{$name}{"stateS"} : "(ext)"; my $sname = defined($attr{$name}{"stateS"}) ? $attr{$name}{"stateS"} : "&#x2607;";
#-- put into READINGS
readingsBeginUpdate($hash);
#-- formats for output #-- formats for output
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
@ -338,28 +327,28 @@ sub OWSWITCH_FormatValues($) {
@unarr= split(/\|/,$hash->{READINGS}{"$owg_channel[$i]"}{UNIT}); @unarr= split(/\|/,$hash->{READINGS}{"$owg_channel[$i]"}{UNIT});
$vstr = $unarr[$vval]; $vstr = $unarr[$vval];
#-- put into readings only when valid
if( ($vval == 1) && ($vvax == 0) ){
$vstr ="???"
}else{
$vstr.= $sname if( ($vval == 0) && ($vvax == 1) ); $vstr.= $sname if( ($vval == 0) && ($vvax == 1) );
$vstr = "ERR" if( ($vval == 1) && ($vvax == 0) ); readingsBulkUpdate($hash,"$owg_channel[$i]",$vstr);
$value1 .= sprintf( "%s: %s", $owg_channel[$i], $vstr);
$value2 .= sprintf( "%s: %s ", $owg_channel[$i], $vstr);
$value3 .= sprintf( "%s: " , $owg_channel[$i]);
#-- put into READINGS
$hash->{READINGS}{"$owg_channel[$i]"}{VAL} = $vstr;
$hash->{READINGS}{"$owg_channel[$i]"}{TIME} = $tn;
#-- insert comma
if( $i<$cnumber{$attr{$name}{"model"}}-1 ){
$value1 .= " ";
$value2 .= ", ";
$value3 .= ", ";
} }
$svalue .= sprintf( "%s: %s" , $owg_channel[$i], $vstr);
#-- insert space
if( $i<($cnumber{$attr{$name}{"model"}}-1) ){
$svalue .= " ";
} }
}
#-- STATE #-- STATE
$hash->{STATE} = $value2; readingsBulkUpdate($hash,"state",$svalue);
readingsEndUpdate($hash,1);
return $value1; return $svalue;
} }
######################################################################################## ########################################################################################
@ -463,7 +452,7 @@ sub OWSWITCH_Get($@) {
} }
#-- process results #-- process results
if( defined($ret) ){ if( defined($ret) ){
return "OWSWITCH: Could not get values from device $name"; return "OWSWITCH: Could not get values from device $name, reason $ret";
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
return "OWSWITCH: $name.$reading => ".OWSWITCH_FormatValues($hash); return "OWSWITCH: $name.$reading => ".OWSWITCH_FormatValues($hash);
@ -498,29 +487,32 @@ sub OWSWITCH_GetValues($) {
#-- Get readings according to interface type #-- Get readings according to interface type
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
if( $interface eq "OWX" ){ if( $interface eq "OWX" ){
#-- max 3 tries
for(my $try=0; $try<3; $try++){
$ret = OWXSWITCH_GetState($hash); $ret = OWXSWITCH_GetState($hash);
last
if( !defined($ret) );
}
#}elsif( $interface eq "OWFS" ){ #}elsif( $interface eq "OWFS" ){
# $ret = OWFSSWITCH_GetValues($hash); # $ret = OWFSSWITCH_GetValues($hash);
}else{ }else{
return "OWSWITCH: GetValues with wrong IODev type $interface"; Log 3, "OWSWITCH: GetValues with wrong IODev type $interface";
return 1;
} }
#-- process results #-- process results
if( defined($ret) ){ if( defined($ret) ){
return "OWSWITCH: Could not get values from device $name"; for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
$owg_val[$i] = 1;
$owg_vax[$i] = 0;
}
Log 3, "OWSWITCH: Could not get values from device $name, reason $ret";
return 1;
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
#-- old state, new state
my $oldval = $hash->{STATE};
$value = OWSWITCH_FormatValues($hash); $value = OWSWITCH_FormatValues($hash);
my $newval = $hash->{STATE};
#--logging depends on setting of the event-attribute
Log 5, $value; Log 5, $value;
my $ev = defined($attr{$name}{"event"}) ? $attr{$name}{"event"} : "on-update";
if( ($ev eq "on-update") || (($ev eq "on-change") && ($newval ne $oldval)) ){
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef);
}
return undef; return undef;
} }
@ -579,7 +571,6 @@ sub OWSWITCH_Set($@) {
return undef; return undef;
} }
#-- Set readings according to interface type #-- Set readings according to interface type
my $interface= $hash->{IODev}->{TYPE}; my $interface= $hash->{IODev}->{TYPE};
@ -598,14 +589,38 @@ sub OWSWITCH_Set($@) {
} }
return "OWSWITCH: invalid output address, must be A,B,... or defined channel name" return "OWSWITCH: invalid output address, must be A,B,... or defined channel name"
if( !defined($fnd) ); if( !defined($fnd) );
#-- prepare gpio value #-- prepare gpio value
my $nval; my $nval;
my $ntim;
my $nstr="";
if( lc($a[3]) eq "on" ){ if( lc($a[3]) eq "on" ){
$nval = 0; $nval = 0;
}elsif( lc($a[3]) eq "off" ){ }elsif( lc($a[3]) eq "off" ){
$nval = 1; $nval = 1;
}elsif( lc($a[3]) =~ m/for-timer/ ){
if( !($a[4] =~ m/\d\d\:\d\d\:\d\d/) ){
if( !($a[4] =~ m/\d{1,4}/ )){
return "OWSWITCH: Wrong data value $a[4], must be time format xx:xx:zz or integer";
} else { } else {
return "OWSWITCH: Wrong data value $a[3], must be ON or OFF"; $ntim = sprintf("%02d:%02d:%02d",int($a[4]/3600),int( ($a[4] % 3600)/60 ),$a[4] %60);
}
} else {
$ntim= $a[4];
}
if( lc($a[3]) eq "on-for-timer" ){
$nval = 0;
$nstr = "$a[0] $a[1] $a[2] off";
}elsif( lc($a[3]) eq "off-for-timer" ){
$nval = 1;
$nstr = "$a[0] $a[1] $a[2] on";
}
}else{
return "OWSWITCH: Wrong data value $a[3], must be on, off, on-for-timer or off-for-timer";
}
if ($nstr ne ""){
fhem("define ".$a[0].".".$owg_fixed[$fnd]."Timer at +".$ntim." set ".$nstr);
} }
#-- OWX interface #-- OWX interface
@ -708,8 +723,70 @@ sub OWXSWITCH_GetState($) {
my ($i,$j,$k); my ($i,$j,$k);
#-- family = 12 => DS2406
if( $hash->{OW_FAMILY} eq "12" ) {
#=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the access channel command
# \xF5 plus the two byte channel control and the value
#-- reading 9 + 3 + 1 data bytes + 2 CRC bytes = 15 bytes
$select=sprintf("\xF5\xDD\xFF");
#-- reset the bus
OWX_Reset($master);
#-- read the data
$res=OWX_Complex($master,$owx_dev,$select,4);
if( $res eq 0 ){
return "not accessible in reading";
}
#-- reset the bus
OWX_Reset($master);
#-- process results
@data=split(//,substr($res,9));
return "invalid data length, ".int(@data)." instead of 7 bytes"
if (@data != 7);
return "invalid CRC"
if ( OWX_CRC16(substr($res,9,5),$data[5],$data[6]) == 0);
$owg_val[0] = (ord($data[3])>>2) & 1;
$owg_vax[0] = ord($data[3]) & 1;
$owg_val[1] = (ord($data[3])>>3) & 1;
$owg_vax[1] = (ord($data[3])>>1) & 1;
#-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the read PIO rtegisters command
# \xF5 plus the two byte channel target address
#-- reading 9 + 3 + 8 data bytes + 2 CRC bytes = 22 bytes
$select=sprintf("\xF0\x88\x00");
#-- reset the bus
OWX_Reset($master);
#-- read the data
$res=OWX_Complex($master,$owx_dev,$select,10);
if( $res eq 0 ){
return "not accessible in reading";
}
#-- reset the bus
OWX_Reset($master);
#-- process results
@data=split(//,substr($res,9));
return "invalid data length, ".int(@data)." instead of 13 bytes"
if (@data != 13);
return "invalid data"
if (ord($data[9])!=255);
return "invalid CRC"
if( OWX_CRC16(substr($res,9,11),$data[11],$data[12]) == 0);
for(my $i=0;$i<8;$i++){
$owg_val[$i] = (ord($data[2])>>$i) & 1;
$owg_vax[$i] = (ord($data[3])>>$i) & 1;
}
#-- family = 3A => DS2413 #-- family = 3A => DS2413
if( $hash->{OW_FAMILY} eq "3A" ) { }elsif( $hash->{OW_FAMILY} eq "3A" ) {
#=============== get gpio values =============================== #=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the read gpio command #-- issue the match ROM command \x55 and the read gpio command
# \xF5 plus 2 empty bytes # \xF5 plus 2 empty bytes
@ -718,79 +795,35 @@ sub OWXSWITCH_GetState($) {
#-- read the data #-- read the data
$res=OWX_Complex($master,$owx_dev,"\xF5",2); $res=OWX_Complex($master,$owx_dev,"\xF5",2);
if( $res eq 0 ){ if( $res eq 0 ){
return "OWXSWITCH: Device $owx_dev not accessible in reading"; return "not accessible in reading";
} }
#-- family = 12 => DS2406
}elsif( $hash->{OW_FAMILY} eq "12" ) {
#=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the access channel command
# \xF5 plus the two byte channel control and the value
$select=sprintf("\xF5\xDC\xFF");
#-- reset the bus #-- reset the bus
OWX_Reset($master); OWX_Reset($master);
#-- read the data
$res=OWX_Complex($master,$owx_dev,$select,1);
if( $res eq 0 ){
return "OWXSWITCH: Device $owx_dev not accessible in writing";
}
#-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== get gpio values ===============================
#-- issue the match ROM command \x55 and the read PIO rtegisters command
# \xF5 plus the two byte channel target address
#-- reading 9 + 3 + 10 data bytes = 22 bytes
$select=sprintf("\xF0\x88\x00");
#-- reset the bus
OWX_Reset($master);
#-- read the data
$res=OWX_Complex($master,$owx_dev,$select,10);
if( $res eq 0 ){
return "OWXSWITCH: Device $owx_dev not accessible in writing";
}
} else {
return "OWXSWITCH: Unknown device family $hash->{OW_FAMILY}\n";
}
#-- process results #-- process results
@data=split(//,substr($res,10)); @data=split(//,substr($res,9));
#return "invalid data length" return "invalid data length, ".int(@data)." instead of 3 bytes"
# if (@data != 22); if (@data != 3);
#return "invalid data" return "invalid data"
# if (ord($data[17])<=0); if ( (15- (ord($data[1])>>4)) != (ord($data[1]) & 15) );
#return "invalid CRC"
# if (OWX_CRC8(substr($res,10,8),$data[18])==0);
#-- reset the bus
OWX_Reset($master);
# note: value 1 corresponds to OFF, 0 to ON normally # note: value 1 corresponds to OFF, 0 to ON normally
# note: val = input value, vax = output value # note: val = input value, vax = output value
#-- family = 3A => DS2413 $owg_val[0] = ord($data[1]) & 1;
if( $hash->{OW_FAMILY} eq "3A" ) { $owg_vax[0] = (ord($data[1])>>1) & 1;
$owg_val[0] = ord($data[0]) & 1; $owg_val[1] = (ord($data[1])>>2) & 1;
$owg_vax[0] = (ord($data[0])>>1) & 1; $owg_vax[1] = (ord($data[1])>>3) & 1;
$owg_val[1] = (ord($data[0])>>2) & 1;
$owg_vax[1] = (ord($data[0])>>3) & 1;
#-- family = 12 => DS2406 } else {
}elsif( $hash->{OW_FAMILY} eq "12" ) { return "unknown device family $hash->{OW_FAMILY}\n";
$owg_val[0] = (ord($data[2])>>2) & 1;
$owg_vax[0] = ord($data[2]) & 1;
$owg_val[1] = (ord($data[2])>>3) & 1;
$owg_vax[1] = (ord($data[2])>>1) & 1;
#-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) {
for(my $i=0;$i<8;$i++){
$owg_val[$i] = (ord($data[2])>>$i) & 1;
$owg_vax[$i] = (ord($data[3])>>$i) & 1;
}
} }
return undef return undef
} }
######################################################################################## ########################################################################################
# #
# OWXSWITCH_SetPage - Set gpio ports of device # OWXSWITCH_SetState - Set gpio ports of device
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# value = integer value for device outputs # value = integer value for device outputs
@ -814,31 +847,20 @@ sub OWXSWITCH_SetState($$) {
my ($i,$j,$k); my ($i,$j,$k);
#-- family = 3A => DS2413
if( $hash->{OW_FAMILY} eq "3A" ) {
#=============== set gpio values ===============================
#-- issue the match ROM command \x55 and the write gpio command
# \x5A plus the value byte and its complement
$select=sprintf("\x5A%c%c",252+$value,3-$value);
#-- reset the bus
OWX_Reset($master);
#-- read the data
$res=OWX_Complex($master,$owx_dev,$select,1);
if( $res eq 0 ){
return "OWXSWITCH: Device $owx_dev not accessible in writing";
}
#-- family = 12 => DS2406 #-- family = 12 => DS2406
}elsif( $hash->{OW_FAMILY} eq "12" ) { if( $hash->{OW_FAMILY} eq "12" ) {
#=============== set gpio values =============================== #=============== set gpio values ===============================
# Writing the output state via the access channel command does # Writing the output state via the access channel command does
# not work contrary to documentation. Using the write status command # not work contrary to documentation. Using the write status command
#-- issue the match ROM command \x55 and the read status command #-- issue the match ROM command \x55 and the read status command
# \xAA at address TA1 = \x07 TA2 = \x00 # \xAA at address TA1 = \x07 TA2 = \x00
#-- reading 9 + 3 + 1 data bytes + 2 CRC bytes = 15 bytes
#-- reset the bus #-- reset the bus
OWX_Reset($master); OWX_Reset($master);
#-- read the data #-- read the data
$res = OWX_Complex($master,$owx_dev,"\xAA\x07\x00",1); $res = OWX_Complex($master,$owx_dev,"\xAA\x07\x00",3);
my $stat = substr($res,10,1); my $stat = ord(substr($res,10,1));
my $statneu = ( $stat & 159 ) | (($value<<5) & 96) ; my $statneu = ( $stat & 159 ) | (($value<<5) & 96) ;
#-- issue the match ROM command \x55 and the write status command #-- issue the match ROM command \x55 and the write status command
# \x55 at address TA1 = \x07 TA2 = \x00 # \x55 at address TA1 = \x07 TA2 = \x00
@ -851,10 +873,23 @@ sub OWXSWITCH_SetState($$) {
if( $res eq 0 ){ if( $res eq 0 ){
return "OWXSWITCH: Device $owx_dev not accessible in writing"; return "OWXSWITCH: Device $owx_dev not accessible in writing";
} }
#-- reset the bus
OWX_Reset($master);
#-- process results
@data=split(//,substr($res,9));
#-- very crude check - should be CRC
if( int(@data) != 6){
return "OWXSWITCH: State could not be set for device $owx_dev";
}
#-- put into local buffer
$owg_val[0] = $value % 2; $owg_val[0] = $value % 2;
$owg_vax[0] = $owg_val[0]; $owg_vax[0] = $owg_val[0];
$owg_val[1] = int($value / 2); $owg_val[1] = int($value / 2);
$owg_vax[1] = $owg_val[1]; $owg_vax[1] = $owg_val[1];
#-- family = 29 => DS2408 #-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) { }elsif( $hash->{OW_FAMILY} eq "29" ) {
#=============== set gpio values =============================== #=============== set gpio values ===============================
@ -869,8 +904,27 @@ sub OWXSWITCH_SetState($$) {
return "OWXSWITCH: Device $owx_dev not accessible in writing"; return "OWXSWITCH: Device $owx_dev not accessible in writing";
} }
} else { #-- process results
return "OWXSWITCH: Unknown device family $hash->{OW_FAMILY}\n"; @data=split(//,substr($res,10));
if( $data[2] ne "\xAA"){
return "OWXSWITCH: State could not be set for device $owx_dev";
}
#-- reset the bus
OWX_Reset($master);
#-- family = 3A => DS2413
}elsif( $hash->{OW_FAMILY} eq "3A" ) {
#=============== set gpio values ===============================
#-- issue the match ROM command \x55 and the write gpio command
# \x5A plus the value byte and its complement
$select=sprintf("\x5A%c%c",252+$value,3-$value);
#-- reset the bus
OWX_Reset($master);
#-- read the data
$res=OWX_Complex($master,$owx_dev,$select,1);
if( $res eq 0 ){
return "OWXSWITCH: Device $owx_dev not accessible in writing";
} }
#-- reset the bus #-- reset the bus
OWX_Reset($master); OWX_Reset($master);
@ -878,24 +932,15 @@ sub OWXSWITCH_SetState($$) {
#-- process results #-- process results
@data=split(//,substr($res,10)); @data=split(//,substr($res,10));
#-- family = 3A => DS2413
if( $hash->{OW_FAMILY} eq "3A" ) {
if( $data[2] ne "\xAA"){ if( $data[2] ne "\xAA"){
return "OWXSWITCH: State could not be set for device $owx_dev"; return "OWXSWITCH: State could not be set for device $owx_dev";
} }
#-- family = 12 => DS2406
}elsif( $hash->{OW_FAMILY} eq "12" ) { }else {
#-- very crude check - should be CRC return "OWXSWITCH: Unknown device family $hash->{OW_FAMILY}\n";
if( int(@data) != 5){
return "OWXSWITCH: State could not be set for device $owx_dev";
} }
#-- family = 29 => DS2408
}elsif( $hash->{OW_FAMILY} eq "29" ) { return undef;
if( $data[2] ne "\xAA"){
return "OWXSWITCH: State could not be set for device $owx_dev";
}
}
return undef
} }
@ -903,64 +948,67 @@ sub OWXSWITCH_SetState($$) {
=pod =pod
=begin html =begin html
<body>
<a name="OWSWITCH"></a>
<h3>OWSWITCH</h3> <h3>OWSWITCH</h3>
<ul>FHEM module to commmunicate with 1-Wire Programmable Switches <br /><br /> Note:<br /> <p>FHEM module to commmunicate with 1-Wire Programmable Switches <br /><br /> Note:<br />
This 1-Wire module so far works only with the OWX interface module. Please define an <a This 1-Wire module so far works only with the OWX interface module. Please define an <a
href="#OWX">OWX</a> device first. <br /> href="#OWX">OWX</a> device first. <br /></p>
<br /><b>Example</b><br /> <br /><h4>Example</h4>
<ul> <p>
<code>define OWX_S OWSWITCH DS2413 B5D502000000 60</code> <code>define OWX_S OWSWITCH DS2413 B5D502000000 60</code>
<br /> <br />
<code>attr OWX_S AName Lampe|light</code> <code>attr OWX_S AName Lampe|light</code>
<br /> <br />
<code>attr OWX_S AUnit AN|AUS</code> <code>attr OWX_S AUnit AN|AUS</code>
<br /> <br />
</ul> </p>
<br /> <br />
<a name="OWSWITCHdefine"></a> <a name="OWSWITCHdefine"></a>
<b>Define</b> <h4>Define</h4>
<p>
<code>define &lt;name&gt; OWSWITCH [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire switch.<br /><br /></p>
<ul> <ul>
<code>define &lt;name&gt; OWSWITCH [&lt;model&gt;] &lt;id&gt;
[&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire switch.<br /><br />
<li> <li>
<code>[&lt;model&gt;]</code><br /> Defines the switch model (and thus 1-Wire <code>[&lt;model&gt;]</code><br /> Defines the switch model (and thus 1-Wire family
family id), currently the following values are permitted: <ul> id), currently the following values are permitted: <ul>
<li>model DS2413 with family id 3A (default if the model parameter is <li>model DS2413 with family id 3A (default if the model parameter is omitted).
omitted). 2 Channel switch with onboard memory</li> 2 Channel switch with onboard memory</li>
<li>model DS2406 with family id 12. 2 Channel switch </li> <li>model DS2406 with family id 12. 2 Channel switch </li>
<li>model DS2406 with family id 29. 8 Channel switch</li> <li>model DS2408 with family id 29. 8 Channel switch</li>
</ul> </ul>
</li> </li>
<li> <li>
<code>&lt;id&gt;</code> <code>&lt;id&gt;</code>
<br />12-character unique ROM id of the converter device without family id and <br />12-character unique ROM id of the converter device without family id and CRC
CRC code </li> code </li>
<li> <li>
<code>&lt;interval&gt;</code> <code>&lt;interval&gt;</code>
<br />Measurement interval in seconds. The default is 300 seconds. </li> <br />Measurement interval in seconds. The default is 300 seconds. </li>
</ul> </ul>
<br /> <a name="OWSWITCHset"></a>
<a name="OWSWITCHset"> <h4>Set</h4>
<b>Set</b></a>
<ul> <ul>
<li><a name="owswitch_interval"> <li><a name="owswitch_interval">
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement <code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement
interval in seconds. The default is 300 seconds. </li> interval in seconds. The default is 300 seconds. </li>
<li><a name="owswitch_output"> <li><a name="owswitch_output">
<code>set &lt;name&gt; output &lt;channel-name&gt; ON | <code>set &lt;name&gt; output &lt;channel-name&gt; on | off | on-for-timer &lt;time&gt; | off-for-timer &lt;time&gt;</code>
OFF</code></a><br />Set value for channel (A,B,... or defined channel name). 1 = OFF, 0 = ON in normal usage. </a><br />Set
See also the note above</li> value for channel (A,B,... or defined channel name). 1 = off, 0 = on in normal
usage. See also the note above.<br/>
on-for-timer/off-for-timer will set the desired value only for the given time,
either given as hh:mm:ss or as integers seconds
and then will return to the opposite value.</li>
<li><a name="owswitch_gpio"> <li><a name="owswitch_gpio">
<code>set &lt;name&gt; gpio &lt;value&gt;</code></a><br />Set values for channels (For 2 channels: 3 = A and B OFF, 1 = B ON 2 = A ON 0 = both ON)</li> <code>set &lt;name&gt; gpio &lt;value&gt;</code></a><br />Set values for
channels (For 2 channels: 3 = A and B off, 1 = B on 2 = A on 0 = both on)</li>
<li><a name="owswitch_init"> <li><a name="owswitch_init">
<code>set &lt;name&gt; init yes</code></a><br /> Re-initialize the device</li> <code>set &lt;name&gt; init yes</code></a><br /> Re-initialize the device</li>
</ul> </ul>
<br /> <br />
<a name="OWSWITCHget"> <a name="OWSWITCHget"></a>
<b>Get</b></a> <h4>Get</h4>
<ul> <ul>
<li><a name="owswitch_id"> <li><a name="owswitch_id">
<code>get &lt;name&gt; id</code></a> <code>get &lt;name&gt; id</code></a>
@ -970,38 +1018,33 @@ sub OWXSWITCH_SetState($$) {
</a> </a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owswitch_interval2"> <li><a name="owswitch_interval2">
<code>get &lt;name&gt; interval</code></a><br />Returns measurement interval <code>get &lt;name&gt; interval</code></a><br />Returns measurement interval in
in seconds. </li> seconds. </li>
<li><a name="owswitch_input"> <li><a name="owswitch_input">
<code>get &lt;name&gt; input &lt;channel-name&gt;</code></a><br /> <code>get &lt;name&gt; input &lt;channel-name&gt;</code></a><br /> state for
state for channel (A,B, ... or defined channel name) channel (A,B, ... or defined channel name) This value reflects the measured value,
This value reflects the measured value, not necessarily the one set as not necessarily the one set as output state, because the output transistors are open
output state, because the output transistors are open collector switches. A measured collector switches. A measured state of 1 = OFF therefore corresponds to an output
state of 1 = OFF therefore corresponds to an output state of 1 = OFF, but a measured state of 1 = OFF, but a measured state of 0 = ON can also be due to an external
state of 0 = ON can also be due to an external shortening of the output.</li> shortening of the output.</li>
<li><a name="owswitch_gpio"> <li><a name="owswitch_gpio">
<code>get &lt;name&gt; gpio</code></a><br />Obtain state of all <code>get &lt;name&gt; gpio</code></a><br />Obtain state of all channels</li>
channels</li>
</ul> </ul>
<br /> <br />
<a name="OWSWITCHattr"> <a name="OWSWITCHattr"></a>
<b>Attributes</b></a> For each of the following attributes, the channel <h4>Attributes</h4> For each of the following attributes, the channel identification A,B,...
identification A,B,... may be used. <ul> may be used. <ul>
<li><a name="owswitch_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name <li><a name="owswitch_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name
&lt;string&gt;|&lt;string&gt;</code></a> &lt;string&gt;|&lt;string&gt;</code></a>
<br />name for the channel | a type description for the measured value. </li> <br />name for the channel | a type description for the measured value. </li>
<li><a name="owswitch_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit <li><a name="owswitch_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit
&lt;string&gt;|&lt;string&gt;</code></a> &lt;string&gt;|&lt;string&gt;</code></a>
<br />display for on | off condition </li> <br />display for on | off condition </li>
<li><a name="owswitch_event"><code>attr &lt;name&gt; event on-change|on-update <li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
</code></a>This attribte work similarly, but not identically to the standard event-on-update-change/event-on-update-reading attribute. href="#event-on-update-reading">event-on-update-reading</a>, <a
<ul><li><code>event on-update</code> (default) will write a notify/FileLog event any time a measurement is received.</li> href="#event-on-change-reading">event-on-change-reading</a>, <a href="#room"
<li><code>event on-change</code> will write a notify/FileLog event only when a measurement is different from the previous one.</li> >room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
</li>
<li>Standard attributes alias, comment, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>, <a href="#webCmd">webCmd</a></li>
</ul>
</ul>
=end html =end html
=cut =cut

View File

@ -4,20 +4,13 @@
# #
# FHEM module to commmunicate with 1-Wire temperature sensors DS1820, DS18S20, DS18B20, DS1822 # FHEM module to commmunicate with 1-Wire temperature sensors DS1820, DS18S20, DS18B20, DS1822
# #
# Attention: This module may communicate with the OWX module, # Prof. Dr. Peter A. Henning
# and also with the 1-Wire File System OWFS
# #
# Prefixes for subroutines of this module: # $Id$
# OW = General 1-Wire routines (Martin Fischer, Peter Henning)
# OWFS = 1-Wire file system (Martin Fischer)
# OWX = 1-Wire bus master interface (Peter Henning)
# #
# Prof. Dr. Peter A. Henning, 2012 # Disclaimer: No code of the former OWTEMP module is contained here
# Martin Fischer, 2011
# #
# Version 2.24 - October, 2012 ########################################################################################
#
# Setup bus device in fhem.cfg as
# #
# define <name> OWTHERM [<model>] <ROM_ID> [interval] # define <name> OWTHERM [<model>] <ROM_ID> [interval]
# #
@ -43,12 +36,8 @@
# Additional attributes are defined in fhem.cfg # Additional attributes are defined in fhem.cfg
# Note: attributes "tempXXXX" are read during every update operation. # Note: attributes "tempXXXX" are read during every update operation.
# #
# attr <name> event on-change/on-update = when to write an event (default= on-update) # attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is down triangle
# # attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is up triangle
# attr <name> stateAL "<string>" = character string for denoting low alarm condition, default is (-),
# overwritten by attribute setting red down triangle
# attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is (+),
# overwritten by attribute setting red up triangle
# attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading # attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius # attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius
# attr <name> tempLow <float> = value for low alarm # attr <name> tempLow <float> = value for low alarm
@ -74,7 +63,6 @@
######################################################################################## ########################################################################################
package main; package main;
#-- Prototypes to make komodo happy
use vars qw{%attr %defs}; use vars qw{%attr %defs};
use strict; use strict;
use warnings; use warnings;
@ -133,7 +121,7 @@ sub OWTHERM_Initialize ($) {
#tempOffset = a temperature offset added to the temperature reading for correction #tempOffset = a temperature offset added to the temperature reading for correction
#tempUnit = a unit of measure: C/F/K #tempUnit = a unit of measure: C/F/K
$hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ". $hash->{AttrList}= "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ".
"event:on-update,on-change ". "event-on-update-reading event-on-change-reading ".
"stateAL stateAH ". "stateAL stateAH ".
"tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ". "tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ".
"tempLow tempHigh"; "tempLow tempHigh";
@ -210,12 +198,14 @@ sub OWTHERM_Define ($$) {
$hash->{ROM_ID} = $fam.".".$id.$crc; $hash->{ROM_ID} = $fam.".".$id.$crc;
$hash->{INTERVAL} = $interval; $hash->{INTERVAL} = $interval;
#-- Couple to I/O device #-- Couple to I/O device, exit if not possible
AssignIoPort($hash); AssignIoPort($hash);
Log 3, "OWTHERM: Warning, no 1-Wire I/O device found for $name." if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | ($hash->{IODev}->{PRESENT} != 1) ){
if(!defined($hash->{IODev}->{NAME})); return "OWTHERM: Warning, no 1-Wire I/O device found for $name.";
}
$modules{OWTHERM}{defptr}{$id} = $hash; $modules{OWTHERM}{defptr}{$id} = $hash;
$hash->{STATE} = "Defined"; #--
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWTHERM: Device $name defined."; Log 3, "OWTHERM: Device $name defined.";
#-- Start timer for initialization in a few seconds #-- Start timer for initialization in a few seconds
@ -241,28 +231,25 @@ sub OWTHERM_InitializeDevice($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my @args; my @args;
#-- more colorful alarm signatures
CommandAttr (undef,"$name stateAL <span style=\"color:red\">&#x25BE;</span>")
if( !defined($attr{$name}{"stateAL"} ));
CommandAttr (undef,"$name stateAH <span style=\"color:red\">&#x25B4;</span>")
if( !defined($attr{$name}{"stateAH"} ));
#-- unit attribute defined ? #-- unit attribute defined ?
$hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
$hash->{READINGS}{"temperature"}{TYPE} = "temperature"; $hash->{READINGS}{"temperature"}{TYPE} = "temperature";
#-- Initial readings temperature sensor #-- Initial readings temperature sensor
$owg_temp = 0.0; $owg_temp = "";
$owg_tl = defined($attr{$name}{"tempLow"}) ? $attr{$name}{"tempLow"} : 0.0; $owg_tl = defined($attr{$name}{"tempLow"}) ? $attr{$name}{"tempLow"} : "";
$owg_th = defined($attr{$name}{"tempHigh"}) ? $attr{$name}{"tempHigh"} : 100.0; $owg_th = defined($attr{$name}{"tempHigh"}) ? $attr{$name}{"tempHigh"} : "";
#-- Initialize all the display stuff
#-- Output formatting because of reading attributes
OWTHERM_FormatValues($hash); OWTHERM_FormatValues($hash);
#-- alarm #-- set status
if ($owg_tl ne ""){
@args = ($name,"tempLow",$owg_tl); @args = ($name,"tempLow",$owg_tl);
OWTHERM_Set($hash,@args); OWTHERM_Set($hash,@args);
}
if ($owg_th ne ""){
@args = ($name,"tempHigh",$owg_th); @args = ($name,"tempHigh",$owg_th);
OWTHERM_Set($hash,@args); OWTHERM_Set($hash,@args);
}
} }
######################################################################################## ########################################################################################
@ -278,14 +265,12 @@ sub OWTHERM_FormatValues($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ($unit,$offset,$factor,$abbr,$vval,$vlow,$vhigh,$statef); my ($unit,$offset,$factor,$abbr,$vval,$vlow,$vhigh,$statef);
my ($value1,$value2,$value3) = ("","",""); my $svalue = "";
my $tn = TimeNow();
#-- attributes defined ? #-- attributes defined ?
$stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : "(-)"; $stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : "&#x25BE;";
$stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : "(+)"; $stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : "&#x25B4;";
$unit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT}; $unit = $hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
$offset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ; $offset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ;
$factor = 1.0; $factor = 1.0;
@ -300,57 +285,51 @@ sub OWTHERM_FormatValues($) {
$factor = 1.8; $factor = 1.8;
} else { } else {
$abbr="?"; $abbr="?";
Log 1, "OWTHERM_FormatValues: unknown unit $unit"; Log 3, "OWTHERM_FormatValues: unknown unit $unit";
} }
#-- these values are rather coplex to obtain, therefore save them in the hash #-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{UNIT} = $unit; $hash->{READINGS}{"temperature"}{UNIT} = $unit;
$hash->{READINGS}{"temperature"}{UNITABBR} = $abbr; $hash->{READINGS}{"temperature"}{UNITABBR} = $abbr;
$hash->{tempf}{offset} = $offset; $hash->{tempf}{offset} = $offset;
$hash->{tempf}{factor} = $factor; $hash->{tempf}{factor} = $factor;
#-- no change in any value if invalid reading
return if( $owg_temp eq "");
#-- correct values for proper offset, factor #-- correct values for proper offset, factor
$vval = ($owg_temp + $offset)*$factor; $vval = ($owg_temp + $offset)*$factor;
#-- put into READINGS
$hash->{READINGS}{"temperature"}{VAL} = $vval;
$hash->{READINGS}{"temperature"}{TIME} = $tn;
#-- correct alarm values for proper offset, factor #-- correct alarm values for proper offset, factor
$vlow = ($owg_tl + $offset)*$factor; $vlow = ($owg_tl + $offset)*$factor;
$vhigh = ($owg_th + $offset)*$factor; $vhigh = ($owg_th + $offset)*$factor;
#-- put into READINGS
$hash->{READINGS}{"tempLow"}{VAL} = $vlow;
$hash->{READINGS}{"tempLow"}{TIME} = $tn;
$hash->{READINGS}{"tempHigh"}{VAL} = $vhigh;
$hash->{READINGS}{"tempHigh"}{TIME} = $tn;
#-- formats for output #-- formats for output
$statef = "%5.2f ".$abbr; $statef = "%5.2f ".$abbr;
$value1 = "temperature: ".sprintf($statef,$vval); $svalue = "temperature: ".sprintf($statef,$vval);
$value2 = sprintf($statef,$vval);
$hash->{ALARM} = 1;
#-- Test for alarm condition #-- Test for alarm condition
$hash->{ALARM} = 1;
if( ($vval <= $vlow) && ( $vval >= $vhigh ) ){ if( ($vval <= $vlow) && ( $vval >= $vhigh ) ){
$value2 .= " ".$stateal.$stateah; $svalue .= " ".$stateal.$stateah;
$value3 .= " ".$stateal.$stateah;
}elsif( $vval <= $vlow ){ }elsif( $vval <= $vlow ){
$value2 .= " ".$stateal; $svalue .= " ".$stateal;
$value3 .= " ".$stateal;
}elsif( $vval >= $vhigh ){ }elsif( $vval >= $vhigh ){
$value2 .= " ".$stateah; $svalue .= " ".$stateah;
$value3 .= " ".$stateah;
} else { } else {
$hash->{ALARM} = 0; $hash->{ALARM} = 0;
} }
#-- put into READINGS
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"temperature",$vval);
readingsBulkUpdate($hash,"tempLow",$vlow);
readingsBulkUpdate($hash,"tempHigh",$vhigh);
#-- STATE #-- STATE
$hash->{STATE} = $value2; readingsBulkUpdate($hash,"state",$svalue);
#-- alarm readingsEndUpdate($hash,1);
#$hash->{READINGS}{alarms}{VAL} = $value3;
#$hash->{READINGS}{alarms}{TIME} = $tn; return $svalue;
return $value1;
} }
######################################################################################## ########################################################################################
@ -485,17 +464,8 @@ sub OWTHERM_GetValues($@) {
} }
$hash->{PRESENT} = 1; $hash->{PRESENT} = 1;
#-- old state, new state
my $oldval = $hash->{STATE};
$value=OWTHERM_FormatValues($hash); $value=OWTHERM_FormatValues($hash);
my $newval = $hash->{STATE};
#--logging depends on setting of the event-attribute
Log 5, $value; Log 5, $value;
my $ev = defined($attr{$name}{"event"}) ? $attr{$name}{"event"} : "on-update";
if( ($ev eq "on-update") || (($ev eq "on-change") && ($newval ne $oldval)) ){
$hash->{CHANGED}[0] = $value;
DoTrigger($name, undef);
}
return undef; return undef;
} }
@ -540,7 +510,7 @@ sub OWTHERM_Set($@) {
return undef; return undef;
} }
#-- set other values depending on interface type #-- set tempLow or tempHigh
my $interface = $hash->{IODev}->{TYPE}; my $interface = $hash->{IODev}->{TYPE};
my $offset = $hash->{tempf}{offset}; my $offset = $hash->{tempf}{offset};
my $factor = $hash->{tempf}{factor}; my $factor = $hash->{tempf}{factor};
@ -551,7 +521,7 @@ sub OWTHERM_Set($@) {
return sprintf("OWTHERM: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax) return sprintf("OWTHERM: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax)
if($value < $mmin || $value > $mmax); if($value < $mmin || $value > $mmax);
#-- seems to be ok, put into the device #-- seems to be ok, put into the device after correcting for offset and factor
$a[2] = int($value/$factor-$offset); $a[2] = int($value/$factor-$offset);
#-- OWX interface #-- OWX interface
@ -664,7 +634,7 @@ sub OWXTHERM_GetValues($) {
my ($hash) = @_; my ($hash) = @_;
my ($i,$j,$k); my ($i,$j,$k,@data);
#-- For default, perform the conversion NOT now #-- For default, perform the conversion NOT now
my $con=1; my $con=1;
@ -702,25 +672,25 @@ sub OWXTHERM_GetValues($) {
} }
#-- process results #-- process results
my @data=split(//,$res); @data=split(//,substr($res,9));
return "invalid data length, ".int(@data)." bytes" return "invalid data length, ".int(@data)." instead of 10 bytes"
if (@data != 19); if (@data != 10);
return "invalid data" return "invalid data"
if (ord($data[17])<=0); if (ord($data[8])<=0);
return "invalid CRC" return "invalid CRC"
if (OWX_CRC8(substr($res,10,8),$data[18])==0); if (OWX_CRC8(substr($res,10,8),$data[9])==0);
#-- this must be different for the different device types #-- this must be different for the different device types
# family = 10 => DS1820, DS18S20 # family = 10 => DS1820, DS18S20
if( $hash->{OW_FAMILY} eq "10" ) { if( $hash->{OW_FAMILY} eq "10" ) {
my $count_remain = ord($data[16]); my $count_remain = ord($data[7]);
my $count_perc = ord($data[17]); my $count_perc = ord($data[8]);
my $delta = -0.25 + ($count_perc - $count_remain)/$count_perc; my $delta = -0.25 + ($count_perc - $count_remain)/$count_perc;
my $lsb = ord($data[10]); my $lsb = ord($data[1]);
my $msb = 0; my $msb = 0;
my $sign = ord($data[11]) & 255; my $sign = ord($data[2]) & 255;
#-- test with -25 degrees #-- test with -25 degrees
#$lsb = 12*16+14; #$lsb = 12*16+14;
@ -733,16 +703,16 @@ sub OWXTHERM_GetValues($) {
$owg_temp = -128+$owg_temp; $owg_temp = -128+$owg_temp;
} }
$owg_th = ord($data[12]) > 127 ? 128-ord($data[12]) : ord($data[12]); $owg_th = ord($data[3]) > 127 ? 128-ord($data[3]) : ord($data[3]);
$owg_tl = ord($data[13]) > 127 ? 128-ord($data[13]) : ord($data[13]); $owg_tl = ord($data[4]) > 127 ? 128-ord($data[4]) : ord($data[4]);
return undef; return undef;
} elsif ( ($hash->{OW_FAMILY} eq "22") || ($hash->{OW_FAMILY} eq "28") ) { } elsif ( ($hash->{OW_FAMILY} eq "22") || ($hash->{OW_FAMILY} eq "28") ) {
my $lsb = ord($data[10]); my $lsb = ord($data[1]);
my $msb = ord($data[11]) & 7; my $msb = ord($data[2]) & 7;
my $sign = ord($data[11]) & 248; my $sign = ord($data[2]) & 248;
#-- test with -55 degrees #-- test with -55 degrees
#$lsb = 9*16; #$lsb = 9*16;
@ -754,8 +724,8 @@ sub OWXTHERM_GetValues($) {
if( $sign !=0 ){ if( $sign !=0 ){
$owg_temp = -128+$owg_temp; $owg_temp = -128+$owg_temp;
} }
$owg_th = ord($data[12]) > 127 ? 128-ord($data[12]) : ord($data[12]); $owg_th = ord($data[3]) > 127 ? 128-ord($data[3]) : ord($data[3]);
$owg_tl = ord($data[13]) > 127 ? 128-ord($data[13]) : ord($data[13]); $owg_tl = ord($data[4]) > 127 ? 128-ord($data[4]) : ord($data[4]);
return undef; return undef;
@ -815,70 +785,64 @@ sub OWXTHERM_SetValues($@) {
return undef; return undef;
} }
1; 1;
=pod =pod
=begin html =begin html
<a name="OWTHERM"></a> <a name="OWTHERM"></a>
<h3>OWTHERM</h3> <h3>OWTHERM</h3>
<ul>FHEM module to commmunicate with 1-Wire bus digital thermometer devices<br /><br /> <p>FHEM module to commmunicate with 1-Wire bus digital thermometer devices<br /><br />
Note:<br /> This is the only 1-Wire module which so far works with both the OWFS and the Note:<br /> This is the only 1-Wire module which so far works with both the OWFS and the
OWX interface module. Please define an <a href="#OWFS">OWFS</a> device or an <a OWX interface module. Please define an <a href="#OWFS">OWFS</a> device or an <a
href="#OWX">OWX</a> device first. <br /> href="#OWX">OWX</a> device first. <br />
<br /><b>Example</b><br /> </p>
<ul> <h4>Example</h4>
<p>
<code>define OWX_T OWTHERM DS18B20 E8D09B030000 300</code> <code>define OWX_T OWTHERM DS18B20 E8D09B030000 300</code>
<br /> <br />
<code>attr OWX_T tempUnit Kelvin</code> <code>attr OWX_T tempUnit Kelvin</code>
<br /> <br />
</ul><br /> </p><br />
<a name="OWTHERMdefine"></a> <a name="OWTHERMdefine"></a>
<b>Define</b> <h4>Define</h4>
<ul> <code>define &lt;name&gt; OWTHERM [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code>
<code>define &lt;name&gt; OWTHERM [&lt;model&gt;] &lt;id&gt;
[&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire digital thermometer device.<br /><br /> <br /><br /> Define a 1-Wire digital thermometer device.<br /><br />
<li> <p>
<code>[&lt;model&gt;]</code><br /> Defines the thermometer model (and thus <code>[&lt;model&gt;]</code><br /> Defines the thermometer model (and thus 1-Wire family
1-Wire family id) currently the following values are permitted: <ul> id) currently the following values are permitted: </p>
<li>model DS1820 with family id 10 (default if the model parameter is <ul>
omitted)</li> <li>model DS1820 with family id 10 (default if the model parameter is omitted)</li>
<li>model DS1822 with family id 22</li> <li>model DS1822 with family id 22</li>
<li>model DS18B20 with family id 28</li> <li>model DS18B20 with family id 28</li>
</ul> </ul>
</li> <p>
<li>
<code>&lt;id&gt;</code> <code>&lt;id&gt;</code>
<br />12-character unique ROM id of the thermometer device without family id and <br />12-character unique ROM id of the thermometer device without family id and CRC
CRC code </li> code </p>
<li> <p>
<code>&lt;interval&gt;</code> <code>&lt;interval&gt;</code>
<br /> Temperature measurement interval in seconds. The default is 300 seconds. </li> <br /> Temperature measurement interval in seconds. The default is 300 seconds. </p>
<br /> Example: <br /> <br /> Example: <br />
<code>define Temp1 OWTHERM 14B598010800 300 </code><br /> <code>define Temp1 OWTHERM 14B598010800 300 </code><br />
</ul>
<br /> <br />
<a name="OWTHERMset"> <a name="OWTHERMset"></a>
<b>Set</b></a> <h4>Set</h4>
<ul> <ul>
<li><a name="owtherm_interval"> <li><a name="owtherm_interval">
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Temperature <code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Temperature
measurement intervall in seconds. The default is 300 seconds.</li> measurement intervall in seconds. The default is 300 seconds.</li>
<li><a name="owtherm_tempHigh"> <li><a name="owtherm_tempHigh">
<code>set &lt;name&gt; tempHigh &lt;float&gt;</code></a> <code>set &lt;name&gt; tempHigh &lt;float&gt;</code></a>
<br /> The high alarm temperature (on the temperature scale chosen by the <br /> The high alarm temperature (on the temperature scale chosen by the attribute
attribute value) </li> value) </li>
<li><a name="owtherm_tempLow"> <li><a name="owtherm_tempLow">
<code>set &lt;name&gt; tempLow &lt;float&gt;</code></a> <code>set &lt;name&gt; tempLow &lt;float&gt;</code></a>
<br /> The low alarm temperature (on the temperature scale chosen by the <br /> The low alarm temperature (on the temperature scale chosen by the attribute
attribute value) </li> value) </li>
</ul> </ul>
<br /> <br />
<a name="OWTHERMget"> <a name="OWTHERMget"></a>
<b>Get</b></a> <h4>Get</h4>
<ul> <ul>
<li><a name="owtherm_id"> <li><a name="owtherm_id">
<code>get &lt;name&gt; id</code></a> <code>get &lt;name&gt; id</code></a>
@ -887,8 +851,8 @@ sub OWXTHERM_SetValues($@) {
<code>get &lt;name&gt; present</code></a> <code>get &lt;name&gt; present</code></a>
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li> <br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
<li><a name="owtherm_interval2"> <li><a name="owtherm_interval2">
<code>get &lt;name&gt; interval</code></a><br />Returns temperature <code>get &lt;name&gt; interval</code></a><br />Returns temperature measurement
measurement interval in seconds.</li> interval in seconds.</li>
<li><a name="owtherm_temperature"> <li><a name="owtherm_temperature">
<code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature. </li> <code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature. </li>
<li><a name="owtherm_alarm"> <li><a name="owtherm_alarm">
@ -896,23 +860,18 @@ sub OWXTHERM_SetValues($@) {
values. </li> values. </li>
</ul> </ul>
<br /> <br />
<a name="OWTHERMattr"> <a name="OWTHERMattr"></a>
<b>Attributes</b></a> <h4>Attributes</h4>
<ul> <ul>
<li><a name="owtherm_stateAL"><code>attr &lt;name&gt; stateAL &lt;string&gt;</code> <li><a name="owtherm_stateAL"><code>attr &lt;name&gt; stateAL &lt;string&gt;</code>
</a> </a>
<br />character string for denoting low alarm condition, default is red down <br />character string for denoting low alarm condition, default is down triangle,
triangle, e.g. the code &lt;span style="color:red"&gt;&amp;#x25BE;&lt;/span&gt; e.g. the code &amp;#x25BE; leading to the sign &#x25BE; </li>
leading to the sign <span style="color:red">&#x25BE;</span>
</li>
<li><a name="owtherm_stateAH"><code>attr &lt;name&gt; stateAH &lt;string&gt;</code> <li><a name="owtherm_stateAH"><code>attr &lt;name&gt; stateAH &lt;string&gt;</code>
</a> </a>
<br />character string for denoting high alarm condition, default is red upward <br />character string for denoting high alarm condition, default is upward
triangle, e.g. the code &lt;span style="color:red"&gt;&amp;#x25B4;&lt;/span&gt; triangle, e.g. the code &amp;#x25B4; leading to the sign &#x25B4; </li>
leading to the sign <span style="color:red">&#x25B4;</span> <li><a name="owtherm_tempOffset"><code>attr &lt;name&gt; tempOffset &lt;float&gt;</code>
</li>
<li><a name="owtherm_tempOffset"><code>attr &lt;name&gt; tempOffset
&lt;float&gt;</code>
</a> </a>
<br />temperature offset in &deg;C added to the raw temperature reading. </li> <br />temperature offset in &deg;C added to the raw temperature reading. </li>
<li><a name="owtherm_tempUnit"><code>attr &lt;name&gt; tempUnit <li><a name="owtherm_tempUnit"><code>attr &lt;name&gt; tempUnit
@ -929,15 +888,11 @@ sub OWXTHERM_SetValues($@) {
</a> </a>
<br /> low alarm temperature (on the temperature scale chosen by the attribute <br /> low alarm temperature (on the temperature scale chosen by the attribute
value). </li> value). </li>
<li><a name="owtherm_event"><code>attr &lt;name&gt; event on-change|on-update <li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a
</code></a>This attribte work similarly, but not identically to the standard event-on-update-change/event-on-update-reading attribute. href="#event-on-update-reading">event-on-update-reading</a>, <a
<ul><li><code>event on-update</code> (default) will write a notify/FileLog event any time a measurement is received.</li> href="#event-on-change-reading">event-on-change-reading</a>, <a href="#room"
<li><code>event on-change</code> will write a notify/FileLog event only when a measurement is different from the previous one.</li> >room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li>
</ul> </ul>
</li>
<li>Standard attributes alias, comment, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>, <a href="#webCmd">webCmd</a></li>
</ul>
</ul>
=end html =end html
=cut =cut