################################################################ # # Copyright notice # # (c) 2008 Copyright: Martin Fischer (m_fischer at gmx dot de) # All rights reserved # # This script 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. # ################################################################ # $Id: 20_OWFS.pm 2516 2013-01-14 10:41:48Z mfr69bs $ package main; use strict; use warnings; use Time::HiRes qw(gettimeofday); use OW; my %models = ( "DS1420" => "", "DS9097" => "", ); my %fc = ( "1:DS9420" => "01", "2:DS1420" => "81", "3:DS1820" => "10", ); my %gets = ( "address" => "", "alias" => "", "crc8" => "", "family" => "", "id" => "", "locator" => "", "present" => "", # "r_address" => "", # "r_id" => "", # "r_locator" => "", "type" => "", ); ############################################## sub OWFS_Initialize($) { my ($hash) = @_; # Provider $hash->{WriteFn} = "OWFS_Write"; $hash->{Clients} = ":OWTEMP:"; # Normal devices $hash->{DefFn} = "OWFS_Define"; $hash->{UndefFn} = "OWFS_Undef"; $hash->{GetFn} = "OWFS_Get"; #$hash->{SetFn} = "OWFS_Set"; $hash->{AttrList} = "IODev do_not_notify:1,0 dummy:1,0 temp-scale:C,F,K,R ". "showtime:1,0 loglevel:0,1,2,3,4,5,6"; } ##################################### sub OWFS_Get($$) { my ($hash,@a) = @_; return "argument is missing @a" if (@a != 2); return "Passive Adapter defined. No Get function implemented." if(!defined($hash->{OW_ID})); return "Unknown argument $a[1], choose one of " . join(",", sort keys %gets) if(!defined($gets{$a[1]})); my $ret = OWFS_GetData($hash,$a[1]); return "$a[0] $a[1] => $ret"; } ##################################### sub OWFS_GetData($$) { my ($hash,$query) = @_; my $name = $hash->{NAME}; my $path = $hash->{OW_PATH}; my $ret = undef; $ret = OW::get("/uncached/$path/$query"); if ($ret) { # strip spaces $ret =~ s/^\s+//g; Log 4, "OWFS $name $query $ret"; $hash->{READINGS}{$query}{VAL} = $ret; $hash->{READINGS}{$query}{TIME} = TimeNow(); return $ret; } else { return undef; } } ##################################### sub OWFS_DoInit($) { my ($hash) = @_; my $name = $hash->{NAME}; my $path; my $ret; if (defined($hash->{OWFS_ID})) { $path = $hash->{OW_FAMILY}.".".$hash->{OWFS_ID}; foreach my $q (sort keys %gets) { $ret = OWFS_GetData($hash,$q); } } $hash->{STATE} = "Initialized" if (!$hash->{STATE}); return undef; } ##################################### sub OWFS_Define($$) { my ($hash, $def) = @_; # define OWFS # define foo OWFS 127.0.0.1:4304 DS1420 93302D000000 my @a = split("[ \t][ \t]*", $def); return "wrong syntax: define OWFS []" if (@a < 2 && int(@a) > 5); my $name = $a[0]; my $dev = $a[2]; # return "wrong device format: use ip:port" # if ($device !~ m/^(.+):(0-9)+$/); my $model = $a[3]; return "Define $name: wrong model: specify one of " . join ",", sort keys %models if (!grep { $_ eq $model } keys %models); if (@a > 4) { my $id = $a[4]; return "Define $name: wrong ID format: specify a 12 digit value" if (uc($id) !~ m/^[0-9|A-F]{12}$/); $hash->{FamilyCode} = \%fc; my $fc = $hash->{FamilyCode}; if (defined ($fc)) { foreach my $c (sort keys %{$fc}) { if ($c =~ m/$model/) { $hash->{OW_FAMILY} = $fc->{$c}; } } } delete ($hash->{FamilyCode}); $hash->{OW_ID} = $id; $hash->{OW_PATH} = $hash->{OW_FAMILY}.".".$hash->{OW_ID}; } $hash->{STATE} = "Defined"; # default temperature-scale: C # C: Celsius, F: Fahrenheit, K: Kelvin, R: Rankine $attr{$name}{"temp-scale"} = "C"; if ($dev eq "none") { $attr{$name}{dummy} = 1; Log 1, "OWFS device is none, commands will be echoed only"; return undef; } Log 3, "OWFS opening OWFS device $dev"; my $po; $po = OW::init($dev); return "Can't connect to $dev: $!" if(!$po); Log 3, "OWFS opened $dev for $name"; Log 1, "OWFS ########################################"; Log 1, "OWFS # IMPORTANT NOTE:"; Log 1, "OWFS # This module is deprecated and will be removed in a future release!"; Log 1, "OWFS # Please use OWServer / OWDevice."; Log 1, "OWFS ########################################"; $hash->{DeviceName} = $dev; $hash->{STATE}=""; my $ret = OWFS_DoInit($hash); return undef; } ##################################### sub OWFS_Undef($$) { my ($hash, $arg) = @_; my $name = $hash->{NAME}; foreach my $d (sort keys %defs) { if (defined($defs{$d}) && defined($defs{$d}{IODev}) && $defs{$d}{IODev} == $hash) { my $lev = ($reread_active ? 4 : 2); Log GetLogLevel($name,$lev), "deleting port for $d"; delete $defs{$d}{IODev}; } } return undef; } 1; =pod =begin html

OWFS

    OWFS is a suite of programs that designed to make the 1-wire bus and its devices easily accessible. The underlying priciple is to create a virtual filesystem, with the unique ID being the directory, and the individual properties of the device are represented as simple files that can be read and written.

    Note: You need the owperl module from http://owfs.org/.

    Define
      define <name> OWFS <owserver-ip:port> <model> [<id>]

      Define a 1-wire device to communicate with an OWFS-Server.

      <owserver-ip:port>
        IP-address:port from OW-Server.
      <model>
        Define the type of the input device. Currently supportet: DS1420, DS9097 (for passive Adapter)
      <id>
        Corresponding to the id of the input device. Only for active Adapter.

      Note:
      If the owserver-ip:port is called none, then no device will be opened, so you can experiment without hardware attached.

      Example:
        #define an active Adapter:
        define DS9490R OWFS 127.0.0.1:4304 DS1420 93302D000000


        #define a passive Adapter:
        define DS9097 OWFS 127.0.0.1:4304 DS9097


    Set
      N/A

    Get
      get <name> <value>

      where value is one of (not supported by passive Devices e.g. DS9097):
      • address (read-only)
        The entire 64-bit unique ID. address starts with the family code.
        Given as upper case hexidecimal digits (0-9A-F).
      • crc8 (read-only)
        The 8-bit error correction portion. Uses cyclic redundancy check. Computed from the preceeding 56 bits of the unique ID number.
        Given as upper case hexidecimal digits (0-9A-F).
      • family (read-only)
        The 8-bit family code. Unique to each type of device.
        Given as upper case hexidecimal digits (0-9A-F).
      • id (read-only)
        The 48-bit middle portion of the unique ID number. Does not include the family code or CRC.
        Given as upper case hexidecimal digits (0-9A-F).
      • locator (read-only)
        Uses an extension of the 1-wire design from iButtonLink company that associated 1-wire physical connections with a unique 1-wire code. If the connection is behind a Link Locator the locator will show a unique 8-byte number (16 character hexidecimal) starting with family code FE.
        If no Link Locator is between the device and the master, the locator field will be all FF.
      • present (read-only)
        Is the device currently present on the 1-wire bus?
      • type (read-only)
        Part name assigned by Dallas Semi. E.g. DS2401 Alternative packaging (iButton vs chip) will not be distiguished.

      Examples:
        get DS9490R type
        DS9490R type => DS1420

        get DS9490R address
        DS9490R address => 8193302D0000002B

    Attributes
=end html =cut