| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010 |
- # $Id: 10_OWServer.pm 16501 2018-03-27 11:27:13Z neubert $
- ################################################################
- #
- # Copyright notice
- #
- # (c) 2012 Copyright: Dr. Boris Neubert & Martin Fischer
- # e-mail: omega at online dot de
- # e-mail: m_fischer at gmx dot de
- #
- # This file is part of fhem.
- #
- # Fhem 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.
- #
- # Fhem 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.
- #
- # You should have received a copy of the GNU General Public License
- # along with fhem. If not, see <http://www.gnu.org/licenses/>.
- #
- ################################################################################
- package main;
- use strict;
- use warnings;
- # this must be the latest OWNet from
- # http://owfs.cvs.sourceforge.net/viewvc/owfs/owfs/module/ownet/perl5/OWNet/lib/OWNet.pm
- # the version at CPAN is outdated and malfunctioning as at 2012-12-19
- #use constant OWNet_version_default => "2.8p17";
- use constant OWNet_version_default => "3.1p5";
- use vars qw($OWNet_version);
- use vars qw(%owfamily);
- # 1-Wire devices (order by family code)
- # http://owfs.sourceforge.net/family.html
- %owfamily = (
- "01" => "DS2401 DS1990A",
- "05" => "DS2405",
- "10" => "DS18S20 DS1920",
- "12" => "DS2406 DS2507",
- "1B" => "DS2436",
- "1D" => "DS2423",
- "1F" => "DS2409",
- "20" => "DS2450",
- "22" => "DS1822",
- "23" => "DS2433",
- "24" => "DS2415 DS1904",
- "26" => "DS2438",
- "27" => "DS2417",
- "28" => "DS18B20",
- "29" => "DS2408",
- "3A" => "DS2413",
- "3B" => "DS1825",
- "7E" => "EDS000XX",
- "81" => "DS1420",
- "FF" => "LCD",
- );
- use vars qw(%gets %sets);
- %gets = (
- "/settings/timeout/directory" => "",
- "/settings/timeout/ftp" => "",
- "/settings/timeout/ha7" => "",
- "/settings/timeout/network" => "",
- "/settings/timeout/presence" => "",
- "/settings/timeout/serial" => "",
- "/settings/timeout/server" => "",
- "/settings/timeout/stable" => "",
- "/settings/timeout/uncached" => "",
- "/settings/timeout/usb" => "",
- "/settings/timeout/volatile" => "",
- "/settings/timeout/w1" => "",
- "/settings/units/pressure_scale" => "",
- "/settings/units/temperature_scale" => "",
- "/uncached/alarm" => "",
- );
- %sets = (
- "timeout/directory" => "",
- "timeout/ftp" => "",
- "timeout/ha7" => "",
- "timeout/network" => "",
- "timeout/presence" => "",
- "timeout/serial" => "",
- "timeout/server" => "",
- "timeout/stable" => "",
- "timeout/uncached" => "",
- "timeout/usb" => "",
- "timeout/volatile" => "",
- "timeout/w1" => "",
- "units/pressure_scale" => "",
- "units/temperature_scale" => "",
- );
- #####################################
- sub
- OWServer_Initialize($)
- {
- my ($hash) = @_;
- # Provider
- $hash->{WriteFn} = "OWServer_Write";
- $hash->{ReadFn} = "OWServer_Read";
- $hash->{DirFn} = "OWServer_Dir";
- $hash->{FindFn} = "OWServer_Find";
- $hash->{Clients} = ":OWDevice:OWAD:OWCOUNT:OWMULTI:OWSWITCH:OWTHERM:";
- # Consumer
- $hash->{DefFn} = "OWServer_Define";
- $hash->{NotifyFn}= "OWServer_Notify";
- $hash->{NotifyOrderPrefix}= "50a-";
- $hash->{UndefFn} = "OWServer_Undef";
- $hash->{GetFn} = "OWServer_Get";
- $hash->{SetFn} = "OWServer_Set";
- # $hash->{AttrFn} = "OWServer_Attr";
- $hash->{AttrList}= "nonblocking " . $readingFnAttributes;
- }
- #####################################
- sub
- OWServer_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t]+", $def, 4);
- my $name = $a[0];
- if(@a < 3) {
- my $msg = "wrong syntax for $name: define <name> OWServer <protocol> [<version>]";
- Log 2, $msg;
- return $msg;
- }
- my $protocol = $a[2];
- $hash->{fhem}{protocol}= $protocol;
- my $version;
- if(@a==4) {
- $version= $a[3];
- Log3 $hash, 5, "$name: Suggesting OWNet version $version";
- if(!OWServer_hasOWNet($version)) {
- Log3 $hash, 2, "$name: Suggested OWNet version $version not available, falling back to default version "
- . OWNet_version_default;
- $version= OWNet_version_default;
- }
- } else {
- $version= OWNet_version_default;
- Log3 $hash, 5, "$name: Tentatively assuming OWNet version $version";
- }
- $hash->{OWNET_VERSION}= $version;
- $hash->{NOTIFYDEV} = "global";
- $hash->{OWNET_VERSION}= OWServer_loadOWNet($hash);
- if( $init_done ) {
- OWServer_OpenDev($hash);
- }
- return undef;
- }
- #####################################
- sub
- OWServer_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);
- Log3 $name, $lev, "deleting OWServer for $d";
- delete $defs{$d}{IODev};
- }
- }
- OWServer_CloseDev($hash);
- return undef;
- }
- #####################################
- sub OWServer_getOWNetfilename($) {
- my ($v)= @_;
- return "lib/OWNet-$v.pm";
- }
- sub OWServer_hasOWNet($) {
- my ($v)= @_;
- my $filename= $attr{global}{modpath}."/FHEM/lib/OWNet-$v.pm";
- return -r $filename;
- }
- sub OWServer_loadOWNet($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- if(defined($OWNet_version)) {
- Log3 $name, 3, "$name: owserver version not checked, using currently loaded OWNet version $OWNet_version";
- return $OWNet_version;
- }
- $OWNet_version= $hash->{OWNET_VERSION};
- my $libfilename= OWServer_getOWNetfilename($OWNet_version);
- Log3 $name, 5, "$name: Loading OWNet version $OWNet_version...";
- require $libfilename;
- Log3 $name, 3, "$name: OWNet version $OWNet_version loaded.";
- my $owserver= OWServer_TryOpenDev($hash);
- if(defined($owserver)) {
- my $version= $owserver->read("/system/configuration/version");
- if(defined($version)) {
- Log3 $name, 3, "$name: owserver version $version found.";
- $hash->{OWSERVER_VERSION}= $version;
- if($OWNet_version eq $version) {
- Log3 $name, 3, "$name: Matching OWNet version already loaded.";
- return $OWNet_version;
- }
- } else {
- Log3 $name, 2, "$name: Could not read owserver version, using OWNet version $OWNet_version.";
- return $OWNet_version;
- }
- my $libfilename= OWServer_getOWNetfilename($version);
- Log3 $name, 5, "$name: Looking for OWNet version $version in $libfilename...";
- if(OWServer_hasOWNet($version)) {
- # we temporarily disable the subroutine warning
- my $handler= $SIG{__WARN__};
- $SIG{__WARN__} = sub {
- my $warning= shift;
- warn $warning unless $warning =~ /Subroutine .* redefined at/;
- };
- Log3 $name, 5, "$name: Loading OWNet version $version...";
- require $libfilename;
- $SIG{__WARN__}= $handler;
- $OWNet_version= $version;
- Log3 $name, 3, "$name: OWNet version $OWNet_version loaded.";
- return $OWNet_version;
- } else {
- Log3 $name, 3, "$name: No matching OWNet version found, using OWNet version $OWNet_version.";
- }
- } else {
- Log3 $name, 2, "$name: Could not connect to owserver, using OWNet version $OWNet_version";
- return $OWNet_version;
- }
- # we should not get here
- return undef;
- }
- #####################################
- sub
- OWServer_CloseDev($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- return unless(defined($hash->{fhem}{owserver}));
- delete $hash->{fhem}{owserver};
- readingsSingleUpdate($hash, "state", "DISCONNECTED", 1);
- }
- ########################
- sub
- OWServer_TryOpenDev($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- OWServer_CloseDev($hash);
- my $protocol= $hash->{fhem}{protocol};
- Log3 $name, 3, "$name: Opening connection to OWServer $protocol...";
- my $owserver= OWNet->new($protocol);
- if($owserver) {
- Log3 $name, 3, "$name: Successfully connected to $protocol.";
- } else {
- Log3 $name, 2, "$name: Could not connect to $protocol.";
- }
- return $owserver
- }
- sub
- OWServer_OpenDev($)
- {
- my ($hash) = @_;
- my $owserver= OWServer_TryOpenDev($hash);
- if(defined($owserver)) {
- $hash->{fhem}{owserver}= $owserver;
- readingsSingleUpdate($hash, "state", "CONNECTED", 1);
- my $ret = OWServer_DoInit($hash);
- }
- return $owserver
- }
- #####################################
- sub
- OWServer_Notify($$)
- {
- my ($hash,$dev) = @_;
- my $name = $hash->{NAME};
- my $type = $hash->{TYPE};
- return if($dev->{NAME} ne "global");
- return if(!grep(m/^INITIALIZED|REREADCFG$/, @{$dev->{CHANGED}}));
- return if($attr{$name} && $attr{$name}{disable});
- OWServer_OpenDev($hash);
- return undef;
- }
- #####################################
- sub
- OWServer_DoInit($)
- {
- my $hash = shift;
- my $name = $hash->{NAME};
- my $owserver= $hash->{fhem}{owserver};
- foreach my $reading (sort keys %gets) {
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,"$reading",$owserver->read("$reading"));
- readingsEndUpdate($hash,1);
- }
- readingsSingleUpdate($hash, "state", "Initialized", 1);
- OWServer_Autocreate($hash);
- return undef;
- }
- #####################################
- sub
- OWServer_Read($@)
- {
- my ($hash,$path)= @_;
- return undef unless(defined($hash->{fhem}{owserver}) || $hash->{LAST_READ_FAILED});
- my $ret= undef;
- if(AttrVal($hash->{NAME},"nonblocking",undef) && $init_done) {
- $hash->{".path"}= $path;
- pipe(READER,WRITER);
- #READER->autoflush(1);
- WRITER->autoflush(1);
- my $pid= fork;
- if(!defined($pid)) {
- Log3 $hash, 1, "OWServer: Cannot fork: $!";
- return undef;
- }
- InternalTimer(gettimeofday()+6, "OWServer_TimeoutChild", $pid, 0);
- if($pid == 0) {
- close READER;
- $ret= $hash->{fhem}{owserver}->read($path);
- $ret =~ s/^\s+//g if(defined($ret));
- my $r= defined($ret) ? $ret : "<undefined>";
- Log3 $hash, 5, "OWServer child read $path: $r";
- delete $hash->{".path"};
- print WRITER $ret if(defined($ret));
- close WRITER;
- # see http://forum.fhem.de/index.php?t=tree&goto=94670
- # changed from
- # exit 0;
- # to
- POSIX::_exit(0);
- }
- Log3 $hash, 5, "OWServer child ID for reading '$path' is $pid";
- close WRITER;
- # http://forum.fhem.de/index.php/topic,16945.0/topicseen.html#msg110673
- my ($rout,$rin, $eout,$ein) = ('','', '','');
- vec($rin, fileno(READER), 1) = 1;
- $ein = $rin;
- my $nfound = select($rout=$rin, undef, $eout=$ein, 4);
- if( $nfound ) {
- $ret= <READER>;
- if(defined($ret)) {
- chomp($ret) } else {
- Log3 $hash, 5, "OWServer: undefined response from child $pid";
- }
- RemoveInternalTimer($pid);
- OWServer_OpenDev($hash) if( $hash->{LAST_READ_FAILED} );
- $hash->{LAST_READ_FAILED} = 0;
- } else {
- Log3 undef, 1, "OWServer: read timeout for child $pid";
- $hash->{NR_READ_FAILED} = 0 if( !$hash->{NR_READ_FAILED} );
- $hash->{NR_READ_FAILED}++;
- OWServer_CloseDev($hash) if( !$hash->{LAST_READ_FAILED} );
- $hash->{LAST_READ_FAILED} = 1;
- }
- close READER;
- } else {
- $ret= $hash->{fhem}{owserver}->read($path);
- $ret =~ s/^\s+//g if(defined($ret));
- $hash->{LAST_READ_FAILED} = 0;
- }
- # if a device does not exist, the server returns undef
- # therefore it's not a good idea to blame the connection
- # and remove the server in such a case.
- #if(!defined($ret)) { OWServer_CloseDev($hash); }
- return $ret;
- }
- #####################################
- sub
- OWServer_TimeoutChild($)
- {
- my $pid= shift;
- Log3 undef, 1, "OWServer: Terminated child $pid" if($pid && kill(9, $pid));
- }
- #####################################
- sub
- OWServer_Write($@)
- {
- my ($hash,$path,$value)= @_;
- return undef if($hash->{LAST_READ_FAILED});
- return undef unless(defined($hash->{fhem}{owserver}));
- return $hash->{fhem}{owserver}->write($path,$value);
- }
- #####################################
- sub
- OWServer_Dir($@)
- {
- my ($hash,$path)= @_;
- return undef if($hash->{LAST_READ_FAILED});
- return undef unless(defined($hash->{fhem}{owserver}));
- $path= ($path) ? $path : "/";
- return $hash->{fhem}{owserver}->dir($path);
- }
- #####################################
- sub
- OWServer_Find($@)
- {
- my ($hash,$slave)= @_;
- return undef if($hash->{LAST_READ_FAILED});
- return undef unless(defined($hash->{fhem}{owserver}));
- my $owserver= $hash->{fhem}{owserver};
- my $fulldir= $owserver->dir("/");
- return undef unless(defined($fulldir));
- my @dir= split(",", $fulldir);
- my $path= undef;
- for my $entry (@dir) {
- $entry = substr($entry,1);
- next if($entry !~ m/^bus.\d+/m);
- my @busdir= split(",",$owserver->dir("/$entry"));
- $path= (grep { m/$slave/i } @busdir) ? $entry : undef;
- last if($path)
- }
- return $path;
- }
- #####################################
- sub
- OWServer_Autocreate($)
- {
- my ($hash)= @_;
- my $name = $hash->{NAME};
- my $acdname= "";
- foreach my $d (keys %defs) {
- next if($defs{$d}{TYPE} ne "autocreate");
- $acdname= $defs{$d}{NAME};
- return undef if(AttrVal($acdname,"disable",undef));
- }
- return undef unless($acdname ne "");
- my $owserver= $hash->{fhem}{owserver};
- my @dir= split(",", $owserver->dir("/"));
- my @devices= grep { m/^\/[0-9a-f]{2}.[0-9a-f]{12}$/i } @dir;
- my %defined = ();
- foreach my $d (keys %defs) {
- next if($defs{$d}{TYPE} !~ /^OW(Device|AD|ID|MULTI|COUNT|LCD|SWITCH|THERM)$/);
- if(defined($defs{$d}{fhem}) && defined($defs{$d}{fhem}{address})) {
- $defined{$defs{$d}{fhem}{address}} = $d;
- } elsif(defined($defs{$d}{OW_ID}) and defined($defs{$d}{OW_FAMILY})) {
- $defined{"$defs{$d}{OW_FAMILY}.$defs{$d}{OW_ID}"} = $d;
- }
- }
- my $created = 0;
- for my $device (@devices) {
- my $address= substr($device,1);
- my $family= substr($address,0,2);
- if(!exists $owfamily{$family}) {
- Log3 $name, 2, "$name: Autocreate: unknown familycode '$family' found. Please report this!";
- next;
- } else {
- my $type= $owserver->read($device . "/type");
- my $owtype= $owfamily{$family};
- if($owtype !~ m/$type/) {
- Log3 $name, 2, "$name: Autocreate: type '$type' not defined in familycode '$family'. Please report this!";
- next;
- } elsif( defined($defined{$address}) ) {
- Log3 $name, 5, "$name address '$address' already defined as '$defined{$address}'";
- next;
- } else {
- my $id= substr($address,3);
- my $devname= $type . "_" . $id;
- Log3 $name, 5, "$name create new device '$devname' for address '$address'";
- my $interval= ($family eq "81") ? "" : " 60";
- my $define= "$devname OWDevice $address" . $interval;
- my $cmdret;
- $cmdret= CommandDefine(undef,$define);
- if($cmdret) {
- Log3 $name, 1, "$name: Autocreate: An error occurred while creating device for address '$address': $cmdret";
- } else {
- $created++;
- $cmdret= CommandAttr(undef,"$devname room OWDevice");
- }
- }
- }
- }
- CommandSave(undef,undef) if( $created && AttrVal($acdname, "autosave", 1 ) );
- return undef;
- }
- #####################################
- sub
- OWServer_Get($@)
- {
- my ($hash, @a) = @_;
- my $name = $a[0];
- return "$name: get needs at least one parameter" if(@a < 2);
- my $cmd= $a[1];
- #my $arg = ($a[2] ? $a[2] : "");
- #my @args= @a; shift @args; shift @args;
- my $owserver= $hash->{fhem}{owserver};
- if($cmd eq "devices") {
- my @dir= split(",", $owserver->dir("/"));
- my @devices= grep { m/^\/[0-9a-f]{2}.[0-9a-f]{12}$/i } @dir;
- my $ret;
- for my $device (@devices) {
- my $name= "";
- my $address= substr($device,1);
- my $type= $owserver->read($device . "/type");
- foreach my $p (keys %defs) {
- $name= concatc(", ", $name, $p) if($defs{$p}{TYPE} eq "OWDevice" and $defs{$p}{fhem}{address} eq $address);
- }
- $ret .= sprintf("%s %10s %s\n", $address, $type, $name);
- }
- return $ret;
- } elsif($cmd eq "errors") {
- my $path= "statistics/errors";
- my @dir= split(",", $owserver->dir($path));
- my $wide= (reverse sort { $a <=> $b } map { length($_) } @dir)[0];
- $wide= $wide-length($path);
- my $ret= "=> $path:\n";
- for my $error (@dir) {
- my $stat= $owserver->read("$path/$error");
- my (undef, $str) = $error =~ m|^(.*[/\\])([^/\\]+?)$|;
- $str =~ s/_/ /g;
- $ret .= sprintf("%-*s %d\n",$wide,$str,($stat) ? $stat : 0);
- }
- return $ret;
- } elsif($cmd eq "/uncached/alarm") {
- # Oliver Vallant, 2017-04-17
- my $path= $cmd;
- my @devices= split(",", $owserver->dir($path));
- my $ret;
- for my $device (@devices) {
- my $name= "";
- my $address= substr($device, rindex($device, "/")+1);
- my $type= $owserver->read($device . "/type");
- foreach my $p (keys %defs) {
- $name= concatc(", ", $name, $p) if($defs{$p}{TYPE} eq "OWDevice" and $defs{$p}{fhem}{address} eq $address);
- }
- $ret .= sprintf("%s %10s %s\n", $address, $type, $name);
- }
- return $ret;
- } elsif(defined($gets{$cmd})) {
- my $ret;
- my $value= $owserver->read($cmd);
- readingsSingleUpdate($hash,$cmd,$value,1);
- return "$cmd => $value";
- } else {
- return "Unknown argument $cmd, choose one of devices ".join(" ", sort keys %gets);
- }
- }
- #####################################
- sub
- OWServer_Set($@)
- {
- my ($hash, @a) = @_;
- my $name = $a[0];
- # usage check
- #my $usage= "Usage: set $name classdef <classname> <filename> OR set $name reopen";
- my $usage= "Unknown argument $a[1], choose one of reopen ".join(" ", sort keys %sets);
- return $usage if($a[1] ne "reopen" && !defined($sets{$a[1]}));
- if((@a == 2) && ($a[1] eq "reopen")) {
- OWServer_OpenDev($hash);
- return undef;
- } elsif(@a == 3) {
- my $cmd= $a[1];
- my $value= $a[2];
- my $owserver= $hash->{fhem}{owserver};
- my $ret= $owserver->write("/settings/$cmd",$value);
- #return $ret if($ret);
- readingsSingleUpdate($hash,"/settings/$cmd",$value,1);
- }
- return undef;
- }
- #####################################
- 1;
- =pod
- =item device
- =item summary controls a One-Wire (1Wire) server instance
- =item summary_DE steuert eine Ausgabe eines One-Wire (1Wire) Servers
- =begin html
- <a name="OWServer"></a>
- <h3>OWServer</h3>
- <ul>
- <br>
- <a name="OWServerdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> OWServer <protocol> [<version>]</code>
- <br><br>
- Defines a logical OWServer device which connects to an owserver.
- owserver is the server component of the
- <a href="http://owfs.org">owfs 1-Wire Filesystem</a>. It serves as abstraction layer
- for any 1-wire devices on a host. <protocol> has
- format <hostname>:<port>.
- For details see
- <a href="http://owfs.org/index.php?page=owserver_protocol">owserver documentation</a>.
- <p>
- The OWServer device uses
- <a href="http://owfs.cvs.sourceforge.net/viewvc/owfs/owfs/module/ownet/perl5/OWNet/lib/OWNet.pm">OWNet.pm from Sourceforge</a>
- to connect to the owserver.
- Currently, OWNet modules for versions 2.8p17 and 3.1p5 are deployed with FHEM.
- You can manually add more versions by extracting OWNet.pm from
- <a href="https://sourceforge.net/projects/owfs/files/owfs/">one of the
- available versions</a> and saving it as as
- <code>FHEM/lib/OWNet-<version>.pm</code> in the FHEM directory
- structure.
- <p>
- The first connection to the owserver is made using version 3.1p5 unless
- you explicitely suggest another version using the optional
- <code><version></code> parameter. You should suggest a OWNet module
- version matching your actual owserver version if FHEM hangs after
- connecting to the owserver.
- <p>
- The OWServer device autodetects the owserver version and chooses a matching
- OWNet module from the list of available OWNet modules. If no matching OWNet
- module is found, the initially suggested version is used. The nightmare situation of two
- OWServer devices connecting to owserver instances with different versions is
- not handled correctly. The server and module versions are stored in the
- internals of the OWServer device for your reference.
- <p>
- The ow* version 3.1p5 packages provided with Debian Stretch and
- the ow* version 2.8p17 packages provided with Debian Jessie are fine.
- The ow* version 2.9 packages provided with Debian Jessie in combination with OWNet.pm as
- deployed with FHEM might have issues (feedback welcome).
- For Debian Jessie you could unzip
- <a href="http://forum.fhem.de/index.php?action=dlattach;topic=12219.0;attach=2463">owfs_2.8p17-1_all.zip</a> and install
- owserver, dependencies and what else you require with <code>dpkg -i <package>.deb</code>.
- <p>
- Please report issues and successes related to versions in the
- <a href="https://forum.fhem.de/index.php/board,26.0.html">1Wire board of the FHEM Forum</a>.
- <p>
- A typical working configuration file <code>/etc/owfs.conf</code> looks as follows:<p>
- <code>
- # server uses device /dev/onewire<br>
- server: device = /dev/onewire<br>
- # clients other than server use server<br>
- ! server: server = localhost:4304<br>
- # port<br>
- server: port = 4304<br>
- # owhttpd<br>
- http: port = 2121<br>
- # owftpd<br>
- ftp: port = 2120<br>
- </code>
- <p>
- The actual 1-wire devices are defined as <a href="#OWDevice">OWDevice</a> devices.
- If <a href="#autocreate">autocreate</a> is enabled, all the devices found are created at
- start of FHEM automatically.
- <br><br>
- This module is completely unrelated to the 1-wire modules with names all in uppercase.
- <br><br>
- Examples:
- <ul>
- <code>define myLocalOWServer OWServer localhost:4304</code><br>
- <code>define myRemoteOWServer OWServer raspi:4304 2.8p17</code><br>
- </ul>
- <br><br>
- Notice: if you get no devices add both <code>localhost</code> and the FQDN of your owserver as server directives
- to the owserver configuration file
- on the remote host.
- <br><br>
- </ul>
- <a name="OWServerset"></a>
- <b>Set</b>
- <ul>
- <code>set <name> <value></code>
- <br><br>
- where <code>value</code> is one of<br><br>
- <li><code>reopen</code><br>
- Reopens the connection to the owserver.
- </li>
- <li>owserver (OWFS) specific settings:
- <ul>
- <li><code>timeout/directory</code></li>
- <li><code>timeout/ftp</code></li>
- <li><code>timeout/ha7</code></li>
- <li><code>timeout/network</code></li>
- <li><code>timeout/presence</code></li>
- <li><code>timeout/serial</code></li>
- <li><code>timeout/server</code></li>
- <li><code>timeout/stable</code></li>
- <li><code>timeout/uncached</code></li>
- <li><code>timeout/usb</code></li>
- <li><code>timeout/volatile</code></li>
- <li><code>timeout/w1</code></li>
- <li><code>units/pressure_scale</code></li>
- <li><code>units/temperature_scale</code></li>
- </ul>
- </li>
- For further informations have look on <a href="http://owfs.org/uploads/owserver.1.html#sect41">owserver manual</a>).
- <br>
- </ul>
- <br><br>
- <a name="OWServerget"></a>
- <b>Get</b>
- <ul>
- <code>get <name> <value></code>
- <br><br>
- where <code>value</code> is one of<br><br>
- <li><code>devices</code><br>
- Lists the addresses and types of all 1-wire devices provided by the owserver. Also shows
- the corresponding <a href="#OWDevice">OWDevice</a> if one is defined for the respective 1-wire devices.
- </li>
- <li><code>errors</code><br>
- List a view of error statistics.</li>
- <li>owserver (OWFS) specific settings:
- <ul>
- <li><code>/settings/timeout/directory</code></li>
- <li><code>/settings/timeout/ftp</code></li>
- <li><code>/settings/timeout/ha7</code></li>
- <li><code>/settings/timeout/network</code></li>
- <li><code>/settings/timeout/presence</code></li>
- <li><code>/settings/timeout/serial</code></li>
- <li><code>/settings/timeout/server</code></li>
- <li><code>/settings/timeout/stable</code></li>
- <li><code>/settings/timeout/uncached</code></li>
- <li><code>/settings/timeout/usb</code></li>
- <li><code>/settings/timeout/volatile</code></li>
- <li><code>/settings/timeout/w1</code></li>
- <li><code>/settings/units/pressure_scale</code></li>
- <li><code>/settings/units/temperature_scale</code></li>
- <li><code>/uncached/alarm</code></li>
- </ul>
- </li>
- For further informations have look on <a href="http://owfs.org/uploads/owserver.1.html#sect41">owserver manual</a>).
- <br>
- </ul>
- <br><br>
- <a name="OWServerattr"></a>
- <b>Attributes</b>
- <ul>
- <li>nonblocking<br>
- Get all readings (OWServer / <a href="#OWDevice">OWDevice</a>) via a child process. This ensures, that FHEM
- is not blocked during communicating with the owserver.<br>
- Example:<br>
- <code> attr <name> nonblocking 1</code>
- </li>
- <li><a href="#eventMap">eventMap</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- <br><br>
- Note: unset <code>nonblocking</code> if you experience lockups of FHEM.
- </ul>
- =end html
- =begin html_DE
- <a name="OWServer"></a>
- <h3>OWServer</h3>
- <ul>
- <br>
- <a name="OWServerdefine"></a>
- <b>Definition</b>
- <ul>
- <code>define <name> OWServer <protocol> [<version>]</code>
- <br><br>
- Definiert eine logische OWServer-Instanz, die sich mit einem owserver
- verbindet. owserver ist die Serverkomponente des
- <a href="http://owfs.org">1-Wire Dateisystems</a>. Sie ermöglicht den Zugriff auf
- alle 1-Wire-Busteilnehmer eines Systems.
- <protocol> hat das Format <hostname>:<port>.
- Nähere Informationen dazu gibt es in
- der <a href="http://owfs.org/index.php?page=owserver_protocol">owserver Dokumentation</a>.
- <p>
- Die OWServer-Instanz verwendet
- <a href="http://owfs.cvs.sourceforge.net/viewvc/owfs/owfs/module/ownet/perl5/OWNet/lib/OWNet.pm">OWNet.pm von Sourceforge</a>,
- um sich mit dem owserver zu verbinden.
- Gegenwärtig werden OWNet-Module für die Versionen 2.8p17 and 3.1p5
- mit FHEM verteilt. Man kann manuell weitere Versionen hinzufügen,
- indem man OWNet.pm aus
- <a href="https://sourceforge.net/projects/owfs/files/owfs/">einer der
- verfügbaren Versionen</a> extrahiert und als
- <code>FHEM/lib/OWNet-<version>.pm</code> in der FHEM-Verzeichnisstruktur
- speichert.
- <p>
- Die erste Verbindung mit dem owserver wird mit der Version 3.1p5 aufgebaut,
- es sei denn, dass man ausdrücklich eine andere Version mit dem
- optionalen Parameter
- <code><version></code> vorschlägt. Man sollte eine
- OWNet-Modulversion vorschlagen, die der tatsächlichen Version von
- owserver entspricht, falls FHEM nach dem Verbindungsaufbau zum owserver
- hängt.
- <p>
- Die OWServer-Instanz erkennt die Version von owserver automatisch und
- wählt das passende OWNet-Modul aus der Liste der verfügbaren
- OWNet-Module aus. Wenn kein passendes OWNet-Modul gefunden wird, wird die
- ursprünglich vorgeschlagene Version verwendet. Die alptraumhafte Situation
- mit zwei OWServer-Instanzen, die sich mit owserver-Instanzen in
- unterschiedlichen Versionen verbinden, wird nicht korrekt gehandhabt.
- Die Versionen von Server und Modul werden zum Nachschauen in den Internals der
- OWServer-Instanz gespeichert.
- <p>
- Die ow*-Pakete in der Version 3.1p5 bei Debian Stretch und
- die ow*-Pakete in der Version 2.8p17 bei Debian Jessie sind gut.
- Die ow*-Pakete in der Version 2.9 bei Debian Jessie in Kombination mit den
- OWNet-Modulen bei FHEM können Auffälligkeiten zeigen (Rückmeldung
- willkommen). Für
- Debian Jessie kann man
- <a href="http://forum.fhem.de/index.php?action=dlattach;topic=12219.0;attach=2463">owfs_2.8p17-1_all.zip</a>
- auspacken und owserver, Abhängigkeiten und was man sonst so braucht
- mittels <code>dpkg -i <package>.deb</code> installieren.
- <p>
- Bitte Auffälligkeiten und Erfolgsmeldungen zu Versionen im
- <a href="https://forum.fhem.de/index.php/board,26.0.html">1Wire-Board des FHEM-Forums</a> berichten.
- <p>
- Eine typische funktionierende Konfigurationsdatei <code>/etc/owfs.conf</code> sieht so aus:<p>
- <code>
- # server uses device /dev/onewire<br>
- server: device = /dev/onewire<br>
- # clients other than server use server<br>
- ! server: server = localhost:4304<br>
- # port<br>
- server: port = 4304<br>
- # owhttpd<br>
- http: port = 2121<br>
- # owftpd<br>
- ftp: port = 2120<br>
- </code>
- <p>
- Die vorhandenen 1-Wire- Busteilnehmer werden als <a href="#OWDevice">OWDevice</a> -Geräte definiert.
- Wenn <a href="#autocreate">autocreate</a> aktiviert ist, werden beim Start von FHEM alle Geräte automatisch erkannt und eingerichtet.
- <br><br>
- <b>Achtung: Dieses Modul ist weder verwandt noch verwendbar mit den 1-Wire Modulen, deren Namen nur aus Großbuchstaben bestehen!</b>
- <br><br>
- Beispiele für die Einrichtung:
- <ul>
- <code>define myLocalOWServer OWServer localhost:4304</code><br>
- <code>define myRemoteOWServer OWServer 192.168.1.100:4304</code><br>
- <code>define myRemoteOWServer OWServer raspi:4304</code><br>
- </ul>
- <br>
- Hinweis: Sollten keine Geräte erkannt werden, kann man versuchen in der owserver- Konfigurationsdatei (owfs.conf) zwei Servereinträge anzulegen:
- Einen mit <code>localhost</code> und einen mit dem "FQDN", bzw. dem Hostnamen, oder der IP-Adresse des Computers, auf dem die Software "owserver" läuft.
- <br><br>
- </ul>
- <a name="OWServerset"></a>
- <b>Set- Befehle</b>
- <ul>
- <code>set <name> <value></code>
- <br><br>
- wobei <code>value</code> für einen der folgenden Befehle steht:<br><br>
- <li><code>reopen</code><br>
- Erneuert die Verbindung zum owserver.
- </li>
- <li>owserver (OWFS) -spezifische Einstellungen:
- <ul>
- <li><code>timeout/directory</code></li>
- <li><code>timeout/ftp</code></li>
- <li><code>timeout/ha7</code></li>
- <li><code>timeout/network</code></li>
- <li><code>timeout/presence</code></li>
- <li><code>timeout/serial</code></li>
- <li><code>timeout/server</code></li>
- <li><code>timeout/stable</code></li>
- <li><code>timeout/uncached</code></li>
- <li><code>timeout/usb</code></li>
- <li><code>timeout/volatile</code></li>
- <li><code>timeout/w1</code></li>
- <li><code>units/pressure_scale</code></li>
- <li><code>units/temperature_scale</code></li>
- </ul>
- </li>
- Nähere Informationen zu diesen Einstellungen gibt es im <a href="http://owfs.org/uploads/owserver.1.html#sect41">owserver- Manual</a>.
- <br>
- </ul>
- <br><br>
- <a name="OWServerget"></a>
- <b>Get- Befehle</b>
- <ul>
- <code>get <name> <value></code>
- <br><br>
- wobei <code>value</code> für einen der folgenden Befehle steht:<br><br>
- <li><code>devices</code><br>
- Gibt eine Liste der Adressen und Typen aller von owserver erkannten Geräte aus. Außerdem
- werden die entsprechenden <a href="#OWDevice">OWDevice-</a> Namen angezeigt, soweit sie bereits definiert sind.
- </li>
- <li><code>errors</code><br>
- Liefert eine Fehlerstatistik zurück.</li>
- <li>owserver (OWFS) -spezifische Einstellungen:
- <ul>
- <li><code>/settings/timeout/directory</code></li>
- <li><code>/settings/timeout/ftp</code></li>
- <li><code>/settings/timeout/ha7</code></li>
- <li><code>/settings/timeout/network</code></li>
- <li><code>/settings/timeout/presence</code></li>
- <li><code>/settings/timeout/serial</code></li>
- <li><code>/settings/timeout/server</code></li>
- <li><code>/settings/timeout/stable</code></li>
- <li><code>/settings/timeout/uncached</code></li>
- <li><code>/settings/timeout/usb</code></li>
- <li><code>/settings/timeout/volatile</code></li>
- <li><code>/settings/timeout/w1</code></li>
- <li><code>/settings/units/pressure_scale</code></li>
- <li><code>/settings/units/temperature_scale</code></li>
- <li><code>/uncached/alarm</code></li>
- </ul>
- </li>
- Nähere Informationen zu diesen Einstellungen gibt es im <a href="http://owfs.org/uploads/owserver.1.html#sect41">owserver- Manual</a>.
- <br>
- </ul>
- <p>
- <a name="OWServerattr"></a>
- <b>Attribute</b>
- <ul>
- <li>nonblocking<br>
- Holt alle readings (OWServer / <a href="#OWDevice">OWDevice</a>) über einen Tochterprozess. Dieses Verfahren stellt sicher,
- dass FHEM während der Kommunikation mit owserver nicht angehalten wird.<br>
- Beispiel:<br>
- <code> attr <name> nonblocking 1</code>
- </li>
- <li><a href="#eventMap">eventMap</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- <br>
- Hinweis: Falls in FHEM trotzdem ungewöhnliche Stillstände auftreten, sollte das Attribut <code>nonblocking</code> wieder deaktiviert werden.<br>
- </ul>
- =end html_DE
- =cut
|