######################################################################################## # # OWVAR.pm # # FHEM module to commmunicate with 1-Wire variable resistor DS2890 # # Prof. Dr. Peter A. Henning # # $Id$ # ######################################################################################## # # define OWVAR [] or . # # where may be replaced by any name string # # is a 1-Wire device type. If omitted AND no FAM_ID given we assume this to be an # DS2890 variable resistor # is a 1-Wire family id, currently allowed values are 2C # is a 12 character (6 byte) 1-Wire ROM ID # without Family ID, e.g. A2D90D000800 # # get id => FAM_ID.ROM_ID.CRC # get present => 1 if device present, 0 if not # get value => query value # get version => OWX version number # set value => wiper setting # # Additional attributes are defined in fhem.cfg # attr Name [|] = name for the channel [|name used in state reading] # attr Unit [|] = unit of measurement for this channel [|unit used in state reading] # attr Function | = The first string is an arbitrary functional expression f(V) involving the variable V. # V is replaced by the raw potentiometer reading (in the range of [0,100]). The second string must be the inverse # function g(U) involving the variable U, such that U can be replaced by the value given in the # set argument. Care has to taken that g(U) is in the range [0,100]. # No check on the validity of these functions is performed, # singularities my crash FHEM. # ######################################################################################## # # This programm is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # The GNU General Public License can be found at # http://www.gnu.org/copyleft/gpl.html. # A copy is found in the textfile GPL.txt and important notices to the license # from the author is found in LICENSE.txt distributed with these scripts. # # This script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ######################################################################################## package main; use vars qw{%attr %defs %modules $readingFnAttributes $init_done}; use strict; use warnings; use Time::HiRes qw( gettimeofday ); #add FHEM/lib to @INC if it's not allready included. Should rather be in fhem.pl than here though... BEGIN { if (!grep(/FHEM\/lib$/,@INC)) { foreach my $inc (grep(/FHEM$/,@INC)) { push @INC,$inc."/lib"; }; }; }; use ProtoThreads; no warnings 'deprecated'; sub Log3($$$); sub AttrVal($$$); my $owx_version="6.0"; my $owg_channel = ""; my %gets = ( "id" => "", "present" => "", "value" => "", "version" => "" ); my %sets = ( "value" => "" ); my %updates = ( "value" => "" ); ######################################################################################## # # The following subroutines are independent of the bus interface # # Prefix = OWVAR # ######################################################################################## # # OWVAR_Initialize # # Parameter hash = hash of device addressed # ######################################################################################## sub OWVAR_Initialize ($) { my ($hash) = @_; $hash->{DefFn} = "OWVAR_Define"; $hash->{UndefFn} = "OWVAR_Undef"; $hash->{GetFn} = "OWVAR_Get"; $hash->{SetFn} = "OWVAR_Set"; $hash->{NotifyFn}= "OWVAR_Notify"; $hash->{InitFn} = "OWVAR_Init"; $hash->{AttrFn} = "OWVAR_Attr"; $hash->{AttrList}= "IODev model:DS2890 ". "Name Function Unit ". $readingFnAttributes; #-- make sure OWX is loaded so OWX_CRC is available if running with OWServer main::LoadModule("OWX"); } ######################################################################################## # # OWVAR_Define - Implements DefFn function # # Parameter hash = hash of device addressed, def = definition string # ######################################################################################## sub OWVAR_Define ($$) { my ($hash, $def) = @_; # define OWVAR [] # e.g.: define flow OWVAR 525715020000 my @a = split("[ \t][ \t]*", $def); my ($name,$model,$fam,$id,$crc,$ret); #-- default $name = $a[0]; $ret = ""; #-- check syntax return "OWVAR: Wrong syntax, must be define OWVAR [] or OWVAR . " if(int(@a) < 2 || int(@a) > 5); #-- different types of definition allowed my $a2 = $a[2]; my $a3 = defined($a[3]) ? $a[3] : ""; #-- no model, 12 characters if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = "DS2890"; CommandAttr (undef,"$name model DS2890"); $fam = "10"; $id = $a[2]; #-- no model, 2+12 characters } elsif( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { $fam = substr($a[2],0,2); $id = substr($a[2],3); if( $fam eq "2C" ){ $model = "DS2890"; CommandAttr (undef,"$name model DS2890"); }else{ return "OWVAR: Wrong 1-Wire device family $fam"; } #-- model, 12 characters } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $model = $a[2]; $id = $a[3]; if( $model eq "DS2890" ){ $fam = "2C"; CommandAttr (undef,"$name model DS2890"); }else{ return "OWVAR: Wrong 1-Wire device model $model"; } } else { return "OWVAR: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value"; } #-- determine CRC Code $crc = sprintf("%02X",OWX_CRC($fam.".".$id."00")); #-- define device internals $hash->{OW_ID} = $id; $hash->{OW_FAMILY} = $fam; $hash->{PRESENT} = 0; $hash->{ROM_ID} = "$fam.$id.$crc"; #-- value globals - always the raw values from/for the device $hash->{owg_val} = ""; #-- Couple to I/O device AssignIoPort($hash); if( !defined($hash->{IODev}) or !defined($hash->{IODev}->{NAME}) ){ return "OWVAR: Warning, no 1-Wire I/O device found for $name."; } else { $hash->{ASYNC} = $hash->{IODev}->{TYPE} eq "OWX_ASYNC" ? 1 : 0; #-- false for now } $modules{OWVAR}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","defined",1); Log3 $name, 3, "OWVAR: Device $name defined."; $hash->{NOTIFYDEV} = "global"; if ($init_done) { OWVAR_Init($hash); } return undef; } ####################################################################################### # # OWVAR_Notify - Implements the Notify function # # Parameter hash = hash of device addressed # a = argument array # ######################################################################################## sub OWVAR_Notify ($$) { my ($hash,$dev) = @_; if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) { OWVAR_Init($hash); } elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) { } } ####################################################################################### # # OWVAR_Init - Implements the Init function # # Parameter hash = hash of device addressed # ######################################################################################## sub OWVAR_Init ($) { my ($hash)=@_; #-- Start timer for updates RemoveInternalTimer($hash); InternalTimer(gettimeofday()+10, "OWVAR_GetValues", $hash, 0); return undef; } ####################################################################################### # # OWVAR_Attr - Set one attribute value for device # # Parameter hash = hash of device addressed # a = argument array # ######################################################################################## sub OWVAR_Attr(@) { my ($do,$name,$key,$value) = @_; my $hash = $defs{$name}; my $ret; if ( $do eq "set") { ARGUMENT_HANDLER: { #-- interval modified at runtime $key eq "IODev" and do { AssignIoPort($hash,$value); if( defined($hash->{IODev}) ) { $hash->{ASYNC} = $hash->{IODev}->{TYPE} eq "OWX_ASYNC" ? 1 : 0; if ($init_done) { OWVAR_Init($hash); } } last; }; } } return $ret; } ######################################################################################## # # OWVAR_ChannelNames - find the real channel names # # Parameter hash = hash of device addressed # ######################################################################################## sub OWVAR_ChannelNames($) { my ($hash) = @_; my $name = $hash->{NAME}; my $state = $hash->{READINGS}{"state"}{VAL}; my ($cname,@cnama,$unit); #-- name $cname = defined($attr{$name}{"Name"}) ? $attr{$name}{"Name"} : "value"; @cnama = split(/\|/,$cname); if( int(@cnama)!=2){ push(@cnama,$cnama[0]); } $owg_channel=$cnama[0]; #-- unit $unit = defined($attr{$name}{"Unit"}) ? $attr{$name}{"Unit"} : "\%"; #-- put into readings $hash->{READINGS}{"value"}{ABBR} = $cnama[1]; $hash->{READINGS}{"value"}{UNIT} = " ".$unit; } ######################################################################################## # # OWVAR_FormatValues - put together various format strings # # Parameter hash = hash of device addressed, fs = format string # ######################################################################################## sub OWVAR_FormatValues($) { my ($hash) = @_; my $name = $hash->{NAME}; my $interface = $hash->{IODev}->{TYPE}; my ($vval,$vlow,$vhigh,$vfunc,$ufunc,$ret); #-- no change in any value if invalid reading #for (my $i=0;$i{owg_val})) || ($hash->{owg_val} eq "") ); #} #-- obtain channel names OWVAR_ChannelNames($hash); #-- put into READINGS readingsBeginUpdate($hash); #-- formats for output if (defined($attr{$name}{"Function"})){ ($vfunc,$ufunc) = split('\|',$attr{$name}{"Function"}); #-- replace by proper values (V -> value) $vfunc =~ s/V/\$hash->{owg_val}/g; $vfunc = eval($vfunc); if( !$vfunc ){ $vval = 0.0; } elsif( $vfunc ne "" ){ $vval = $vfunc; } else { $vval = "???"; } }else{ $vval = $hash->{owg_val}; } #-- string buildup for return value, STATE and alarm my $svalue .= sprintf( "%s: %5.3f%s", $hash->{READINGS}{"value"}{ABBR}, $vval,$hash->{READINGS}{"value"}{UNIT}); #-- put into READINGS $vval = sprintf( "%5.3f", $vval); readingsBulkUpdate($hash,$owg_channel,$vval); #-- STATE readingsBulkUpdate($hash,"state",$svalue); readingsEndUpdate($hash,1); return $svalue; } ######################################################################################## # # OWVAR_Get - Implements GetFn function # # Parameter hash = hash of device addressed, a = argument array # ######################################################################################## sub OWVAR_Get($@) { my ($hash, @a) = @_; my $reading = $a[1]; my $name = $hash->{NAME}; my $model = $hash->{OW_MODEL}; my $value = undef; my $ret = ""; #-- check syntax return "OWVAR: Get argument is missing @a" if(int(@a) < 2); #-- check argument return "OWVAR: Get with unknown argument $a[1], choose one of ".join(" ", sort keys %gets) if(!defined($gets{$a[1]})); #-- get id if($a[1] eq "id") { $value = $hash->{ROM_ID}; return "$name.id => $value"; } #-- hash of the busmaster my $master = $hash->{IODev}; #-- Get other values according to interface type my $interface= $hash->{IODev}->{TYPE}; #-- get present if($a[1] eq "present" ) { #-- OWX interface if( $interface =~ /^OWX/ ){ #-- asynchronous mode if( $hash->{ASYNC} ){ Log3 $name, 1,"OWVAR: Get ASYNC interface not implemented"; #eval { # OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash)); #}; #return GP_Catch($@) if $@; return "$name.present => ".ReadingsVal($name,"present","unknown"); } else { $value = OWX_Verify($master,$hash->{ROM_ID}); } $hash->{PRESENT} = $value; return "$name.present => $value"; } else { return "OWVAR: Verification not yet implemented for interface $interface"; } } #-- get version if( $a[1] eq "version") { return "$name.version => $owx_version"; } if( $a[1] eq "value") { #-- OWX interface if( $interface eq "OWX" ){ #-- not different from getting all values .. $ret = OWXVAR_GetValues($hash); }elsif( $interface eq "OWX_ASYNC" ){ Log3 $name,1,"OWVAR: Get ASYNC interface not implemented"; #eval { # $ret = OWX_ASYNC_RunToCompletion($hash,OWXVAR_PT_GetValues($hash)); #}; #$ret = GP_Catch($@) if $@; #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSVAR_GetValues($hash); #-- Unknown interface }else{ return "OWVAR: Get with wrong IODev type $interface"; } } #-- process results if( $master->{ASYNCHRONOUS} ){ return "OWVAR: $name getting value, please wait for completion"; }else{ #-- when we have a return code, we have an error if( defined($ret) ){ return "OWVAR: Could not get values from device $name, return was $ret"; } #-- return the special reading if ($reading eq "value") { return "OWVAR: $name.value => ". $hash->{READINGS}{"value"}{VAL}; } else { return undef; } } } ####################################################################################### # # OWVAR_GetValues - Updates the readings from device # # Parameter hash = hash of device addressed # ######################################################################################## sub OWVAR_GetValues($@) { my $hash = shift; my $name = $hash->{NAME}; my $value = ""; my $ret; #-- check if device needs to be initialized if( $hash->{READINGS}{"state"}{VAL} eq "defined"){ OWVAR_InitializeDevice($hash); OWVAR_FormatValues($hash); } #-- restart timer for updates RemoveInternalTimer($hash); #InternalTimer(time()+$hash->{INTERVAL}, "OWVAR_GetValues", $hash, 0); #-- Get values according to interface type my $interface= $hash->{IODev}->{TYPE}; if( $interface eq "OWX" ){ #-- max 3 tries for(my $try=0; $try<3; $try++){ $ret = OWXVAR_GetValues($hash); last if( !defined($ret) ); } }elsif( $interface eq "OWX_ASYNC" ){ Log3 $name, 1,"OWVAR: Get ASYNC interface not implemented"; }elsif( $interface eq "OWServer" ){ $ret = OWFSVAR_GetValues($hash); }else{ Log3 $name, 3, "OWVAR: GetValues with wrong IODev type $interface"; return 1; } #-- process results if( defined($ret) ){ $hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1; if( $hash->{ERRCOUNT} > 5 ){ $hash->{INTERVAL} = 9999; } return "OWVAR: Could not get values from device $name for ".$hash->{ERRCOUNT}." times, reason $ret"; } return undef; } ######################################################################################## # # OWVAR_InitializeDevice - delayed setting of initial readings # # Parameter hash = hash of device addressed # ######################################################################################## sub OWVAR_InitializeDevice($) { my ($hash) = @_; my $name = $hash->{NAME}; my $interface = $hash->{IODev}->{TYPE}; my $ret=""; my ($ret1,$ret2); #-- Initial readings $hash->{owg_val} = "0.0"; $hash->{ERRCOUNT} = 0; #-- Set state to initialized readingsSingleUpdate($hash,"state","initialized",1); return OWVAR_GetValues($hash); } ####################################################################################### # # OWVAR_Set - Set one value for device # # Parameter hash = hash of device addressed # a = argument string # ######################################################################################## sub OWVAR_Set($@) { my ($hash, @a) = @_; #-- for the selector: which values are possible return join(" ", sort keys %sets) if(@a == 2); #-- check syntax return "OWVAR: Set needs one parameter" if(int(@a) != 3); #-- check argument return "OWVAR: Set with unknown argument $a[1], choose one of ".join(",", sort keys %sets) if(!defined($sets{$a[1]})); #-- define vars my $key = $a[1]; my $value = $a[2]; my $ret = undef; my($vfunc,$ufunc); my $name = $hash->{NAME}; my $model = $hash->{OW_MODEL}; my $interface = $hash->{IODev}->{TYPE}; #-- formats for input if (defined($attr{$name}{"Function"})){ ($vfunc,$ufunc) = split('\|',$attr{$name}{"Function"}); #-- replace by proper values (U -> ) $ufunc =~ s/U/\$value/g; $ufunc = eval($ufunc); if( !$ufunc ){ $value = 0.0; } elsif( $ufunc ne "" ){ $value = $ufunc; } else { $value = "???"; } } #-- put into device #-- OWX interface if( $interface eq "OWX" ){ $ret = OWXVAR_SetValues($hash,$key,$value); }elsif( $interface eq "OWX_ASYNC" ){ Log3 $name, 1,"OWVAR: Set ASYNC interface not implemented"; #-- OWFS interface }elsif( $interface eq "OWServer" ){ $ret = OWFSVAR_SetValues($hash,$key,$value); } else { return "OWVAR: Set with wrong IODev type $interface"; } #-- process results if( defined($ret) ){ return "OWVAR: Could not set device $name, reason: ".$ret; } #-- process results $hash->{PRESENT} = 1; OWVAR_FormatValues($hash); Log3 $name, 4, "OWVAR: Set $hash->{NAME} $key $value"; return undef; } ######################################################################################## # # OWVAR_Undef - Implements UndefFn function # # Parameter hash = hash of device addressed # ######################################################################################## sub OWVAR_Undef ($) { my ($hash) = @_; delete($modules{OWVAR}{defptr}{$hash->{OW_ID}}); RemoveInternalTimer($hash); return undef; } ######################################################################################## # # The following subroutines in alphabetical order are only for a 1-Wire bus connected # via OWFS # # Prefix = OWFSVAR # ######################################################################################## # # OWFSVAR_GetValues - Get values from device # # Parameter hash = hash of device addressed # ######################################################################################## sub OWFSVAR_GetValues($) { my ($hash) = @_; #-- ID of the device my $owx_add = substr($hash->{ROM_ID},0,15); #-- hash of the busmaster my $master = $hash->{IODev}; my $name = $hash->{NAME}; #-- reset presence $hash->{PRESENT} = 0; #-- get values - or should we rather get the uncached ones ? Log 1, "OWVAR: trying to read from OWserver /$owx_add/wiper"; my $val = OWServer_Read($master,"/$owx_add/wiper"); return "no return from OWServer" if( !defined($val) ); return "empty return from OWServer" if( $val eq "" ); $hash->{owg_val}=sprintf("%5.2f",(1.0-$val/255.0)*100); #-- and now from raw to formatted values $hash->{PRESENT} = 1; my $value = OWVAR_FormatValues($hash); return undef; } ######################################################################################## # # OWFSVAR_SetValues - Set values in device # # Parameter hash = hash of device addressed # ######################################################################################## sub OWFSVAR_SetValues($$$) { my ($hash,$key,$value) = @_; #-- ID of the device my $owx_add = substr($hash->{ROM_ID},0,15); #-- hash of the busmaster my $master = $hash->{IODev}; my $name = $hash->{NAME}; #-- translate from 0..100 to 0..255 return sprintf("OWFSVAR: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",0,100) if($value < 0 || $value > 100); my $pos = floor((100-$value)*2.55+0.5); Log 1,"OWVAR: trying to write to OWserver /$owx_add/wiper => $pos"; OWServer_Write($master, "/$owx_add/wiper/",$pos); return undef } ######################################################################################## # # The following subroutines in alphabetical order are only for a 1-Wire bus connected # directly to the FHEM server # # Prefix = OWXVAR # ######################################################################################## # # OWXVAR_BinValues - Process reading from one device - translate binary into raw # # Parameter hash = hash of device addressed # context = mode for evaluating the binary data # proc = processing instruction, also passed to OWX_Read. # bitwise interpretation !! # if 0, nothing special # if 1 = bit 0, a reset will be performed not only before, but also after # the last operation in OWX_Read # if 2 = bit 1, the initial reset of the bus will be suppressed # if 8 = bit 3, the fillup of the data with 0xff will be suppressed # if 16= bit 4, the insertion will be at the top of the queue # owx_dev = ROM ID of slave device # crcpart = part of the data that needs to be part of the CRC check # numread = number of bytes to receive # res = result string # # ######################################################################################## sub OWXVAR_BinValues($$$$$$$) { my ($hash, $context, $reset, $owx_dev, $crcpart, $numread, $res) = @_; my ($i,$j,$k,@data); my $change = 0; my $master = $hash->{IODev}; my $name = $hash->{NAME}; my $msg; OWX_WDBG($name,"OWVAR: $name: BinValues called with ",$res) if( $main::owx_debug>2 ); #-- process results #die "OWVAR: $name not accessible in 2nd step" unless ( defined $res and $res ne 0 ); if( $context eq "getstate" ) { #-- process results @data=split(//,$res); if (@data != 2) { $msg="Error- $name returns invalid data length, ".int(@data)." instead of 2 bytes "; }else{ $msg="No error"; my $stat = ord($data[0]); my $val = ord($data[1]); $hash->{owg_val}=sprintf("%5.2f",(1.0-$val/255.0)*100); #-- and now from raw to formatted values $hash->{PRESENT} = 1; my $value = OWVAR_FormatValues($hash); #Log3 $hash->{NAME}, 5, $value; } OWX_WDBG($name,"OWXVAR_BinValues: ".$msg,$res) if( $main::owx_debug>2 ); return undef; }elsif( $context eq "setstate" ) { my $val = ord($res); #$hash->{owg_val}=sprintf("%5.2f",(1-$val/255.0)*100); #-- process results if (length($res) != 1){ $msg="$name returns invalid data length, ".length($res)." instead of 1 bytes, "; }elsif($val ne $crcpart){ $msg="$name returns invalid data $val instead of $crcpart, " }else{ $msg="No error, val = $val"; } OWX_WDBG($name,"OWXVAR_BinValues: ".$msg,$res) if( $main::owx_debug>2 ); #### master slave context proc owx_dev data crcpart numread startread callback delay # 2 suppresses the initial bus reset, 16 inserts at top of queue OWX_Qomplex($master, $hash, "confirm", 18, $owx_dev, "\x96", 0, 0, 11, undef, 0); return undef; } } ######################################################################################## # # OWXVAR_GetValues - Trigger reading from one device # # Parameter hash = hash of device addressed # ######################################################################################## sub OWXVAR_GetValues($) { my ($hash) = @_; #-- ID of the device my $owx_dev = $hash->{ROM_ID}; #-- hash of the busmaster my $master = $hash->{IODev}; my $name = $hash->{NAME}; #-- NOW ask the specific device #-- issue the match ROM command \x55 and the read wiper command \xF0 #-- reading 9 + 1 + 2 data bytes and 0 CRC byte = 12 bytes #-- OLD OWX interface if( !$master->{ASYNCHRONOUS} ){ OWX_Reset($master); my $res=OWX_Complex($master,$owx_dev,"\xF0",2); return "OWVAR: $name not accessible in reading" if( $res eq 0 ); return "OWVAR: $name has returned invalid data" if( length($res)!=12); OWX_Reset($master); eval { OWXVAR_BinValues($hash,"getstate",0,$owx_dev,0,2,substr($res,10,2)); }; return $@ ? $@ : undef; #-- NEW OWX interface }else{ #### master slave context proc owx_dev data crcpart numread startread callback delay OWX_Qomplex($master, $hash, "getstate", 0, $owx_dev, "\xF0", 0, 2, 10, \&OWXVAR_BinValues, 0); return undef; } } ####################################################################################### # # OWXVAR_SetValues - Implements SetFn function # # Parameter hash = hash of device addressed # a = argument array # ####################################################################################### sub OWXVAR_SetValues($$$) { my ($hash, $key,$value) = @_; #-- ID of the device my $owx_dev = $hash->{ROM_ID}; #-- hash of the busmaster my $master = $hash->{IODev}; my $name = $hash->{NAME}; #-- translate from 0..100 to 0..255 return sprintf("OWXVAR: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",0,100) if($value < 0 || $value > 100); my $pos = floor((100-$value)*2.55+0.5); #-- issue the match ROM command \x55 and the write wiper command \x0F, # followed by 1 bytes of data # my $select=sprintf("\x0F%c",$pos); #-- OLD OWX interface if( !$master->{ASYNCHRONOUS} ){ OWX_Reset($master); my $res=OWX_Complex($master,$owx_dev,$select,1); return "OWXVAR: $name not accessible" if( $res eq 0 ); my $rv=ord(substr($res,11,1)); return "OWXVAR: $name: Set failed with return value $rv from set value $pos" if($rv ne $pos); my $res2=OWX_Complex($master,$owx_dev,"\x96",1); my $rv2=ord(substr($res2,11,1)); return "OWXVAR: $name: Set failed with return value $rv2 from release value" if($rv2 ne 0); OWX_Reset($master); $hash->{owg_val}=sprintf("%5.2f",(1-$pos/255.0)*100); #-- NEW OWX interface }else{ #### master slave context proc owx_dev data crcpart numread startread callback delay OWX_Qomplex($master, $hash, "setstate", 0, $owx_dev, $select, $pos, 1, 11, \&OWXVAR_BinValues, 0); $hash->{owg_val}=sprintf("%5.2f",(1-$pos/255.0)*100); } return undef; } 1; =pod =begin html

OWVAR

FHEM module to commmunicate with 1-Wire bus digital potentiometer devices of type DS2890

This 1-Wire module works with the OWX interface module, but not yet with the OWServer interface module.

Example

define OWX_P OWVAR E8D09B030000
attr OWX_P Function 1.02 * V + 0.58 | (U-0.58) / 1.02


Define

define <name> OWVAR <id> or
define <name> OWVAR <fam>.<id>

Define a 1-Wire digital potentiometer device.

  • <fam>
    2-character unique family id, must be 2C
  • <id>
    12-character unique ROM id of the thermometer device without family id and CRC code

Set

  • set <name> value <float>
    The value of the potentiometer resistance against ground. Arguments may be in the range of [0,100] without a Function attribute, or in the range needed for a Function

Get


Attributes

=end html =cut