######################################################################################## # # OWID.pm # # FHEM module to commmunicate with general 1-Wire ID-ROMS # # Prof. Dr. Peter A. Henning # # $Id$ # ######################################################################################## # # define OWID [interval] or OWID . [interval] # # 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 # [interval] is an optional query interval in seconds # # set interval => set query interval for checking presence # # get id => FAM_ID.ROM_ID.CRC # get present => 1 if device present, 0 if not # get version => OWX version number # # ######################################################################################## # # This programm is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # The GNU General Public License can be found at # http://www.gnu.org/copyleft/gpl.html. # A copy is found in the textfile GPL.txt and important notices to the license # from the author is found in LICENSE.txt distributed with these scripts. # # This script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ######################################################################################## package main; use vars qw{%attr %defs %modules $readingFnAttributes $init_done}; use strict; use warnings; sub Log($$); my $owx_version="3.24"; #-- declare variables my %gets = ( "present" => "", "interval" => "", "id" => "", "version" => "" ); my %sets = ( "interval" => "" ); my %updates = ( "present" => "" ); ######################################################################################## # # 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} = "OWID_Set"; $hash->{AttrFn} = "OWID_Attr"; $hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model loglevel:0,1,2,3,4,5 ". "interval ". $readingFnAttributes; #make sure OWX is loaded so OWX_CRC is available if running with OWServer main::LoadModule("OWX"); } ######################################################################################### # # 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,$interval,$model,$fam,$id,$crc,$ret); #-- default $name = $a[0]; $interval = 300; $ret = ""; #-- check syntax return "OWID: Wrong syntax, must be define OWID [] [interval] or OWAD . [interval]" if(int(@a) < 2 || int(@a) > 5); #-- different types of definition allowed my $a2 = $a[2]; my $a3 = defined($a[3]) ? $a[3] : ""; #-- no model, 2+12 characters if( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) { $fam = substr($a[2],0,2); $id = substr($a[2],3); if(int(@a)>=4) { $interval = $a[3]; } if( $fam eq "01" ){ $model = "DS2401"; CommandAttr (undef,"$name model DS2401"); }else{ $model = "unknown"; CommandAttr (undef,"$name model unknown"); } #-- model or family id, 12 characters } elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) { $id = $a[3]; if(int(@a)>=5) { $interval = $a[4]; } #-- family id, 2 characters if( $a2 =~ m/^[0-9|a-f|A-F]{2}$/ ) { $fam = $a[2]; if( $fam eq "01" ){ $model = "DS2401"; CommandAttr (undef,"$name model DS2401"); }else{ $model = "unknown"; CommandAttr (undef,"$name model unknown"); } }else{ $model = $a[2]; if( $model eq "DS2401" ){ $fam = "01"; CommandAttr (undef,"$name model DS2401"); }else{ return "OWID: Unknown 1-Wire device model $model"; } } } else { return "OWID: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value"; } #-- determine CRC Code $crc = sprintf("%02X",OWX_CRC($fam.".".$id."00")); #-- Define device internals $hash->{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); if( !defined($hash->{IODev}->{NAME}) | !defined($hash->{IODev}) | !defined($hash->{IODev}->{PRESENT}) ){ return "OWID: Warning, no 1-Wire I/O device found for $name."; } $modules{OWID}{defptr}{$id} = $hash; #-- readingsSingleUpdate($hash,"state","Defined",1); Log 3, "OWID: Device $name defined."; #-- Initialization reading according to interface type my $interface= $hash->{IODev}->{TYPE}; #-- Start timer for updates InternalTimer(time()+5+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0); #-- readingsSingleUpdate($hash,"state","Initialized",1); return undef; } ####################################################################################### # # OWID_Attr - Set one attribute value for device # # Parameter hash = hash of device addressed # a = argument array # ######################################################################################## sub OWID_Attr(@) { my ($do,$name,$key,$value) = @_; my $hash = $defs{$name}; my $ret; if ( $do eq "set") { ARGUMENT_HANDLER: { $key eq "interval" and do { # check value return "OWID: Set with short interval, must be > 1" if(int($value) < 1); # update timer $hash->{INTERVAL} = $value; if ($init_done) { RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 1); } last; }; } } return $ret; } ######################################################################################## # # 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 interval if($a[1] eq "interval") { $value = $hash->{INTERVAL}; return "$name.interval => $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; if( $value == 0 ){ readingsSingleUpdate($hash,"state","not present",1); } else { readingsSingleUpdate($hash,"state","present",1); } return "$name.present => $value"; } #-- get version if( $a[1] eq "version") { return "$name.version => $owx_version"; } } ######################################################################################## # # OWID_GetValues - Updates the reading from one device # # Parameter hash = hash of device addressed # ######################################################################################## sub OWID_GetValues($) { my $hash = shift; my $name = $hash->{NAME}; my $value = ""; my $ret = ""; my $offset; my $factor; #-- restart timer for updates RemoveInternalTimer($hash); InternalTimer(time()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 1); #-- hash of the busmaster my $master = $hash->{IODev}; $value = OWX_Verify($master,$hash->{ROM_ID}); $hash->{PRESENT} = $value; if( $value == 0 ){ readingsSingleUpdate($hash,"state","not present",1); } else { readingsSingleUpdate($hash,"state","present",1); } } ####################################################################################### # # OWID_Set - Set one value for device # # Parameter hash = hash of device addressed # a = argument array # ######################################################################################## sub OWID_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 "OWID: Set needs at least one parameter" if( int(@a)<3 ); #-- check argument if( !defined($sets{$a[1]}) ){ return "OWID: Set with unknown argument $a[1]"; } my $name = $hash->{NAME}; #-- set new timer interval if($key eq "interval") { # check value return "OWID: Set with short interval, must be > 1" if(int($value) < 1); # update timer $hash->{INTERVAL} = $value; RemoveInternalTimer($hash); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 1); return undef; } } ######################################################################################## # # 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; =pod =begin html

OWID

FHEM module for 1-Wire devices that know only their unique ROM ID

This 1-Wire module works with the OWX interface module or with the OWServer interface module Please define an OWX device or OWServer device first.


Example


define ROM1 OWX_ID OWCOUNT 09.CE780F000000 10


Define

define <name> OWID <fam> <id> [<interval>] or
define <name> OWID <fam>.<id> [<interval>]

Define a 1-Wire device.

  • <fam>
    2-character unique family id, see above
  • <id>
    12-character unique ROM id of the converter device without family id and CRC code
  • <interval>
    Interval in seconds for checking the presence of the device. The default is 300 seconds.

Set


Get

=end html =cut