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

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

This commit is contained in:
pahenning 2013-04-04 03:48:29 +00:00
parent 2e8f1cee71
commit d4564d8d63
7 changed files with 643 additions and 461 deletions

View File

@ -27,6 +27,7 @@
# get <name> reading => measurement for all channels
# get <name> alarm => alarm measurement settings for all channels
# get <name> status => alarm and i/o status for all channels
# get <name> version => OWX version number
#
# set <name> interval => set period for measurement
#
@ -74,12 +75,13 @@ use strict;
use warnings;
sub Log($$);
my $owx_version="3.21";
#-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B","C","D");
my @owg_channel = ("A","B","C","D");
#-- value globals
my @owg_status;
my $owg_state;
#-- channel name - fixed is the first array, variable the second
my @owg_fixed = ("A","B","C","D");
my @owg_channel = ("A","B","C","D");
#-- channel values - always the raw values from the device
my @owg_val=("","","","");
#-- channel mode - fixed for now
@ -102,6 +104,7 @@ my %gets = (
"reading" => "",
"alarm" => "",
"status" => "",
"version" => ""
);
my %sets = (
@ -261,6 +264,49 @@ sub OWAD_Define ($$) {
return undef;
}
########################################################################################
#
# OWAD_ChannelNames - find the real channel names
#
# Parameter hash = hash of device addressed
#
########################################################################################
sub OWAD_ChannelNames($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL};
my ($cname,@cnama,$unit,@unarr);
for (my $i=0;$i<int(@owg_fixed);$i++){
#-- name
$cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|voltage";
@cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWAD: Incomplete channel name specification $cname. Better use $cname|<type of data>"
if( $state eq "defined");
push(@cnama,"unknown");
}
$owg_channel[$i]=$cnama[0];
#-- unit
$unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "Volt|V";
@unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWAD: Incomplete channel unit specification $unit. Better use $unit|<abbreviation>"
if( $state eq "defined");
push(@unarr,"");
}
#-- put into readings
$hash->{READINGS}{$owg_channel[$i]}{TYPE} = $cnama[1];
$hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unarr[0];
$hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unarr[1];
}
}
########################################################################################
#
# OWAD_InitializeDevice - delayed setting of initial readings and channel names
@ -272,35 +318,14 @@ sub OWAD_Define ($$) {
sub OWAD_InitializeDevice($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $name = $hash->{NAME};
my $interface = $hash->{IODev}->{TYPE};
#-- Initial readings
@owg_val = ("","","","");
#-- Set channel names, channel units and alarm values
#-- Initial alarm values
for( my $i=0;$i<int(@owg_fixed);$i++) {
#-- name
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|voltage";
my @cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWAD: Incomplete channel name specification $cname. Better use $cname|<type of data>";
push(@cnama,"unknown");
}
#-- unit
my $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "Volt|V";
my @unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWAD: Incomplete channel unit specification $unit. Better use $unit|<abbreviation>";
push(@unarr,"");
}
#-- put into readings
$owg_channel[$i] = $cnama[0];
$hash->{READINGS}{"$owg_channel[$i]"}{TYPE} = $cnama[1];
$hash->{READINGS}{"$owg_channel[$i]"}{UNIT} = $unarr[0];
$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR} = $unarr[1];
$hash->{ERRCOUNT} = 0;
#-- alarm enabling
@ -363,6 +388,7 @@ sub OWAD_FormatValues($) {
my ($offset,$factor,$vval,$vlow,$vhigh,$vfunc,$ret);
my $vfuncall = "";
my $svalue = "";
#-- insert initial values
for( my $k=0;$k<int(@owg_fixed);$k++ ){
$vfuncall .= "\$owg_val[$k]=$owg_val[$k];";
@ -384,22 +410,19 @@ sub OWAD_FormatValues($) {
return if( $owg_val[$i] eq "");
}
#-- obtain channel names
OWAD_ChannelNames($hash);
#-- check if device needs to be initialized
OWAD_InitializeDevice($hash)
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
#-- put into READINGS
readingsBeginUpdate($hash);
#-- formats for output
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 @cnama = split(/\|/,$cname);
$owg_channel[$i]=$cnama[0];
my $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "Volt|V";
my @unarr= split(/\|/,$unit);
#-- skip a few things when the values are undefined or zero
if( !defined($owg_val[$i]) ){
$svalue .= "$owg_channel[$i]: ???"
@ -419,12 +442,15 @@ sub OWAD_FormatValues($) {
} else {
$vfunc = "V$owg_fixed[$i]";
}
$hash->{tempf}{"$owg_fixed[$i]"}{function} = $vfunc;
$hash->{tempf}{$owg_fixed[$i]}{function} = $vfunc;
#-- replace by proper values (VA -> $owg_val[0] etc.)
# careful: how to prevent {VAL} from being replaced ?
for( my $k=0;$k<int(@owg_fixed);$k++ ){
my $sstr = "V$owg_fixed[$k]";
$vfunc =~ s/VAL/WERT/g;
$vfunc =~ s/$sstr/\$owg_val[$k]/g;
$vfunc =~ s/WERT/VAL/g;
}
#-- determine the measured value from the function
@ -446,7 +472,7 @@ sub OWAD_FormatValues($) {
$main::attr{$name}{$owg_fixed[$i]."High"}=$vhigh;
#-- string buildup for return value, STATE and alarm
$svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$unarr[1]);
$svalue .= sprintf( "%s: %5.3f %s", $owg_channel[$i], $vval,$hash->{READINGS}{$owg_channel[$i]}{UNITABBR});
#-- Test for alarm condition
$alarm = "none";
@ -548,6 +574,11 @@ sub OWAD_Get($@) {
return "$name.interval => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
}
#-- reset presence
$hash->{PRESENT} = 0;
@ -757,11 +788,12 @@ sub OWAD_Set($@) {
#-- define vars
my $ret = undef;
my $channel = undef;
my $channon = undef;
my $channo = undef;
my $factor;
my $offset;
my $condx;
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
@ -779,11 +811,11 @@ sub OWAD_Set($@) {
#-- find out which channel we have
my $tc =$key;
if( $tc =~ s/(.*)(Alarm|Low|High)/$channel=$1/se ) {
if( $tc =~ s/(.*)(Alarm|Low|High)/$channon=$1/se ) {
for (my $i=0;$i<int(@owg_fixed);$i++){
if( $tc eq $owg_fixed[$i] ){
$channo = $i;
$channel = $tc;
$channon = $tc;
last;
}
}

View File

@ -28,17 +28,18 @@
# get <name> midnight <channel> => todays starting value for counter
# get <name> counter <channel> => value for counter
# get <name> counters => values for both counters
# get <name> version => OWX version number
#
# set <name> interval => set query interval for measurement
# set <name> memory <page> => 32 byte string into page 0..13
# set <name> midnight <channel> => todays starting value for counter
#
# 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.
#
# attr <name> LogM <string> = device name (not file name) of monthly log file
# 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>Rate <string>|<string> = name for the channel ratw | a type description for the measured value
# 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>Mode <string> = counting mode = normal(default) or daily
@ -52,7 +53,7 @@
# after each interval <date> <name> <channel>: <value> <unit> <value> / <unit>/<period> <channel>: <value> <unit> / <value> <unit>/<period>
# example: 2012-07-30_00:07:55 OWX_C Taste: 17.03 p 28.1 p/h B: 7.0 cts 0.0 cts/min
# after midnight <new date> <name> <old day> <old date> <channel>: <value> <unit> <channel>: <value> <unit>
# example: 2012-07-30_00:00:57 OWX_C D_29: 2012-7-29_23:59:59 Taste: 110.0 p, B: 7.0 cts
# example: 2012-07-30_00:00:57 OWX_C D29: 2012-7-29_23:59:59 Taste: 110.0 p, B: 7.0 cts
########################################################################################
#
# This programm is free software; you can redistribute it and/or modify
@ -78,10 +79,12 @@ use strict;
use warnings;
sub Log($$);
#-- channel name - fixed is the first array, variable the second
my @owg_fixed = ("A","B");
my @owg_channel;
my @owg_rate;
my $owx_version="3.21";
#-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B");
my @owg_channel = ("A","B");
my @owg_rate = ("A_rate","B_rate");
#-- channel values - always the raw values from the device
my @owg_val;
my @owg_midnight;
@ -94,7 +97,9 @@ my %gets = (
"memory" => "",
"midnight" => "",
"counter" => "",
"counters" => ""
"counters" => "",
"month" => "",
"version" => ""
);
my %sets = (
@ -108,7 +113,6 @@ my %updates = (
"counter" => ""
);
########################################################################################
#
# The following subroutines are independent of the bus interface
@ -136,6 +140,7 @@ sub OWCOUNT_Initialize ($) {
$readingFnAttributes;
for( my $i=0;$i<int(@owg_fixed);$i++ ){
$attlist .= " ".$owg_fixed[$i]."Name";
$attlist .= " ".$owg_fixed[$i]."Rate";
$attlist .= " ".$owg_fixed[$i]."Offset";
$attlist .= " ".$owg_fixed[$i]."Factor";
$attlist .= " ".$owg_fixed[$i]."Unit";
@ -218,32 +223,98 @@ sub OWCOUNT_Define ($$) {
$hash->{IODev}=$attr{$name}{"IODev"}
if( defined($attr{$name}{"IODev"}) );
AssignIoPort($hash);
if( (!defined($hash->{IODev}->{NAME})) || (!defined($hash->{IODev})) ){
if( (!defined($hash->{IODev}->{NAME})) || (!defined($hash->{IODev})) ){
return "OWSWITCH: Warning, no 1-Wire I/O device found for $name.";
}
#if( $hash->{IODev}->{PRESENT} != 1 ){
# return "OWSWITCH: Warning, 1-Wire I/O device ".$hash->{IODev}->{NAME}." not present for $name.";
#}
$modules{OWCOUNT}{defptr}{$id} = $hash;
#--
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWCOUNT: Device $name defined.";
#-- Initialization reading according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- Start timer for initialization in a few seconds
InternalTimer(time()+5, "OWCOUNT_InitializeDevice", $hash, 0);
#-- Start timer for updates
InternalTimer(time()+5+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0);
InternalTimer(time()+10, "OWCOUNT_GetValues", $hash, 0);
return undef;
}
########################################################################################
#
# OWCOUNT_ChannelNames - find the real channel names
#
# Parameter hash = hash of device addressed
#
########################################################################################
sub OWCOUNT_ChannelNames($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL};
my ($cname,@cnama,$unit,@unarr,$runit,$period);
for (my $i=0;$i<int(@owg_fixed);$i++){
#-- name
$cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|event";
@cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWCOUNT: Incomplete channel name specification $cname. Better use $cname|<type of data>"
if( $state eq "defined");
push(@cnama,"unknown");
}
#-- unit
$unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "counts|cts";
@unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWCOUNT: Incomplete channel unit specification $unit. Better use $unit|<abbreviation>"
if( $state eq "defined");
push(@unarr,"");
}
#-- put into readings
$owg_channel[$i]=$cnama[0];
$hash->{READINGS}{$owg_channel[$i]}{TYPE} = $cnama[1];
$hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unarr[0];
$hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unarr[1];
$period = defined($attr{$name}{$owg_fixed[$i]."Period"}) ? $attr{$name}{$owg_fixed[$i]."Period"} : "hour";
#-- put into readings
$hash->{READINGS}{$owg_channel[$i]}{PERIOD} = $period;
#-- rate
$cname = defined($attr{$name}{$owg_fixed[$i]."Rate"}) ? $attr{$name}{$owg_fixed[$i]."Rate"} : $cnama[0]."_rate|".$cnama[1]."_rate";
@cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWCOUNT: Incomplete rate name specification $cname. Better use $cname|<type of data>"
if( $state eq "defined");
push(@cnama,"unknown");
}
#-- rate unit
my $runit = "";
if( $period eq "hour" ){
$runit = "/h";
}elsif( $period eq "minute" ){
$runit = "/min";
} else {
$runit = "/s";
}
#-- put into readings
$owg_rate[$i]=$cnama[0];
$hash->{READINGS}{$owg_rate[$i]}{TYPE} = $cnama[1];
$hash->{READINGS}{$owg_rate[$i]}{UNIT} = $unarr[0].$runit;
$hash->{READINGS}{$owg_rate[$i]}{UNITABBR} = $unarr[1].$runit;
#-- some special cases
# Energy/Power
$hash->{READINGS}{$owg_rate[$i]}{UNIT} = "kW"
if ($unarr[0].$runit eq "kWh/h" );
$hash->{READINGS}{$owg_rate[$i]}{UNITABBR} = "kW"
if ($unarr[1].$runit eq "kWh/h" );
}
}
########################################################################################
#
# OWCOUNT_InitializeDevice - delayed setting of initial readings and channel names
@ -257,79 +328,15 @@ sub OWCOUNT_InitializeDevice($) {
my $name = $hash->{NAME};
$hash->{PRESENT} = 0;
#-- Set channel names, channel units and alarm values
#-- initial values
for( my $i=0;$i<int(@owg_fixed);$i++) {
#-- initial readings
$owg_val[$i] = "";
$owg_midnight[$i] = 0.0;
#-- name
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|event";
my @cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWCOUNT: Incomplete channel name specification $cname. Better use $cname|<type of data>";
push(@cnama,"unknown");
}
#-- unit
my $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "counts|cts";
my @unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWCOUNT: Incomplete channel unit specification $unit. Better use <long unit desc>|$unit";
push(@unarr,"");
}
#-- rate unit
my $period = defined($attr{$name}{$owg_fixed[$i]."Period"}) ? $attr{$name}{$owg_fixed[$i]."Period"} : "hour";
#-- offset and scale factor
my $offset = defined($attr{$name}{$owg_fixed[$i]."Offset"}) ? $attr{$name}{$owg_fixed[$i]."Offset"} : 0;
my $factor = defined($attr{$name}{$owg_fixed[$i]."Factor"}) ? $attr{$name}{$owg_fixed[$i]."Factor"} : 1;
#-- put into readings
$owg_channel[$i] = $cnama[0];
$hash->{READINGS}{"$owg_channel[$i]"}{TYPE} = $cnama[1];
$hash->{READINGS}{"$owg_channel[$i]"}{UNIT} = $unarr[0];
$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR} = $unarr[1];
$hash->{READINGS}{"$owg_channel[$i]"}{PERIOD} = $period;
$hash->{READINGS}{"$owg_channel[$i]"}{OFFSET} = $offset;
$hash->{READINGS}{"$owg_channel[$i]"}{FACTOR} = $factor;
$owg_rate[$i] = $cnama[0]."_rate";
my $runit = "";
if( $period eq "hour" ){
$runit = "/h";
}elsif( $period eq "minute" ){
$runit = "/min";
} else {
$runit = "/s";
}
$hash->{READINGS}{"$owg_rate[$i]"}{TYPE} = $cnama[1]."_rate";
$hash->{READINGS}{"$owg_rate[$i]"}{UNIT} = $unarr[0].$runit;
$hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR} = $unarr[1].$runit;
#-- some special cases
# Energy/Power
$hash->{READINGS}{"$owg_rate[$i]"}{UNIT} = "kW"
if ($unarr[0].$runit eq "kWh/h" );
$hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR} = "kW"
if ($unarr[1].$runit eq "kWh/h" );
$owg_midnight[$i] = "";
}
#-- set status according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- OWX interface
if( !defined($interface) ){
return "OWCOUNT: Interface missing";
} elsif( $interface eq "OWX" ){
#-- OWFS interface
#}elsif( $interface eq "OWFS" ){
# $ret = OWFSAD_GetPage($hash,"reading");
#-- Unknown interface
}else{
return "OWCOUNT: InitializeDevice with wrong IODev type $interface";
}
#-- Initialize all the display stuff
OWCOUNT_FormatValues($hash);
return undef;
}
########################################################################################
@ -344,70 +351,93 @@ sub OWCOUNT_FormatValues($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my ($offset,$factor,$period,$unit,$runit,$midnight,$vval,$vrate);
my ($offset,$factor,$period,$unit,$runit,$vval,$vrate);
my ($svalue,$dvalue,$mvalue) = ("","","");
my $galarm = 0;
my $tn = TimeNow();
my ($sec, $min, $hour, $day, $month, $year, $wday,$yday,$isdst) = localtime(time);
my ($seco,$mino,$houro,$dayo,$montho,$yearo,$dayrest);
my ($dt,$dv,$dval,$delt,$delf);
my ($daily, $dt,$dval,$dval2,$deltim,$delt,$delf);
my $daybreak = 0;
my $monthbreak = 0;
my $present = $hash->{PRESENT};
#-- no change in any value if invalid reading
#for (my $i=0;$i<int(@owg_fixed);$i++){
# return if( $owg_val[$i] eq "");
#}
#-- obtain channel names
OWCOUNT_ChannelNames($hash);
#-- check if device needs to be initialized
OWCOUNT_InitializeDevice($hash)
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
#-- Check, whether we have a new day at the next reading
$deltim = $hour*60.0+$min+$sec/60.0 - (1440 - $hash->{INTERVAL}/60.0);
if( $deltim>=0 ){
$daybreak = 1;
$monthbreak = 0;
#-- Timer data from tomorrow
my ($secn,$minn,$hourn,$dayn,$monthn,$yearn,$wdayn,$ydayn,$isdstn) = localtime(time() + $hash->{INTERVAL} + 3600);
#-- Check, whether we have a new month
if( $dayn == 1 ){
$monthbreak = 1;
}
}
#-- put into READINGS
readingsBeginUpdate($hash);
#-- formats for output
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];
my @cnama = split(/\|/,$cname);
$owg_channel[$i]= $cnama[0];
$owg_rate[$i] = $cnama[0]."_rate";
#-- mode normal or daily
$daily = 0;
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){
$daily = 1;
}
}
$offset = $hash->{READINGS}{"$owg_channel[$i]"}{OFFSET};
$factor = $hash->{READINGS}{"$owg_channel[$i]"}{FACTOR};
$unit = $hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR};
$period = $hash->{READINGS}{"$owg_channel[$i]"}{PERIOD};
$runit = $hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR};
#-- offset and scale factor
$offset = defined($attr{$name}{$owg_fixed[$i]."Offset"}) ? $attr{$name}{$owg_fixed[$i]."Offset"} : 0;
$factor = defined($attr{$name}{$owg_fixed[$i]."Factor"}) ? $attr{$name}{$owg_fixed[$i]."Factor"} : 1;
#-- put into READINGS
$hash->{READINGS}{$owg_channel[$i]}{OFFSET} = $offset;
$hash->{READINGS}{$owg_channel[$i]}{FACTOR} = $factor;
$unit = $hash->{READINGS}{$owg_channel[$i]}{UNITABBR};
$period = $hash->{READINGS}{$owg_channel[$i]}{PERIOD};
$runit = $hash->{READINGS}{$owg_rate[$i]}{UNITABBR};
#-- skip some things if undefined
if( $owg_val[$i] eq ""){
$svalue .= $owg_channel[$i].": ???";
}else{
#-- only if attribute value mode=daily, take the midnight value from memory
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){
$midnight = $owg_midnight[$i];
#-- parse float from midnight
$midnight =~ /([\d\.]+)/;
$midnight = 0.0 if(!(defined($midnight)));
} else {
$midnight = 0.0;
}
} else {
$midnight = 0.0;
}
#-- correct values for proper offset, factor
# careful: midnight value has not been corrected so far !
#-- 1 decimal
if( $factor == 1.0 ){
$vval = int(($owg_val[$i] + $offset - $midnight)*10)/10;
#-- 3 decimals
if( $daily == 1){
$vval = int( (($owg_val[$i] + $offset)*$factor - $owg_midnight[$i])*100)/100;
} else {
$vval = int((($owg_val[$i] + $offset)*$factor - $midnight)*1000)/1000;
$vval = int( ($owg_val[$i] + $offset)*$factor*100)/100;
}
#-- get the old values
my $oldval = $hash->{READINGS}{"$owg_channel[$i]"}{VAL};
my $oldtim = $hash->{READINGS}{"$owg_channel[$i]"}{TIME};
#-- rate calculation: get the old values
my $oldval = $hash->{READINGS}{$owg_channel[$i]}{VAL};
my $oldtim = $hash->{READINGS}{$owg_channel[$i]}{TIME};
$oldtim = "" if(!defined($oldtim));
#-- safeguard against the case where no previous measurement
if( length($oldtim) > 0 ){
#-- correct counter wraparound since last reading
if( $vval < $oldval) {
$oldval -= 65536*(65536*$factor);
}
#-- previous measurement time
($yearo,$montho,$dayrest) = split(/-/,$oldtim);
$dayo = substr($dayrest,0,2);
@ -416,38 +446,7 @@ sub OWCOUNT_FormatValues($) {
#-- time dfifference to previous measurement and to midnight
$delt = ($hour-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco);
$delf = $hour *3600 + $min *60 + $sec - 86400;
if( ($delf+$hash->{INTERVAL}) >= 0 ){
$daybreak = 1;
#-- Timer data from tomorrow
my ($secn,$minn,$hourn,$dayn,$monthn,$yearn,$wdayn,$ydayn,$isdstn) = localtime(time() + 24*60*60);
#-- Check, whether we have a new month
if( (($delf+$hash->{INTERVAL}) > 0) && ($dayn == 1) ){
$monthbreak =1;
}
}
#-- correct $vval for wraparound of 32 bit counter
if( ($vval < $oldval) && ($daybreak==0) && ($present==1) ){
Log 1,"OWCOUNT TODO: Counter wraparound";
}
if( $daybreak==1 ){
#-- linear extrapolation
$dt = -$delf/$delt;
$dv = ($vval-$oldval)*$dt;
$dval = $vval+$dv;
#-- in any mode store the interpolated value in the midnight store
OWXCOUNT_SetPage($hash,14+$i,sprintf("%f",$dval));
#-- string buildup for monthly logging
$dvalue .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dval,$unit);
if( $day<$dayo ){
$monthbreak = 1;
Log 1, "OWCOUNT: Change of month";
#-- string buildup for yearly logging
$mvalue .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dval,$unit);
}
}
#-- rate
if( ($delt > 0.0) && $present ){
$vrate = ($vval-$oldval)/$delt;
@ -460,42 +459,59 @@ sub OWCOUNT_FormatValues($) {
}elsif( $period eq "minute" ){
$vrate*=60;
}
$vrate = int($vrate * 1000)/1000;
if( !defined($runit) ){
Log 1,"OWCOUNT: Error in rate unit definition. i=$i, owg_rate[i]=".$owg_rate[$i];
$runit = "ERR";
}
$vrate = int($vrate * 100)/100;
#--midnight extrapolation only possible if previous measurement
if( $daybreak==1 ){
#-- linear extrapolation
$dt = -$delf/$delt;
$dval = int(($vval+($vval-$oldval)*$dt)*100)/100;
if( $daily == 1 ){
$dval2 = $dval+$owg_midnight[$i];
} else {
$dval2 = $dval;
}
#-- in any mode store the interpolated value in the midnight store
OWXCOUNT_SetPage($hash,14+$i,sprintf("%f",$dval2));
#-- string buildup for monthly and yearly logging
$dvalue .= sprintf( " %s: %5.1f %s", $owg_channel[$i], $dval,$unit);
$mvalue .= sprintf( " %s: %%5.1f %s", $owg_channel[$i], $unit);
} #-- end daybreak
#-- string buildup for return value and STATE
#-- 1 decimal
if( $factor == 1.0 ){
$svalue .= sprintf( "%s: %5.1f %s / %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit);
$svalue .= sprintf( "%s: %5.1f %s %s: %5.2f %s", $owg_channel[$i], $vval,$unit,$owg_rate[$i],$vrate,$runit);
#-- 3 decimals
} else {
$svalue .= sprintf( "%s: %5.3f %s / %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit);
$svalue .= sprintf( "%s: %5.3f %s %s: %5.2f %s", $owg_channel[$i], $vval,$unit,$owg_rate[$i],$vrate,$runit);
}
}
readingsBulkUpdate($hash,"$owg_channel[$i]",$vval);
readingsBulkUpdate($hash,"$owg_rate[$i]",$vrate);
readingsBulkUpdate($hash,$owg_channel[$i],$vval);
readingsBulkUpdate($hash,$owg_rate[$i],$vrate);
}
#-- insert space
if( $i<int(@owg_fixed)-1 ){
$svalue .= " ";
$dvalue .= " ";
}
}
}#-- end channel loop
#-- Daily/monthly cumulated value
#-- daybreak postprocessing
if( $daybreak == 1 ){
#-- TODO: recall the monthly summary
#--my @month = OWCOUNT_GetMonth($hash);
#my $total = $month[0]+$vval;
my $total;
#-- daily/monthly accumulated value
my @monthv = OWCOUNT_GetMonth($hash);
my $total0 = @monthv[0]->[1];
my $total1 = @monthv[1]->[1];
$dvalue = sprintf("D%02d ",$day).$dvalue;
readingsBulkUpdate($hash,"day",$dvalue);
if( $monthbreak == 1){
$mvalue = sprintf("M_%02d SOME VALUE",$month);
$mvalue = sprintf("M%02d ",$month+1).$mvalue;
$mvalue = sprintf($mvalue,$total0,$total1);
readingsBulkUpdate($hash,"month",$mvalue);
Log 1,$name." has monthbreak ".$mvalue;
}
}
@ -523,8 +539,7 @@ sub OWCOUNT_Get($@) {
my $value = undef;
my $ret = "";
my $page;
my $channo = undef;
my $channel;
my ($unit,$daily);
#-- check syntax
return "OWCOUNT: Get argument is missing @a"
@ -555,9 +570,44 @@ sub OWCOUNT_Get($@) {
return "$name.interval => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
}
#-- reset presence
#-- TODO: THIS IS TOO STRONG !!!
#$hash->{PRESENT} = 0;
$hash->{PRESENT} = 0;
#-- get channel names
OWCOUNT_ChannelNames($hash);
#-- get month
if($a[1] eq "month") {
$value="$name.month =>\n";
my @month2 = OWCOUNT_GetMonth($hash);
#-- error case
if( int(@month2) == 1 ){
return $month2[0];
}
#-- 3 entries for each day
for(my $i=0;$i<int(@month2);$i++){
$unit = $hash->{READINGS}{$owg_channel[$i]}{UNITABBR};
#-- mode = daily ?
$daily = 0;
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){
$daily = 1;
}
}
if( $daily==1){
$value .= $owg_channel[$i]." monthly sum ".$month2[$i]->[1]." ".$unit.
" (average ".$month2[$i]->[2]." ".$unit."/d)\n";
}else{
$value .= $owg_channel[$i]." last midnight ".$month2[$i]->[1]." ".$unit."\n";
}
}
return $value;
}
#-- get memory page/counter according to interface type
my $interface= $hash->{IODev}->{TYPE};
@ -565,14 +615,14 @@ sub OWCOUNT_Get($@) {
#-- check syntax for getting memory page 0..13 or midnight A/B
if( ($reading eq "memory") || ($reading eq "midnight") ){
if( $reading eq "memory" ){
return "OWCOUNT: set needs parameter when reading memory: <page>"
return "OWCOUNT: get needs parameter when reading memory: <page>"
if( int(@a)<2 );
$page=int($a[2]);
if( ($page<0) || ($page>13) ){
return "OWXCOUNT: Wrong memory page requested";
}
}else{
return "OWCOUNT: set needs parameter when reading midnight: <channel>"
return "OWCOUNT: get needs parameter when reading midnight: <channel>"
if( int(@a)<2 );
#-- find out which channel we have
if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){
@ -644,8 +694,7 @@ sub OWCOUNT_Get($@) {
return "OWCOUNT: Could not get values from device $name";
}
$hash->{PRESENT} = 1;
return "OWCOUNT: $name.$reading => ".OWCOUNT_FormatValues($hash);
return "OWCOUNT: $name.$reading => ".OWCOUNT_FormatValues($hash);
}
########################################################################################
@ -666,54 +715,67 @@ sub OWCOUNT_GetMonth($) {
my $val;
my @month = ();
my @month2 = ();
my @channel;
my ($total,$total2,$deltim,$av);
my @mchannel;
my ($total,$total2,$daily,$deltim,$av);
#-- Check current logfile
my $ln = $attr{$name}{"LogM"};
if( !(defined($ln))){
Log 1,"OWCOUNT_GetMonth: Attribute LogM is missing";
return undef;
} else {
my $lf = $defs{$ln}{currentlogfile};
my $ret = open(OWXFILE, "< $lf" );
if( $ret) {
while( <OWXFILE> ){
#-- line looks as
# 2013-02-09_23:59:31 <name> day D_09 <aname>: 180.0 cts <bname>: 180.0 cts etc.
my $line = $_;
chomp($line);
if ( $line =~ m/$regexp/i){
my @linarr = split(' ',$line);
my $day = $linarr[3];
$day =~ s/D_0+//;
@channel = ();
for (my $i=0;$i<int(@owg_fixed);$i++){
$val = $linarr[5+3*$i];
push(@channel,$val);
}
push(@month,[@channel]);
}
#-- get channel names
OWCOUNT_ChannelNames($hash);
my $lf = $defs{$ln}{currentlogfile};
my $ret = open(OWXFILE, "< $lf" );
if( $ret) {
while( <OWXFILE> ){
#-- line looks as
# 2013-02-09_23:59:31 <name> day: D09 <aname>: 180.0 <unit> <bname>: 180.0 <unit> etc.
my $line = $_;
chomp($line);
if ( $line =~ m/$regexp/i){
my @linarr = split(' ',$line);
my $day = $linarr[3];
$day =~ s/D_0+//;
@mchannel = ();
for (my $i=0;$i<int(@owg_fixed);$i++){
$val = $linarr[5+3*$i];
push(@mchannel,$val);
}
push(@month,[@mchannel]);
}
}
}
#-- sum and average
for (my $i=0;$i<int(@owg_fixed);$i++){
$total = 0.0;
#-- sum and average
for (my $i=0;$i<int(@owg_fixed);$i++){
$total = 0.0;
#-- summing only if mode daily
$daily = 0;
if( defined($attr{$name}{$owg_fixed[$i]."Mode"} )){
if( $attr{$name}{$owg_fixed[$i]."Mode"} eq "daily"){
$daily = 1;
}
}
if( $daily==1){
for (my $j=0;$j<int(@month);$j++){
$total += $month[$j][$i];
}
#-- add data from current day
$total = int($total*100)/100;
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime(time);
my $deltim = ($hour+$min/60.0 + $sec/3600.0)/24.0;
my $total2 = int(100*($total+$hash->{READINGS}{"$owg_channel[$i]"}{VAL}))/100;
my $av = int(100*$total2/(int(@month)+$deltim))/100;
push(@month2,[($total,$total2,$av)]);
}
return @month2;
#-- add data from current day also for non-summed mode
$total = int($total*100)/100;
$total2 = int(100*($total+$hash->{READINGS}{$owg_channel[$i]}{VAL}))/100;
#-- number of days so far, including the present day
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime(time);
my $deltim = int(@month)+($hour+$min/60.0 + $sec/3600.0)/24.0;
my $av = int(100*$total2/$deltim)/100;
#-- output format
push(@month2,[($total,$total2,$av)]);
}
return @month2;
}
#######################################################################################
@ -731,8 +793,6 @@ sub OWCOUNT_GetValues($) {
my $model = $hash->{OW_MODEL};
my $value = "";
my $ret = "";
my $offset;
my $factor;
#-- define warnings
my $warn = "none";
@ -742,7 +802,7 @@ sub OWCOUNT_GetValues($) {
RemoveInternalTimer($hash);
InternalTimer(time()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 1);
#-- reset presence - maybe this is too strong
#-- reset presence -
$hash->{PRESENT} = 0;
#-- Get readings according to interface type
@ -802,11 +862,10 @@ sub OWCOUNT_Set($@) {
my $ret = undef;
my $page;
my $data;
my $channo = undef;
my $channel;
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
my ($cname,@cnama,@channel);
#-- set new timer interval
if($key eq "interval") {
# check value
@ -819,6 +878,9 @@ sub OWCOUNT_Set($@) {
return undef;
}
#-- get channel names
OWCOUNT_ChannelNames($hash);
#-- set memory page/counter according to interface type
my $interface= $hash->{IODev}->{TYPE};
@ -922,7 +984,7 @@ sub OWFSCOUNT_GetPage($$) {
if( ($page<0) || ($page>15) ){
return "OWXCOUNT: Wrong memory page requested";
}
#-- get values - or shoud we rather get the uncached ones ?
#-- get values - or shoud we rather get the uncached ones ?
if( $page == 14) {
$vval = OWServer_Read($master,"/$owx_add/counters.A");
$owg_str = OWServer_Read($master,"/$owx_add/pages/page.14");
@ -934,6 +996,10 @@ sub OWFSCOUNT_GetPage($$) {
if( ($vval eq "") || ($owg_str eq "") );
$owg_val[0] = $vval;
#-- parse float from midnight
$owg_str =~ /([\d\.]+)/;
$owg_str = int($owg_str*100)/100;
$owg_str = 0.0 if(!(defined($owg_str)));
$owg_midnight[0] = $owg_str;
}elsif( $page == 15) {
@ -947,6 +1013,10 @@ sub OWFSCOUNT_GetPage($$) {
if( ($vval eq "") || ($owg_str eq "") );
$owg_val[1] = $vval;
#-- parse float from midnight
$owg_str =~ /([\d\.]+)/;
$owg_str = int($owg_str*100)/100;
$owg_str = 0.0 if(!(defined($owg_str)));
$owg_midnight[1] = $owg_str;
}else {
$owg_str = OWServer_Read($master,"/$owx_add/pages/page.".$page);
@ -1066,14 +1136,21 @@ sub OWXCOUNT_GetPage($$) {
return "OWXCOUNT: Device $owx_dev returns invalid data";
}
#-- first ignore memory and only use counter (Fehler gefunden von jamesgo)
my $value = (ord($data[3])<<24) + (ord($data[2])<<16) +(ord($data[1])<<8) + ord($data[0]);
if( $page == 14) {
$owg_val[0] = $value;
#-- parse float from midnight
$owg_str =~ /([\d\.]+)/;
$owg_str = int($owg_str*100)/100;
$owg_str = 0.0 if(!(defined($owg_str)));
$owg_midnight[0] = $owg_str;
}elsif( $page == 15) {
$owg_val[1] = $value;
#-- parse float from midnight
$owg_str =~ /([\d\.]+)/;
$owg_str = int($owg_str*100)/100;
$owg_str = 0.0 if(!(defined($owg_str)));
$owg_midnight[1] = $owg_str;
}
@ -1158,13 +1235,17 @@ sub OWXCOUNT_SetPage($$$) {
(prerequisite: Add this module's name to the list of clients in OWServer).
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/><p/>
<br /><h4>Example</h4><br />
<code>define OWX_C OWCOUNT DS2423 CE780F000000 300</code>
<code>define OWC OWCOUNT 1D.CE780F000000 60</code>
<br />
<code>attr OWX_C AName Water|volume</code>
<code>attr OWC AName Energie|energy</code>
<br />
<code>attr OWX_C AUnit liters|l</code>
<code>attr OWC AUnit kWh|kWh</code>
<br />
<code>attr OWX_CAMode daily</code>
<code>attr OWC APeriod hour</code>
<br />
<code>attr OWC ARate Leistung|power</code>
<br />
<code>attr OWX_AMode daily</code>
<br />
<br />
<a name="OWCOUNTdefine"></a>
@ -1240,10 +1321,10 @@ sub OWXCOUNT_SetPage($$$) {
<a name="OWCOUNTattr"></a>
<h4>Attributes</h4>
<ul>
<li><a name="owcount_logm"><code>attr &lt;name&gt; LogM
<li><a name="owcount_logm"><code>attr &lt;name&gt; LogM
&lt;string&gt;|</code></a>
<br />device name (not file name) of monthly log file.</li>
</ul>
</ul>
<p>For each of the following attributes, the channel identification A,B may be used.</p>
<ul>
<li><a name="owcount_cname"><code>attr &lt;name&gt; &lt;channel&gt;Name
@ -1252,6 +1333,9 @@ sub OWXCOUNT_SetPage($$$) {
<li><a name="owcount_cunit"><code>attr &lt;name&gt; &lt;channel&gt;Unit
&lt;string&gt;|&lt;string&gt;</code></a>
<br />unit of measurement for this channel | its abbreviation. </li>
<li><a name="owcount_crate"><code>attr &lt;name&gt; &lt;channel&gt;Rate
&lt;string&gt;|&lt;string&gt;</code></a>
<br />name for the channel rate | a type description for the measured value. </li>
<li><a name="owcount_coffset"><code>attr &lt;name&gt; &lt;channel&gt;Offset
&lt;float&gt;</code></a>
<br />offset added to the reading in this channel. </li>

View File

@ -24,6 +24,7 @@
#
# get <name> id => FAM_ID.ROM_ID.CRC
# get <name> present => 1 if device present, 0 if not
# get <name> version => OWX version number
#
#
########################################################################################
@ -51,11 +52,13 @@ use strict;
use warnings;
sub Log($$);
my $owx_version="3.21";
#-- declare variables
my %gets = (
"present" => "",
"interval" => "",
"id" => ""
"id" => "",
"version" => ""
);
my %sets = (
"interval" => ""
@ -224,7 +227,7 @@ sub OWID_Get($@) {
return "$name.id => $value";
}
#-- get interval
#-- get interval
if($a[1] eq "interval") {
$value = $hash->{INTERVAL};
return "$name.interval => $value";
@ -243,6 +246,12 @@ sub OWID_Get($@) {
}
return "$name.present => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
}
}

View File

@ -23,6 +23,7 @@
# get <name> counter => four values (16 Bit) of the gpio counter
# get <name> version => firmware version of the LCD adapter
# get <name> memory <page> => get one of the internal memory pages 0..6
# get <name> version => OWX version number
#
# set <name> alert red|yellow|beep|none => set one of the alert states (gpio pins)
# set <name> icon <num> on|off|blink => set one of the icons 0..14
@ -61,6 +62,7 @@ use strict;
use warnings;
sub Log($$);
my $owx_version="3.21";
#-- controller may be HD44780 or KS0073
# these values have to be changed for different display
# geometries or memory maps
@ -77,7 +79,7 @@ my %gets = (
"memory" => "",
"gpio" => "",
"counter" => "",
"version" => "",
"version" => ""
#"register" => "",
#"data" => ""
);
@ -253,7 +255,7 @@ sub OWLCD_Get($@) {
#-- get version
if($a[1] eq "version") {
$value = OWXLCD_Get($hash,"version");
return "$name.version => $value";
return "$name.version => $owx_version (LCD firmware $value)";
}
#-- get EEPROM content

View File

@ -28,6 +28,7 @@
# get <name> temperature => temperature measurement
# get <name> VDD => supply voltage measurement
# get <name> V|raw => raw external voltage measurement
# get <name> version => OWX version number
#
# set <name> interval => set period for measurement
#
@ -68,6 +69,7 @@ use strict;
use warnings;
sub Log($$);
my $owx_version="3.21";
#-- temperature and voltage globals - always the raw values from the device
my $owg_temp;
my $owg_volt;
@ -81,8 +83,9 @@ my %gets = (
"reading" => "",
"temperature" => "",
"VDD" => "",
"V" => "",
"VAD" => "",
"raw" => "",
"version" => ""
);
my %sets = (
@ -210,80 +213,55 @@ sub OWMULTI_Define ($$) {
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWMULTI: Device $name defined.";
#-- Start timer for initialization in a few seconds
InternalTimer(time()+10, "OWMULTI_InitializeDevice", $hash, 0);
#-- Start timer for updates
InternalTimer(time()+10+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
InternalTimer(time()+10, "OWMULTI_GetValues", $hash, 0);
return undef;
}
########################################################################################
#
# OWMULTI_InitializeDevice - delayed setting of initial readings and channel names
# OWMULTI_ChannelNames - find the real channel names
#
# Parameter hash = hash of device addressed
#
########################################################################################
sub OWMULTI_InitializeDevice($) {
sub OWMULTI_ChannelNames($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my @args;
#-- unit attribute defined ?
$hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
$hash->{READINGS}{"temperature"}{TYPE} = "temperature";
#-- Initial readings
$owg_temp = "";
$owg_volt = "";
$owg_vdd = "";
my $state = $hash->{READINGS}{"state"}{VAL};
my ($cname,@cnama,$unit,@unarr);
my ($tunit,$toffset,$tfactor,$tabbr,$vfunc);
#-- Set channel name, channel unit for voltage channel
my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage";
my @cnama = split(/\|/,$cname);
$cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage";
@cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWMULTI: Incomplete channel name specification $cname. Better use $cname|<type of data>";
Log 1, "OWMULTI: Incomplete channel name specification $cname. Better use $cname|<type of data>"
if( $state eq "defined");
push(@cnama,"unknown");
}
#-- unit
my $unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "Volt|V";
my @unarr= split(/\|/,$unit);
$unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "Volt|V";
@unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWMULTI: Incomplete channel unit specification $unit. Better use $unit|<abbreviation>";
Log 1, "OWMULTI: Incomplete channel unit specification $unit. Better use $unit|<abbreviation>"
if( $state eq "defined");
push(@unarr,"");
}
#-- put into readings
$owg_channel = $cnama[0];
$hash->{READINGS}{"$owg_channel"}{TYPE} = $cnama[1];
$hash->{READINGS}{"$owg_channel"}{UNIT} = $unarr[0];
$hash->{READINGS}{"$owg_channel"}{UNITABBR} = $unarr[1];
$hash->{READINGS}{$owg_channel}{TYPE} = $cnama[1];
$hash->{READINGS}{$owg_channel}{UNIT} = $unarr[0];
$hash->{READINGS}{$owg_channel}{UNITABBR} = $unarr[1];
#-- Initialize all the display stuff
OWMULTI_FormatValues($hash);
}
########################################################################################
#
# OWMULTI_FormatValues - put together various format strings
#
# Parameter hash = hash of device addressed, fs = format string
#
########################################################################################
sub OWMULTI_FormatValues($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my ($tunit,$toffset,$tfactor,$tabbr,$tval,$vfunc,$vval);
my $svalue = "";
#-- attributes defined ?
#-- temperature scale
$hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius";
$tunit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT};
$toffset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ;
$tfactor = 1.0;
@ -301,21 +279,64 @@ sub OWMULTI_FormatValues($) {
$tabbr="?";
Log 1, "OWMULTI_FormatValues: unknown unit $tunit";
}
#-- these values are rather complex to obtain, therefore save them in the hash
$hash->{READINGS}{"temperature"}{TYPE} = "temperature";
$hash->{READINGS}{"temperature"}{UNIT} = $tunit;
$hash->{READINGS}{"temperature"}{UNITABBR} = $tabbr;
$hash->{tempf}{offset} = $toffset;
$hash->{tempf}{factor} = $tfactor;
}
########################################################################################
#
# OWMULTI_InitializeDevice - delayed setting of initial readings and channel names
#
# Parameter hash = hash of device addressed
#
########################################################################################
sub OWMULTI_InitializeDevice($) {
my ($hash) = @_;
my $name = $hash->{NAME};
#-- Initial readings
$owg_temp = "";
$owg_volt = "";
$owg_vdd = "";
}
########################################################################################
#
# OWMULTI_FormatValues - put together various format strings
#
# Parameter hash = hash of device addressed, fs = format string
#
########################################################################################
sub OWMULTI_FormatValues($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my ($toffset,$tfactor,$tval,$vfunc,$vval);
my $svalue = "";
#-- no change in any value if invalid reading
return if( $owg_temp eq "");
return if( ($owg_temp eq "") || ($owg_vdd == 0) );
#-- obtain channel names
OWMULTI_ChannelNames($hash);
#-- check if device needs to be initialized
OWMULTI_InitializeDevice($hash)
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
#-- correct values for proper offset, factor
$tval = ($owg_temp + $toffset)*$tfactor;
my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage";
my @cnama = split(/\|/,$cname);
$owg_channel=$cnama[0];
$toffset = $hash->{tempf}{offset};
$tfactor = $hash->{tempf}{factor};
$tval = ($owg_temp + $toffset)*$tfactor;
#-- attribute VFunction defined ?
$vfunc = defined($attr{$name}{"VFunction"}) ? $attr{$name}{"VFunction"} : "V";
@ -338,11 +359,11 @@ sub OWMULTI_FormatValues($) {
}
#-- string buildup for return value, STATE
$svalue .= sprintf( "%s: %5.2f %s (T: %5.2f %s)", $owg_channel, $vval,$hash->{READINGS}{"$owg_channel"}{UNITABBR},$tval,$tabbr);
$svalue .= sprintf( "%s: %5.2f %s (T: %5.2f %s)", $owg_channel, $vval,$hash->{READINGS}{$owg_channel}{UNITABBR},$tval,$hash->{READINGS}{"temperature"}{UNITABBR});
#-- put into READINGS
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"$owg_channel",$vval);
readingsBulkUpdate($hash,$owg_channel,$vval);
readingsBulkUpdate($hash,"VDD",$owg_vdd);
readingsBulkUpdate($hash,"temperature",$tval);
@ -407,6 +428,11 @@ sub OWMULTI_Get($@) {
return "$name.interval => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
}
#-- reset presence
$hash->{PRESENT} = 0;
@ -427,12 +453,16 @@ sub OWMULTI_Get($@) {
return "OWMULTI: Could not get values from device $name, reason $ret";
}
$hash->{PRESENT} = 1;
OWMULTI_FormatValues($hash);
#-- return the special reading
if ($reading eq "reading") {
return "OWMULTI: $name.reading => ".
$hash->{READINGS}{"$owg_channel"}{VAL};
return "OWMULTI: $name.reading => ".OWMULTI_FormatValues($hash);
}
#-- return the special reading
if ($reading eq "VAD") {
return "OWMULTI: $name.VAD => ".
$hash->{READINGS}{$owg_channel}{VAL};
}
if ($reading eq "temperature") {
return "OWMULTI: $name.temperature => ".
@ -442,7 +472,7 @@ sub OWMULTI_Get($@) {
return "OWMULTI: $name.VDD => ".
$hash->{READINGS}{"VDD"}{VAL};
}
if ( ($reading eq "V")|($reading eq "raw")) {
if ( $reading eq "raw") {
return "OWMULTI: $name.V => ".
$owg_volt;
}
@ -483,14 +513,12 @@ sub OWMULTI_GetValues($@) {
}elsif( $interface eq "OWServer" ){
$ret = OWFSMULTI_GetValues($hash);
}else{
Log 3, "OWMULTI: GetValues with wrong IODev type $interface";
return 1;
return "OWMULTI: GetValues with wrong IODev type $interface";
}
#-- process results
if( defined($ret) ){
Log 3, "OWMULTI: Could not get values from device $name, reason $ret";
return 1;
return "OWMULTI: Could not get values from device $name, reason $ret";
}
$hash->{PRESENT} = 1;
@ -825,10 +853,6 @@ sub OWXMULTI_GetValues($) {
$owg_volt = ($msb*256+ $lsb)/100;
return undef;
#} else {
# return "OWXMULTI: Unknown device family $hash->{OW_FAMILY}\n";
#}
}
#######################################################################################
@ -886,8 +910,8 @@ sub OWXMULTI_SetValues($@) {
<p>FHEM module to commmunicate with 1-Wire multi-sensors, currently the DS2438 smart battery
monitor<br /> <br />This 1-Wire module works with the OWX interface module or with the OWServer interface module
(prerequisite: Add this module's name to the list of clients in OWServer).
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br/></p>
<br /><h4>Example</h4>
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first.</p>
<h4>Example</h4>
<p>
<code>define OWX_M OWMULTI 7C5034010000 45</code>
<br />
@ -896,14 +920,13 @@ sub OWXMULTI_SetValues($@) {
<code>attr OWX_M VUnit percent|%</code>
<br />
<code>attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T)</code>
<br />
</p><br />
</p>
<a name="OWMULTIdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWMULTI [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWMULTI &lt;fam&gt;.&lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire multi-sensor<br /><br /></p>
<br /><br /> Define a 1-Wire multi-sensor</p>
<ul>
<li>
<code>[&lt;model&gt;]</code><br /> Defines the sensor model (and thus 1-Wire family
@ -925,7 +948,6 @@ sub OWXMULTI_SetValues($@) {
<code>&lt;interval&gt;</code>
<br />Measurement interval in seconds. The default is 300 seconds. </li>
</ul>
<br />
<a name="OWMULTIset"></a>
<h4>Set</h4>
<ul>
@ -933,7 +955,6 @@ sub OWXMULTI_SetValues($@) {
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Measurement
interval in seconds. The default is 300 seconds. </li>
</ul>
<br />
<a name="OWMULTIget"></a>
<h4>Get</h4>
<ul>
@ -948,7 +969,9 @@ sub OWXMULTI_SetValues($@) {
<code>get &lt;name&gt; interval</code></a><br />Returns measurement interval in
seconds. </li>
<li><a name="owmulti_reading">
<code>get &lt;name&gt; reading</code></a><br />Obtain the measurement value from
<code>get &lt;name&gt; reading</code></a><br />Obtain the measurement values </li>
<li><a name="owmulti_vad">
<code>get &lt;name&gt; VAD</code></a><br />Obtain the measurement value from
VFunction. </li>
<li><a name="owmulti_temperature">
<code>get &lt;name&gt; temperature</code></a><br />Obtain the temperature value. </li>
@ -958,7 +981,6 @@ sub OWXMULTI_SetValues($@) {
<code>get &lt;name&gt; V</code> or <code>get &lt;name&gt;
raw</code></a><br />Obtain the raw external voltage measurement. </li>
</ul>
<br />
<a name="OWMULTIattr"></a>
<h4>Attributes</h4>
<ul>

View File

@ -30,6 +30,7 @@
# state of 1 = OFF therefore corresponds to an output state of 1 = OFF, but a measured
# state of 0 = ON can also be due to an external shortening of the output.
# get <name> gpio => values for channels
# get <name> version => OWX version number
#
# set <name> interval => set period for measurement
# set <name> output <channel-name> on|off|on-for-timer <int>|on-for-timer <int>
@ -74,9 +75,11 @@ use strict;
use warnings;
sub Log($$);
#-- channel name - fixed is the first array, variable the second
my @owg_fixed = ("A","B","C","D","E","F","G","H");
my @owg_channel;
my $owx_version="3.21";
#-- fixed raw channel name, flexible channel name
my @owg_fixed = ("A","B","C","D","E","F","G","H");
my @owg_channel = ("A","B","C","D","E","F","G","H");
#-- channel values - always the raw input resp. output values from the device
my @owg_val;
my @owg_vax;
@ -86,7 +89,8 @@ my %gets = (
"present" => "",
"interval" => "",
"input" => "",
"gpio" => ""
"gpio" => "",
"version" => ""
);
my %sets = (
@ -133,7 +137,7 @@ sub OWSWITCH_Initialize ($) {
"stateS ".
$readingFnAttributes;
#-- correct list of attributes
#-- initial list of attributes
for( my $i=0;$i<8;$i++ ){
$attlist .= " ".$owg_fixed[$i]."Name";
$attlist .= " ".$owg_fixed[$i]."Unit";
@ -185,15 +189,12 @@ sub OWSWITCH_Define ($$) {
if(int(@a)>=4) { $interval = $a[3]; }
if( $fam eq "3A" ){
$model = "DS2413";
@owg_fixed = ("A","B");
CommandAttr (undef,"$name model DS2413");
}elsif( $fam eq "12" ){
$model = "DS2406";
@owg_fixed = ("A","B");
CommandAttr (undef,"$name model DS2406");
}elsif( $fam eq "29" ){
$model = "DS2408";
@owg_fixed = ("A","B","C","D","E","F","G","H");
CommandAttr (undef,"$name model DS2408");
}else{
return "OWSWITCH: Wrong 1-Wire device family $fam";
@ -205,15 +206,12 @@ sub OWSWITCH_Define ($$) {
if(int(@a)>=5) { $interval = $a[4]; }
if( $model eq "DS2413" ){
$fam = "3A";
@owg_fixed = ("A","B");
CommandAttr (undef,"$name model DS2413");
}elsif( $model eq "DS2406" ){
$fam = "12";
@owg_fixed = ("A","B");
CommandAttr (undef,"$name model DS2406");
}elsif( $model eq "DS2408" ){
$fam = "29";
@owg_fixed = ("A","B","C","D","E","F","G","H");
CommandAttr (undef,"$name model DS2408");
}else{
return "OWSWITCH: Wrong 1-Wire device model $model";
@ -221,7 +219,7 @@ sub OWSWITCH_Define ($$) {
} else {
return "OWSWITCH: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value";
}
#-- determine CRC Code - only if this is a direct interface
$crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00";
@ -244,19 +242,57 @@ sub OWSWITCH_Define ($$) {
#--
readingsSingleUpdate($hash,"state","defined",1);
Log 3, "OWSWITCH: Device $name defined.";
#-- Initialization reading according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- Start timer for initialization in a few seconds
InternalTimer(time()+10, "OWSWITCH_InitializeDevice", $hash, 0);
#-- Start timer for updates
InternalTimer(time()+10+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
InternalTimer(time()+10, "OWSWITCH_GetValues", $hash, 0);
return undef;
}
########################################################################################
#
# OWSWITCH_ChannelNames - find the real channel names
#
# Parameter hash = hash of device addressed
#
########################################################################################
sub OWSWITCH_ChannelNames($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $state = $hash->{READINGS}{"state"}{VAL};
my ($cname,@cnama,$unit,@unarr);
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
#-- name
$cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|onoff";
@cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWSWITCH: Incomplete channel name specification $cname. Better use $cname|<type of data>"
if( $state eq "defined");
push(@cnama,"unknown");
}
#-- put into readings
$owg_channel[$i] = $cnama[0];
$hash->{READINGS}{$owg_channel[$i]}{TYPE} = $cnama[1];
#-- unit
my $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "ON|OFF";
my @unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWSWITCH: Wrong channel unit specification $unit, replaced by ON|OFF"
if( $state eq "defined");
$unit="ON|OFF";
}
#-- put into readings
$hash->{READINGS}{$owg_channel[$i]}{UNIT} = $unit;
$hash->{READINGS}{$owg_channel[$i]}{UNITABBR} = $unit;
}
}
########################################################################################
#
# OWSWITCH_InitializeDevice - delayed setting of initial readings and channel names
@ -266,55 +302,16 @@ sub OWSWITCH_Define ($$) {
########################################################################################
sub OWSWITCH_InitializeDevice($) {
my ($hash) = @_;
my $name = $hash->{NAME};
#-- Set channel names, channel units
#-- Initial readings
for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) {
#-- Initial readings ERR
$owg_val[$i] = 1;
$owg_vax[$i] = 0;
#-- name
my $cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i]."|onoff";
my @cnama = split(/\|/,$cname);
if( int(@cnama)!=2){
Log 1, "OWSWITCH: Incomplete channel name specification $cname. Better use $cname|<type of data>";
push(@cnama,"unknown");
}
#-- unit
my $unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "ON|OFF";
my @unarr= split(/\|/,$unit);
if( int(@unarr)!=2 ){
Log 1, "OWSWITCH: Wrong channel unit specification $unit, replaced by ON|OFF";
$unit="ON|OFF";
}
#-- put into readings
$owg_channel[$i] = $cnama[0];
$hash->{READINGS}{"$owg_channel[$i]"}{TYPE} = $cnama[1];
$hash->{READINGS}{"$owg_channel[$i]"}{UNIT} = $unit;
$hash->{READINGS}{"$owg_channel[$i]"}{UNITABBR} = $unit;
}
#-- set status according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- OWX interface
if( !defined($interface) ){
return "OWSWITCH: Interface missing";
} elsif( $interface eq "OWX" ){
#-- OWFS interface
#}elsif( $interface eq "OWFS" ){
# $ret = OWFSAD_GetPage($hash,"reading");
#-- Unknown interface
}else{
return "OWSWITCH: InitializeDevice with wrong IODev type $interface";
}
#-- Initialize all the display stuff
OWSWITCH_FormatValues($hash);
}
########################################################################################
@ -329,20 +326,24 @@ sub OWSWITCH_FormatValues($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my ($offset,$factor,$vval,$vvax,$vstr,$cname,$unit,@unarr,@cnama,$valid);
my ($offset,$factor,$vval,$vvax,$vstr,@unarr,$valid);
my $svalue = "";
#-- external shortening signature
my $sname = defined($attr{$name}{"stateS"}) ? $attr{$name}{"stateS"} : "&#x2607;";
#-- obtain channel names
OWSWITCH_ChannelNames($hash);
#-- check if device needs to be initialized
OWSWITCH_InitializeDevice($hash)
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
#-- put into READINGS
readingsBeginUpdate($hash);
#-- formats for output
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
$cname = defined($attr{$name}{$owg_fixed[$i]."Name"}) ? $attr{$name}{$owg_fixed[$i]."Name"} : $owg_fixed[$i];
@cnama = split(/\|/,$cname);
$owg_channel[$i]=$cnama[0];
#-- input state is 0 = ON or 1 = OFF
$vval = $owg_val[$i];
@ -350,8 +351,7 @@ sub OWSWITCH_FormatValues($) {
$vvax = $owg_vax[$i];
#-- string buildup for return value and STATE
$unit = defined($attr{$name}{$owg_fixed[$i]."Unit"}) ? $attr{$name}{$owg_fixed[$i]."Unit"} : "ON|OFF";
@unarr= split(/\|/,$unit);
@unarr= split(/\|/,$hash->{READINGS}{$owg_channel[$i]}{UNIT});
$vstr = $unarr[$vval];
#-- put into readings only when valid
@ -359,7 +359,7 @@ sub OWSWITCH_FormatValues($) {
$vstr ="???"
}else{
$vstr.= $sname if( ($vval == 0) && ($vvax == 1) );
readingsBulkUpdate($hash,"$owg_channel[$i]",$vstr);
readingsBulkUpdate($hash,$owg_channel[$i],$vstr);
}
$svalue .= sprintf( "%s: %s" , $owg_channel[$i], $vstr);
@ -367,7 +367,6 @@ sub OWSWITCH_FormatValues($) {
if( $i<($cnumber{$attr{$name}{"model"}}-1) ){
$svalue .= " ";
}
}
#-- STATE
@ -393,9 +392,7 @@ sub OWSWITCH_Get($@) {
my $model = $hash->{OW_MODEL};
my ($value,$value2,$value3) = (undef,undef,undef);
my $ret = "";
my $offset;
my $factor;
my $page;
my ($offset,$factor,$page,$cname,@cnama,@channel);
#-- check syntax
return "OWSWITCH: Get argument is missing @a"
@ -426,14 +423,21 @@ sub OWSWITCH_Get($@) {
return "$name.interval => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
}
#-- reset presence
$hash->{PRESENT} = 0;
#-- get channel names
OWSWITCH_ChannelNames($hash);
#-- get values according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- get single state
# TODO: WAS passiert, wenn channel name noch falsch ist ?
if( $reading eq "input" ){
return "OWSWITCH: get needs parameter when reading input: <channel>"
if( int(@a)<2 );
@ -451,17 +455,16 @@ sub OWSWITCH_Get($@) {
if( $interface eq "OWX" ){
$ret = OWXSWITCH_GetState($hash);
#-- OWFS interface
#}elsif( $interface eq "OWFS" ){
# $ret = OWFSSWITCH_GetPage($hash,"reading");
}elsif( $interface eq "OWFS" ){
$ret = OWFSSWITCH_GetState($hash);
#-- Unknown interface
}else{
return "OWSWITCH: Get with wrong IODev type $interface";
}
#-- process results
OWSWITCH_FormatValues($hash);
my @states = split(/,/,$hash->{STATE});
return $a[2]." = ".$states[$fnd];
$hash->{PRESENT} = 1;
return $name.".".$a[2]." => ".$hash->{READINGS}{$owg_channel[$fnd]}{VAL};
#-- get all states
}elsif( $reading eq "gpio" ){
@ -475,14 +478,13 @@ sub OWSWITCH_Get($@) {
}else{
return "OWSWITCH: Get with wrong IODev type $interface";
}
#-- process results
if( defined($ret) ){
return "OWSWITCH: Could not get values from device $name, reason $ret";
}
$hash->{PRESENT} = 1;
return "OWSWITCH: $name.$reading => ".OWSWITCH_FormatValues($hash);
}
#-- process results
if( defined($ret) ){
return "OWSWITCH: Could not get values from device $name, reason $ret";
}
$hash->{PRESENT} = 1;
return "OWSWITCH: $name.$reading => ".OWSWITCH_FormatValues($hash);
}
#######################################################################################
@ -558,6 +560,11 @@ sub OWSWITCH_Set($@) {
my $key = $a[1];
my $value = $a[2];
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
my ($ret,$cname,@cnama,@channel);
#-- for the selector: which values are possible
if (@a == 2){
my $newkeys = join(" ", sort keys %sets);
@ -569,20 +576,12 @@ sub OWSWITCH_Set($@) {
return "OWSWITCH: Set with unknown argument $a[1]";
}
#-- define vars
my $ret = undef;
my $channel = undef;
my $channo = undef;
my $condx;
my $name = $hash->{NAME};
my $model = $hash->{OW_MODEL};
#-- reset the device
if($key eq "init") {
return "OWCOUNT: init needs parameter 'yes'"
return "OWSWITCH: init needs parameter 'yes'"
if($value ne "yes");
OWSWITCH_InitializeDevice($hash);
return "OWCOUNT: Re-initialized device";
return "OWSWITCH: Re-initialized device $name";
}
#-- set new timer interval
@ -596,18 +595,21 @@ sub OWSWITCH_Set($@) {
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 1);
return undef;
}
#-- obtain channel names
OWSWITCH_ChannelNames($hash);
#-- Set readings according to interface type
my $interface= $hash->{IODev}->{TYPE};
#-- set single state
# TODO: WAS passiert, wenn channel name noch falsch ist ?
if( $key eq "output" ){
return "OWSWITCH: get needs parameter when writing output: <channel>"
if( int(@a)<2 );
#-- find out which channel we have
my $fnd=undef;
for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){
Log 1," testing $a[2] against $owg_channel[$i] and $owg_fixed[$i]";
if( ($a[2] eq $owg_channel[$i]) || ($a[2] eq $owg_fixed[$i]) ){
$fnd=$i;
last;
@ -724,8 +726,6 @@ sub OWSWITCH_Undef ($) {
#
# Prefix = OWFSSWITCH
#
########################################################################################
########################################################################################
#
# OWFSSWITCH_GetState - Get gpio ports from device
@ -1103,23 +1103,21 @@ sub OWXSWITCH_SetState($$) {
<p>FHEM module to commmunicate with 1-Wire Programmable Switches <br />
<br />This 1-Wire module works with the OWX interface module or with the OWServer interface module
(prerequisite: Add this module's name to the list of clients in OWServer).
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br /></p>
<br /><h4>Example</h4>
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first.</p>
<h4>Example</h4>
<p>
<code>define OWX_S OWSWITCH DS2413 B5D502000000 60</code>
<br />
<code>attr OWX_S AName Lampe|light</code>
<br />
<code>attr OWX_S AUnit AN|AUS</code>
<br />
</p>
<br />
<a name="OWSWITCHdefine"></a>
<h4>Define</h4>
<p>
<code>define &lt;name&gt; OWSWITCH [&lt;model&gt;] &lt;id&gt; [&lt;interval&gt;]</code> or <br/>
<code>define &lt;name&gt; OWSWITCH &lt;fam&gt;.&lt;id&gt; [&lt;interval&gt;]</code>
<br /><br /> Define a 1-Wire switch.<br /><br /></p>
<br /><br /> Define a 1-Wire switch.<br /><br />
<ul>
<li>
<code>[&lt;model&gt;]</code><br /> Defines the switch model (and thus 1-Wire family
@ -1162,7 +1160,6 @@ sub OWXSWITCH_SetState($$) {
<li><a name="owswitch_init">
<code>set &lt;name&gt; init yes</code></a><br /> Re-initialize the device</li>
</ul>
<br />
<a name="OWSWITCHget"></a>
<h4>Get</h4>
<ul>
@ -1186,7 +1183,6 @@ sub OWXSWITCH_SetState($$) {
<li><a name="owswitch_gpio">
<code>get &lt;name&gt; gpio</code></a><br />Obtain state of all channels</li>
</ul>
<br />
<a name="OWSWITCHattr"></a>
<h4>Attributes</h4> For each of the following attributes, the channel identification A,B,...
may be used. <ul>

View File

@ -29,6 +29,7 @@
# get <name> interval => query interval
# get <name> temperature => temperature measurement
# get <name> alarm => alarm temperature settings
# get <name> version => OWX version number
#
# set <name> interval => set period for measurement
# set <name> tempLow => lower alarm temperature setting
@ -40,6 +41,9 @@
# attr <name> stateAH "<string>" = character string for denoting high alarm condition, default is up triangle
# 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> tempConv onkick|onread = determines, whether a temperature measurement will happen when "kicked"
# through the OWX backend module (all temperature sensors at the same time), or on
# reading the sensor (1 second waiting time).
# attr <name> tempLow <float> = value for low alarm
# attr <name> tempHigh <float> = value for high alarm
#
@ -68,6 +72,7 @@ use strict;
use warnings;
sub Log($$);
my $owx_version="3.21";
#-- temperature globals - always the raw values from/for the device
my $owg_temp = "";
my $owg_th = "";
@ -82,7 +87,8 @@ my %gets = (
"present" => "",
"interval" => "",
"temperature" => "",
"alarm" => ""
"alarm" => "",
"version" => ""
);
my %sets = (
@ -122,7 +128,7 @@ sub OWTHERM_Initialize ($) {
$hash->{AttrList}= "IODev model:DS1820,DS18B20,DS1822 loglevel:0,1,2,3,4,5 ".
"stateAL stateAH ".
"tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ".
"tempLow tempHigh ".
"tempConv:onkick,onread tempLow tempHigh ".
$readingFnAttributes;
}
@ -274,6 +280,23 @@ sub OWTHERM_InitializeDevice($) {
$hash->{tempf}{offset} = $offset;
$hash->{tempf}{factor} = $factor;
#-- Check if temperature conversion is consistent
if( $interface eq "OWX" ){
if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){
if( !(defined($attr{$hash->{IODev}->{NAME}}{dokick})) ||
( defined($attr{$hash->{IODev}->{NAME}}{dokick}) && ($attr{$hash->{IODev}->{NAME}}{dokick} eq "0") )){
Log 1,"OWTHERM: Attribute tempConv=onkick changed to onread for $name because interface is not kicking";
$attr{$name}{tempConv}="onread";
}
}
}elsif( $interface eq "OWServer" ){
if( !(defined($attr{$name}{tempConv})) ||
(defined($attr{$name}{tempConv}) && ($attr{$name}{tempConv} eq "onread") ) ){
Log 1,"OWTHERM: Attribute tempConv=onread changed to onkick for $name because interface is OWFS";
$attr{$name}{tempConv}="onread";
}
}
#-- Set the attribute values if defined
if( defined($attr{$name}{"tempLow"}) ){
$value = $attr{$name}{"tempLow"};
@ -437,11 +460,16 @@ sub OWTHERM_Get($@) {
}
#-- get interval
if($reading eq "interval") {
if($a[1] eq "interval") {
$value = $hash->{INTERVAL};
return "$name.interval => $value";
}
#-- get version
if( $a[1] eq "version") {
return "$name.version => $owx_version";
}
#-- reset presence
$hash->{PRESENT} = 0;
@ -778,9 +806,10 @@ sub OWXTHERM_GetValues($) {
my $owx_dev = $hash->{ROM_ID};
#-- hash of the busmaster
my $master = $hash->{IODev};
my $name = $hash->{NAME};
#-- check, if the conversion has been called before - only on devices with real power
if( defined($attr{$hash->{IODev}->{NAME}}{buspower}) && ( $attr{$hash->{IODev}->{NAME}}{buspower} eq "real") ){
#-- check, if the conversion has been called before for all sensors
if( defined($attr{$name}{tempConv}) && ( $attr{$name}{tempConv} eq "onkick") ){
$con=0;
}
@ -981,7 +1010,9 @@ sub OWXTHERM_SetValues($@) {
<ul>
<li><a name="owtherm_interval">
<code>set &lt;name&gt; interval &lt;int&gt;</code></a><br /> Temperature
measurement intervall in seconds. The default is 300 seconds.</li>
readout intervall in seconds. The default is 300 seconds. <b>Attention:</b>This is the
readout interval. Whether an actual temperature measurement is performed, is determined by the
tempConv attribute </li>
<li><a name="owtherm_tempHigh">
<code>set &lt;name&gt; tempHigh &lt;float&gt;</code></a>
<br /> The high alarm temperature (on the temperature scale chosen by the attribute
@ -1022,6 +1053,12 @@ sub OWXTHERM_SetValues($@) {
</a>
<br />character string for denoting high alarm condition, default is upward
triangle, e.g. the code &amp;#x25B4; leading to the sign &#x25B4; </li>
<li><a name="owtherm_tempConv">
<code>attr &lt;name&gt; tempConv onkick|onread</code>
</a>
<br /> determines, whether a temperature measurement will happen when "kicked"
through the OWX backend module (all temperature sensors at the same time), or on
reading the sensor (1 second waiting time, default). </li>
<li><a name="owtherm_tempOffset"><code>attr &lt;name&gt; tempOffset &lt;float&gt;</code>
</a>
<br />temperature offset in &deg;C added to the raw temperature reading. </li>