diff --git a/fhem/contrib/1-Wire/00_OWX.pm b/fhem/contrib/1-Wire/00_OWX.pm deleted file mode 100644 index 4e4b515cd..000000000 --- a/fhem/contrib/1-Wire/00_OWX.pm +++ /dev/null @@ -1,2083 +0,0 @@ -######################################################################################## -# -# OWX.pm -# -# TODO: Abfangen, wenn das Serial Device nach Öffnung nicht existiert ??? -# set init als rediscover ausführen. -# ungültige ID's von ungültigen devices => rauswerfen. -# -# FHEM module to commmunicate with 1-Wire bus devices -# * via an active DS2480/DS2482/DS2490/DS9097U bus master interface attached to an USB port -# * via a passive DS9097 interface attached to an USB port -# * via a network-attached CUNO -# Internally these interfaces are vastly different, read the corresponding Wiki pages -# http://fhemwiki.de/wiki/Interfaces_f%C3%BCr_1-Wire -# -# Version 2.24 - October, 2012 -# -# Prof. Dr. Peter A. Henning, 2012 -# -# define OWX for USB interfaces or -# define OWX for a CUNO or COC interface -# -# where may be replaced by any name string -# is a serial (USB) device -# is a CUNO or COC device -# -# get alarms => find alarmed 1-Wire devices (not with CUNO) -# get devices => find all 1-Wire devices -# -# set interval => set period for temperature conversion and alarm testing -# set followAlarms on/off => determine whether an alarm is followed by a search for -# alarmed devices -# -# attr buspower real/parasitic - whether the 1-Wire bus is really powered or -# the 1-Wire devices take their power from the data wire (parasitic is default !) -# -# Ordering of subroutines in this module -# 1. Subroutines independent of bus interface type -# 2. Subroutines for a specific type of the interface -# -######################################################################################## -# -# 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 strict; -use warnings; -use Device::SerialPort; -use vars qw{%attr %defs}; - -require "$attr{global}{modpath}/FHEM/DevIo.pm"; - -sub Log($$); - -# Line counter -my $cline=0; - -# These we may get on request -my %gets = ( - "alarms" => "A", - "devices" => "D" -); - -# These occur in a pulldown menu as settable values for the bus master -my %sets = ( - "interval" => "T", - "followAlarms" => "F" -); - -# These are attributes -my %attrs = ( -); - -#-- some globals needed for the 1-Wire module -my $owx_hwdevice; -#-- baud rate serial interface -my $owx_baud=9600; -#-- Debugging 0,1,2,3 -my $owx_debug=0; -#-- bus master mode -my $owx_mode="undef"; -#-- bus interface -my $owx_interface=""; -#-- 8 byte 1-Wire device address -my @owx_ROM_ID =(0,0,0,0 ,0,0,0,0); -#-- List of addresses found on the bus -my @owx_devs=(); -my @owx_fams=(); -my @owx_alarm_devs=(); -#-- 16 byte search string -my @owx_search=(0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0); -#-- search state for 1-Wire bus search -my $owx_LastDiscrepancy = 0; -my $owx_LastFamilyDiscrepancy = 0; -my $owx_LastDeviceFlag = 0; - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -######################################################################################## -# -# OWX_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWX_Initialize ($) { - my ($hash) = @_; - #-- Provider - $hash->{Clients} = ":OWAD:OWCOUNT:OWID:OWLCD:OWMULTI:OWSWITCH:OWTHERM:"; - - #-- Normal Devices - $hash->{DefFn} = "OWX_Define"; - $hash->{UndefFn} = "OWX_Undef"; - $hash->{GetFn} = "OWX_Get"; - $hash->{SetFn} = "OWX_Set"; - $hash->{AttrList}= "loglevel:0,1,2,3,4,5,6 buspower:real,parasitic"; -} - -######################################################################################## -# -# OWX_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################## - -sub OWX_Define ($$) { - my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); - - #-- check syntax - if(int(@a) < 3){ - return "OWX: Syntax error - must be define OWX" - } - - #-- check syntax - Log 1,"OWX: Warning - Some parameter(s) ignored, must be define OWX |" - if(int(@a) > 3); - #-- If this line contains 3 parameters, it is the bus master definition - my $dev = $a[2]; - - #-- TODO: what should we do when the specified device name contains @ already ? - $hash->{DeviceName} = $dev."\@9600"; - #-- Dummy 1-Wire ROM identifier - $hash->{ROM_ID} = "FF"; - - #-- First step: check if we have a directly connected serial interface or a CUNO/COC attached - # (mod suggested by T.Faust) - if ( $dev =~ m/\/dev\/.*/ ){ - #-- TODO: what should we do when the specified device name contains @ already ? - $hash->{DeviceName} = $dev."\@9600"; - #-- Second step in case of serial device: open the serial device to test it - my $msg = "OWX: Serial device $dev"; - my $ret = DevIo_OpenDev($hash,0,undef); - $owx_hwdevice = $hash->{USBDev}; - if(!defined($owx_hwdevice)){ - Log 1, $msg." not defined"; - return "OWX: Can't open serial device $dev: $!" - } else { - Log 1,$msg." defined"; - } - $owx_hwdevice->reset_error(); - $owx_hwdevice->baudrate(9600); - $owx_hwdevice->databits(8); - $owx_hwdevice->parity('none'); - $owx_hwdevice->stopbits(1); - $owx_hwdevice->handshake('none'); - $owx_hwdevice->write_settings; - #-- store with OWX device - $hash->{INTERFACE} = "serial"; - $hash->{HWDEVICE} = $owx_hwdevice; - - #-- sleeping for some time - select(undef,undef,undef,0.1); - - } else { - $hash->{DeviceName} = $dev; - #-- Second step in case of CUNO: See if we can open it - my $msg = "OWX: CUNO/COC device $dev"; - $owx_hwdevice = $main::defs{$dev}; - if($owx_hwdevice){ - Log 1,$msg." defined"; - #-- store with OWX device - $hash->{INTERFACE} = "CUNO"; - $hash->{HWDEVICE} = $owx_hwdevice; - #-- reset the 1-Wire system in CUNO - CUL_SimpleWrite($owx_hwdevice, "Oi"); - }else{ - Log 1, $msg." not defined"; - return "OWX: Can't open CUNO/COC device $dev: $!" - } - } - #-- Third step: see, if a bus interface is detected - if (!OWX_Detect($hash)){ - $hash->{STATE} = "Failed"; - $hash->{PRESENT} = 0; - $init_done = 1; - return undef; - } - - #-- In 10 seconds discover all devices on the 1-Wire bus - InternalTimer(gettimeofday()+10, "OWX_Discover", $hash,0); - - #-- Default settings - $hash->{interval} = 300; # kick every minute - $hash->{followAlarms} = "off"; - $hash->{ALARMED} = "no"; - - #-- InternalTimer blocks if init_done is not true - my $oid = $init_done; - $hash->{PRESENT} = 1; - $hash->{STATE} = "Initialized"; - $init_done = 1; - #-- Intiate first alarm detection and eventually conversion in a minute or so - InternalTimer(gettimeofday() + $hash->{interval}, "OWX_Kick", $hash,1); - $init_done = $oid; - $hash->{STATE} = "Active"; - return undef; -} - -######################################################################################## -# -# OWX_Alarms - Find devices on the 1-Wire bus, -# which have the alarm flag set -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : no device present -# -######################################################################################## - -sub OWX_Alarms ($) { - my ($hash) = @_; - my $name = $hash->{NAME}; - my @owx_alarm_names=(); - - #-- Discover all alarmed devices on the 1-Wire bus - @owx_alarm_devs=(); - my $res = OWX_First_SER($hash,"alarm"); - while( $owx_LastDeviceFlag==0 && $res != 0){ - $res = $res & OWX_Next_SER($hash,"alarm"); - } - if( @owx_alarm_devs == 0){ - return "OWX: No alarmed 1-Wire devices found on bus $name"; - } - - #-- walk through all the devices to get their proper fhem names - foreach my $fhem_dev (sort keys %main::defs) { - #-- skip if busmaster - next if( $name eq $main::defs{$fhem_dev}{NAME} ); - #-- all OW types start with OW - next if( substr($main::defs{$fhem_dev}{TYPE},0,2) ne "OW"); - foreach my $owx_dev (@owx_alarm_devs) { - #-- two pieces of the ROM ID found on the bus - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - my $id_owx = $owx_f.".".$owx_rnf; - - #-- skip if not in alarm list - if( $owx_dev eq $main::defs{$fhem_dev}{ROM_ID} ){ - $main::defs{$fhem_dev}{STATE} = "Alarmed"; - push(@owx_alarm_names,$main::defs{$fhem_dev}{NAME}); - } - } - } - #-- so far, so good - what do we want to do with this ? - return "OWX: Alarmed 1-Wire devices found on bus $name (".join(",",@owx_alarm_names).")"; -} - -######################################################################################## -# -# OWX_Complex - Send match ROM, data block and receive bytes as response -# -# Parameter hash = hash of bus master, -# owx_dev = ROM ID of device -# data = string to send -# numread = number of bytes to receive -# -# Return response, if OK -# 0 if not OK -# -######################################################################################## - -sub OWX_Complex ($$$$) { - my ($hash,$owx_dev,$data,$numread) =@_; - my $name = $hash->{NAME}; - - #-- get the interface - $owx_interface = $hash->{INTERFACE}; - $owx_hwdevice = $hash->{HWDEVICE}; - - #-- interface error - if( !(defined($owx_interface))){ - Log 3,"OWX: Complex called with unknown interface on bus $name"; - return 0; - #-- here we treat the directly connected serial interfaces - }elsif( ($owx_interface eq "DS2480") || ($owx_interface eq "DS9097") ){ - return OWX_Complex_SER($hash,$owx_dev,$data,$numread); - - #-- here we treat the network-connected CUNO - }elsif( $owx_interface eq "CUNO" ){ - return OWX_Complex_CUNO($hash,$owx_dev,$data,$numread); - - #-- interface error - }else{ - Log 3,"OWX: Complex called with unknown interface $owx_interface on bus $name"; - return 0; - } -} - -######################################################################################## -# -# OWX_CRC - Check the CRC8 code of a device address in @owx_ROM_ID -# -# Parameter romid = if not zero, return the CRC8 value instead of checking it -# -######################################################################################## - -my @crc8_table = ( - 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, - 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, - 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, - 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, - 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, - 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, - 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, - 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, - 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, - 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, - 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, - 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, - 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, - 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, - 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, - 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53); - - -sub OWX_CRC ($) { - my ($romid) = @_; - my $crc8=0; - - if( $romid eq "0" ){ - for(my $i=0; $i<8; $i++){ - $crc8 = $crc8_table[ $crc8 ^ $owx_ROM_ID[$i] ]; - } - return $crc8; - } else { - #-- from search string to byte id - $romid=~s/\.//g; - for(my $i=0;$i<8;$i++){ - $owx_ROM_ID[$i]=hex(substr($romid,2*$i,2)); - } - for(my $i=0; $i<7; $i++){ - $crc8 = $crc8_table[ $crc8 ^ $owx_ROM_ID[$i] ]; - } - return $crc8; - } -} - -######################################################################################## -# -# OWX_CRC - Check the CRC8 code of an a byte string -# -# Parameter string, crc. -# If crc is defined, make a comparison, otherwise output crc8 -# -######################################################################################## - -sub OWX_CRC8 ($$) { - my ($string,$crc) = @_; - my $crc0=ord($crc); - my $crc8=0; - my @strhex; - - for(my $i=0; $i<8; $i++){ - $strhex[$i]=ord(substr($string,$i,1)); - $crc8 = $crc8_table[ $crc8 ^ $strhex[$i] ]; - } - - if( defined($crc) ){ - if ( $crc0 == $crc8 ){ - return 1; - }else{ - return 0; - } - }else{ - return $crc8; - } -} - -######################################################################################## -# -# OWX_CRC16 - Calculate the CRC16 code of a string -# -# TODO UNFINISHED CODE -# -# Parameter crc - previous CRC code, c next character -# -######################################################################################## - -sub OWX_CRC16($) { - my ($data) = @_; - - my $crc=0; - for( my $i=0; $i New CRC value = %x",$crc; - } - return $crc; -} - - -sub OWX_DOCRC16($$) { - my ($crc,$c) = @_; - - #-- polynomial for x^16 + x^15 + x^2 + 1 - my $mask = 0xA001; - - my $i; - for($i=0;$i<8;$i++) { - if(($crc ^ ord($c)) & 1) { - $crc=($crc>>1)^$mask; - } else { - $crc>>=1; - } - $c>>=1; - } - return ($crc); -} - -######################################################################################## -# -# OWX_Detect - Detect 1-Wire interface -# TODO: HAS TO BE SPLIT INTO INTERFACE DEPENDENT AND INDEPENDENT PART -# -# Method rather crude - treated as an 2480, and see whatis returned -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : not OK -# -######################################################################################## - -sub OWX_Detect ($) { - my ($hash) = @_; - - my ($i,$j,$k,$l,$res,$ret,$ress); - my $name = $hash->{NAME}; - my $ress0 = "OWX: 1-Wire bus $name: interface "; - $ress = $ress0; - - #-- get the interface - $owx_interface = $hash->{INTERFACE}; - $owx_hwdevice = $hash->{HWDEVICE}; - - #-- here we treat the directly connected serial interfaces - if($owx_interface eq "serial"){ - #-- timing byte for DS2480 - OWX_Query_2480($hash,"\xC1"); - - #-- Max 4 tries to detect an interface - for($l=0;$l<4;$l++) { - #-- write 1-Wire bus (Fig. 2 of Maxim AN192) - $res = OWX_Query_2480($hash,"\x17\x45\x5B\x0F\x91"); - - #-- process 4/5-byte string for detection - if( !defined($res)){ - $res=""; - $ret=0; - }elsif( ($res eq "\x16\x44\x5A\x00\x90") || ($res eq "\x16\x44\x5A\x00\x93")){ - $ress .= "master DS2480 detected for the first time"; - $owx_interface="DS2480"; - $ret=1; - } elsif( $res eq "\x17\x45\x5B\x0F\x91"){ - $ress .= "master DS2480 re-detected"; - $owx_interface="DS2480"; - $ret=1; - } elsif( ($res eq "\x17\x0A\x5B\x0F\x02") || ($res eq "\x00\x17\x0A\x5B\x0F\x02") || ($res eq "\x30\xf8\x00") ){ - $ress .= "passive DS9097 detected"; - $owx_interface="DS9097"; - $ret=1; - } else { - $ret=0; - } - last - if( $ret==1 ); - $ress .= "not found, answer was "; - for($i=0;$i".$ob."<="; - if( !defined($ob)){ - $ob=""; - $ret=0; - }elsif( $ob =~ m/OK.*/){ - $owx_interface="CUNO"; - $ress .= "DS2482 detected in $owx_hwdevice->{NAME}"; - $ret=1; - } else { - $ret=0; - } - last - if( $ret==1 ); - $ress .= "not found, answer was ".$ob; - Log 1, $ress; - $ress = $ress0; - #-- sleeping for some time - select(undef,undef,undef,0.5); - } - if( $ret == 0 ){ - $owx_interface=undef; - $ress .= "in $owx_hwdevice->{NAME} could not be addressed"; - } - } - #-- store with OWX device - $hash->{INTERFACE} = $owx_interface; - Log 1, $ress; - return $ret; -} - -######################################################################################## -# -# OWX_Discover - Discover devices on the 1-Wire bus, -# autocreate devices if not already present -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : no device present -# -######################################################################################## - -sub OWX_Discover ($) { - my ($hash) = @_; - my $res; - my $name = $hash->{NAME}; - - #-- get the interface - $owx_interface = $hash->{INTERFACE}; - $owx_hwdevice = $hash->{HWDEVICE}; - - #-- Discover all devices on the 1-Wire bus - @owx_devs=(); - my @owx_names=(); - #-- directly connected interface - if( $owx_interface =~ m/DS.*/ ){ - $res = OWX_First_SER($hash,"discover"); - while( $owx_LastDeviceFlag==0 && $res!=0 ){ - $res = $res & OWX_Next_SER($hash,"discover"); - } - #-- Ask the cuno - }else { - CUL_SimpleWrite($owx_hwdevice, "OCf"); - #-- sleeping for some time - select(undef,undef,undef,3); - CUL_SimpleWrite($owx_hwdevice, "Oc"); - select(undef,undef,undef,0.5); - my $ob = OWX_SimpleRead($owx_hwdevice); - if( $ob ){ - foreach my $dx (split(/\n/,$ob)){ - $dx =~ s/\d+\://; - my $ddx = substr($dx,14,2)."."; - #-- reverse data from culfw - for( my $i=1;$i<7;$i++){ - $ddx .= substr($dx,14-2*$i,2); - } - $ddx .= ".".substr($dx,0,2); - push (@owx_devs,$ddx); - } - } - } - #-- Go through all devices found on this bus - foreach my $owx_dev (@owx_devs) { - #-- three pieces of the ROM ID found on the bus - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - my $owx_crc = substr($owx_dev,15,3); - my $id_owx = $owx_f.".".$owx_rnf; - - my $match = 0; - - #-- Check against all existing devices - foreach my $fhem_dev (sort keys %main::defs) { - #-- skip if busmaster - # next if( $hash->{NAME} eq $main::defs{$fhem_dev}{NAME} ); - #-- all OW types start with OW - next if( substr($main::defs{$fhem_dev}{TYPE},0,2) ne "OW"); - my $id_fhem = substr($main::defs{$fhem_dev}{ROM_ID},0,15); - #-- skip interface device - next if( length($id_fhem) != 15 ); - #-- testing if equal to the one found here - # even with improper family - # Log 1, " FHEM-Device = ".substr($id_fhem,3,12)." OWX discovered device ".substr($id_owx,3,12); - if( substr($id_fhem,3,12) eq substr($id_owx,3,12) ) { - #-- warn if improper family id - if( substr($id_fhem,0,2) ne substr($id_owx,0,2) ){ - Log 1, "OWX: Warning, $fhem_dev is defined with improper family id ".substr($id_fhem,0,2). - ", correcting to ".substr($id_owx,0,2); - $main::defs{$fhem_dev}{OW_FAMILY} = substr($id_owx,0,2); - } - push(@owx_names,$main::defs{$fhem_dev}{NAME}); - #-- replace the ROM ID by the proper value including CRC - $main::defs{$fhem_dev}{ROM_ID}=$owx_dev; - $main::defs{$fhem_dev}{PRESENT}=1; - $match = 1; - last; - } - # - } - - #-- autocreate the device - if( $match==0 ){ - #-- Default name OWX_FF_XXXXXXXXXXXX, default type = OWX_FF - my $name = sprintf "OWX_%s_%s",$owx_f,$owx_rnf; - #-- Family 10 = Temperature sensor, assume DS1820 as default - if( $owx_f eq "10" ){ - CommandDefine(undef,"$name OWTHERM DS1820 $owx_rnf"); - #-- Family 12 = Switch, assume DS2406 as default - }elsif( $owx_f eq "12" ){ - CommandDefine(undef,"$name OWSWITCH DS2406 $owx_rnf"); - #-- Family 1D = Counter/RAM, assume DS2423 as default - }elsif( $owx_f eq "1D" ){ - CommandDefine(undef,"$name OWCOUNT DS2423 $owx_rnf"); - #-- Family 20 = A/D converter, assume DS2450 as default - } elsif( $owx_f eq "20" ){ - CommandDefine(undef,"$name OWAD DS2450 $owx_rnf"); - #-- Family 22 = Temperature sensor, assume DS1822 as default - }elsif( $owx_f eq "22" ){ - CommandDefine(undef,"$name OWTHERM DS1822 $owx_rnf"); - #-- Family 26 = Multisensor, assume DS2438 as default - }elsif( $owx_f eq "26" ){ - CommandDefine(undef,"$name OWMULTI DS2438 $owx_rnf"); - #-- Family 28 = Temperature sensor, assume DS18B20 as default - }elsif( $owx_f eq "28" ){ - CommandDefine(undef,"$name OWTHERM DS18B20 $owx_rnf"); - #-- Family 29 = Switch, assume DS2408 as default - }elsif( $owx_f eq "29" ){ - CommandDefine(undef,"$name OWSWITCH DS2408 $owx_rnf"); - #-- Family 3A = Switch, assume DS2413 as default - }elsif( $owx_f eq "3A" ){ - CommandDefine(undef,"$name OWSWITCH DS2413 $owx_rnf"); - #-- Family FF = LCD display - }elsif( $owx_f eq "FF" ){ - CommandDefine(undef,"$name OWLCD $owx_rnf"); - #-- All unknown families are ID only (ID-Chips have family id 09) - } else { - CommandDefine(undef,"$name OWID $owx_f $owx_rnf"); - } - #-- yes, it is on the bus and therefore present - push(@owx_names,$name); - $main::defs{$name}{PRESENT}=1; - #-- THIS IODev, default room - CommandAttr (undef,"$name IODev $hash->{NAME}"); - CommandAttr (undef,"$name room OWX"); - #-- replace the ROM ID by the proper value - $main::defs{$name}{ROM_ID}=$owx_dev; - } - } - - #-- final step: Undefine all 1-Wire devices which are not on this bus but have this IODev - foreach my $fhem_dev (sort keys %main::defs) { - #-- skip if malformed device - #next if( !defined($main::defs{$fhem_dev}{NAME}) ); - #-- all OW types start with OW - next if( substr($main::defs{$fhem_dev}{TYPE},0,2) ne "OW"); - #-- skip if the device is present. - next if( $main::defs{$fhem_dev}{PRESENT} == 1); - #-- skip if different IODev - next if( $main::defs{$fhem_dev}{IODev}{NAME} ne $hash->{NAME} ); - Log 1, "OWX: Deleting unused 1-Wire device $main::defs{$fhem_dev}{NAME} of type $main::defs{$fhem_dev}{TYPE}"; - CommandDelete(undef,$main::defs{$fhem_dev}{NAME}); - } - Log 1, "OWX: 1-Wire devices found on bus $name: (".join(",",@owx_names).")"; - return "OWX: 1-Wire devices found on bus $name: (".join(",",@owx_names).")"; -} - -######################################################################################## -# -# OWX_Get - Implements GetFn function -# -# Parameter hash = hash of the bus master a = argument array -# -######################################################################################## - -sub OWX_Get($@) { - my ($hash, @a) = @_; - return "OWX: Get needs exactly one parameter" if(@a != 2); - - my $name = $hash->{NAME}; - my $owx_dev = $hash->{ROM_ID}; - - if( $a[1] eq "alarms") { - my $res = OWX_Alarms($hash); - #-- process result - return $res - - } elsif( $a[1] eq "devices") { - my $res = OWX_Discover($hash); - #-- process result - return $res - - } else { - return "OWX: Get with unknown argument $a[1], choose one of ". - join(",", sort keys %gets); - } -} - -######################################################################################## -# -# OWX_Kick - Initiate some processes in all devices -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : Not OK -# -######################################################################################## - -sub OWX_Kick($) { - my($hash) = @_; - my $ret; - - #-- Call us in n seconds again. - InternalTimer(gettimeofday()+ $hash->{interval}, "OWX_Kick", $hash,1); - #-- During reset we see if an alarmed device is present. - OWX_Reset($hash); - - #-- Only if we have real power on the bus - if( defined($attr{$hash->{NAME}}{buspower}) && ($attr{$hash->{NAME}}{buspower} eq "real") ){ - #-- issue the skip ROM command \xCC followed by start conversion command \x44 - $ret = OWX_Complex($hash,"","\xCC\x44",0); - if( $ret eq 0 ){ - Log 3, "OWX: Failure in temperature conversion\n"; - return 0; - } - #-- sleeping for some time - select(undef,undef,undef,0.5); - } - return 1; -} - -######################################################################################## -# -# OWX_Reset - Reset the 1-Wire bus -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : not OK -# -######################################################################################## - -sub OWX_Reset ($) { - my ($hash)=@_; - - #-- get the interface - $owx_interface = $hash->{INTERFACE}; - $owx_hwdevice = $hash->{HWDEVICE}; - - #-- interface error - if( !(defined($owx_interface))){ - Log 3,"OWX: Reset called with undefined interface"; - return 0; - }elsif( $owx_interface eq "DS2480" ){ - return OWX_Reset_2480($hash); - }elsif( $owx_interface eq "DS9097" ){ - return OWX_Reset_9097($hash); - }elsif( $owx_interface eq "CUNO" ){ - return OWX_Reset_CUNO($hash); - }else{ - Log 3,"OWX: Reset called with unknown interface $owx_interface"; - return 0; - } -} - -######################################################################################## -# -# OWX_Set - Implements SetFn function -# -# Parameter hash , a = argument array -# -######################################################################################## - -sub OWX_Set($@) { - my ($hash, @a) = @_; - my $name = shift @a; - my $res; - - #-- First we need to find the ROM ID corresponding to the device name - my $owx_romid = $hash->{ROM_ID}; - Log 5, "OWX_Set request $name $owx_romid ".join(" ",@a); - - #-- for the selector: which values are possible - return join(" ", sort keys %sets) if(@a != 2); - return "OWX_Set: With unknown argument $a[0], choose one of " . join(" ", sort keys %sets) - if(!defined($sets{$a[0]})); - - #-- Set timer value - if( $a[0] eq "interval" ){ - #-- only values >= 15 secs allowed - if( $a[1] >= 15){ - $hash->{interval} = $a[1]; - $res = 1; - } else { - $res = 0; - } - } - - #-- Set alarm behaviour - if( $a[0] eq "followAlarms" ){ - #-- only values >= 15 secs allowed - if( (lc($a[1]) eq "off") && ($hash->{followAlarms} eq "on") ){ - $hash->{interval} = "off"; - $res = 1; - }elsif( (lc($a[1]) eq "on") && ($hash->{followAlarms} eq "off") ){ - $hash->{interval} = "off"; - $res = 1; - } else { - $res = 0; - } - - } - Log GetLogLevel($name,3), "OWX_Set $name ".join(" ",@a)." => $res"; - DoTrigger($name, undef) if($init_done); - return "OWX_Set => $name ".join(" ",@a)." => $res"; -} - -######################################################################################## -# -# OWX_Undef - Implements UndefFn function -# -# Parameter hash = hash of the bus master, name -# -######################################################################################## - -sub OWX_Undef ($$) { - my ($hash, $name) = @_; - RemoveInternalTimer($hash); - DevIo_CloseDev($hash); - return undef; -} - -######################################################################################## -# -# OWX_Verify - Verify a particular device on the 1-Wire bus -# -# Parameter hash = hash of bus master, dev = 8 Byte ROM ID of device to be tested -# -# Return 1 : device found -# 0 : device not -# -######################################################################################## - -sub OWX_Verify ($$) { - my ($hash,$dev) = @_; - my $i; - - #-- get the interface - $owx_interface = $hash->{INTERFACE}; - $owx_hwdevice = $hash->{HWDEVICE}; - - #-- directly connected interface - if( ($owx_interface eq "DS2480") || ($owx_interface eq "DS9097") ){ - return OWX_Verify_SER($hash,$dev) - #-- Ask the cuno - }elsif( $owx_interface eq "CUNO" ) { - return OWX_Verify_CUNO($hash,$dev) - } else { - Log 1,"OWX: Verify called with unknown interface"; - return 0; - } -} - -######################################################################################## -# -# The following subroutines in alphabetical order are only for direct serial bus interface -# -######################################################################################## -# -# OWX_Complex_SER - Send match ROM, data block and receive bytes as response -# -# Parameter hash = hash of bus master, -# owx_dev = ROM ID of device -# data = string to send -# numread = number of bytes to receive -# -# Return response, if OK -# 0 if not OK -# -######################################################################################## - -sub OWX_Complex_SER ($$$$) { - my ($hash,$owx_dev,$data,$numread) =@_; - - my $select; - my $res = ""; - my $res2 = ""; - my ($i,$j,$k); - - #-- has match ROM part - if( $owx_dev ){ - #-- ID of the device - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- 8 byte 1-Wire device address - my @owx_ROM_ID =(0,0,0,0 ,0,0,0,0); - #-- from search string to byte id - $owx_dev=~s/\.//g; - for(my $i=0;$i<8;$i++){ - $owx_ROM_ID[$i]=hex(substr($owx_dev,2*$i,2)); - } - $select=sprintf("\x55%c%c%c%c%c%c%c%c",@owx_ROM_ID).$data; - #-- has no match ROM part - } else { - $select=$data; - } - #-- has receive data part - if( $numread >0 ){ - #$numread += length($data); - for( my $i=0;$i<$numread;$i++){ - $select .= "\xFF"; - }; - } - - #-- for debugging - if( $owx_debug > 1){ - $res2 = "OWX_Complex_SER: Sending out "; - for($i=0;$i 1){ - $res2 = "OWX_Complex_SER: Receiving "; - for($i=0;$i{HWDEVICE}; - $owx_hwdevice->baudrate($owx_baud); - $owx_hwdevice->write_settings; - - if( $owx_debug > 2){ - my $res = "OWX: Sending out "; - for($i=0;$iwrite($cmd); - - Log 1, "OWX: Write incomplete $count_out ne ".(length($cmd))."" if ( $count_out != length($cmd) ); - #-- sleeping for some time - select(undef,undef,undef,0.04); - - #-- read the data - my ($count_in, $string_in) = $owx_hwdevice->read(48); - - if( $owx_debug > 2){ - my $res = "OWX: Receiving "; - for($i=0;$i<$count_in;$i++){ - $j=int(ord(substr($string_in,$i,1))/16); - $k=ord(substr($string_in,$i,1))%16; - $res.=sprintf "0x%1x%1x ",$j,$k; - } - Log 3, $res; - } - - #-- sleeping for some time - select(undef,undef,undef,0.04); - return($string_in); -} - -######################################################################################## -# -# OWX_Reset_2480 - Reset the 1-Wire bus (Fig. 4 of Maxim AN192) -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : not OK -# -######################################################################################## - -sub OWX_Reset_2480 ($) { - - my ($hash)=@_; - my $cmd=""; - - my ($res,$r1,$r2); - #-- if necessary, prepend \xE3 character for command mode - if( $owx_mode ne "command" ){ - $cmd = "\xE3"; - } - #-- Reset command \xC5 - $cmd = $cmd."\xC5"; - #-- write 1-Wire bus - $res =OWX_Query_2480($hash,$cmd); - - #-- if not ok, try for max. a second time - $r1 = ord(substr($res,0,1)) & 192; - if( $r1 != 192){ - #Log 1, "Trying second reset"; - $res =OWX_Query_2480($hash,$cmd); - } - - #-- process result - $r1 = ord(substr($res,0,1)) & 192; - if( $r1 != 192){ - Log 3, "OWX: Reset failure"; - return 0; - } - $hash->{ALARMED} = "no"; - - $r2 = ord(substr($res,0,1)) & 3; - - if( $r2 == 3 ){ - #Log 3, "OWX: No presence detected"; - return 1; - }elsif( $r2 ==2 ){ - Log 1, "OWX: Alarm presence detected"; - $hash->{ALARMED} = "yes"; - } - return 1; -} - -######################################################################################## -# -# OWX_Search_2480 - Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing -# search state. -# -# Parameter hash = hash of bus master, mode=alarm,discover or verify -# -# Return 1 : device found, ROM number in owx_ROM_ID and pushed to list (LastDeviceFlag=0) -# or only in owx_ROM_ID (LastDeviceFlag=1) -# 0 : device not found, or ot searched at all -# -######################################################################################## - -sub OWX_Search_2480 ($$) { - my ($hash,$mode)=@_; - - my ($sp1,$sp2,$response,$search_direction,$id_bit_number); - - #-- Response search data parsing operates bytewise - $id_bit_number = 1; - - select(undef,undef,undef,0.5); - - #-- clear 16 byte of search data - @owx_search=(0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0); - #-- Output search data construction (Fig. 9 of Maxim AN192) - # operates on a 16 byte search response = 64 pairs of two bits - while ( $id_bit_number <= 64) { - #-- address single bits in a 16 byte search string - my $newcpos = int(($id_bit_number-1)/4); - my $newimsk = ($id_bit_number-1)%4; - #-- address single bits in a 8 byte id string - my $newcpos2 = int(($id_bit_number-1)/8); - my $newimsk2 = ($id_bit_number-1)%8; - - if( $id_bit_number <= $owx_LastDiscrepancy){ - #-- first use the ROM ID bit to set the search direction - if( $id_bit_number < $owx_LastDiscrepancy ) { - $search_direction = ($owx_ROM_ID[$newcpos2]>>$newimsk2) & 1; - #-- at the last discrepancy search into 1 direction anyhow - } else { - $search_direction = 1; - } - #-- fill into search data; - $owx_search[$newcpos]+=$search_direction<<(2*$newimsk+1); - } - #--increment number - $id_bit_number++; - } - #-- issue data mode \xE1, the normal search command \xF0 or the alarm search command \xEC - # and the command mode \xE3 / start accelerator \xB5 - if( $mode ne "alarm" ){ - $sp1 = "\xE1\xF0\xE3\xB5"; - } else { - $sp1 = "\xE1\xEC\xE3\xB5"; - } - #-- issue data mode \xE1, device ID, command mode \xE3 / end accelerator \xA5 - $sp2=sprintf("\xE1%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\xE3\xA5",@owx_search); - $response = OWX_Query_2480($hash,$sp1); - $response = OWX_Query_2480($hash,$sp2); - - #-- interpret the return data - if( length($response)!=16 ) { - Log 3, "OWX: Search 2nd return has wrong parameter with length = ".length($response).""; - return 0; - } - #-- Response search data parsing (Fig. 11 of Maxim AN192) - # operates on a 16 byte search response = 64 pairs of two bits - $id_bit_number = 1; - #-- clear 8 byte of device id for current search - @owx_ROM_ID =(0,0,0,0 ,0,0,0,0); - - while ( $id_bit_number <= 64) { - #-- adress single bits in a 16 byte string - my $newcpos = int(($id_bit_number-1)/4); - my $newimsk = ($id_bit_number-1)%4; - - #-- retrieve the new ROM_ID bit - my $newchar = substr($response,$newcpos,1); - - #-- these are the new bits - my $newibit = (( ord($newchar) >> (2*$newimsk) ) & 2) / 2; - my $newdbit = ( ord($newchar) >> (2*$newimsk) ) & 1; - - #-- output for test purpose - #print "id_bit_number=$id_bit_number => newcpos=$newcpos, newchar=0x".int(ord($newchar)/16). - # ".".int(ord($newchar)%16)." r$id_bit_number=$newibit d$id_bit_number=$newdbit\n"; - - #-- discrepancy=1 and ROM_ID=0 - if( ($newdbit==1) and ($newibit==0) ){ - $owx_LastDiscrepancy=$id_bit_number; - if( $id_bit_number < 9 ){ - $owx_LastFamilyDiscrepancy=$id_bit_number; - } - } - #-- fill into device data; one char per 8 bits - $owx_ROM_ID[int(($id_bit_number-1)/8)]+=$newibit<<(($id_bit_number-1)%8); - - #-- increment number - $id_bit_number++; - } - return 1; -} - -######################################################################################## -# -# OWX_WriteBytePower_2480 - Send byte to bus with power increase (Fig. 16 of Maxim AN192) -# -# Parameter hash = hash of bus master, dbyte = byte to send -# -# Return 1 : OK -# 0 : not OK -# -######################################################################################## - -sub OWX_WriteBytePower_2480 ($$) { - - my ($hash,$dbyte) =@_; - my $cmd="\x3F"; - my $ret="\x3E"; - #-- if necessary, prepend \xE3 character for command mode - if( $owx_mode ne "command") { - $cmd = "\xE3".$cmd; - } - #-- distribute the bits of data byte over several command bytes - for (my $i=0;$i<8;$i++){ - my $newbit = (ord($dbyte) >> $i) & 1; - my $newchar = 133 | ($newbit << 4); - my $newchar2 = 132 | ($newbit << 4) | ($newbit << 1) | $newbit; - #-- last command byte still different - if( $i == 7){ - $newchar = $newchar | 2; - } - $cmd = $cmd.chr($newchar); - $ret = $ret.chr($newchar2); - } - #-- write 1-Wire bus - my $res = OWX_Query($hash,$cmd); - #-- process result - if( $res eq $ret ){ - Log 5, "OWX: WriteBytePower OK"; - return 1; - } else { - Log 3, "OWX: WriteBytePower failure"; - return 0; - } -} - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a DS9097 bus interface -# -######################################################################################## -# -# OWX_Block_9097 - Send data block ( -# -# Parameter hash = hash of bus master, data = string to send -# -# Return response, if OK -# 0 if not OK -# -######################################################################################## - -sub OWX_Block_9097 ($$) { - my ($hash,$data) =@_; - - my $data2=""; - my $res=0; - for (my $i=0; $i{HWDEVICE}; - $owx_hwdevice->baudrate($owx_baud); - $owx_hwdevice->write_settings; - - if( $owx_debug > 2){ - my $res = "OWX: Sending out "; - for($i=0;$iwrite($cmd); - - Log 1, "OWX: Write incomplete $count_out ne ".(length($cmd))."" if ( $count_out != length($cmd) ); - #-- sleeping for some time - select(undef,undef,undef,0.01); - - #-- read the data - my ($count_in, $string_in) = $owx_hwdevice->read(48); - - if( $owx_debug > 2){ - my $res = "OWX: Receiving "; - for($i=0;$i<$count_in;$i++){ - $j=int(ord(substr($string_in,$i,1))/16); - $k=ord(substr($string_in,$i,1))%16; - $res.=sprintf "0x%1x%1x ",$j,$k; - } - Log 3, $res; - } - - #-- sleeping for some time - select(undef,undef,undef,0.01); - - return($string_in); -} - -######################################################################################## -# -# OWX_ReadBit_9097 - Read 1 bit from 1-wire bus (Fig. 5/6 from Maxim AN214) -# -# Parameter hash = hash of bus master -# -# Return bit value -# -######################################################################################## - -sub OWX_ReadBit_9097 ($) { - my ($hash) = @_; - - #-- set baud rate to 115200 and query!!! - my $sp1="\xFF"; - $owx_baud=115200; - my $res=OWX_Query_9097($hash,$sp1); - $owx_baud=9600; - #-- process result - if( substr($res,0,1) eq "\xFF" ){ - return 1; - } else { - return 0; - } -} - -######################################################################################## -# -# OWX_Reset_9097 - Reset the 1-Wire bus (Fig. 4 of Maxim AN192) -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : not OK -# -######################################################################################## - -sub OWX_Reset_9097 ($) { - - my ($hash)=@_; - my $cmd=""; - - #-- Reset command \xF0 - $cmd="\xF0"; - #-- write 1-Wire bus - my $res =OWX_Query_9097($hash,$cmd); - #-- TODO: process result - #-- may vary between 0x10, 0x90, 0xe0 - return 1; -} - -######################################################################################## -# -# OWX_Search_9097 - Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing -# search state. -# -# Parameter hash = hash of bus master, mode=alarm,discover or verify -# -# Return 1 : device found, ROM number in owx_ROM_ID and pushed to list (LastDeviceFlag=0) -# or only in owx_ROM_ID (LastDeviceFlag=1) -# 0 : device not found, or ot searched at all -# -######################################################################################## - -sub OWX_Search_9097 ($$) { - - my ($hash,$mode)=@_; - - my ($sp1,$sp2,$response,$search_direction,$id_bit_number); - - #-- Response search data parsing operates bitwise - $id_bit_number = 1; - my $rom_byte_number = 0; - my $rom_byte_mask = 1; - my $last_zero = 0; - - #-- issue search command - $owx_baud=115200; - $sp2="\x00\x00\x00\x00\xFF\xFF\xFF\xFF"; - $response = OWX_Query_9097($hash,$sp2); - $owx_baud=9600; - #-- issue the normal search command \xF0 or the alarm search command \xEC - #if( $mode ne "alarm" ){ - # $sp1 = 0xF0; - #} else { - # $sp1 = 0xEC; - #} - - #$response = OWX_TouchByte($hash,$sp1); - - #-- clear 8 byte of device id for current search - @owx_ROM_ID =(0,0,0,0 ,0,0,0,0); - - while ( $id_bit_number <= 64) { - #loop until through all ROM bytes 0-7 - my $id_bit = OWX_TouchBit_9097($hash,1); - my $cmp_id_bit = OWX_TouchBit_9097($hash,1); - - #print "id_bit = $id_bit, cmp_id_bit = $cmp_id_bit\n"; - - if( ($id_bit == 1) && ($cmp_id_bit == 1) ){ - #print "no devices present at id_bit_number=$id_bit_number \n"; - next; - } - if ( $id_bit != $cmp_id_bit ){ - $search_direction = $id_bit; - } else { - # hä ? if this discrepancy if before the Last Discrepancy - # on a previous next then pick the same as last time - if ( $id_bit_number < $owx_LastDiscrepancy ){ - if (($owx_ROM_ID[$rom_byte_number] & $rom_byte_mask) > 0){ - $search_direction = 1; - } else { - $search_direction = 0; - } - } else { - # if equal to last pick 1, if not then pick 0 - if ($id_bit_number == $owx_LastDiscrepancy){ - $search_direction = 1; - } else { - $search_direction = 0; - } - } - # if 0 was picked then record its position in LastZero - if ($search_direction == 0){ - $last_zero = $id_bit_number; - # check for Last discrepancy in family - if ($last_zero < 9) { - $owx_LastFamilyDiscrepancy = $last_zero; - } - } - } - # print "search_direction = $search_direction, last_zero=$last_zero\n"; - # set or clear the bit in the ROM byte rom_byte_number - # with mask rom_byte_mask - #print "ROM byte mask = $rom_byte_mask, search_direction = $search_direction\n"; - if ( $search_direction == 1){ - $owx_ROM_ID[$rom_byte_number] |= $rom_byte_mask; - } else { - $owx_ROM_ID[$rom_byte_number] &= ~$rom_byte_mask; - } - # serial number search direction write bit - $response = OWX_WriteBit_9097($hash,$search_direction); - # increment the byte counter id_bit_number - # and shift the mask rom_byte_mask - $id_bit_number++; - $rom_byte_mask <<= 1; - #-- if the mask is 0 then go to new rom_byte_number and - if ($rom_byte_mask == 256){ - $rom_byte_number++; - $rom_byte_mask = 1; - } - $owx_LastDiscrepancy = $last_zero; - } - return 1; -} - -######################################################################################## -# -# OWX_TouchBit_9097 - Write/Read 1 bit from 1-wire bus (Fig. 5-8 from Maxim AN 214) -# -# Parameter hash = hash of bus master -# -# Return bit value -# -######################################################################################## - -sub OWX_TouchBit_9097 ($$) { - my ($hash,$bit) = @_; - - my $sp1; - #-- set baud rate to 115200 and query!!! - if( $bit == 1 ){ - $sp1="\xFF"; - } else { - $sp1="\x00"; - } - $owx_baud=115200; - my $res=OWX_Query_9097($hash,$sp1); - $owx_baud=9600; - #-- process result - my $sp2=substr($res,0,1); - if( $sp1 eq $sp2 ){ - return 1; - }else { - return 0; - } -} - -######################################################################################## -# -# OWX_TouchByte_9097 - Write/Read 8 bit from 1-wire bus -# -# Parameter hash = hash of bus master -# -# Return bit value -# -######################################################################################## - -sub OWX_TouchByte_9097 ($$) { - my ($hash,$byte) = @_; - - my $loop; - my $result=0; - my $bytein=$byte; - - for( $loop=0; $loop < 8; $loop++ ){ - #-- shift result to get ready for the next bit - $result >>=1; - #-- if sending a 1 then read a bit else write 0 - if( $byte & 0x01 ){ - if( OWX_ReadBit_9097($hash) ){ - $result |= 0x80; - } - } else { - OWX_WriteBit_9097($hash,0); - } - $byte >>= 1; - } - return $result; -} - -######################################################################################## -# -# OWX_WriteBit_9097 - Write 1 bit to 1-wire bus (Fig. 7/8 from Maxim AN 214) -# -# Parameter hash = hash of bus master -# -# Return bit value -# -######################################################################################## - -sub OWX_WriteBit_9097 ($$) { - my ($hash,$bit) = @_; - - my $sp1; - #-- set baud rate to 115200 and query!!! - if( $bit ==1 ){ - $sp1="\xFF"; - } else { - $sp1="\x00"; - } - $owx_baud=115200; - my $res=OWX_Query_9097($hash,$sp1); - $owx_baud=9600; - #-- process result - if( substr($res,0,1) eq $sp1 ){ - return 1; - } else { - return 0; - } -} - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a CUNO interface -# -######################################################################################## -# -# OWX_Complex_CUNO - Send match ROM, data block and receive bytes as response -# -# Parameter hash = hash of bus master, -# owx_dev = ROM ID of device -# data = string to send -# numread = number of bytes to receive -# -# Return response, if OK -# 0 if not OK -# -######################################################################################## - -sub OWX_Complex_CUNO ($$$$) { - my ($hash,$owx_dev,$data,$numread) =@_; - - my $select; - my $res = ""; - - #-- has match ROM part - if( $owx_dev ){ - #-- ID of the device - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- 8 byte 1-Wire device address - my @owx_ROM_ID =(0,0,0,0 ,0,0,0,0); - #-- from search string to reverse string id - $owx_dev=~s/\.//g; - for(my $i=0;$i<8;$i++){ - $owx_ROM_ID[7-$i]=substr($owx_dev,2*$i,2); - } - $select=sprintf("Om%s%s%s%s%s%s%s%s",@owx_ROM_ID); - Log 3,"OWX: Sending match ROM to CUNO ".$select - if( $owx_debug > 1); - CUL_SimpleWrite($owx_hwdevice, $select); - my $ob = OWX_SimpleRead($owx_hwdevice); - #-- padding first 9 bytes into result string, since we have this - # in the serial interfaces as well - $res .= "000000000"; - } - #-- has data part - if ( $data ){ - OWX_Send_CUNO($hash,$data); - $res .= $data; - } - #-- has receive part - if( $numread > 0 ){ - #$numread += length($data); - $res.=OWX_Receive_CUNO($hash,$numread); - } - Log 3,"OWX: returned from CUNO $res" - if( $owx_debug > 1); - return $res; -} - -######################################################################################## -# -# OWX_Receive_CUNO - Read from the CUNO -# -# Parameter: hash = hash of bus master, numread = number of bytes to read -# -# Return: string received from the CUNO -# -######################################################################################## - -sub OWX_Receive_CUNO ($$) { - my ($hash,$numread) = @_; - my $res=""; - my $res2=""; - - for( - my $i=0;$i<$numread;$i++){ - CUL_SimpleWrite($owx_hwdevice, "OrB"); - my $ob = OWX_SimpleRead($owx_hwdevice); - #-- process results - if( !(defined($ob)) ){ - return ""; - #-- four bytes received makes one byte of result - }elsif( length($ob) == 4 ){ - $res .= sprintf("%c",hex(substr($ob,0,2))); - $res2 .= "0x".substr($ob,0,2)." "; - #-- 20 bytes received = leftover from match - }elsif( length($ob) == 20 ){ - $numread++; - }else{ - Log 1,"OWX: Received unexpected number of ".length($ob)." bytes from CUNO/COC"; - } - } - Log 3, "OWX: Receive from CUNO/COC $numread bytes = $res2" - if( $owx_debug > 1); - - return($res); -} - -######################################################################################## -# -# OWX_Reset_CUNO - Reset the 1-Wire bus -# -# Parameter hash = hash of bus master -# -# Return 1 : OK -# 0 : not OK -# -######################################################################################## - -sub OWX_Reset_CUNO ($) { - CUL_SimpleWrite($owx_hwdevice, "ORb"); - my $ob = OWX_SimpleRead($owx_hwdevice); - if( substr($ob,0,4) eq "OK:1" ){ - return 1; - }else{ - return 0 - } -} - -######################################################################################### -# -# OWX_Send_CUNO - Send data block -# -# Parameter hash = hash of bus master, data = string to send -# -# Return response, if OK -# 0 if not OK -# -######################################################################################## - -sub OWX_Send_CUNO ($$) { - my ($hash,$data) =@_; - my ($i,$j,$k); - my $res = ""; - my $res2 = ""; - - for( $i=0;$i 1); -} - -######################################################################################### -# -# OWX_SimpleRead - Reading with retry. -# Suggested in this way by Dirk Tostmann -# -# Parameter hash = hash of device -# -# Return response, if OK -# 0 if not OK -# -######################################################################################## - -sub OWX_SimpleRead($) -{ - my ($hash) = @_; - my $buf = DevIo_DoSimpleRead($owx_hwdevice); - - # Lets' try again: Some drivers return len(0) on the first read... - if(defined($buf) && length($buf) == 0) { - #-- allow some time - select(undef,undef,undef,0.5); - $buf = DevIo_DoSimpleRead($owx_hwdevice); - } - - if(!defined($buf) || length($buf) == 0) { - DevIo_Disconnected($hash); - return undef; - } - return $buf; -} -######################################################################################## -# -# OWX_Verify_CUNO - Verify a particular device on the 1-Wire bus -# -# Parameter hash = hash of bus master, dev = 8 Byte ROM ID of device to be tested -# -# Return 1 : device found -# 0 : device not -# -######################################################################################## - -sub OWX_Verify_CUNO ($$) { - my ($hash,$dev) = @_; - my $i; - - #-- Ask the cuno - CUL_SimpleWrite($owx_hwdevice, "OCf"); - #-- sleeping for some time - select(undef,undef,undef,3); - CUL_SimpleWrite($owx_hwdevice, "Oc"); - my $ob = OWX_SimpleRead($owx_hwdevice); - if( $ob ){ - foreach my $dx (split(/\n/,$ob)){ - $dx =~ s/\d+\://; - my $ddx = substr($dx,14,2)."."; - #-- reverse data from culfw - for( my $i=1;$i<7;$i++){ - $ddx .= substr($dx,14-2*$i,2); - } - $ddx .= ".".substr($dx,0,2); - return 1 if( $dev eq $ddx); - } - return 0; - } else { - return 0; - } -} - -1; diff --git a/fhem/contrib/1-Wire/21_OWAD.pm b/fhem/contrib/1-Wire/21_OWAD.pm deleted file mode 100644 index 17a0caa2b..000000000 --- a/fhem/contrib/1-Wire/21_OWAD.pm +++ /dev/null @@ -1,1024 +0,0 @@ -######################################################################################## -# -# OWAD.pm -# -# WIESO UNINITIALIZED in 623FF -# -# 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 -# -# Version 2.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWAD [] [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type. If omitted, we assume this to be an -# DS2450 A/D converter -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => FAM_ID.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get reading => measurement for all channels -# get alarm => alarm measurement settings for all channels -# get status => alarm and i/o status for all channels -# -# set interval => set period for measurement -# -# Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B,C,D -# Note: attributes are read only during initialization procedure - later changes are not used. -# -# attr event on-change/on-update = when to write an event (default= on-update) -# -# attr stateAL0 "" = character string for denoting low normal condition, default is green down triangle -# attr stateAH0 "" = character string for denoting high normal condition, default is green up triangle -# attr stateAL1 "" = character string for denoting low alarm condition, default is red down triangle -# attr stateAH1 "" = character string for denoting high alarm condition, default is red up triangle -# attr Name | = name for the channel | a type description for the measured value -# attr Unit | = unit of measurement for this channel | its abbreviation -# attr Offset = offset added to the reading in this channel -# attr Factor = factor multiplied to (reading+offset) in this channel -# attr Alarm = alarm setting in this channel, either both, low, high or none (default) -# attr Low = measurement value (on the scale determined by offset and factor) for low alarm -# attr High = measurement value (on the scale determined by offset and factor) for high alarm -# -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -use strict; -use warnings; -sub Log($$); - -#-- 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; -#-- channel values - always the raw values from the device -my @owg_val; -#-- channel mode - fixed for now -my @owg_mode = ("input","input","input","input"); -#-- resolution in bit - fixed for now -my @owg_resoln = (16,16,16,16); -#-- raw range in mV - fixed for now -my @owg_range = (5100,5100,5100,5100); -#-- alarm status 0 = disabled, 1 = enabled, but not alarmed, 2 = alarmed -my @owg_slow; -my @owg_shigh; -#-- alarm values - always the raw values committed to the device -my @owg_vlow; -my @owg_vhigh; -#-- variables for display strings -my ($stateal1,$stateah1,$stateal0,$stateah0); - -my %gets = ( - "id" => "", - "present" => "", - "interval" => "", - "reading" => "", - "alarm" => "", - "status" => "", -); - -my %sets = ( - "interval" => "" -); - -my %updates = ( - "present" => "", - "reading" => "", - "alarm" => "", - "status" => "" -); - - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWAD -# -######################################################################################## -# -# OWAD_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWAD_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWAD_Define"; - $hash->{UndefFn} = "OWAD_Undef"; - $hash->{GetFn} = "OWAD_Get"; - $hash->{SetFn} = "OWAD_Set"; - #Name = channel name - #Offset = a v(oltage) offset added to the reading - #Factor = a v(oltage) factor multiplied with (reading+offset) - #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 ". - "stateAL0 stateAL1 stateAH0 stateAH1 event:on-update,on-change "; - - for( my $i=0;$i<4;$i++ ){ - $attlist .= " ".$owg_fixed[$i]."Name"; - $attlist .= " ".$owg_fixed[$i]."Offset"; - $attlist .= " ".$owg_fixed[$i]."Factor"; - $attlist .= " ".$owg_fixed[$i]."Unit"; - $attlist .= " ".$owg_fixed[$i]."Alarm"; - $attlist .= " ".$owg_fixed[$i]."Low"; - $attlist .= " ".$owg_fixed[$i]."High"; - } - $hash->{AttrList} = $attlist; -} - -######################################################################################### -# -# OWAD_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################### - -sub OWAD_Define ($$) { - my ($hash, $def) = @_; - - # define OWAD [] [interval] - # e.g.: define flow OWAD 525715020000 300 - my @a = split("[ \t][ \t]*", $def); - - my ($name,$model,$fam,$id,$crc,$interval,$scale,$ret); - - #-- default - $name = $a[0]; - $interval = 300; - $scale = ""; - $ret = ""; - - #-- check syntax - return "OWAD: Wrong syntax, must be define OWAD [] [interval]" - if(int(@a) < 2 || int(@a) > 5); - - #-- check if this is an old style definition, e.g. is missing - my $a2 = $a[2]; - my $a3 = defined($a[3]) ? $a[3] : ""; - if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = "DS2450"; - $id = $a[2]; - if(int(@a)>=4) { $interval = $a[3]; } - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = $a[2]; - return "OWAD: Wrong 1-Wire device model $model" - if( $model ne "DS2450"); - $id = $a[3]; - if(int(@a)>=5) { $interval = $a[4]; } - } else { - return "OWAD: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # determine CRC Code - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC("20.".$id."00")) : "00"; - - #-- Define device internals - $hash->{ROM_ID} = "20.".$id.$crc; - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = "20"; - $hash->{PRESENT} = 0; - $hash->{INTERVAL} = $interval; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWAD: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - $modules{OWAD}{defptr}{$id} = $hash; - $hash->{STATE} = "Defined"; - Log 3, "OWAD: 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, "OWAD_InitializeDevice", $hash, 0); - - #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 0); - - return undef; -} - -######################################################################################## -# -# OWAD_InitializeDevice - delayed setting of initial readings and channel names -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWAD_InitializeDevice($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - - $stateal1 = defined($attr{$name}{stateAL1}) ? $attr{$name}{stateAL1} : ""; - $stateah1 = defined($attr{$name}{stateAH1}) ? $attr{$name}{stateAH1} : ""; - $stateal0 = defined($attr{$name}{stateAL0}) ? $attr{$name}{stateAL0} : ""; - $stateah0 = defined($attr{$name}{stateAH0}) ? $attr{$name}{stateAH0} : ""; - - #-- Initial readings - @owg_val = (0.0,0.0,0.0,0.0); - @owg_slow = (0,0,0,0); - @owg_shigh = (0,0,0,0); - - #-- Set channel names, channel units and alarm values - for( my $i=0;$i"; - 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|"; - 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 - $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]"}{OFFSET} = $offset; - $hash->{READINGS}{"$owg_channel[$i]"}{FACTOR} = $factor; - - #-- 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; - }; - $owg_vlow[$i] = ($vlow/$factor - $offset); - $owg_vhigh[$i] = ($vhigh/$factor - $offset); - } - - #-- set status according to interface type - my $interface= $hash->{IODev}->{TYPE}; - - #-- OWX interface - if( !defined($interface) ){ - return "OWAD: Interface missing"; - } elsif( $interface eq "OWX" ){ - OWXAD_SetPage($hash,"alarm"); - OWXAD_SetPage($hash,"status"); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); - #-- Unknown interface - }else{ - return "OWAD: InitializeDevice with wrong IODev type $interface"; - } - - #-- Initialize all the display stuff - OWAD_FormatValues($hash); -} - -######################################################################################## -# -# OWAD_FormatValues - put together various format strings -# -# Parameter hash = hash of device addressed, fs = format string -# -######################################################################################## - -sub OWAD_FormatValues($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - my ($offset,$factor,$vval,$vlow,$vhigh); - my ($value1,$value2,$value3) = ("","",""); - my $galarm = 0; - - my $tn = TimeNow(); - - #-- formats for output - for (my $i=0;$i{READINGS}{"$owg_channel[$i]"}{OFFSET}; - $factor = $hash->{READINGS}{"$owg_channel[$i]"}{FACTOR}; - #-- correct values for proper offset, factor - $vval = int(($owg_val[$i] + $offset)*$factor*1000)/1000;; - #-- put into READINGS - $hash->{READINGS}{"$owg_channel[$i]"}{VAL} = $vval; - $hash->{READINGS}{"$owg_channel[$i]"}{TIME} = $tn; - - #-- correct alarm values for proper offset, factor - $vlow = int(($owg_vlow[$i] + $offset)*$factor*1000)/1000; - $vhigh = int(($owg_vhigh[$i] + $offset)*$factor*1000)/1000; - - #-- put into READINGS - $hash->{READINGS}{$owg_channel[$i]."Low"}{VAL} = $vlow; - $hash->{READINGS}{$owg_channel[$i]."Low"}{TIME} = $tn; - $hash->{READINGS}{$owg_channel[$i]."High"}{VAL} = $vhigh; - $hash->{READINGS}{$owg_channel[$i]."High"}{TIME} = $tn; - - #-- string buildup for return value, STATE and alarm - $value1 .= 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]); - - #-- Test for alarm condition - #-- alarm signature low - if( $owg_slow[$i] == 0 ) { - #$value2 .= " "; - $value3 .= "-"; - } else { - if( $vval > $vlow ){ - $owg_slow[$i] = 1; - $value2 .= $stateal0; - $value3 .= $stateal0; - } else { - $galarm = 1; - $owg_slow[$i] = 2; - $value2 .= $stateal1; - $value3 .= $stateal1; - } - } - #-- alarm signature high - if( $owg_shigh[$i] == 0 ) { - #$value2 .= " "; - $value3 .= "-"; - } else { - if( $vval < $vhigh ){ - $owg_shigh[$i] = 1; - $value2 .= $stateah0; - $value3 .= $stateah0; - } else { - $galarm = 1; - $owg_shigh[$i] = 2; - $value2 .= $stateah1; - $value3 .= $stateah1; - } - } - - #-- insert comma - if( $i{STATE} = $value2; - #-- alarm - $hash->{ALARM} = $galarm; - $hash->{READINGS}{alarms}{VAL} = $value3; - $hash->{READINGS}{alarms}{TIME} = $tn; - return $value1; -} - -######################################################################################## -# -# OWAD_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWAD_Get($@) { - my ($hash, @a) = @_; - - my $reading = $a[1]; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my ($value,$value2,$value3) = (undef,undef,undef); - my $ret = ""; - my $offset; - my $factor; - - #-- check syntax - return "OWAD: Get argument is missing @a" - if(int(@a) != 2); - - #-- check argument - return "OWAD: 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"; - } - - #-- get present - if($a[1] eq "present") { - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } - - #-- get interval - if($a[1] eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - - #-- reset presence - $hash->{PRESENT} = 0; - - #-- get reading according to interface type - my $interface= $hash->{IODev}->{TYPE}; - if($a[1] eq "reading") { - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXAD_GetPage($hash,"reading"); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); - #-- Unknown interface - }else{ - return "OWAD: Get with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - return "OWAD: $name.$reading => ".OWAD_FormatValues($hash); - } - - #-- get alarm values according to interface type - if($a[1] eq "alarm") { - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXAD_GetPage($hash,"alarm"); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"alarm"); - #-- Unknown interface - }else{ - return "OWAD: Get with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - OWAD_FormatValues($hash); - - #-- output string looks differently here - $value = ""; - for (my $i=0;$i{READINGS}{$owg_channel[$i]."Low"}{VAL}, - $hash->{READINGS}{$owg_channel[$i]."High"}{VAL}; - } - return "OWAD: $name.$reading => $value"; - } - - #-- get status values according to interface type - if($a[1] eq "status") { - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXAD_GetPage($hash,"status"); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"status"); - #-- Unknown interface - }else{ - return "OWAD: Get with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - OWAD_FormatValues($hash); - return "OWAD: $name.$reading => ".$hash->{READINGS}{alarms}{VAL}; - } -} - -####################################################################################### -# -# OWAD_GetValues - Updates the reading from one device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWAD_GetValues($) { - my $hash = shift; - - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my $value = ""; - my $ret = ""; - my $offset; - my $factor; - - #-- define warnings - my $warn = "none"; - $hash->{ALARM} = "0"; - - #-- restart timer for updates - RemoveInternalTimer($hash); - InternalTimer(time()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 1); - - #-- reset presence - $hash->{PRESENT} = 0; - - #-- Get readings, alarms and stati according to interface type - my $interface= $hash->{IODev}->{TYPE}; - if( $interface eq "OWX" ){ - $ret = OWXAD_GetPage($hash,"reading"); - $ret = OWXAD_GetPage($hash,"alarm"); - $ret = OWXAD_GetPage($hash,"status"); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); - }else{ - return "OWAD: GetValues with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWAD: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - - #-- old state, new state - my $oldval = $hash->{STATE}; - $value=OWAD_FormatValues($hash); - my $newval = $hash->{STATE}; - #--logging depends on setting of the event-attribute - 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; -} - -####################################################################################### -# -# OWAD_Set - Set one value for device -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWAD_Set($@) { - my ($hash, @a) = @_; - - my $key = $a[1]; - my $value = $a[2]; - - #-- for the selector: which values are possible - if (@a == 2){ - my $newkeys = join(" ", sort keys %sets); - for( my $i=0;$i{NAME}; - my $model = $hash->{OW_MODEL}; - - #-- set new timer interval - if($key eq "interval") { - # check value - return "OWAD: Set with short interval, must be > 1" - if(int($value) < 1); - # update timer - $hash->{INTERVAL} = $value; - RemoveInternalTimer($hash); - InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWAD_GetValues", $hash, 1); - return undef; - } - - #-- find out which channel we have - my $tc =$key; - if( $tc =~ s/(.*)(Alarm|Low|High)/$channel=$1/se ) { - for (my $i=0;$i{IODev}->{TYPE}; - - #-- check alarm values - if( $key =~ m/(.*)(Alarm)/ ) { - return "OWAD: Set with wrong value $value for $key, allowed is none/low/high/both" - if($value ne "none" && $value ne "low" && $value ne "high" && $value ne "both"); - if( $value eq "low" || $value eq "both" ){ - $owg_slow[$channo]=1; - } else{ - $owg_slow[$channo]=0; - } - if( $value eq "high" || $value eq "both" ){ - $owg_shigh[$channo]=1; - } else{ - $owg_shigh[$channo]=0; - } - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXAD_SetPage($hash,"status"); - return $ret - if(defined($ret)); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_SetValues($hash,@a); - # return $ret - # if(defined($ret)); - } else { - return "OWAD: Set with wrong IODev type $interface"; - } - }elsif( $key =~ m/(.*)(Low|High)/ ) { - $offset = $attr{$name}{$owg_fixed[$channo]."Offset"}; - $factor = $attr{$name}{$owg_fixed[$channo]."Factor"}; - - #-- find upper and lower boundaries for given offset/factor - my $mmin = 0.0; - - $mmin += $offset if ( $offset ); - $mmin *= $factor if ( $factor ); - - my $mmax = $owg_range[$channo]/1000; - $mmax += $offset if ( $offset ); - $mmax *= $factor if ( $factor ); - - return sprintf("OWAD: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax) - if($value < $mmin || $value > $mmax); - - $value /= $factor if ( $factor ); - $value -= $offset if ( $offset ); - #-- round to those numbers understood by the device - my $value2 = int($value*255000/$owg_range[$channo])*$owg_range[$channo]/255000; - - #-- set alarm value in the device - if( $key =~ m/(.*)Low/ ){ - $owg_vlow[$channo] = $value2; - } elsif( $key =~ m/(.*)High/ ){ - $owg_vhigh[$channo] = $value2; - } - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXAD_SetPage($hash,"alarm"); - return $ret - if(defined($ret)); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_SetValues($hash,@a); - # return $ret - # if(defined($ret)); - } else { - return "OWAD: Set with wrong IODev type $interface"; - } - } - - #-- process results - we have to reread the device - $hash->{PRESENT} = 1; - OWAD_GetValues($hash); - OWAD_FormatValues($hash); - Log 4, "OWAD: Set $hash->{NAME} $key $value"; - - return undef; -} - -######################################################################################## -# -# OWAD_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWAD_Undef ($) { - my ($hash) = @_; - delete($modules{OWAD}{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 = OWFSAD -# -######################################################################################## - - - - - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a 1-Wire bus connected -# directly to the FHEM server -# -# Prefix = OWXAD -# -######################################################################################## -# -# OWXAD_GetPage - Get one memory page from device -# -# Parameter hash = hash of device addressed -# page = "reading", "alarm" or "status" -# -######################################################################################## - -sub OWXAD_GetPage($$) { - - my ($hash,$page) = @_; - - my ($select, $res, $res2, $res3, @data); - - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #=============== get the voltage reading =============================== - if( $page eq "reading") { - OWX_Reset($master); - #-- issue the match ROM command \x55 and the start conversion command - $res= OWX_Complex($master,$owx_dev,"\x3C\x0F\x00\xFF\xFF",0); - if( $res eq 0 ){ - return "OWXAD: Device $owx_dev not accessible for conversion"; - } - #-- conversion needs some 5 ms per channel - select(undef,undef,undef,0.02); - - #-- issue the match ROM command \x55 and the read conversion page command - # \xAA\x00\x00 - $select="\xAA\x00\x00"; - #=============== get the alarm reading =============================== - } elsif ( $page eq "alarm" ) { - #-- issue the match ROM command \x55 and the read alarm page command - # \xAA\x10\x00 - $select="\xAA\x10\x00"; - #=============== get the status reading =============================== - } elsif ( $page eq "status" ) { - #-- issue the match ROM command \x55 and the read status memory page command - # \xAA\x08\x00 r - $select="\xAA\x08\x00"; - #=============== wrong value requested =============================== - } else { - return "OWXAD: Wrong memory page requested"; - } - - #-- reset the bus - OWX_Reset($master); - #-- reading 9 + 3 + 8 data bytes and 2 CRC bytes = 22 bytes - $res=OWX_Complex($master,$owx_dev,$select,10); - #Log 1, "OWXAD: Device $owx_dev returns data of length ".length($res); - if( $res eq 0 ){ - return "OWXAD: Device $owx_dev not accessible in reading $page page"; - } - - #-- reset the bus - OWX_Reset($master); - - #-- process results - @data=split(//,$res); - return "OWXAD: invalid data length, ".int(@data)." bytes" - if (@data != 22); - #return "invalid data" - # if (ord($data[17])<=0); - #return "invalid CRC" - # if (OWX_CRC8(substr($res,10,8),$data[18])==0); - - #=============== get the voltage reading =============================== - if( $page eq "reading"){ - for( $i=0;$i{ROM_ID}; - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #=============== set the alarm values =============================== - if ( $page eq "alarm" ) { - #-- issue the match ROM command \x55 and the set alarm page command - # \x55\x10\x00 reading 8 data bytes and 2 CRC bytes - $select="\x55\x10\x00"; - for( $i=0;$i<4;$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]); - } - #=============== set the status =============================== - } elsif ( $page eq "status" ) { - my ($sb1,$sb2); - #-- issue the match ROM command \x55 and the set status memory page command - # \x55\x08\x00 reading 8 data bytes and 2 CRC bytes - $select="\x55\x08\x00"; - for( $i=0;$i<4;$i++){ - if( $owg_mode[$i] eq "input" ){ - #-- resolution (TODO: check !) - $sb1 = $owg_resoln[$i]-1; - #-- alarm enabled - $sb2 = ( $owg_slow[$i] > 0 ) ? 4 : 0; - $sb2 += ( $owg_shigh[$i] > 0 ) ? 8 : 0; - #-- range - $sb2 |= 1 - if( $owg_range[$i] > 2550 ); - } else { - $sb1 = 128; - $sb2 = 0; - } - $select .= sprintf "%c\xFF\xFF\xFF",$sb1; - $select .= sprintf "%c\xFF\xFF\xFF",$sb2; - } - #=============== wrong page write attempt =============================== - } else { - return "OWXAD: Wrong memory page write attempt"; - } - - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- process results - if( $res eq 0 ){ - return "OWXAD: Device $owx_dev not accessible for writing"; - } - - return undef; -} - -1; diff --git a/fhem/contrib/1-Wire/21_OWCOUNT.pm b/fhem/contrib/1-Wire/21_OWCOUNT.pm deleted file mode 100644 index a5f159630..000000000 --- a/fhem/contrib/1-Wire/21_OWCOUNT.pm +++ /dev/null @@ -1,1020 +0,0 @@ -######################################################################################## -# -# OWCOUNT.pm -# -# FHEM module to commmunicate with 1-Wire Counter/RAM DS2423 -# -# 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 -# -# Version 2.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWCOUNT [] [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type. If omitted, we assume this to be an -# DS2423 Counter/RAM -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => FAM_ID.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get memory => 32 byte string from page 0..13 -# get midnight => todays starting value for counter -# get counter => value for counter -# get counters => values for both counters -# -# set interval => set query interval for measurement -# set memory => 32 byte string into page 0..13 -# set midnight => todays starting value for counter -# set init yes => re-initialize device -# -# Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B -# Note: attributes are read only during initialization procedure - later changes are not used. -# -# attr event on-change/on-update = when to write an event (default= on-update) -# -# attr UnitInReading = whether the physical unit is written into the reading = 1 (default) or 0 -# attr Name | = name for the channel | a type description for the measured value -# attr Unit | = unit of measurement for this channel | its abbreviation -# attr Offset = offset added to the reading in this channel -# attr Factor = factor multiplied to (reading+offset) in this channel -# attr Mode = counting mode = normal(default) or daily -# attr Period = period for rate calculation = hour (default), minute or second -# -# In normal counting mode each returned counting value will be factor*(reading+offset) -# In daily counting mode each returned counting value will be factor*(reading+offset)-midnight -# where midnight is stored as string in the 32 byte memory associated with the counter -# -# Log Lines -# after each interval : / : / -# 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 : : -# 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 -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -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; -#-- channel values - always the raw values from the device -my @owg_val; -my @owg_midnight; -my $owg_str; - -my %gets = ( - "id" => "", - "present" => "", - "interval" => "", - "memory" => "", - "midnight" => "", - "counter" => "", - "counters" => "" -); - -my %sets = ( - "interval" => "", - "memory" => "", - "midnight" => "", - "init" => "" -); - -my %updates = ( - "present" => "", - "counter" => "" -); - - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWCOUNT -# -######################################################################################## -# -# OWCOUNT_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWCOUNT_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWCOUNT_Define"; - $hash->{UndefFn} = "OWCOUNT_Undef"; - $hash->{GetFn} = "OWCOUNT_Get"; - $hash->{SetFn} = "OWCOUNT_Set"; - - #-- see header for attributes - my $attlist = "IODev do_not_notify:0,1 showtime:0,1 model:DS2423 loglevel:0,1,2,3,4,5 UnitInReading:0,1 ". - "event:on-update,on-change"; - for( my $i=0;$i{AttrList} = $attlist; -} - -######################################################################################### -# -# OWCOUNT_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################### - -sub OWCOUNT_Define ($$) { - my ($hash, $def) = @_; - - my @a = split("[ \t][ \t]*", $def); - my ($name,$model,$fam,$id,$crc,$interval,$scale,$ret); - - #-- default - $name = $a[0]; - $interval = 300; - $scale = ""; - $ret = ""; - - #-- check syntax - return "OWCOUNT: Wrong syntax, must be define OWCOUNT [] [interval]" - if(int(@a) < 2 || int(@a) > 5); - - #-- check if this is an old style definition, e.g. is missing - my $a2 = $a[2]; - my $a3 = defined($a[3]) ? $a[3] : ""; - if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = "DS2423"; - $id = $a[2]; - if(int(@a)>=4) { $interval = $a[3]; } - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = $a[2]; - return "OWCOUNT: Wrong 1-Wire device model $model" - if( $model ne "DS2423"); - $id = $a[3]; - if(int(@a)>=5) { $interval = $a[4]; } - } else { - return "OWCOUNT: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # determine CRC Code - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC("1D.".$id."00")) : "00"; - - #-- Define device internals - $hash->{ROM_ID} = "1D.".$id.$crc; - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = "1D"; - $hash->{PRESENT} = 0; - $hash->{INTERVAL} = $interval; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWCOUNT: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - $modules{OWCOUNT}{defptr}{$id} = $hash; - $hash->{STATE} = "Defined"; - 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()+1, "OWCOUNT_InitializeDevice", $hash, 0); - - #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 0); - - return undef; -} - -######################################################################################## -# -# OWCOUNT_InitializeDevice - delayed setting of initial readings and channel names -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWCOUNT_InitializeDevice($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - $hash->{PRESENT} = 0; - - #-- Set channel names, channel units and alarm values - for( my $i=0;$i"; - 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 |$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" ); - #Log 1,"OWCOUNT InitializeDevice with period $period and UNITABBR = ".$hash->{READINGS}{"$owg_rate[$i]"}{UNITABBR}; - - } - - #-- 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); -} - -######################################################################################## -# -# OWCOUNT_FormatValues - put together various format strings and assemble STATE variable -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWCOUNT_FormatValues($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - my ($offset,$factor,$period,$unit,$runit,$midnight,$vval,$vrate); - my ($value1,$value2,$value3,$value4,$value5) = ("","","","",""); - 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 $daybreak = 0; - my $monthbreak = 0; - - my $present = $hash->{PRESENT}; - #-- remove units if they are unwanted - my $unir = defined($attr{$name}{"UnitInReading"}) ? $attr{$name}{"UnitInReading"} : 1; - - #-- formats for output - for (my $i=0;$i{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}; - - #-- 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 - } else { - $vval = int((($owg_val[$i] + $offset)*$factor - $midnight)*1000)/1000; - } - - #-- 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 ){ - #-- time difference in seconds - ($yearo,$montho,$dayrest) = split(/-/,$oldtim); - $dayo = substr($dayrest,0,2); - ($houro,$mino,$seco) = split(/:/,substr($dayrest,3)); - my $delt = ($hour-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco); - #-- correct time for wraparound at midnight - if( ($delt<0) && ($present==1)){ - $daybreak = 1; - $delt += 86400; - } - #-- 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 interpolation - my $dt = ((24-$houro)*3600 -$mino*60 - $seco)/( ($hour+24-$houro)*3600 + ($min-$mino)*60 + ($sec-$seco) ); - my $dv = $oldval*(1-$dt)+$vval*$dt; - #-- correct reading in daily mode - if( $midnight > 0.0 ){ - $vval -= $dv; - $delt *= (1-$dt); - $oldval = 0.0; - } - #-- in any mode store the interpolated value in the midnight store - $midnight += $dv; - OWXCOUNT_SetPage($hash,14+$i,sprintf("%f",$midnight)); - #-- string buildup for monthly logging - $value4 .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dv,$unit); - if( $day<$dayo ){ - $monthbreak = 1; - Log 1, "OWCOUNT: Change of month"; - #-- string buildup for yearly logging - $value5 .= sprintf( "%s: %5.1f %s", $owg_channel[$i], $dv,$unit); - } - } - #-- rate - if( ($delt > 0.0) && $present ){ - $vrate = ($vval-$oldval)/$delt; - } else { - $vrate = 0.0; - } - #-- correct rate for period setting - if( $period eq "hour" ){ - $vrate*=3600; - }elsif( $period eq "minute" ){ - $vrate*=60; - } - - if( !defined($runit) ){ - Log 1,"OWCOUNT: Error in rate unit definition. i=$i, owg_rate[i]=".$owg_rate[$i]; - $runit = "ERR"; - } - - #-- string buildup for return value and STATE - if( $unir ){ - #-- 1 decimal - if( $factor == 1.0 ){ - $value1 .= sprintf( "%s: %5.1f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit); - $value2 .= sprintf( "%s: %5.1f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit); - #-- 3 decimals - } else { - $value1 .= sprintf( "%s: %5.3f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit); - $value2 .= sprintf( "%s: %5.2f %s %5.2f %s", $owg_channel[$i], $vval,$unit,$vrate,$runit); - } - }else { - #-- 1 decimal - if( $factor == 1.0 ){ - $value1 .= sprintf( "%s: %5.1f %5.2f", $owg_channel[$i], $vval,$vrate); - $value2 .= sprintf( "%s: %5.1f %5.2f", $owg_channel[$i], $vval,$vrate); - #-- 3 decimals - } else { - $value1 .= sprintf( "%s: %5.3f %5.2f", $owg_channel[$i], $vval,$vrate); - $value2 .= sprintf( "%s: %5.2f %5.2f", $owg_channel[$i], $vval,$vrate); - } - } - $value3 .= sprintf( "%s: " , $owg_channel[$i]); - } - #-- put into READINGS - $hash->{READINGS}{"$owg_channel[$i]"}{VAL} = $vval; - #-- but times and rate only when valid - if( $present ){ - $hash->{READINGS}{"$owg_channel[$i]"}{TIME} = $tn; - $hash->{READINGS}{"$owg_rate[$i]"}{VAL} = $vrate; - $hash->{READINGS}{"$owg_rate[$i]"}{TIME} = $tn; - } else { - $hash->{READINGS}{"$owg_channel[$i]"}{TIME} = ""; - $hash->{READINGS}{"$owg_rate[$i]"}{VAL} = ""; - $hash->{READINGS}{"$owg_rate[$i]"}{TIME} = ""; - } - #-- insert comma - if( $i{STATE} = $value2; - - #-- write units as header if they are unwanted in lines - if( $unir == 0 ){ - #TODO: the entry into CHANGED must be into the lowest array position - } - - if( $daybreak == 1 ){ - $value4 = sprintf("D_%d: %d-%d-%d_23:59:59 %s",$dayo,$yearo,$montho,$dayo,$value4); - #-- needs to be higher array elements, - $hash->{CHANGED}[1] = $value4; - Log 1,$name." ".$value4; - if( $monthbreak == 1){ - $value5 = sprintf("M_%d: %d-%d-%d_23:59:59 %s",$montho,$yearo,$montho,$dayo,$value5); - #-- needs to be higher array elements, - $hash->{CHANGED}[2] = $value5; - Log 1,$name." ".$value5; - } - } - return $value1; -} - -######################################################################################## -# -# OWCOUNT_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWCOUNT_Get($@) { - my ($hash, @a) = @_; - - my $reading = $a[1]; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my $value = undef; - my $ret = ""; - my $page; - my $channo = undef; - my $channel; - - #-- check syntax - return "OWCOUNT: Get argument is missing @a" - if(int(@a) < 2); - - #-- check argument - return "OWCOUNT: 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"; - } - - #-- get present - if($a[1] eq "present") { - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } - - #-- get interval - if($a[1] eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - - #-- reset presence - #-- TODO: THIS IS TOO STRONG !!! - #$hash->{PRESENT} = 0; - - #-- get memory page/counter according to interface type - my $interface= $hash->{IODev}->{TYPE}; - - #-- 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: " - 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: " - if( int(@a)<2 ); - #-- find out which channel we have - if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ - $page=14; - }elsif( ($a[2] eq $owg_channel[1]) || ($a[2] eq "B") ){ - $page=15; - } else { - return "OWCOUNT: invalid midnight counter address, must be A, B or defined channel name" - } - } - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXCOUNT_GetPage($hash,$page); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); - #-- Unknown interface - }else{ - return "OWCOUNT: Get with wrong IODev type $interface"; - } - #-- when we have a return code, we have an error - if( $ret ){ - return $ret; - }else{ - return "OWCOUNT: $name.$reading [$page] =>".$owg_str; - } - } - - #-- check syntax for getting counter - if( $reading eq "counter" ){ - return "OWCOUNT: get needs parameter when reading counter: " - if( int(@a)<2 ); - #-- find out which channel we have - if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ - $page=14; - }elsif( ($a[2] eq $owg_channel[1]) || ($a[2] eq "B") ){ - $page=15; - } else { - return "OWCOUNT: invalid counter address, must be A, B or defined channel name" - } - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXCOUNT_GetPage($hash,$page); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); - #-- Unknown interface - }else{ - return "OWCOUNT: Get with wrong IODev type $interface"; - } - #-- check syntax for getting counters - }elsif( $reading eq "counters" ){ - return "OWCOUNT: get needs no parameter when reading counters" - if( int(@a)==1 ); - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXCOUNT_GetPage($hash,14); - $ret = OWXCOUNT_GetPage($hash,15); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); - }else{ - return "OWCOUNT: GetValues with wrong IODev type $interface"; - } - } - #-- process results - if( $ret ){ - return "OWCOUNT: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - return "OWCOUNT: $name.$reading => ".OWCOUNT_FormatValues($hash); - -} - -####################################################################################### -# -# OWCOUNT_GetValues - Updates the reading from one device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWCOUNT_GetValues($) { - my $hash = shift; - - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my $value = ""; - my $ret = ""; - my $offset; - my $factor; - - #-- define warnings - my $warn = "none"; - $hash->{ALARM} = "0"; - - #-- restart timer for updates - RemoveInternalTimer($hash); - InternalTimer(time()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 1); - - #-- reset presence - maybe this is too strong - $hash->{PRESENT} = 0; - - #-- Get readings according to interface type - my $interface= $hash->{IODev}->{TYPE}; - if( $interface eq "OWX" ){ - $ret = OWXCOUNT_GetPage($hash,14); - $ret = OWXCOUNT_GetPage($hash,15); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); - }else{ - return "OWCOUNT: GetValues with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWCOUNT: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - - #-- old state, new state - my $oldval = $hash->{STATE}; - $value=OWCOUNT_FormatValues($hash); - my $newval = $hash->{STATE}; - #--logging depends on setting of the event-attribute - 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; -} - -####################################################################################### -# -# OWCOUNT_Set - Set one value for device -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWCOUNT_Set($@) { - my ($hash, @a) = @_; - - my $key = $a[1]; - my $value = $a[2]; - - #-- for the selector: which values are possible - if (@a == 2){ - my $newkeys = join(" ", keys %sets); - return $newkeys ; - } - - #-- check syntax - return "OWCOUNT: Set needs one parameter" - if( int(@a)!=3 ); - #-- check argument - if( !defined($sets{$a[1]}) ){ - return "OWCOUNT: Set with unknown argument $a[1]"; - } - - #-- define vars - my $ret = undef; - my $page; - my $data; - my $channo = undef; - my $channel; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - - #-- reset the device - if($key eq "init") { - return "OWCOUNT: init needs parameter 'yes'" - if($value ne "yes"); - OWCOUNT_InitializeDevice($hash); - return "OWCOUNT: Re-initialized device"; - } - - #-- set new timer interval - if($key eq "interval") { - # check value - return "OWCOUNT: Set with short interval, must be > 1" - if(int($value) < 1); - # update timer - $hash->{INTERVAL} = $value; - RemoveInternalTimer($hash); - InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWCOUNT_GetValues", $hash, 1); - return undef; - } - - #-- set memory page/counter according to interface type - my $interface= $hash->{IODev}->{TYPE}; - - #-- check syntax for setting memory page 0..13 or midnight A/B - if( ($key eq "memory") || ($key eq "midnight") ){ - if( $key eq "memory" ){ - return "OWCOUNT: set needs parameter when writing memory: " - if( int(@a)<2 ); - $page=int($a[2]); - if( ($page<0) || ($page>13) ){ - return "OWXCOUNT: Wrong memory page write attempted"; - } - }else{ - return "OWCOUNT: set needs parameter when writing midnight: " - if( int(@a)<2 ); - #-- find out which channel we have - if( ($a[2] eq $owg_channel[0]) || ($a[2] eq "A") ){ - $page=14; - }elsif( ($a[2] eq $owg_channel[1]) || ($a[2] eq "B") ){ - $page=15; - } else { - return "OWCOUNT: invalid midnight counter address, must be A, B or defined channel name" - } - } - - $data=$a[3]; - for( my $i=4;$i 32 ){ - Log 1,"OWXCOUNT: memory data truncated to 32 characters"; - $data=substr($data,0,32); - }elsif( length($data) < 32 ){ - for(my $i=length($data)-1;$i<32;$i++){ - $data.=" "; - } - } - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXCOUNT_SetPage($hash,$page,$data); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_setPage($hash,$page,$data); - #-- Unknown interface - }else{ - return "OWCOUNT: Set with wrong IODev type $interface"; - } - } - - #-- process results - we have to reread the device - $hash->{PRESENT} = 1; - OWCOUNT_GetValues($hash); - OWCOUNT_FormatValues($hash); - Log 4, "OWCOUNT: Set $hash->{NAME} $key $value"; -} - -######################################################################################## -# -# OWCOUNT_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWCOUNT_Undef ($) { - my ($hash) = @_; - delete($modules{OWCOUNT}{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 = OWFSCOUNT -# -######################################################################################## - - - - - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a 1-Wire bus connected -# directly to the FHEM server -# -# Prefix = OWXCOUNT -# -######################################################################################## -# -# OWXAD_GetPage - Get one memory page + counter from device -# -# Parameter hash = hash of device addressed -# page = 0..15 -# -######################################################################################## - -sub OWXCOUNT_GetPage($$) { - my ($hash,$page) = @_; - - my ($select, $res, $res2, $res3, @data); - - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #=============== wrong value requested =============================== - if( ($page<0) || ($page>15) ){ - return "OWXCOUNT: Wrong memory page requested"; - } - #=============== get memory + counter =============================== - #-- issue the match ROM command \x55 and the read memory + counter command - # \xA5 TA1 TA2 reading 40 data bytes and 2 CRC bytes - my $ta2 = ($page*32) >> 8; - my $ta1 = ($page*32) & 255; - #Log 1, "OWXCOUNT: getting page Nr. $ta2 $ta1"; - $select=sprintf("\xA5%c%c",$ta1,$ta2); - #-- reset the bus - OWX_Reset($master); - #-- reading 9 + 3 + 40 data bytes and 2 CRC bytes = 54 bytes - $res=OWX_Complex($master,$owx_dev,$select,42); - if( $res eq 0 ){ - return "OWX: Device $owx_dev not accessible in reading $page page"; - } - - #-- process results - if( length($res) < 54 ) { - #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in first step"; - #-- read the data in a second step - $res.=OWX_Complex($master,"","",0); - #-- process results - if( length($res) < 54 ) { - #Log 1, "OWXCOUNT: warning, have received ".length($res)." bytes in second step"; - #-- read the data in a third step - $res.=OWX_Complex($master,"","",0); - } - } - #-- reset the bus - OWX_Reset($master); - - #-- process results - @data=split(//,$res); - return "OWXCOUNT: invalid data length, ".length($res)." bytes in three steps" - if( length($res) < 54); - #return "invalid data" - # if (ord($data[17])<=0); - #return "invalid CRC" - # if (OWX_CRC8(substr($res,10,8),$data[18])==0); - - #-- first 12 byte are 9 ROM ID +3 command, next 32 are memory - #-- memory part, treated as string - $owg_str=substr($res,12,32); - #-- counter part - if( ($page == 14) || ($page == 15) ){ - @data=split(//,substr($res,44)); - if ( ($data[4] | $data[5] | $data[6] | $data[7]) ne "\x00" ){ - Log 1, "OWXCOUNT: Device $owx_dev returns invalid data ".ord($data[4])." ".ord($data[5])." ".ord($data[6])." ".ord($data[7]); - 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; - $owg_midnight[0] = $owg_str; - }elsif( $page == 15) { - $owg_val[1] = $value; - $owg_midnight[1] = $owg_str; - } - } - - return undef; -} - -######################################################################################## -# -# OWXCOUNT_SetPage - Set one memory page of device -# -# Parameter hash = hash of device addressed -# page = "alarm" or "status" -# -######################################################################################## - -sub OWXCOUNT_SetPage($$$) { - - my ($hash,$page,$data) = @_; - - my ($select, $res, $res2, $res3); - - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - #=============== wrong value requested =============================== - if( ($page<0) || ($page>15) ){ - return "OWXCOUNT: Wrong memory page requested"; - } - #=============== set memory ========================================= - #-- issue the match ROM command \x55 and the write scratchpad command - # \x0F TA1 TA2 and the read scratchpad command reading 3 data bytes - my $ta2 = ($page*32) >> 8; - my $ta1 = ($page*32) & 255; - #Log 1, "OWXCOUNT: setting page Nr. $ta2 $ta1"; - $select=sprintf("\x0F%c%c",$ta1,$ta2).$data; - #-- reset the bus - OWX_Reset($master); - #-- reading 9 + 3 + 16 bytes = 29 bytes - $res=OWX_Complex($master,$owx_dev,$select,0); - if( $res eq 0 ){ - return "OWX: Device $owx_dev not accessible in writing scratchpad"; - } - - #-- issue the match ROM command \x55 and the read scratchpad command - # \xAA - #-- reset the bus - OWX_Reset($master); - #-- reading 9 + 4 + 16 bytes = 28 bytes - # TODO: sometimes much less than 28 - $res=OWX_Complex($master,$owx_dev,"\xAA",28); - if( length($res) < 13 ){ - return "OWX: Device $owx_dev not accessible in reading scratchpad"; - } - - #-- issue the match ROM command \x55 and the copy scratchpad command - # \x5A followed by 3 byte authentication code - $select="\x5A".substr($res,10,3); - #-- reset the bus - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,6); - - #-- process results - if( $res eq 0 ){ - return "OWXCOUNT: Device $owx_dev not accessible for writing"; - } - - return undef; -} - -1; diff --git a/fhem/contrib/1-Wire/21_OWID.pm b/fhem/contrib/1-Wire/21_OWID.pm deleted file mode 100644 index 45c6c9135..000000000 --- a/fhem/contrib/1-Wire/21_OWID.pm +++ /dev/null @@ -1,212 +0,0 @@ -######################################################################################## -# -# OWID.pm -# -# FHEM module to commmunicate with general 1-Wire ID-ROMS -# -# 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) -# -# Prof. Dr. Peter A. Henning, 2012 -# -# Version 2.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWID -# -# where may be replaced by any name string -# -# is a 2 character (1 byte) 1-Wire Family ID -# -# 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 -# -# -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -use strict; -use warnings; -sub Log($$); - -#-- declare variables -my %gets = ( - "present" => "", - "id" => "" -); -my %sets = (); -my %updates = (); - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWID -# -######################################################################################## -# -# OWID_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWID_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWID_Define"; - $hash->{UndefFn} = "OWID_Undef"; - $hash->{GetFn} = "OWID_Get"; - $hash->{SetFn} = undef; - my $attlist = "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 "; - $hash->{AttrList} = $attlist; -} - -######################################################################################### -# -# OWID_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################### - -sub OWID_Define ($$) { - my ($hash, $def) = @_; - - #-- define OWID - my @a = split("[ \t][ \t]*", $def); - - my ($name,$fam,$id,$crc,$ret); - - #-- default - $name = $a[0]; - $ret = ""; - - #-- check syntax - return "OWID: Wrong syntax, must be define OWID " - if(int(@a) !=4 ); - - #-- check id - if( $a[2] =~ m/^[0-9|a-f|A-F]{2}$/ ) { - $fam = $a[2]; - } else { - return "OWID: $a[0] family id $a[2] invalid, specify a 2 digit value"; - } - if( $a[3] =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $id = $a[3]; - } else { - return "OWID: $a[0] ID $a[3] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # determine CRC Code YY - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; - - #-- Define device internals - $hash->{ROM_ID} = $fam.".".$id.$crc; - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = $fam; - $hash->{PRESENT} = 0; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWID: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - - $modules{OWID}{defptr}{$id} = $hash; - - $hash->{STATE} = "Defined"; - Log 3, "OWID: Device $name defined."; - - #-- Initialization reading according to interface type - my $interface= $hash->{IODev}->{TYPE}; - - $hash->{STATE} = "Initialized"; - return undef; -} - -######################################################################################## -# -# OWID_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWID_Get($@) { - my ($hash, @a) = @_; - - my $reading = $a[1]; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my $value = undef; - my $ret = ""; - my $offset; - my $factor; - - #-- check syntax - return "OWID: Get argument is missing @a" - if(int(@a) != 2); - - #-- check argument - return "OWID: 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"; - } - - #-- get present - if($a[1] eq "present") { - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } -} - -######################################################################################## -# -# OWID_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWID_Undef ($) { - my ($hash) = @_; - delete($modules{OWID}{defptr}{$hash->{OW_ID}}); - RemoveInternalTimer($hash); - return undef; -} - -1; diff --git a/fhem/contrib/1-Wire/21_OWLCD.pm b/fhem/contrib/1-Wire/21_OWLCD.pm deleted file mode 100644 index 2f9c27cfc..000000000 --- a/fhem/contrib/1-Wire/21_OWLCD.pm +++ /dev/null @@ -1,1037 +0,0 @@ -######################################################################################## -# -# OWLCD.pm -# -# FHEM module to commmunicate with the 1-Wire LCD hardware -# -# 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 -# -# Prof. Dr. Peter A. Henning, 2012 -# -# Version 2.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWLCD -# -# where may be replaced by any name string -# -# 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 gpio => current state of the gpio pins (15 = all off, 0 = all on) -# get counter => four values (16 Bit) of the gpio counter -# get version => firmware version of the LCD adapter -# get memory => get one of the internal memory pages 0..6 -# -# set alert red|yellow|beep|none => set one of the alert states (gpio pins) -# set icon on|off|blink => set one of the icons 0..14 -# set icon 15 0..6 => set icon no. 15 in one of its values -# set line => set one of the display lines 0..3 -# set memory set one of the internal memory pages 0..6 -# set gpio => state of the gpio pins 0..7 -# set backlight on|off => set backlight on or off -# set lcd on|off => set LCD power on or off -# set reset => reset the display -# set test => display a test content -# -# Careful: Not ASCII ! strange Codepage -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -use strict; -use warnings; -sub Log($$); - -#-- controller may be HD44780 or KS0073 -# these values have to be changed for different display -# geometries or memory maps -my $lcdcontroller = "KS0073"; -my $lcdlines = 4; -my $lcdchars = 20; -my @lcdpage = (0,32,64,96); -#my @lcdpage = (0,64,20,84); - -#-- declare variables -my %gets = ( - "present" => "", - "id" => "", - "memory" => "", - "gpio" => "", - "counter" => "", - "version" => "", - #"register" => "", - #"data" => "" -); -my %sets = ( - "icon" => "", - "line" => "", - "alert" => "", - "memory" => "", - "gpio" => "", - "backlight" => "", - "lcd" => "", - "reset" => "", - "test" => "" - -); -my %updates = (); - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWLCD -# -######################################################################################## -# -# OWLCD_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWLCD_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWLCD_Define"; - $hash->{UndefFn} = "OWLCD_Undef"; - $hash->{GetFn} = "OWLCD_Get"; - $hash->{SetFn} = "OWLCD_Set"; - my $attlist = "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5 ". - ""; - $hash->{AttrList} = $attlist; -} - -######################################################################################### -# -# OWLCD_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################### - -sub OWLCD_Define ($$) { - my ($hash, $def) = @_; - - #-- define OWLCD - my @a = split("[ \t][ \t]*", $def); - - my ($name,$fam,$id,$crc,$ret); - - #-- default - $name = $a[0]; - $ret = ""; - - #-- check syntax - return "OWLCD: Wrong syntax, must be define OWLCD " - if(int(@a) !=3 ); - - #-- check id - if( $a[2] =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $id = $a[2]; - } else { - return "OWLCD: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # determine CRC Code - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC("FF.".$id."00")) : "00"; - - #-- Define device internals - $hash->{ROM_ID} = "FF.".$id.$crc; - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = "FF"; - $hash->{PRESENT} = 0; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWLCD: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - - $modules{OWLCD}{defptr}{$id} = $hash; - - $hash->{STATE} = "Defined"; - Log 3, "OWLCD: Device $name defined."; - - #-- Initialization reading according to interface type - my $interface= $hash->{IODev}->{TYPE}; - #-- OWX interface - if( $interface eq "OWX" ){ - OWXLCD_InitializeDevice($hash); - #-- set backlight on - OWXLCD_SetFunction($hash,"bklon",0); - #-- erase all icons - OWXLCD_SetIcon($hash,0,0); - #-- erase alarm state - OWXLCD_SetFunction($hash,"gpio",15); - #-- Unknown interface - }else{ - return "OWLCD: Wrong IODev type $interface"; - } - $hash->{STATE} = "Initialized"; - return undef; -} - -######################################################################################## -# -# OWLCD_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWLCD_Get($@) { - my ($hash, @a) = @_; - - my $reading = $a[1]; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my $value = undef; - my $ret = ""; - my $offset; - my $factor; - - #-- check syntax - return "OWLCD: Get argument is missing @a" - if(int(@a) < 2); - - #-- check argument - return "OWLCD: 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"; - } - - #-- get present - if($a[1] eq "present") { - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } - - #-- get gpio states - if($a[1] eq "gpio") { - $value = OWXLCD_Get($hash,"gpio"); - return "$name.gpio => $value"; - } - - #-- get gpio counters - if($a[1] eq "counter") { - $value = OWXLCD_Get($hash,"counter"); - return "$name.counter => $value"; - } - - #-- get version - if($a[1] eq "version") { - $value = OWXLCD_Get($hash,"version"); - return "$name.version => $value"; - } - - #-- get EEPROM content - if($a[1] eq "memory") { - my $page = ($a[2] =~ m/\d/) ? int($a[2]) : 0; - Log 1,"Calling GetMemory with page $page"; - $value = OWXLCD_GetMemory($hash,$page); - return "$name $reading $page => $value"; - } -} - -####################################################################################### -# -# OWLCD_Set - Set one value for device -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWLCD_Set($@) { - my ($hash, @a) = @_; - - my $key = $a[1]; - my $value = $a[2]; - my ($line,$icon,$i); - - #-- for the selector: which values are possible - return join(" ", keys %sets) - if ( (@a == 2) && !(($key eq "reset") || ($key eq "test")) ); - - #-- check argument - if( !defined($sets{$a[1]}) ){ - return "OWLCD: Set with unknown argument $a[1]"; - } - - #-- check syntax for setting line - if( $key eq "line" ){ - return "OWLCD: Set needs one or two parameters when setting line value: <#line> " - if( int(@a)<3 ); - $line = ($a[2] =~ m/\d/) ? $a[2] : 0; - $value = $a[3]; - if( defined($value) ){ - for( $i=4; $i< int(@a); $i++){ - $value .= " ".$a[$i]; - } - }else{ - $value=""; - } - #-- check syntax for setting memory - } elsif( $key eq "memory" ){ - return "OWLCD: Set needs two parameters when setting memory page: <#page> " - if( int(@a)<4 ); - $line = ($a[2] =~ m/\d/) ? int($a[2]) : 0; - $value = $a[3]; - for( $i=4; $i< int(@a); $i++){ - $value .= " ".$a[$i]; - } - #-- check syntax for setting alert - } elsif( $key eq "alert" ){ - return "OWLCD: Set needs a parameter when setting alert: /none/off" - if( int(@a)<3 ); - #-- check syntax for setting icon - } elsif ( $key eq "icon" ){ - if( ($a[2] ne "0") && ($a[2] ne "none") ){ - return "OWLCD: Set needs two parameters when setting icon value: <#icon> on/off/blink (resp. 0..5/off/blink for #16)" - if( (int(@a)!=4) ); - $icon = ($a[2] =~ m/\d\d?/) ? $a[2] : 0; - $value = $a[3]; - } else { - return "OWLCD: Set needs only one parameter when resetting icons" - if( (int(@a)!=3) ); - $icon = 0; - $value = "OFF"; - } - #-- check syntax for reset and test - } elsif ( ($key eq "reset") || ($key eq "test") ){ - return "OWLCD: Set needs no parameters when setting $key value" - if( int(@a)!=2 ); - #-- other syntax - } else { - return "OWLCD: Set needs one parameter when setting $key value" - if( int(@a)!=3 ); - } - - #-- define vars - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - - #-- set gpio ports from all off = to all on = 7 - if($key eq "gpio") { - #-- check value and write to device - return "OWLCD: Set with wrong value for gpio port, must be 0 <= gpio <= 7" - if( ! ((int($value) >= 0) && (int($value) <= 7)) ); - OWXLCD_SetFunction($hash, "gpio", int($value)); - return undef; - } - - #-- set LCD ON or OFF - if($key eq "lcd") { - #-- check value and write to device - if( uc($value) eq "ON"){ - OWXLCD_SetFunction($hash, "lcdon", 0); - }elsif( uc($value) eq "OFF" ){ - OWXLCD_SetFunction($hash, "lcdoff", 0); - } else { - return "OWLCD: Set with wrong value for lcd, must be on/off" - } - return undef; - } - - #-- set LCD Backlight ON or OFF - if($key eq "backlight") { - #-- check value and write to device - if( uc($value) eq "ON"){ - OWXLCD_SetFunction($hash, "bklon", 0); - }elsif( uc($value) eq "OFF" ){ - OWXLCD_SetFunction($hash, "bkloff", 0); - } else { - return "OWLCD: Set with wrong value for backlight, must be on/off" - } - return undef; - } - - #-- reset - if($key eq "reset") { - OWXLCD_SetFunction($hash,"reset",0); - OWXLCD_SetIcon($hash,0,0); - OWXLCD_SetFunction($hash,"gpio",15); - return undef; - } - - #-- set icon - if($key eq "icon") { - return "OWLCD: Wrong icon type, choose 0..16" - if( ( 0 > $icon ) || ($icon > 16) ); - #-- check value and write to device - if( $icon == 16 ){ - if( uc($value) eq "OFF" ){ - OWXLCD_SetIcon($hash, 16, 0); - }elsif( uc($value) eq "BLINK" ){ - OWXLCD_SetIcon($hash, 16, 6); - }elsif( ((int($value) > 0) && (int($value) < 6)) ){ - OWXLCD_SetIcon($hash, 16, int($value)); - } else { - return "OWLCD: Set with wrong value for icon #16, must be 0..5/off/blink" - } - }else{ - if( uc($value) eq "OFF"){ - OWXLCD_SetIcon($hash, $icon, 0); - }elsif( uc($value) eq "ON" ){ - OWXLCD_SetIcon($hash, $icon, 1); - }elsif( uc($value) eq "BLINK" ){ - OWXLCD_SetIcon($hash, $icon, 2); - } else { - return "OWLCD: Set with wrong value for icon $icon, must be on/off/blink" - } - } - return undef; - } - - #-- set a single LCD line - if($key eq "line") { - return "OWLCD: Wrong line number, choose 0..".$lcdlines - if( ( 0 > $line ) || ($line > ($lcdlines-1)) ); - return "OWLCD: Wrong line length, must be < ".$lcdchars - if( length($value) > $lcdchars ); - #-- check value and write to device - OWXLCD_SetLine($hash,$line,$value); - return undef; - } - - #-- set memory page 0..6 - if($key eq "memory") { - return "OWLCD: Wrong page number, choose 0..6" - if( (0 > $line) || ($line > 6) ); - return "OWLCD: Wrong line length, must be <=16 " - if( length($value) > 16 ); - #-- check value and write to device - Log 1,"Calling SetMemory with page $line"; - OWXLCD_SetMemory($hash,$line,$value); - return undef; - } - - #-- set alert - if($key eq "alert") { - if(lc($value) eq "beep") { - OWXLCD_SetFunction($hash,"gpio",14); - return undef; - }elsif(lc($value) eq "red") { - OWXLCD_SetFunction($hash,"gpio",13); - return undef; - }elsif(lc($value) eq "yellow") { - OWXLCD_SetFunction($hash,"gpio",11); - return undef; - }elsif( (lc($value) eq "off") || (lc($value) eq "none") ) { - OWXLCD_SetFunction($hash,"gpio",15); - return undef; - }else{ - return "OWLCD: Set with wrong value for alert type, must be beep/red/yellow/off"; - } - } - - #-- start test - if($key eq "test") { - OWXLCD_SetLine($hash,0,"Hallo Welt"); - OWXLCD_SetLine($hash,1,"Mary had a big lamb"); - OWXLCD_SetLine($hash,2,"Solar 4.322 kW "); - OWXLCD_SetLine($hash,3,"\x5B\x5C\x5E\x7B\x7C\x7E\xBE"); - return undef; - } -} - -######################################################################################## -# -# OWLCD_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWLCD_Undef ($) { - my ($hash) = @_; - delete($modules{OWLCD}{defptr}{$hash->{OW_ID}}); - RemoveInternalTimer($hash); - return undef; -} - -######################################################################################## -# -# OWXLCD_Byte - write a single byte to the LCD device -# -# Parameter hash = hash of device addressed -# cmd = register or data -# byte = byte -# -######################################################################################## - -sub OWXLCD_Byte($$$) { - - my ($hash,$cmd,$byte) = @_; - - my ($select, $select2, $res, $res2, $res3, @data); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- hash of the busmaster - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #=============== write to LCD register =============================== - if ( $cmd eq "register" ) { - #-- issue the read LCD register command \x10 - $select = sprintf("\x10%c",$byte); - #=============== write to LCD data =============================== - }elsif ( $cmd eq "data" ) { - #-- issue the read LCD data command \x12 - $select = sprintf("\x12%c",$byte); - #=============== wrong value requested =============================== - } else { - return "OWXLCD: Wrong byte write attempt"; - } - - #-- write to device - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - #-- process results - if( $res eq 0 ){ - return "OWLCD: Device $owx_dev not accessible for writing a byte"; - } - - return undef; -} - -######################################################################################## -# -# OWXLCD_Get - get values from the LCD device -# -# Parameter hash = hash of device addressed -# cmd = command string -# -######################################################################################## - -sub OWXLCD_Get($$) { - - my ($hash,$cmd,$value) = @_; - - my ($select, $select2, $len, $addr, $res, $res2, $res3, @data); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- hash of the busmaster - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #=============== fill scratch with gpio ports =============================== - if ( $cmd eq "gpio" ) { - #-- issue the read GPIO command \x22 (1 byte) - $select = "\x22"; - $len = 1; - #=============== fill scratch with gpio counters =============================== - }elsif ( $cmd eq "counter" ) { - #-- issue the read counter command \x23 (8 bytes) - $select = "\x23"; - $len = 8; - #=============== fill scratch with version =============================== - }elsif ( $cmd eq "version" ) { - #-- issue the read version command \x41 - $select = "\x41"; - $len = 16; - } else { - return "OWXLCD: Wrong get attempt"; - } - #-- write to device - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- process results - if( $res eq 0 ){ - return "OWLCD: Device $owx_dev not accessible for reading"; - } - - #-- issue the read scratchpad command \xBE - $select2 = "\xBE"; - #-- write to device - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select2,$len); - - #-- process results - if( $res eq 0 ){ - return "OWLCD: Device $owx_dev not accessible for reading in 2nd step"; - } - - #-- process results (10 byes or more have been sent) - $res = substr($res,10); - - #=============== gpio ports =============================== - if ( $cmd eq "gpio" ) { - return ord($res); - #=============== gpio counters =============================== - }elsif ( $cmd eq "counter" ) { - for( $i=0; $i<4; $i++){ - $data[$i] = ord(substr($res,2*$i+1,1))*256+ord(substr($res,2*$i,1)); - } - return join(" ",@data); - #=============== version =============================== - }elsif ( $cmd eq "version" ) { - return $res; - } - - return $res; -} - -######################################################################################## -# -# OWXLCD_GetMemory - get memory page from LCD device (EXPERIMENTAL) -# -# Parameter hash = hash of device addressed -# page = memory page address -# -######################################################################################## - -sub OWXLCD_GetMemory($$) { - - my ($hash,$page) = @_; - - my ($select, $res, $res2, $res3); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- hash of the busmaster - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #-- issue the match ROM command \x55 and the copy eeprom to scratchpad command \x4E - #Log 1," page read is ".$page; - $select = sprintf("\4E%c\x10\x37",$page); - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- process results - if( $res eq 0 ){ - return "OWLCD: Device $owx_dev not accessible for reading"; - } - - #-- sleeping for some time - #select(undef,undef,undef,0.5); - - #-- issue the match ROM command \x55 and the read scratchpad command \xBE - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,"\xBE",16); - - #-- process results - if( $res eq 0 ){ - return "OWLCD: Device $owx_dev not accessible for reading in 2nd step"; - } - - #-- process results (10 byes or more have been sent) - $res2 = substr($res,11,16); - - Log 1," Having received ".length($res)." bytes"; - return $res2; -} - -######################################################################################## -# -# OWXLCD_InitializeDevice - initialize the display -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWXLCD_InitializeDevice($) { - my ($hash) = @_; - - my ($i,$data,$select, $res); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- hash of the busmaster - my $master = $hash->{IODev}; - - #-- supposedly we do not need to do anything with a HD44780 - if( $lcdcontroller eq "HD44780"){ - return undef; - #-- need some additional sequence for KS0073 - }elsif ( $lcdcontroller eq "KS0073"){ - - #-- Function Set: 4 bit data size, RE => 0 = \x20 - #OWXLCD_Byte($hash,"register",32); - - #-- Entry Mode Set: cursor auto increment = \x06 - #OWXLCD_Byte($hash,"register",6); - - #-- Function Set: 4 bit data size, RE => 1, blink Enable = \x26 - OWXLCD_Byte($hash,"register",38); - - #-- Ext. Function Set: 4 line mode = \x09 - OWXLCD_Byte($hash,"register",9); - - #-- Function Set: 4 bit data size, RE => 0 = \x20 - OWXLCD_Byte($hash,"register",32); - - #-- Display ON/OFF: display on, cursor off, blink off = \x0C - OWXLCD_Byte($hash,"register",12); - - #-- Clear Display - OWXLCD_Byte($hash,"register",1); - - return undef; - #-- or else - } else { - return "OWXLCD: Wrong LCD controller type"; - } - -} - -######################################################################################## -# -# OWXLCD_SetFunction - write state and values of the LCD device -# -# Parameter hash = hash of device addressed -# cmd = command string -# value = data value -# -######################################################################################## - -sub OWXLCD_SetFunction($$$) { - - my ($hash,$cmd,$value) = @_; - - my ($select, $res, $res2, $res3, @data); - - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #=============== set gpio ports =============================== - if ( $cmd eq "gpio" ) { - #-- issue the write GPIO command - # \x21 followed by the data value (= integer 0 - 7) - $select = sprintf("\x21%c",$value); - #=============== switch LCD on =============================== - }elsif ( $cmd eq "lcdon" ) { - #-- issue the lcd on cmd - $select = "\x03"; - #=============== switch LCD off =============================== - }elsif ( $cmd eq "lcdoff" ) { - #-- issue the lcd off cmd - $select = "\x05"; - #=============== switch LCD backlight on =============================== - }elsif ( $cmd eq "bklon" ) { - #-- issue the backlight on cmd - $select = "\x08"; - #=============== switch LCD backlight off =============================== - }elsif ( $cmd eq "bkloff" ) { - #-- issue the backlight off cmd - $select = "\x07"; - #=============== switch LCD backlight off =============================== - }elsif ( $cmd eq "reset" ) { - #-- issue the clear LCD command - $select = "\x49"; - #=============== wrong write attempt =============================== - } else { - return "OWXLCD: Wrong function selected"; - } - - #-- write to device - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - #-- process results - if( $res eq 0 ){ - return "OWLCD: Device $owx_dev not accessible for writing"; - } - - return undef; -} - -######################################################################################## -# -# OWXLCD_SetIcon - set one of the icons -# -# Parameter hash = hash of device addressed -# icon = address of the icon used = 0,1 .. 16 (0 = all off) -# value = data value: 0 = off, 1 = on, 2 = blink -# for battery icon 16: 0 = off, 1 = empty ... 5 = full, 6 = empty blink -# -######################################################################################## - -sub OWXLCD_SetIcon($$$) { - my ($hash,$icon,$value) = @_; - - my ($i,$data,$select, $res); - - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - #-- only for KS0073 - if ( $lcdcontroller eq "KS0073"){ - - #-- write 16 zeros to erase all icons - if( $icon == 0){ - #-- 4 bit data size, RE => 1, blink Enable = \x26 - $select = "\x10\x26"; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- SEGRAM addres to 0 = \x40, - $select = "\x10\x40"; - #-- write 16 zeros to scratchpad - $select .= "\x4E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- issue the copy scratchpad to LCD command \x48 - $select="\x48"; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - } else { - #-- determine data value - if( int($icon) != 16 ){ - if( $value == 0 ){ - $data = 0; - } elsif ( $value == 1) { - $data = 16; - } elsif ( $value == 2) { - $data = 80; - } else { - return "OWXLCD: Wrong data value $value for icon $icon"; - } - } else { - if( $value == 0 ){ - $data = 0; - } elsif ( $value == 1) { - $data = 16; - } elsif ( $value == 2) { - $data = 24; - } elsif ( $value == 3) { - $data = 28; - } elsif ( $value == 4) { - $data = 30; - } elsif ( $value == 5) { - $data = 31; - } elsif ( $value == 6) { - $data = 80; - } else { - return "OWXLCD: Wrong data value $value for icon $icon"; - } - } - #-- 4 bit data size, RE => 1, blink Enable = \x26 - $select = "\x10\x26"; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- SEGRAM addres to 0 = \x40 + icon address - $select = sprintf("\x10%c",63+$icon); - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- data - $select = sprintf("\x12%c",$data); - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - } - - #-- return to normal state - $select = "\x10\x20"; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - #-- or else - } else { - return "OWXLCD: Wrong LCD controller type"; - } -} - -######################################################################################## -# -# OWXLCD_SetLine - set one of the display lines -# -# Parameter hash = hash of device addressed -# line = line number (0..3) -# msg = data string to be written -# -######################################################################################## - -sub OWXLCD_SetLine($$$) { - - my ($hash,$line,$msg) = @_; - - my ($select, $res, $res2, $res3, $i, $msgA, $msgB); - $res2 = ""; - $line = int($line); - $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 - if( $msg =~ m/.*\°\;.*/ ) { - my @ma = split(/\°\;/,$msg); - $msg = $ma[0]."\x80".$ma[1]; - } - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - #-- split if longer than 16 bytes, fill each with blanks - # has already been checked to be <= $lcdchars - if( $lcdchars > 16 ){ - if( length($msg) > 16 ) { - $msgA = substr($msg,0,16); - $msgB = substr($msg,16,length($msg)-16); - for($i = 0;$i<$lcdchars-length($msg);$i++){ - $msgB .= "\x20"; - } - } else { - $msgA = $msg; - for($i = 0;$i<16-length($msg);$i++){ - $msgA .= "\x20"; - } - for($i = 0;$i<$lcdchars-16;$i++){ - $msgB .= "\x20"; - } - } - }else{ - $msgA = $msg; - for($i = 0;$i<$lcdchars-length($msg);$i++){ - $msgA .= "\x20"; - } - $msgB = undef; - } - - #-- issue the match ROM command \x55 and the write scratchpad command \x4E - # followed by LCD page address and the text - $select=sprintf("\x4E%c",$lcdpage[$line]).$msgA; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- issue the copy scratchpad to LCD command \x48 - $select="\x48"; - OWX_Reset($master); - $res3=OWX_Complex($master,$owx_dev,$select,0); - - #-- if second string available: - if( defined($msgB) ) { - #select(undef,undef,undef,0.005); - #-- issue the match ROM command \x55 and the write scratchpad command \x4E - # followed by LCD page address and the text - $select=sprintf("\x4E%c",$lcdpage[$line]+16).$msgB; - OWX_Reset($master); - $res2=OWX_Complex($master,$owx_dev,$select,0); - - #-- issue the copy scratchpad to LCD command \x48 - $select="\x48"; - OWX_Reset($master); - $res3=OWX_Complex($master,$owx_dev,$select,0); - } - - #-- process results - if( ($res eq 0) || ($res2 eq 0) || ($res3 eq 0) ){ - return "OWLCD: Device $owx_dev not accessible for writing"; - } - - return undef; - -} - -######################################################################################## -# -# OWXLCD_SetMemory - set internal nonvolatile memory -# -# Parameter hash = hash of device addressed -# page = page number (0..14) -# msg = data string to be written -# -######################################################################################## - -sub OWXLCD_SetMemory($$$) { - - my ($hash,$page,$msg) = @_; - - my ($select, $res, $res2, $res3, $i, $msgA); - $page = int($page); - $msg = defined($msg) ? $msg : ""; - - #-- ID of the device, hash of the busmaster - my $owx_dev = $hash->{ROM_ID}; - my $master = $hash->{IODev}; - - #-- fillup with blanks - $msgA = $msg; - for($i = 0;$i<16-length($msg);$i++){ - $msgA .= "\x20"; - } - - #-- issue the match ROM command \x55 and the write scratchpad command \x4E - # followed by LCD page address and the text - #Log 1," page written is ".$page; - $select=sprintf("\x4E\%c",$page).$msgA; - OWX_Reset($master); - $res=OWX_Complex($master,$owx_dev,$select,0); - - #-- issue the copy scratchpad to EEPROM command \x39 - OWX_Reset($master); - $res2=OWX_Complex($master,$owx_dev,"\x39",0); - - #-- process results - if( ($res eq 0) || ($res2 eq 0) ){ - return "OWLCD: Device $owx_dev not accessible for writing"; - } - - return undef; - -} - -1; diff --git a/fhem/contrib/1-Wire/21_OWMULTI.pm b/fhem/contrib/1-Wire/21_OWMULTI.pm deleted file mode 100644 index 1807c5819..000000000 --- a/fhem/contrib/1-Wire/21_OWMULTI.pm +++ /dev/null @@ -1,850 +0,0 @@ -######################################################################################## -# -# OWMULTI.pm -# -# FHEM module to commmunicate with 1-Wire chip DS2438Z - Smart Battery Monitor -# -# Prefixes for subroutines of this module: -# OW = General 1-Wire routines (Martin Fischer, Peter Henning) -# OWX = 1-Wire bus master interface (Peter Henning) -# -# Prof. Dr. Peter A. Henning, 2012 -# -# Version 2.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWMULTI [] [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type. If omitted, we assume this to be an -# DS2438 -# -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => OW_FAMILY.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get reading => measurement value obtained from VFunction -# get temperature => temperature measurement -# get VDD => supply voltage measurement -# get V|raw => raw external voltage measurement -# -# set interval => set period for measurement -# -# Additional attributes are defined in fhem.cfg -# Note: attributes "tempXXXX" are read during every update operation. -# -# attr event on-change/on-update = when to write an event (default= on-update) -# -# attr tempOffset = temperature offset in degree Celsius added to the raw temperature reading -# attr tempUnit = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius -# attr VName | = name for the channel | a type description for the measured value -# attr VUnit | = unit of measurement for the voltage channel | its abbreviation -# attr Vfunction = arbitrary functional expression involving the values VDD, V, T -# VDD is replaced by the measured supply voltage in Volt, -# V by the measured external voltage -# T by the measured and corrected temperature in its unit -# -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -use strict; -use warnings; -sub Log($$); - -#-- temperature and voltage globals - always the raw values from the device -my $owg_temp; -my $owg_volt; -my $owg_vdd; -my $owg_channel; - -my %gets = ( - "id" => "", - "present" => "", - "interval" => "", - "reading" => "", - "temperature" => "", - "VDD" => "", - "V" => "", - "raw" => "", -); - -my %sets = ( - "interval" => "", -); - -my %updates = ( - "present" => "", - "reading" => "", -); - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWMULTI -# -######################################################################################## -# -# OWMULTI_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWMULTI_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWMULTI_Define"; - $hash->{UndefFn} = "OWMULTI_Undef"; - $hash->{GetFn} = "OWMULTI_Get"; - $hash->{SetFn} = "OWMULTI_Set"; - #tempOffset = a temperature offset added to the temperature reading for correction - #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 ". - "event:on-update,on-change ". - "tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ". - "VName VUnit VFunction"; - } - -######################################################################################## -# -# OWMULTI_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################## - -sub OWMULTI_Define ($$) { - my ($hash, $def) = @_; - - # define OWMULTI [] [interval] - # e.g.: define flow OWMULTI 525715020000 300 - my @a = split("[ \t][ \t]*", $def); - - my ($name,$model,$fam,$id,$crc,$interval,$ret); - my $tn = TimeNow(); - - #-- default - $name = $a[0]; - $interval = 300; - $ret = ""; - - #-- check syntax - return "OWMULTI: Wrong syntax, must be define OWMULTI [] [interval]" - if(int(@a) < 2 || int(@a) > 6); - - #-- check if this is an old style definition, e.g. is missing - my $a2 = $a[2]; - my $a3 = defined($a[3]) ? $a[3] : ""; - if( ($a2 eq "none") || ($a3 eq "none") ) { - return "OWMULTI: ID = none is obsolete now, please redefine"; - } elsif( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = "DS2438"; - $id = $a[2]; - if(int(@a)>=4) { $interval = $a[3]; } - Log 1, "OWMULTI: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 5); - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = $a[2]; - $id = $a[3]; - if(int(@a)>=5) { $interval = $a[4]; } - Log 1, "OWMULTI: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 6); - } else { - return "OWMULTI: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS2438" ){ - $fam = "26"; - }else{ - return "OWMULTI: Wrong 1-Wire device model $model"; - } - # determine CRC Code - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; - - #-- define device internals - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = $fam; - $hash->{PRESENT} = 0; - $hash->{ROM_ID} = $fam.".".$id.$crc; - $hash->{INTERVAL} = $interval; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWMULTI: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - $modules{OWMULTI}{defptr}{$id} = $hash; - $hash->{STATE} = "Defined"; - 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()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0); - - return undef; -} - -######################################################################################## -# -# 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}; - my @args; - - #-- unit attribute defined ? - $hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius"; - $hash->{READINGS}{"temperature"}{TYPE} = "temperature"; - - #-- Initial readings temperature sensor - $owg_temp = 0.0; - $owg_volt = 0.0; - $owg_vdd = 5.0; - #-- Set channel name, channel unit for voltage channel - my $cname = defined($attr{$name}{"VName"}) ? $attr{$name}{"VName"} : "voltage|voltage"; - my @cnama = split(/\|/,$cname); - if( int(@cnama)!=2){ - Log 1, "OWMULTI: Incomplete channel name specification $cname. Better use $cname|"; - push(@cnama,"unknown"); - } - - #-- unit - my $unit = defined($attr{$name}{"VUnit"}) ? $attr{$name}{"VUnit"} : "Volt|V"; - my @unarr= split(/\|/,$unit); - if( int(@unarr)!=2 ){ - Log 1, "OWMULTI: Incomplete channel unit specification $unit. Better use $unit|"; - 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]; - - #-- 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 ($value1,$value2) = ("",""); - - my $tn = TimeNow(); - - #-- attributes defined ? - $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; - - if( $tunit eq "Celsius" ){ - $tabbr = "°C"; - } elsif ($tunit eq "Kelvin" ){ - $tabbr = "K"; - $toffset += "273.16" - } elsif ($tunit eq "Fahrenheit" ){ - $tabbr = "°F"; - $toffset = ($toffset+32)/1.8; - $tfactor = 1.8; - } else { - $tabbr="?"; - Log 1, "OWMULTI_FormatValues: unknown unit $tunit"; - } - #-- these values are rather coplex to obtain, therefore save them in the hash - $hash->{READINGS}{"temperature"}{UNIT} = $tunit; - $hash->{READINGS}{"temperature"}{UNITABBR} = $tabbr; - $hash->{tempf}{offset} = $toffset; - $hash->{tempf}{factor} = $tfactor; - - #-- correct values for proper offset, factor - $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 @cnama = split(/\|/,$cname); - $owg_channel=$cnama[0]; - - #-- attribute VFunction defined ? - $vfunc = defined($attr{$name}{"VFunction"}) ? $attr{$name}{"VFunction"} : "V"; - - #-- replace by proper values - $vfunc =~ s/VDD/\$owg_vdd/g; - $vfunc =~ s/V/\$owg_volt/g; - $vfunc =~ s/T/\$tval/g; - - #-- determine the measured value from the function - $vfunc = "\$owg_vdd = $owg_vdd; \$owg_volt = $owg_volt; \$tval = $tval; ".$vfunc; - $vfunc = eval($vfunc); - if( $vfunc ne "" ){ - $vval = int( $vfunc*1000 )/1000; - } 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 - $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); - $value2 .= sprintf( "%s: %5.2f %s (T: %5.2f %s)", $owg_channel, $vval,$hash->{READINGS}{"$owg_channel"}{UNITABBR},$tval,$tabbr); - - #-- STATE - $hash->{STATE} = $value2; - - return $value1; -} - -######################################################################################## -# -# OWMULTI_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWMULTI_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 "OWMULTI: Get argument is missing @a" - if(int(@a) != 2); - - #-- check argument - return "OWMULTI: 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"; - } - - #-- Get other values according to interface type - my $interface= $hash->{IODev}->{TYPE}; - - #-- get present - if($a[1] eq "present" ) { - #-- OWX interface - if( $interface eq "OWX" ){ - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } else { - return "OWMULTI: Verification not yet implemented for interface $interface"; - } - } - - #-- get interval - if($reading eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - - #-- reset presence - $hash->{PRESENT} = 0; - - #-- OWX interface - if( $interface eq "OWX" ){ - #-- not different from getting all values .. - $ret = OWXMULTI_GetValues($hash); - #-- OWFS interface not yet implemented - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSMULTI_GetValues($hash); - #-- Unknown interface - }else{ - return "OWMULTI: Get with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWMULTI: Could not get values from device $name, return was $ret"; - } - $hash->{PRESENT} = 1; - OWMULTI_FormatValues($hash); - - #-- return the special reading - if ($reading eq "reading") { - return "OWMULTI: $name.reading => ". - $hash->{READINGS}{"$owg_channel"}{VAL}; - } - if ($reading eq "temperature") { - return "OWMULTI: $name.temperature => ". - $hash->{READINGS}{"temperature"}{VAL}; - } - if ($reading eq "VDD") { - return "OWMULTI: $name.VDD => ". - $hash->{READINGS}{"VDD"}{VAL}; - } - if ( ($reading eq "V")|($reading eq "raw")) { - return "OWMULTI: $name.V => ". - $owg_volt; - } - return undef; -} - -####################################################################################### -# -# OWMULTI_GetValues - Updates the readings from device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWMULTI_GetValues($@) { - my $hash = shift; - - my $name = $hash->{NAME}; - my $value = ""; - my $ret = ""; - - #-- restart timer for updates - RemoveInternalTimer($hash); - InternalTimer(time()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 1); - - #-- reset presence - $hash->{PRESENT} = 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 = OWXMULTI_GetValues($hash); - last - if( !defined($ret) ); - } - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSTHERM_GetValues($hash); - }else{ - Log 3, "OWMULTI: GetValues with wrong IODev type $interface"; - return 1; - } - - #-- process results - if( defined($ret) ){ - Log 3, "OWMULTI: Could not get values from device $name, reason $ret"; - return 1; - } - $hash->{PRESENT} = 1; - - #-- old state, new state - my $oldval = $hash->{STATE}; - $value=OWMULTI_FormatValues($hash); - my $newval = $hash->{STATE}; - #--logging depends on setting of the event-attribute - 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; -} - -####################################################################################### -# -# OWMULTI_Set - Set one value for device -# -# Parameter hash = hash of device addressed -# a = argument string -# -######################################################################################## - -sub OWMULTI_Set($@) { - my ($hash, @a) = @_; - - #-- for the selector: which values are possible - return join(" ", sort keys %sets) if(@a == 2); - #-- check syntax - return "OWMULTI: Set needs one parameter" - if(int(@a) != 3); - #-- check argument - return "OWMULTI: 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 $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - - #-- set new timer interval - if($key eq "interval") { - # check value - return "OWMULTI: Set with short interval, must be > 1" - if(int($value) < 1); - # update timer - $hash->{INTERVAL} = $value; - RemoveInternalTimer($hash); - InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 1); - return undef; - } - - #-- set other values depending on interface type - my $interface = $hash->{IODev}->{TYPE}; - my $offset = $hash->{tempf}{offset}; - my $factor = $hash->{tempf}{factor}; - - #-- find upper and lower boundaries for given offset/factor - my $mmin = (-55+$offset)*$factor; - my $mmax = (125+$offset)*$factor; - return sprintf("OWMULTI: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax) - if($value < $mmin || $value > $mmax); - - #-- seems to be ok, put into the device - $a[2] = int($value/$factor-$offset); - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXMULTI_SetValues($hash,@a); - #-- OWFS interface not yet implemented - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSTHERM_SetValues($hash,@a); - # return $ret - # if(defined($ret)); - } else { - return "OWMULTI: Set with wrong IODev type $interface"; - } - - #-- process results - we have to reread the device - $hash->{PRESENT} = 1; - OWMULTI_GetValues($hash); - OWMULTI_FormatValues($hash); - Log 4, "OWMULTI: Set $hash->{NAME} $key $value"; - - return undef; -} - -######################################################################################## -# -# OWMULTI_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWMULTI_Undef ($) { - my ($hash) = @_; - - delete($modules{OWMULTI}{defptr}{$hash->{OW_ID}}); - RemoveInternalTimer($hash); - return undef; -} - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a 1-Wire bus connected -# directly to the FHEM server -# -# Prefix = OWXMULTI -# -######################################################################################## -# -# OWXMULTI_GetValues - Get reading from one device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWXMULTI_GetValues($) { - - my ($hash) = @_; - - my ($i,$j,$k,$res,$res2); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - #-- hash of the busmaster - my $master = $hash->{IODev}; - - #-- switch the device to current measurement off, VDD only - OWX_Reset($master); - #-- issue the match ROM command \x55 and the write scratchpad command - if( OWX_Complex($master,$owx_dev,"\x4E\x00\x08",0) eq 0 ){ - return "$owx_dev write status failed"; - } - - #-- copy scratchpad to register - OWX_Reset($master); - #-- issue the match ROM command \x55 and the copy scratchpad command - if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){ - return "$owx_dev copy scratchpad failed"; - } - - #-- initiate temperature conversion - OWX_Reset($master); - #-- issue the match ROM command \x55 and the start conversion command - if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){ - return "$owx_dev temperature conversion failed"; - } - #-- conversion needs some 10 ms ! - select(undef,undef,undef,0.012); - - #-- initiate voltage conversion - OWX_Reset($master); - #-- issue the match ROM command \x55 and the start conversion command - if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){ - return "$owx_dev voltage conversion failed"; - } - #-- conversion needs some 4 ms ! - select(undef,undef,undef,0.006); - - #-- from memory to scratchpad - OWX_Reset($master); - #-- issue the match ROM command \x55 and the recall memory command - if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){ - return "$owx_dev recall memory failed"; - } - #-- copy needs some 10 ms ! - select(undef,undef,undef,0.012); - - #-- NOW ask the specific device - OWX_Reset($master); - #-- issue the match ROM command \x55 and the read scratchpad command \xBE - #-- reading 9 + 2 + 9 data bytes = 20 bytes - $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9); - #Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes"; - #-- process results - if( $res eq 0 ){ - return "$owx_dev not accessible in 2nd step"; - } - - # $res2 = "====> OWXMULTI Received "; - # for(my $i=0;$i DS2438 - - #-- temperature - my $lsb = ord($data[12]); - my $msb = ord($data[13]) & 127; - my $sign = ord($data[13]) & 128; - - #-- test with -55 degrees - #$lsb = 0; - #$sign = 1; - #$msb = 73; - - #-- 2's complement form = signed bytes - $owg_temp = $msb+ $lsb/256; - if( $sign !=0 ){ - $owg_temp = -128+$owg_temp; - } - - #-- voltage - $lsb = ord($data[14]); - $msb = ord($data[15]) & 3; - - #-- test with 5V - #$lsb = 244; - #$msb = 1; - - #-- supply voltage - $owg_vdd = ($msb*256+ $lsb)/100; - - #-- switch the device to current measurement off, V external only - OWX_Reset($master); - #-- issue the match ROM command \x55 and the write scratchpad command - if( OWX_Complex($master,$owx_dev,"\x4E\x00\x00",0) eq 0 ){ - return "$owx_dev write status failed"; - } - - #-- copy scratchpad to register - OWX_Reset($master); - #-- issue the match ROM command \x55 and the copy scratchpad command - if( OWX_Complex($master,$owx_dev,"\x48\x00",0) eq 0){ - return "$owx_dev copy scratchpad failed"; - } - - #-- initiate voltage conversion - OWX_Reset($master); - #-- issue the match ROM command \x55 and the start conversion command - if( OWX_Complex($master,$owx_dev,"\xB4",0) eq 0 ){ - return "$owx_dev voltage conversion failed"; - } - #-- conversion needs some 4 ms ! - select(undef,undef,undef,0.006); - - #-- from memory to scratchpad - OWX_Reset($master); - #-- issue the match ROM command \x55 and the recall memory command - if( OWX_Complex($master,$owx_dev,"\xB8\x00",0) eq 0 ){ - return "$owx_dev recall memory failed"; - } - #-- copy needs some 10 ms ! - select(undef,undef,undef,0.012); - - #-- NOW ask the specific device - OWX_Reset($master); - #-- issue the match ROM command \x55 and the read scratchpad command \xBE - #-- reading 9 + 2 + 9 data bytes = 20 bytes - $res=OWX_Complex($master,$owx_dev,"\xBE\x00",9); - #Log 1,"OWXMULTI: data length from reading device is ".length($res)." bytes"; - #-- process results - if( $res eq 0 ){ - return "$owx_dev not accessible in 2nd step"; - } - - # $res2 = "====> OWXMULTI Received "; - # for(my $i=0;$i DS2438 - - #-- voltage - $lsb = ord($data[14]); - $msb = ord($data[15]) & 3; - - #-- test with 7.2 V - #$lsb = 208; - #$msb = 2; - - #-- external voltage - $owg_volt = ($msb*256+ $lsb)/100; - - return undef; - - #} else { - # return "OWXMULTI: Unknown device family $hash->{OW_FAMILY}\n"; - #} -} - -####################################################################################### -# -# OWXMULTI_SetValues - Implements SetFn function -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWXMULTI_SetValues($@) { - my ($hash, @a) = @_; - - my ($i,$j,$k); - - my $name = $hash->{NAME}; - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - #-- hash of the busmaster - my $master = $hash->{IODev}; - - #-- define vars - my $key = $a[1]; - my $value = $a[2]; - - OWX_Reset($master); - - #-- issue the match ROM command \x55 and the write scratchpad command \x4E, - # followed by the write EEPROM command \x48 - # - # so far writing the EEPROM does not work properly. - # 1. \x48 directly appended to the write scratchpad command => command ok, no effect on EEPROM - # 2. \x48 appended to match ROM => command not ok. - # 3. \x48 sent by WriteBytePower after match ROM => command ok, no effect on EEPROM - - my $select=sprintf("\x4E%c%c\x48",0,0); - my $res=OWX_Complex($master,$owx_dev,$select,0); - - if( $res eq 0 ){ - return "OWXMULTI: Device $owx_dev not accessible"; - } - - DoTrigger($name, undef) if($init_done); - return undef; -} - - - -1; diff --git a/fhem/contrib/1-Wire/21_OWSWITCH.pm b/fhem/contrib/1-Wire/21_OWSWITCH.pm deleted file mode 100644 index ff5a409a4..000000000 --- a/fhem/contrib/1-Wire/21_OWSWITCH.pm +++ /dev/null @@ -1,894 +0,0 @@ -######################################################################################## -# -# OWSWITCH.pm -# -# FHEM module to commmunicate with 1-Wire adressable switches DS2413, DS206, DS2408 -# -# Attention: This module may communicate with the OWX module, -# but currently not with the 1-Wire File System OWFS -# -# TODO: Kanalattribute ändern zur Laufzeit. -# -# -# 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.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWSWITCH [] [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type. If omitted, we assume this to be an -# DS2413. Allowed values are DS2413, DS2406 -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => FAM_ID.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get input => state for channel (name A, B or defined channel name) -# note: this value reflects the measured value, not necessarily the one set as -# output state, because the output transistors are open collector switches. A measured -# 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 gpio => values for channels -# -# set interval => set period for measurement -# set output ON|OFF => set value for channel (name A, B or defined channel name) -# note: 1 = OFF, 0 = ON in normal usage. See also the note above -# set gpio value => set values for channels (3 = both OFF, 1 = B ON 2 = A ON 0 = both ON) -# set init yes => re-initialize device -# -# Additional attributes are defined in fhem.cfg, in some cases per channel, where =A,B -# Note: attributes are read only during initialization procedure - later changes are not used. -# -# attr event on-change/on-update = when to write an event (default= on-update) -# -# attr Name | = name for the channel | a type description for the measured value -# attr Unit | = values to display in state variable for on|off condition -# attr stateS = character string denoting external shortening condition -# -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -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; -#-- channel values - always the raw input resp. output values from the device -my @owg_val; -my @owg_vax; - -my %gets = ( - "id" => "", - "present" => "", - "interval" => "", - "input" => "", - "gpio" => "" -); - -my %sets = ( - "interval" => "", - "output" => "", - "gpio" => "", - "init" => "" -); - -my %updates = ( - "present" => "", - "gpio" => "" -); - -my %cnumber = ( - "DS2413" => 2, - "DS2406" => 2, - "DS2408" => 8 - ); - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWSWITCH -# -######################################################################################## -# -# OWSWITCH_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWSWITCH_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWSWITCH_Define"; - $hash->{UndefFn} = "OWSWITCH_Undef"; - $hash->{GetFn} = "OWSWITCH_Get"; - $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 ". - "event:on-update,on-change"; - - #TODO: correct number of channels - - for( my $i=0;$i<8;$i++ ){ - $attlist .= " ".$owg_fixed[$i]."Name"; - $attlist .= " ".$owg_fixed[$i]."Unit"; - $attlist .= " ".$owg_fixed[$i]."stateS"; - } - $hash->{AttrList} = $attlist; -} - -######################################################################################### -# -# OWSWITCH_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################### - -sub OWSWITCH_Define ($$) { - my ($hash, $def) = @_; - - # define OWSWITCH [] [interval] - # e.g.: define flow OWSWITCH 525715020000 300 - my @a = split("[ \t][ \t]*", $def); - - my ($name,$model,$fam,$id,$crc,$interval,$scale,$ret); - - #-- default - $name = $a[0]; - $interval = 300; - $scale = ""; - $ret = ""; - - #-- check syntax - return "OWSWITCH: Wrong syntax, must be define OWSWITCH [] [interval]" - if(int(@a) < 2 || int(@a) > 5); - - #-- check if this is an old style definition, e.g. is missing - my $a2 = $a[2]; - my $a3 = defined($a[3]) ? $a[3] : ""; - if( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = "DS2413"; - $id = $a[2]; - if(int(@a)>=4) { $interval = $a[3]; } - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = $a[2]; - $id = $a[3]; - if(int(@a)>=5) { $interval = $a[4]; } - } else { - return "OWSWITCH: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS2413" ){ - $fam = "3A"; - CommandAttr (undef,"$name model DS2413"); - }elsif( $model eq "DS2406" ){ - $fam = "12"; - CommandAttr (undef,"$name model DS2406"); - }elsif( $model eq "DS2408" ){ - $fam = "29"; - CommandAttr (undef,"$name model DS2408"); - }else{ - return "OWSWITCH: Wrong 1-Wire device model $model"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # determine CRC Code - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; - - #-- Define device internals - $hash->{ROM_ID} = $fam.".".$id.$crc; - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = $fam; - $hash->{PRESENT} = 0; - $hash->{INTERVAL} = $interval; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWSWITCH: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - $modules{OWSWITCH}{defptr}{$id} = $hash; - $hash->{STATE} = "Defined"; - 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()+1, "OWSWITCH_InitializeDevice", $hash, 0); - - #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0); - - return undef; -} - -######################################################################################## -# -# OWSWITCH_InitializeDevice - delayed setting of initial readings and channel names -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWSWITCH_InitializeDevice($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - - #-- Set channel names, channel units - for( my $i=0;$i<$cnumber{$attr{$name}{"model"}} ;$i++) { - #-- Initial readings OFF - $owg_val[$i] = 1; - $owg_vax[$i] = 1; - #-- 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|"; - 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); -} - -######################################################################################## -# -# OWSWITCH_FormatValues - put together various format strings -# -# Parameter hash = hash of device addressed, fs = format string -# -######################################################################################## - -sub OWSWITCH_FormatValues($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - my ($offset,$factor,$vval,$vvax,$vstr,$cname,@cnama,@unarr); - my ($value1,$value2,$value3) = ("","",""); - - my $tn = TimeNow(); - - #-- 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]; - #-- output state is 0 = ON or 1 = OFF - $vvax = $owg_vax[$i]; - - #-- string buildup for return value and STATE - @unarr= split(/\|/,$hash->{READINGS}{"$owg_channel[$i]"}{UNIT}); - $cname = defined($attr{$name}{$owg_fixed[$i]."stateS"}) ? $attr{$name}{$owg_fixed[$i]."stateS"} : ""; - $vstr = $unarr[$vval]; - $vstr .= $cname if( ($vval == 0) && ($vvax == 1) ); - $vstr = "ERR" if( ($vval == 1) && ($vvax == 0) ); - - $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 .= ", "; - } - } - #-- STATE - $hash->{STATE} = $value2; - - return $value1; -} - -######################################################################################## -# -# OWSWITCH_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWSWITCH_Get($@) { - my ($hash, @a) = @_; - - my $reading = $a[1]; - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my ($value,$value2,$value3) = (undef,undef,undef); - my $ret = ""; - my $offset; - my $factor; - my $page; - - #-- check syntax - return "OWSWITCH: Get argument is missing @a" - if(int(@a) < 2); - - #-- check argument - return "OWSWITCH: 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"; - } - - #-- get present - if($a[1] eq "present") { - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } - - #-- get interval - if($a[1] eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - - #-- reset presence - $hash->{PRESENT} = 0; - - #-- 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: " - if( int(@a)<2 ); - my $fnd=undef; - for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ - if( ($a[2] eq $owg_channel[$i]) || ($a[2] eq $owg_fixed[$i]) ){ - $fnd=$i; - last; - } - } - return "OWSWITCH: invalid output address, must be A,B,... or defined channel name" - if( !defined($fnd) ); - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXSWITCH_GetState($hash); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSSWITCH_GetPage($hash,"reading"); - #-- 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]; - - #-- get all states - }elsif( $reading eq "gpio" ){ - return "OWSWITCH: get needs no parameter when reading gpio" - if( int(@a)==1 ); - - if( $interface eq "OWX" ){ - $ret = OWXSWITCH_GetState($hash); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetValues($hash); - }else{ - return "OWSWITCH: GetValues with wrong IODev type $interface"; - } - } - #-- process results - if( defined($ret) ){ - return "OWSWITCH: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - return "OWSWITCH: $name.$reading => ".OWSWITCH_FormatValues($hash); - -} - -####################################################################################### -# -# OWSWITCH_GetValues - Updates the reading from one device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWSWITCH_GetValues($) { - my $hash = shift; - - my $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - my $value = ""; - my $ret = ""; - my $offset; - my $factor; - - #-- restart timer for updates - RemoveInternalTimer($hash); - InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 1); - - #-- reset presence - $hash->{PRESENT} = 0; - - #-- Get readings according to interface type - my $interface= $hash->{IODev}->{TYPE}; - if( $interface eq "OWX" ){ - $ret = OWXSWITCH_GetState($hash); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSSWITCH_GetValues($hash); - }else{ - return "OWSWITCH: GetValues with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWSWITCH: Could not get values from device $name"; - } - $hash->{PRESENT} = 1; - #-- old state, new state - my $oldval = $hash->{STATE}; - $value=OWSWITCH_FormatValues($hash); - my $newval = $hash->{STATE}; - #--logging depends on setting of the event-attribute - 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; -} - -####################################################################################### -# -# OWSWITCH_Set - Set one value for device -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWSWITCH_Set($@) { - my ($hash, @a) = @_; - - my $key = $a[1]; - my $value = $a[2]; - - #-- for the selector: which values are possible - if (@a == 2){ - my $newkeys = join(" ", sort keys %sets); - return $newkeys ; - } - - #-- check argument - if( !defined($sets{$a[1]}) ){ - 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'" - if($value ne "yes"); - OWSWITCH_InitializeDevice($hash); - return "OWCOUNT: Re-initialized device"; - } - - #-- set new timer interval - if($key eq "interval") { - # check value - return "OWSWITCH: Set with short interval, must be > 1" - if(int($value) < 1); - # update timer - $hash->{INTERVAL} = $value; - RemoveInternalTimer($hash); - InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 1); - return undef; - } - - - #-- 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: " - if( int(@a)<2 ); - #-- find out which channel we have - my $fnd=undef; - for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ - if( ($a[2] eq $owg_channel[$i]) || ($a[2] eq $owg_fixed[$i]) ){ - $fnd=$i; - last; - } - } - return "OWSWITCH: invalid output address, must be A,B,... or defined channel name" - if( !defined($fnd) ); - #-- prepare gpio value - my $nval; - if( lc($a[3]) eq "on" ){ - $nval = 0; - }elsif( lc($a[3]) eq "off" ){ - $nval = 1; - }else{ - return "OWSWITCH: Wrong data value $a[3], must be ON or OFF"; - } - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXSWITCH_GetState($hash); - $value = 0; - #-- vax or val ? - for (my $i=0;$i<$cnumber{$attr{$name}{"model"}};$i++){ - $value += ($owg_vax[$i]<<$i) - if( $i != $fnd ); - $value += ($nval<<$i) - if( $i == $fnd ); - } - $ret = OWXSWITCH_SetState($hash,$value); - #-- OWFS interface - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSAD_GetPage($hash,"reading"); - #-- Unknown interface - }else{ - return "OWSWITCH: Get with wrong IODev type $interface"; - } - - #-- set state - }elsif( $key eq "gpio" ){ - #-- check value and write to device - return "OWSWITCH: Set with wrong value for gpio port, must be 0 <= gpio <= ".(1 << $cnumber{$attr{$name}{"model"}} - 1) - if( ! ((int($value) >= 0) && (int($value) <= (1 << $cnumber{$attr{$name}{"model"}} -1 ))) ); - - if( $interface eq "OWX" ){ - $ret = OWXSWITCH_SetState($hash,int($value)); - #}elsif( $interface eq "OWFS" ){ - # $ret = OWFSSWITCH_GetValues($hash); - }else{ - return "OWSWITCH: GetValues with wrong IODev type $interface"; - } - } - - #-- process results - we have to reread the device - $hash->{PRESENT} = 1; - OWSWITCH_GetValues($hash); - #OWSWITCH_FormatValues($hash); - Log 4, "OWSWITCH: Set $hash->{NAME} $key $value"; - #$hash->{CHANGED}[0] = $value; - return undef; -} - -######################################################################################## -# -# OWSWITCH_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWSWITCH_Undef ($) { - my ($hash) = @_; - delete($modules{OWSWITCH}{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 = OWFSSWITCH -# -######################################################################################## - - - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a 1-Wire bus connected -# directly to the FHEM server -# -# Prefix = OWXSWITCH -# -######################################################################################## -# -# OWXAD_GetState - Get gpio ports from device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWXSWITCH_GetState($) { - my ($hash) = @_; - - my ($select, $res, $res2, $res3, @data); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- hash of the busmaster - my $master = $hash->{IODev}; - - my ($i,$j,$k); - - #-- family = 3A => DS2413 - if( $hash->{OW_FAMILY} eq "3A" ) { - #=============== get gpio values =============================== - #-- issue the match ROM command \x55 and the read gpio command - # \xF5 plus 2 empty bytes - #-- reset the bus - OWX_Reset($master); - #-- read the data - $res=OWX_Complex($master,$owx_dev,"\xF5",2); - if( $res eq 0 ){ - return "OWXSWITCH: Device $owx_dev 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 - 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 - @data=split(//,substr($res,10)); - #return "invalid data length" - # if (@data != 22); - #return "invalid data" - # if (ord($data[17])<=0); - #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: val = input value, vax = output value - #-- family = 3A => DS2413 - if( $hash->{OW_FAMILY} eq "3A" ) { - $owg_val[0] = ord($data[0]) & 1; - $owg_vax[0] = (ord($data[0])>>1) & 1; - $owg_val[1] = (ord($data[0])>>2) & 1; - $owg_vax[1] = (ord($data[0])>>3) & 1; - - #-- family = 12 => DS2406 - }elsif( $hash->{OW_FAMILY} eq "12" ) { - $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 -} - -######################################################################################## -# -# OWXSWITCH_SetPage - Set gpio ports of device -# -# Parameter hash = hash of device addressed -# value = integer value for device outputs -# -######################################################################################## - -sub OWXSWITCH_SetState($$) { - - my ($hash,$value) = @_; - - - my ($select, $res, $res2, @data); - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - my $owx_rnf = substr($owx_dev,3,12); - my $owx_f = substr($owx_dev,0,2); - - #-- hash of the busmaster - my $master = $hash->{IODev}; - - 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 - }elsif( $hash->{OW_FAMILY} eq "12" ) { - #=============== set gpio values =============================== - # Writing the output state via the access channel command does - # not work contrary to documentation. Using the write status command - #-- issue the match ROM command \x55 and the read status command - # \xAA at address TA1 = \x07 TA2 = \x00 - #-- reset the bus - OWX_Reset($master); - #-- read the data - $res = OWX_Complex($master,$owx_dev,"\xAA\x07\x00",1); - my $stat = substr($res,10,1); - my $statneu = ( $stat & 159 ) | (($value<<5) & 96) ; - #-- issue the match ROM command \x55 and the write status command - # \x55 at address TA1 = \x07 TA2 = \x00 - # - $select=sprintf("\x55\x07\x00%c",$statneu); - #-- reset the bus - OWX_Reset($master); - #-- read the data - $res=OWX_Complex($master,$owx_dev,$select,2); - if( $res eq 0 ){ - return "OWXSWITCH: Device $owx_dev not accessible in writing"; - } - $owg_val[0] = $value % 2; - $owg_vax[0] = $owg_val[0]; - $owg_val[1] = int($value / 2); - $owg_vax[1] = $owg_val[1]; - #-- family = 29 => DS2408 - }elsif( $hash->{OW_FAMILY} eq "29" ) { - #=============== 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",$value,255-$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"; - } - - } else { - return "OWXSWITCH: Unknown device family $hash->{OW_FAMILY}\n"; - } - #-- reset the bus - OWX_Reset($master); - - #-- process results - @data=split(//,substr($res,10)); - - #-- family = 3A => DS2413 - if( $hash->{OW_FAMILY} eq "3A" ) { - if( $data[2] ne "\xAA"){ - return "OWXSWITCH: State could not be set for device $owx_dev"; - } - #-- family = 12 => DS2406 - }elsif( $hash->{OW_FAMILY} eq "12" ) { - #-- very crude check - should be CRC - if( int(@data) != 5){ - return "OWXSWITCH: State could not be set for device $owx_dev"; - } - #-- family = 29 => DS2408 - }elsif( $hash->{OW_FAMILY} eq "29" ) { - if( $data[2] ne "\xAA"){ - return "OWXSWITCH: State could not be set for device $owx_dev"; - } - } - return undef - -} - -1; diff --git a/fhem/contrib/1-Wire/21_OWTHERM.pm b/fhem/contrib/1-Wire/21_OWTHERM.pm deleted file mode 100755 index c2c962cc3..000000000 --- a/fhem/contrib/1-Wire/21_OWTHERM.pm +++ /dev/null @@ -1,815 +0,0 @@ -######################################################################################## -# -# OWTHERM.pm -# -# FHEM module to commmunicate with 1-Wire temperature sensors DS1820, DS18S20, DS18B20, DS1822 -# -# Attention: This module may communicate with the OWX module, -# and also with the 1-Wire File System OWFS -# -# Prefixes for subroutines of this module: -# 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 -# Martin Fischer, 2011 -# -# Version 2.24 - October, 2012 -# -# Setup bus device in fhem.cfg as -# -# define OWTHERM [] [interval] -# -# where may be replaced by any name string -# -# is a 1-Wire device type. If omitted, we assume this to be an -# DS1820 temperature sensor -# Currently allowed values are DS1820, DS18B20, DS1822 -# is a 12 character (6 byte) 1-Wire ROM ID -# without Family ID, e.g. A2D90D000800 -# [interval] is an optional query interval in seconds -# -# get id => OW_FAMILY.ROM_ID.CRC -# get present => 1 if device present, 0 if not -# get interval => query interval -# get temperature => temperature measurement -# get alarm => alarm temperature settings -# -# set interval => set period for measurement -# set tempLow => lower alarm temperature setting -# set tempHigh => higher alarm temperature setting -# -# Additional attributes are defined in fhem.cfg -# Note: attributes "tempXXXX" are read during every update operation. -# -# attr event on-change/on-update = when to write an event (default= on-update) -# -# attr stateAL "" = character string for denoting low alarm condition, default is red down triangle -# attr stateAH "" = character string for denoting high alarm condition, default is red up triangle -# attr tempOffset = temperature offset in degree Celsius added to the raw temperature reading -# attr tempUnit = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit or C/K/F, default is Celsius -# attr tempLow = value for low alarm -# attr tempHigh = value for high alarm -# -######################################################################################## -# -# 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; - -#-- Prototypes to make komodo happy -use vars qw{%attr %defs}; -use strict; -use warnings; -sub Log($$); - -#-- temperature globals - always the raw values from the device -my $owg_temp = 0; -my $owg_th = 0; -my $owg_tl = 0; - -#-- variables for display strings -my $stateal; -my $stateah; - -my %gets = ( - "id" => "", - "present" => "", - "interval" => "", - "temperature" => "", - "alarm" => "" -); - -my %sets = ( - "interval" => "", - "tempHigh" => "", - "tempLow" => "" -); - -my %updates = ( - "present" => "", - "temperature" => "", - "alarm" => "" -); - -######################################################################################## -# -# The following subroutines are independent of the bus interface -# -# Prefix = OWTHERM -# -######################################################################################## -# -# OWTHERM_Initialize -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWTHERM_Initialize ($) { - my ($hash) = @_; - - $hash->{DefFn} = "OWTHERM_Define"; - $hash->{UndefFn} = "OWTHERM_Undef"; - $hash->{GetFn} = "OWTHERM_Get"; - $hash->{SetFn} = "OWTHERM_Set"; - #tempOffset = a temperature offset added to the temperature reading for correction - #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 ". - "event:on-update,on-change ". - "stateAL stateAH ". - "tempOffset tempUnit:C,Celsius,F,Fahrenheit,K,Kelvin ". - "tempLow tempHigh"; - } - -######################################################################################## -# -# OWTHERM_Define - Implements DefFn function -# -# Parameter hash = hash of device addressed, def = definition string -# -######################################################################################## - -sub OWTHERM_Define ($$) { - my ($hash, $def) = @_; - - # define OWTHERM [] [interval] - # e.g.: define flow OWTHERM 525715020000 300 - my @a = split("[ \t][ \t]*", $def); - - my ($name,$model,$fam,$id,$crc,$interval,$ret); - my $tn = TimeNow(); - - #-- default - $name = $a[0]; - $interval = 300; - $ret = ""; - - #-- check syntax - return "OWTHERM: Wrong syntax, must be define OWTHERM [] [interval]" - if(int(@a) < 2 || int(@a) > 6); - - #-- check if this is an old style definition, e.g. is missing - my $a2 = $a[2]; - my $a3 = defined($a[3]) ? $a[3] : ""; - if( ($a2 eq "none") || ($a3 eq "none") ) { - return "OWTHERM: ID = none is obsolete now, please redefine"; - } elsif( $a2 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = "DS1820"; - $id = $a[2]; - if(int(@a)>=4) { $interval = $a[3]; } - Log 1, "OWTHERM: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 5); - } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { - $model = $a[2]; - $id = $a[3]; - if(int(@a)>=5) { $interval = $a[4]; } - Log 1, "OWTHERM: Parameter [alarminterval] is obsolete now - must be set with I/O-Device" - if(int(@a) == 6); - } else { - return "OWTHERM: $a[0] ID $a[2] invalid, specify a 12 digit value"; - } - - #-- 1-Wire ROM identifier in the form "FF.XXXXXXXXXXXX.YY" - # FF = family id follows from the model - # YY must be determined from id - if( $model eq "DS1820" ){ - $fam = "10"; - }elsif( $model eq "DS1822" ){ - $fam = "22"; - }elsif( $model eq "DS18B20" ){ - $fam = "28"; - }else{ - return "OWTHERM: Wrong 1-Wire device model $model"; - } - # determine CRC Code - only if this is a direct interface - $crc = defined($hash->{IODev}->{INTERFACE}) ? sprintf("%02x",OWX_CRC($fam.".".$id."00")) : "00"; - - #-- define device internals - $hash->{ALARM} = 0; - $hash->{OW_ID} = $id; - $hash->{OW_FAMILY} = $fam; - $hash->{PRESENT} = 0; - $hash->{ROM_ID} = $fam.".".$id.$crc; - $hash->{INTERVAL} = $interval; - - #-- Couple to I/O device - AssignIoPort($hash); - Log 3, "OWTHERM: Warning, no 1-Wire I/O device found for $name." - if(!defined($hash->{IODev}->{NAME})); - $modules{OWTHERM}{defptr}{$id} = $hash; - $hash->{STATE} = "Defined"; - Log 3, "OWTHERM: Device $name defined."; - - #-- Start timer for initialization in a few seconds - InternalTimer(time()+10, "OWTHERM_InitializeDevice", $hash, 0); - - #-- Start timer for updates - InternalTimer(time()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 0); - - return undef; -} - -######################################################################################## -# -# OWTHERM_InitializeDevice - delayed setting of initial readings and channel names -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWTHERM_InitializeDevice($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - my @args; - - $stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : ""; - $stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : ""; - - #-- unit attribute defined ? - $hash->{READINGS}{"temperature"}{UNIT} = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : "Celsius"; - $hash->{READINGS}{"temperature"}{TYPE} = "temperature"; - - #-- Initial readings temperature sensor - $owg_temp = 0.0; - $owg_tl = defined($attr{$name}{"tempLow"}) ? $attr{$name}{"tempLow"} : 0.0; - $owg_th = defined($attr{$name}{"tempHigh"}) ? $attr{$name}{"tempHigh"} : 100.0; - #-- Initialize all the display stuff - OWTHERM_FormatValues($hash); - #-- alarm - @args = ($name,"tempLow",$owg_tl); - OWTHERM_Set($hash,@args); - @args = ($name,"tempHigh",$owg_th); - OWTHERM_Set($hash,@args); - -} - -######################################################################################## -# -# OWTHERM_FormatValues - put together various format strings -# -# Parameter hash = hash of device addressed, fs = format string -# -######################################################################################## - -sub OWTHERM_FormatValues($) { - my ($hash) = @_; - - my $name = $hash->{NAME}; - my ($unit,$offset,$factor,$abbr,$vval,$vlow,$vhigh,$statef); - my ($value1,$value2,$value3) = ("","",""); - - my $tn = TimeNow(); - - #-- attributes defined ? - $stateal = defined($attr{$name}{stateAL}) ? $attr{$name}{stateAL} : ""; - $stateah = defined($attr{$name}{stateAH}) ? $attr{$name}{stateAH} : ""; - $unit = defined($attr{$name}{"tempUnit"}) ? $attr{$name}{"tempUnit"} : $hash->{READINGS}{"temperature"}{UNIT}; - $offset = defined($attr{$name}{"tempOffset"}) ? $attr{$name}{"tempOffset"} : 0.0 ; - $factor = 1.0; - - if( $unit eq "Celsius" ){ - $abbr = "°C"; - } elsif ($unit eq "Kelvin" ){ - $abbr = "K"; - $offset += "273.16" - } elsif ($unit eq "Fahrenheit" ){ - $abbr = "°F"; - $offset = ($offset+32)/1.8; - $factor = 1.8; - } else { - $abbr="?"; - Log 1, "OWTHERM_FormatValues: unknown unit $unit"; - } - #-- these values are rather coplex to obtain, therefore save them in the hash - $hash->{READINGS}{"temperature"}{UNIT} = $unit; - $hash->{READINGS}{"temperature"}{UNITABBR} = $abbr; - $hash->{tempf}{offset} = $offset; - $hash->{tempf}{factor} = $factor; - - #-- correct values for proper 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 - $vlow = ($owg_tl + $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 - $statef = "%5.2f ".$abbr; - $value1 = "temperature: ".sprintf($statef,$vval); - $value2 = sprintf($statef,$vval); - $hash->{ALARM} = 1; - - #-- Test for alarm condition - if( ($vval <= $vlow) && ( $vval >= $vhigh ) ){ - $value2 .= " ".$stateal.$stateah; - $value3 .= " ".$stateal.$stateah; - }elsif( $vval <= $vlow ){ - $value2 .= " ".$stateal; - $value3 .= " ".$stateal; - }elsif( $vval >= $vhigh ){ - $value2 .= " ".$stateah; - $value3 .= " ".$stateah; - } else { - $hash->{ALARM} = 0; - } - - #-- STATE - $hash->{STATE} = $value2; - #-- alarm - #$hash->{READINGS}{alarms}{VAL} = $value3; - #$hash->{READINGS}{alarms}{TIME} = $tn; - return $value1; -} - -######################################################################################## -# -# OWTHERM_Get - Implements GetFn function -# -# Parameter hash = hash of device addressed, a = argument array -# -######################################################################################## - -sub OWTHERM_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 "OWTHERM: Get argument is missing @a" - if(int(@a) != 2); - - #-- check argument - return "OWTHERM: 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"; - } - - #-- Get other values according to interface type - my $interface= $hash->{IODev}->{TYPE}; - - #-- get present - if($a[1] eq "present" ) { - #-- OWX interface - if( $interface eq "OWX" ){ - #-- hash of the busmaster - my $master = $hash->{IODev}; - $value = OWX_Verify($master,$hash->{ROM_ID}); - $hash->{PRESENT} = $value; - return "$name.present => $value"; - } else { - return "OWTHERM: Verification not yet implemented for interface $interface"; - } - } - - #-- get interval - if($reading eq "interval") { - $value = $hash->{INTERVAL}; - return "$name.interval => $value"; - } - - #-- reset presence - $hash->{PRESENT} = 0; - - #-- OWX interface - if( $interface eq "OWX" ){ - #-- not different from getting all values .. - $ret = OWXTHERM_GetValues($hash); - #-- OWFS interface - }elsif( $interface eq "OWFS" ){ - $ret = OWFSTHERM_GetValues($hash); - #-- Unknown interface - }else{ - return "OWTHERM: Get with wrong IODev type $interface"; - } - - #-- process results - if( defined($ret) ){ - return "OWTHERM: Could not get values from device $name, return was $ret"; - } - $hash->{PRESENT} = 1; - OWTHERM_FormatValues($hash); - - #-- return the special reading - if ($reading eq "temperature") { - return "OWTHERM: $name.temperature => ". - $hash->{READINGS}{"temperature"}{VAL}; - } elsif ($reading eq "alarm") { - return "OWTHERM: $name.alarm => L ".$hash->{READINGS}{"tempLow"}{VAL}. - " H ".$hash->{READINGS}{"tempHigh"}{VAL}; - } - return undef; -} - -####################################################################################### -# -# OWTHERM_GetValues - Updates the readings from device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWTHERM_GetValues($@) { - my $hash = shift; - - my $name = $hash->{NAME}; - my $value = ""; - my $ret = ""; - - #-- restart timer for updates - RemoveInternalTimer($hash); - InternalTimer(time()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 1); - - #-- reset presence - $hash->{PRESENT} = 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 = OWXTHERM_GetValues($hash); - last - if( !defined($ret) ); - } - }elsif( $interface eq "OWFS" ){ - $ret = OWFSTHERM_GetValues($hash); - }else{ - Log 3, "OWTHERM: GetValues with wrong IODev type $interface"; - return 1; - } - - #-- process results - if( defined($ret) ){ - Log 3, "OWTHERM: Could not get values from device $name, reason $ret"; - return 1; - } - $hash->{PRESENT} = 1; - - #-- old state, new state - my $oldval = $hash->{STATE}; - $value=OWTHERM_FormatValues($hash); - my $newval = $hash->{STATE}; - #--logging depends on setting of the event-attribute - 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; -} - -####################################################################################### -# -# OWTHERM_Set - Set one value for device -# -# Parameter hash = hash of device addressed -# a = argument string -# -######################################################################################## - -sub OWTHERM_Set($@) { - my ($hash, @a) = @_; - - #-- for the selector: which values are possible - return join(" ", sort keys %sets) if(@a == 2); - #-- check syntax - return "OWTHERM: Set needs one parameter" - if(int(@a) != 3); - #-- check argument - return "OWTHERM: 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 $name = $hash->{NAME}; - my $model = $hash->{OW_MODEL}; - - #-- set new timer interval - if($key eq "interval") { - # check value - return "OWTHERM: Set with short interval, must be > 1" - if(int($value) < 1); - # update timer - $hash->{INTERVAL} = $value; - RemoveInternalTimer($hash); - InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWTHERM_GetValues", $hash, 1); - return undef; - } - - #-- set other values depending on interface type - my $interface = $hash->{IODev}->{TYPE}; - my $offset = $hash->{tempf}{offset}; - my $factor = $hash->{tempf}{factor}; - - #-- find upper and lower boundaries for given offset/factor - my $mmin = (-55+$offset)*$factor; - my $mmax = (125+$offset)*$factor; - return sprintf("OWTHERM: Set with wrong value $value for $key, range is [%3.1f,%3.1f]",$mmin,$mmax) - if($value < $mmin || $value > $mmax); - - #-- seems to be ok, put into the device - $a[2] = int($value/$factor-$offset); - - #-- OWX interface - if( $interface eq "OWX" ){ - $ret = OWXTHERM_SetValues($hash,@a); - #-- OWFS interface - }elsif( $interface eq "OWFS" ){ - $ret = OWFSTHERM_SetValues($hash,@a); - return $ret - if(defined($ret)); - } else { - return "OWTHERM: Set with wrong IODev type $interface"; - } - - #-- process results - we have to reread the device - $hash->{PRESENT} = 1; - OWTHERM_GetValues($hash); - OWTHERM_FormatValues($hash); - Log 4, "OWTHERM: Set $hash->{NAME} $key $value"; - - return undef; -} - -######################################################################################## -# -# OWTHERM_Undef - Implements UndefFn function -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWTHERM_Undef ($) { - my ($hash) = @_; - - delete($modules{OWTHERM}{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 = OWFSTHERM -# -######################################################################################## -# -# OWFSTHERM_GetValues - Get reading from one device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWFSTHERM_GetValues($) -{ - my ($hash) = @_; - - my $ret = OW::get("/uncached/".$hash->{OW_FAMILY}.".".$hash->{OW_ID}."/temperature"); - if( defined($ret) ) { - $hash->{PRESENT} = 1; - $owg_temp = $ret; - $owg_th = OW::get("/uncached/".$hash->{OW_FAMILY}.".".$hash->{OW_ID}."/temphigh"); - $owg_tl = OW::get("/uncached/".$hash->{OW_FAMILY}.".".$hash->{OW_ID}."/templow"); - } else { - $hash->{PRESENT} = 0; - $owg_temp = 0.0; - $owg_th = 0.0; - $owg_tl = 0.0; - } - - return undef; -} - -####################################################################################### -# -# OWFSTHERM_SetValues - Implements SetFn function -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWFSTHERM_SetValues($@) { - my ($hash, @a) = @_; - - #-- define vars - my $key = lc($a[1]); - my $value = $a[2]; - - return OW::put($hash->{OW_FAMILY}.".".$hash->{OW_ID}."/$key",$value); -} - -######################################################################################## -# -# The following subroutines in alphabetical order are only for a 1-Wire bus connected -# directly to the FHEM server -# -# Prefix = OWXTHERM -# -######################################################################################## -# -# OWXTHERM_GetValues - Get reading from one device -# -# Parameter hash = hash of device addressed -# -######################################################################################## - -sub OWXTHERM_GetValues($) { - - my ($hash) = @_; - - my ($i,$j,$k); - - #-- For default, perform the conversion NOT now - my $con=1; - - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - #-- hash of the busmaster - my $master = $hash->{IODev}; - - #-- 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") ){ - $con=0; - } - - #-- if the conversion has not been called before - if( $con==1 ){ - OWX_Reset($master); - #-- issue the match ROM command \x55 and the start conversion command - if( OWX_Complex($master,$owx_dev,"\x44",0) eq 0 ){ - return "$owx_dev not accessible"; - } - #-- conversion needs some 950 ms - but we may also do it in shorter time ! - select(undef,undef,undef,1.0); - } - - #-- NOW ask the specific device - OWX_Reset($master); - #-- issue the match ROM command \x55 and the read scratchpad command \xBE - #-- reading 9 + 1 + 8 data bytes and 1 CRC byte = 19 bytes - my $res=OWX_Complex($master,$owx_dev,"\xBE",9); - #Log 1,"OWXTHERM: data length from reading device is ".length($res)." bytes"; - #-- process results - if( $res eq 0 ){ - return "$owx_dev not accessible in 2nd step"; - } - - #-- process results - my @data=split(//,$res); - return "invalid data length, ".int(@data)." bytes" - if (@data != 19); - return "invalid data" - if (ord($data[17])<=0); - return "invalid CRC" - if (OWX_CRC8(substr($res,10,8),$data[18])==0); - - #-- this must be different for the different device types - # family = 10 => DS1820, DS18S20 - if( $hash->{OW_FAMILY} eq "10" ) { - - my $count_remain = ord($data[16]); - my $count_perc = ord($data[17]); - my $delta = -0.25 + ($count_perc - $count_remain)/$count_perc; - - my $lsb = ord($data[10]); - my $msb = 0; - my $sign = ord($data[11]) & 255; - - #-- test with -25 degrees - #$lsb = 12*16+14; - #$sign = 1; - #$delta = 0; - - #-- 2's complement form = signed bytes - $owg_temp = int($lsb/2) + $delta; - if( $sign !=0 ){ - $owg_temp = -128+$owg_temp; - } - - $owg_th = ord($data[12]) > 127 ? 128-ord($data[12]) : ord($data[12]); - $owg_tl = ord($data[13]) > 127 ? 128-ord($data[13]) : ord($data[13]); - - return undef; - - } elsif ( ($hash->{OW_FAMILY} eq "22") || ($hash->{OW_FAMILY} eq "28") ) { - - my $lsb = ord($data[10]); - my $msb = ord($data[11]) & 7; - my $sign = ord($data[11]) & 248; - - #-- test with -55 degrees - #$lsb = 9*16; - #$sign = 1; - #$msb = 7; - - #-- 2's complement form = signed bytes - $owg_temp = $msb*16+ $lsb/16; - if( $sign !=0 ){ - $owg_temp = -128+$owg_temp; - } - $owg_th = ord($data[12]) > 127 ? 128-ord($data[12]) : ord($data[12]); - $owg_tl = ord($data[13]) > 127 ? 128-ord($data[13]) : ord($data[13]); - - return undef; - - } else { - return "OWXTHERM: Unknown device family $hash->{OW_FAMILY}\n"; - } -} - -####################################################################################### -# -# OWXTHERM_SetValues - Implements SetFn function -# -# Parameter hash = hash of device addressed -# a = argument array -# -######################################################################################## - -sub OWXTHERM_SetValues($@) { - my ($hash, @a) = @_; - - my ($i,$j,$k); - - my $name = $hash->{NAME}; - #-- ID of the device - my $owx_dev = $hash->{ROM_ID}; - #-- hash of the busmaster - my $master = $hash->{IODev}; - - #-- define vars - my $key = $a[1]; - my $value = $a[2]; - $owg_tl = $value if( $key eq "tempLow" ); - $owg_th = $value if( $key eq "tempHigh" ); - - #-- put into 2's complement formed (signed byte) - my $tlp = $owg_tl < 0 ? 128 - $owg_tl : $owg_tl; - my $thp = $owg_th < 0 ? 128 - $owg_th : $owg_th; - - OWX_Reset($master); - - #-- issue the match ROM command \x55 and the write scratchpad command \x4E, - # followed by the write EEPROM command \x48 - # - # so far writing the EEPROM does not work properly. - # 1. \x48 directly appended to the write scratchpad command => command ok, no effect on EEPROM - # 2. \x48 appended to match ROM => command not ok. - # 3. \x48 sent by WriteBytePower after match ROM => command ok, no effect on EEPROM - - my $select=sprintf("\x4E%c%c\x48",$thp,$tlp); - my $res=OWX_Complex($master,$owx_dev,$select,0); - - if( $res eq 0 ){ - return "OWXTHERM: Device $owx_dev not accessible"; - } - - DoTrigger($name, undef) if($init_done); - return undef; -} - - - -1; diff --git a/fhem/contrib/1-Wire/LCD_Terminal1.png b/fhem/contrib/1-Wire/LCD_Terminal1.png deleted file mode 100755 index 0c953e3da..000000000 Binary files a/fhem/contrib/1-Wire/LCD_Terminal1.png and /dev/null differ diff --git a/fhem/contrib/1-Wire/LCD_Terminal2.png b/fhem/contrib/1-Wire/LCD_Terminal2.png deleted file mode 100755 index b86a1342f..000000000 Binary files a/fhem/contrib/1-Wire/LCD_Terminal2.png and /dev/null differ diff --git a/fhem/contrib/1-Wire/Schaltplan_Aktives_1-Wire_Interface.png b/fhem/contrib/1-Wire/Schaltplan_Aktives_1-Wire_Interface.png deleted file mode 100644 index 5b2bf4613..000000000 Binary files a/fhem/contrib/1-Wire/Schaltplan_Aktives_1-Wire_Interface.png and /dev/null differ diff --git a/fhem/contrib/1-Wire/Schaltplan_Passives_1-Wire_Interface.png b/fhem/contrib/1-Wire/Schaltplan_Passives_1-Wire_Interface.png deleted file mode 100644 index 0cd477b1d..000000000 Binary files a/fhem/contrib/1-Wire/Schaltplan_Passives_1-Wire_Interface.png and /dev/null differ diff --git a/fhem/contrib/1-Wire/Schaltplan_USB_1-Wire_Interface.png b/fhem/contrib/1-Wire/Schaltplan_USB_1-Wire_Interface.png deleted file mode 100644 index 4c5f08cef..000000000 Binary files a/fhem/contrib/1-Wire/Schaltplan_USB_1-Wire_Interface.png and /dev/null differ diff --git a/fhem/contrib/1-Wire/commandref.html b/fhem/contrib/1-Wire/commandref.html deleted file mode 100755 index 67d5537ac..000000000 --- a/fhem/contrib/1-Wire/commandref.html +++ /dev/null @@ -1,786 +0,0 @@ - - - - - - -

OWX

-
    FHEM module to commmunicate with 1-Wire bus devices
      -
    • via an active DS2480/DS2482/DS2490/DS9097U bus master interface attached to an - USB port or
    • -
    • via a passive DS9097 interface attached to an USB port or
    • -
    • via a network-attached CUNO or through a COC on the RaspBerry Pi
    • -
    Internally these interfaces are vastly different, read the corresponding Wiki pages -
    -
    - Example
    -
      - define OWio1 OWX /dev/ttyUSB1 -
      - define OWio2 OWX COC -
      -
    -
    - - Define -
      - define <name> OWX <serial-device> or
      - define <name> OWX <cuno/coc-device> -

      Define a 1-Wire interface to communicate with a 1-Wire bus.
      -
      -
    • - <serial-device> The serial device (e.g. USB port) to which - the 1-Wire bus is attached.
    • -
    • - <cuno-device> The previously defined CUNO to which the 1-Wire - bus is attached.
    • -
    -
    - - Set -
      -
    • - set <name> interval <value> - -

      sets the time period in seconds for "kicking" the 1-Wire bus - (default is 300 seconds). This means:
        -
      • With 1-Wire bus interfaces that do not supply power to the 1-Wire bus - (attr buspower parasitic), the 1-Wire bus is reset at these intervals.
      • -
      • With 1-Wire bus interfaces that supply power to the 1-Wire bus (attr - buspower = real), all temperature measurement devices on the bus receive - the command to start a temperature conversion (saves a lot of time when - reading)
      • -
      • With 1-Wire bus interfaces that contain a busmaster chip, the response - to a reset pulse contains information about alarms.
      • -

      -
    • -
    • - set <name> followAlarms on|off - -

      instructs the module to start an alarm search in case a reset pulse - discovers any 1-Wire device which has the alarm flag set.
    • -
    -
    - - Get -
      -
    • - get <name> alarms -

      performs an "alarm search" for devices on the 1-Wire bus and, if - found, generates an event in the log (not with CUNO).
    • -
      -
    • - get <name> devices -

      redicovers all devices on the 1-Wire bus. If a device found has a - previous definition, this is automatically used. If a device is found but has no - definition, it is autocreated. If a defined device is not on the 1-Wire bus, it - is autodeleted.
    • -
      -
      -
    - - Attributes - -
- - -

OWAD

-
    FHEM module to commmunicate with 1-Wire A/D converters

    Note:
    This - 1-Wire module so far works only with the OWX interface module. Please define an OWX device first.
    -
    Example
    -
      - define OWX_AD OWAD 724610000000 45 -
      - attr OWX_AD DAlarm high -
      - attr OWX_AD DFactor 31.907097 -
      - attr OWX_AD DHigh 50.0 -
      - attr OWX_AD DName relHumidity|humidity -
      - attr OWX_AD DOffset -0.8088 -
      - attr OWX_AD DUnit percent|% -
      -

    - - Define -
      - define <name> OWAD [<model>] <id> [<interval>] -

      Define a 1-Wire A/D converter.

      -
    • - [<model>]
      Defines the A/D converter model (and thus - 1-Wire family id), currently the following values are permitted:
        -
      • model DS2450 with family id 20 (default if the model parameter is - omitted)
      • -
      -
    • -
    • - <id> -
      12-character unique ROM id of the converter device without family id and - CRC code
    • -
    • - <interval> -
      Measurement interval in seconds. The default is 300 seconds.
    • -
      -
    -
    - - Set - -
    - - Get - -
    - - Attributes -
      -
    • attr <name> stateAL0 - <string> -
      character string for denoting low normal condition, default is green down - triangle, e.g. the code <span - style="color:green">&#x25BE;</span> leading to the sign -
    • -
    • attr <name> stateAH0 - <string> -
      character string for denoting high alarm condition, default is green - upward triangle, e.g. the code <span - style="color:green">&#x25B4;</span> leading to the sign -
    • -
    • attr <name> stateAL1 - <string> -
      character string for denoting low alarm condition, default is red down - triangle, e.g. the code <span style="color:red">&#x25BE;</span> - leading to the sign
    • -
    • attr <name> stateAH1 - <string> -
      character string for denoting high alarm condition, default is red upward - triangle, e.g. the code <span style="color:red">&#x25B4;</span> - leading to the sign -
    • -
    For each of the following attributes, the channel identification A,B,C,D may be - used. -
- - -

OWCOUNT

- - - -

OWID

-
    FHEM module for 1-Wire devices that know only their unique ROM ID
    -
    Note:
    This 1-Wire module so far works only with the OWX interface module. - Please define an OWX device first.
    -
    Example
    -
      - define ROM1 OWX_ID OWCOUNT CE780F000000 -
      -

    - - Define -
      - define <name> OWID <id> -

      Define a 1-Wire device.

      -
    • - <id> -
      12-character unique ROM id of the converter device without family id and - CRC code
    • -
    -
    - - Get - -
    -
- - -

OWLCD

- - - -

OWMULTI

-
    FHEM module to commmunicate with 1-Wire multi-sensors, currently the DS2438 smart battery monitor

    Note:
    This - 1-Wire module so far works only with the OWX interface module. Please define an OWX device first.
    -
    Example
    -
      - define OWX_M OWMULTI 7C5034010000 45 -
      - attr OWX_M VName relHumidity|humidity -
      - attr OWX_M VUnit percent|% -
      - attr OWX_M VFunction (161.29 * V / VDD - 25.8065)/(1.0546 - 0.00216 * T) -
      -

    - - Define -
      - define <name> OWMULTI [<model>] <id> [<interval>] -

      Define a 1-Wire multi-sensor

      -
    • - [<model>]
      Defines the sensor model (and thus - 1-Wire family id), currently the following values are permitted:
        -
      • model DS2438 with family id 26 (default if the model parameter is - omitted). Measured is a temperature value, an external voltage and the current supply voltage
      • -
      -
    • -
    • - <id> -
      12-character unique ROM id of the converter device without family id and - CRC code
    • -
    • - <interval> -
      Measurement interval in seconds. The default is 300 seconds.
    • -
      -
    -
    - - Set - -
    - - Get - -
    - - Attributes - - - -

    OWSWITCH

    -
      FHEM module to commmunicate with 1-Wire Programmable Switches

      Note:
      - This 1-Wire module so far works only with the OWX interface module. Please define an OWX device first.
      -
      Example
      -
        - define OWX_S OWSWITCH DS2413 B5D502000000 60 -
        - attr OWX_S AName Lampe|light -
        - attr OWX_S AUnit AN|AUS -
        -
      -
      - - Define -
        - define <name> OWSWITCH [<model>] <id> - [<interval>] -

        Define a 1-Wire switch.

        -
      • - [<model>]
        Defines the switch model (and thus 1-Wire - family id), currently the following values are permitted:
          -
        • model DS2413 with family id 3A (default if the model parameter is - omitted). 2 Channel switch with onboard memory
        • -
        • model DS2406 with family id 12. 2 Channel switch
        • -
        • model DS2406 with family id 29. 8 Channel switch
        • -
        -
      • -
      • - <id> -
        12-character unique ROM id of the converter device without family id and - CRC code
      • -
      • - <interval> -
        Measurement interval in seconds. The default is 300 seconds.
      • -
      -
      - - Set - -
      - - Get -
        -
      • - get <name> id -
        Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC
      • -
      • - get <name> present - -
        Returns 1 if this 1-Wire device is present, otherwise 0.
      • -
      • - get <name> interval
        Returns measurement interval - in seconds.
      • -
      • - get <name> input <channel-name>
        - state for channel (A,B, ... or defined channel name) - This value reflects the measured value, not necessarily the one set as - output state, because the output transistors are open collector switches. A measured - 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
        Obtain state of all - channels
      • -
      -
      - - Attributes For each of the following attributes, the channel - identification A,B,... may be used. -
    - - -

    OWTHERM

    -
      FHEM module to commmunicate with 1-Wire bus digital thermometer devices

      - Note:
      This is the only 1-Wire module which so far works with both the OWFS and the - OWX interface module. Please define an OWFS device or an OWX device first.
      -
      Example
      -
        - define OWX_T OWTHERM DS18B20 E8D09B030000 300 -
        - attr OWX_T tempUnit Kelvin -
        -

      - - Define -
        - define <name> OWTHERM [<model>] <id> - [<interval>] -

        Define a 1-Wire digital thermometer device.

        -
      • - [<model>]
        Defines the thermometer model (and thus - 1-Wire family id) currently the following values are permitted:
          -
        • model DS1820 with family id 10 (default if the model parameter is - omitted)
        • -
        • model DS1822 with family id 22
        • -
        • model DS18B20 with family id 28
        • -
        -
      • -
      • - <id> -
        12-character unique ROM id of the thermometer device without family id and - CRC code
      • -
      • - <interval> -
        Temperature measurement interval in seconds. The default is 300 seconds.
      • -
        Example:
        - define Temp1 OWTHERM 14B598010800 300
        -
      -
      - - Set - -
      - - Get - -
      - - Attributes - -
    - - -
    - -