| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089 |
- # $Id: 11_OWDevice.pm 14523 2017-06-16 05:15:56Z neubert $
- ##############################################################################
- #
- # 11_OWDevice.pm
- # Copyright by 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;
- no if $] >= 5.017011, warnings => 'experimental::smartmatch';
- use vars qw(%owdevice);
- # 1-Wire devices (order by family code)
- # http://owfs.sourceforge.net/family.html
- $owdevice{"01"} = {
- # DS2401 - Silicon Serial Number
- # DS1990A - Serial Number iButton
- "read" => [],
- "write" => [],
- "poll" => [ qw(id) ],
- "state" => [],
- "interface" => "id",
- };
- $owdevice{"05"} = {
- # DS2405 - Addressable Switch
- "read" => [ qw(PIO sensed) ],
- "write" => [ qw(PIO) ],
- "poll" => [ qw(sensed) ],
- "state" => [ qw(sensed) ],
- "event" => { qw(0 closed 1 opened) },
- "interface" => "state",
- };
- $owdevice{"10"} = {
- # DS18S20 - High-Precision 1-Wire Digital Thermometer
- # DS1920 - iButton version of the thermometer
- "read" => [ qw(power),
- qw(temperature templow temphigh) ],
- "write" => [ qw(templow temphigh) ],
- "poll" => [ qw(temperature) ],
- "state" => [ qw(temperature) ],
- "alarm" => 1,
- "interface" => "temperature",
- };
- $owdevice{"12"} = {
- # DS2406, DS2407 - Dual Addressable Switch with 1kbit Memory
- "read" => [ qw(channels),
- qw(latch.A latch.B latch.ALL latch.BYTE),
- qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.ALL),
- qw(PIO.A PIO.B PIO.ALL PIO.BYTE),
- qw(power),
- qw(sensed.A sensed.B sensed.ALL sensed.BYTE),
- qw(set_alarm),
- qw(TAI8570/pressure TAI8570/sibling TAI8570/temperature),
- qw(T8A/volt.0 T8A/volt.1 T8A/volt.2 T8A/volt.3 T8A/volt.4 T8A/volt.5 T8A/volt.6),
- qw(T8A/volt.7 T8A/volt.ALL) ],
- "write" => [ qw(latch.A latch.B latch.ALL latch.BYTE),
- qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.ALL),
- qw(PIO.A PIO.B PIO.ALL PIO.BYTE),
- qw(sensed.A sensed.B sensed.ALL sensed.BYTE),
- qw(set_alarm), ],
- "poll" => [ qw(sensed.A sensed.B) ],
- "state" => [ qw(sensed.A sensed.B) ],
- "alarm" => 1,
- "event" => { qw(0 off 1 on) },
- "interface" => "state",
- };
- $owdevice{"1B"} = {
- # DS2436 - Battery ID/Monitor Chip
- "read" => [ qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4 pages/page.ALL),
- qw(temperature),
- qw(volts),
- qw(counter/cycles) ],
- "write" => [ qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4 pages/page.ALL),
- qw(counter/increment counter/reset) ],
- "poll" => [ qw(temperature volts counter/cycles) ],
- "state" => [ qw(temperature volts counter/cycles) ],
- "interface" => "multisensor",
- };
- $owdevice{"1D"} = {
- # DS2423 - 4kbit 1-Wire RAM with Counter
- "read" => [ qw(counters.A counters.B counters.ALL),
- qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4 pages/page.5),
- qw(pages/page.6 pages/page.7 pages/page.8 pages/page.9 pages/page.10 pages/page.11),
- qw(pages/page.12 pages/page.13 pages/page.14 pages/page.15),
- qw(pages/count.0 pages/count.1 pages/count.2 pages/count.3 pages/count.4 pages/count.5),
- qw(pages/count.6 pages/count.7 pages/count.8 pages/count.9 pages/count.10 pages/count.11),
- qw(pages/count.12 pages/count.13 pages/count.14 pages/count.15) ],
- "write" => [ qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4 pages/page.5),
- qw(pages/page.6 pages/page.7 pages/page.8 pages/page.9 pages/page.10 pages/page.11),
- qw(pages/page.12 pages/page.13 pages/page.14 pages/page.15) ],
- "poll" => [ qw(counters.A counters.B) ],
- "state" => [ qw(counters.A counters.B) ],
- "offset" => [ qw(counters.A counters.B) ],
- "interface" => "counter",
- };
- $owdevice{"1F"} = {
- # DS2409 - Microlan Coupler
- "read" => [],
- "write" => [],
- "poll" => [],
- "state" => [],
- "interface" => "none",
- };
- $owdevice{"20"} = {
- # DS2450 - Quad A/D Converter
- "read" => [ qw(alarm/high.A alarm/high.B alarm/high.C alarm/high.D alarm/high.ALL),
- qw(alarm/low.A alarm/low.B alarm/low.C alarm/low.D alarm/low.ALL),
- qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.ALL),
- qw(PIO.A PIO.B PIO.C PIO.D PIO.ALL),
- qw(power),
- qw(set_alarm/high.A set_alarm/high.B set_alarm/high.C set_alarm/high.D set_alarm/high.ALL),
- qw(set_alarm/low.A set_alarm/low.B set_alarm/low.C set_alarm/low.D set_alarm/low.ALL),
- qw(set_alarm/volthigh.A set_alarm/volthigh.B set_alarm/volthigh.C set_alarm/volthigh.D),
- qw(set_alarm/volthigh.ALL),
- qw(set_alarm/volt2high.A set_alarm/volt2high.B set_alarm/volt2high.C set_alarm/volt2high.D),
- qw(set_alarm/volt2high.ALL),
- qw(set_alarm/voltlow.A set_alarm/voltlow.B set_alarm/voltlow.C set_alarm/voltlow.D),
- qw(set_alarm/voltlow.ALL),
- qw(set_alarm/volt2low.A set_alarm/volt2low.B set_alarm/volt2low.C set_alarm/volt2low.D),
- qw(set_alarm/volt2low.ALL),
- qw(set_alarm/unset),
- qw(volt.A volt.B volt.C volt.D volt.ALL),
- qw(8bit/volt.A 8bit/volt.B 8bit/volt.C 8bit/volt.D 8bit/volt.ALL),
- qw(volt2.A volt2.B volt2.C volt2.D volt2.ALL),
- qw(8bit/volt2.A 8bit/volt2.B 8bit/volt2.C 8bit/volt2.D 8bit/volt2.ALL),
- qw(CO2/power CO2/ppm CO2/status) ],
- "write" => [ qw(alarm/high.A alarm/high.B alarm/high.C alarm/high.D alarm/high.ALL),
- qw(alarm/low.A alarm/low.B alarm/low.C alarm/low.D alarm/low.ALL),
- qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.ALL),
- qw(PIO.A PIO.B PIO.C PIO.D PIO.ALL),
- qw(power),
- qw(set_alarm/high.A set_alarm/high.B set_alarm/high.C set_alarm/high.D set_alarm/high.ALL),
- qw(set_alarm/low.A set_alarm/low.B set_alarm/low.C set_alarm/low.D set_alarm/low.ALL),
- qw(set_alarm/volthigh.A set_alarm/volthigh.B set_alarm/volthigh.C set_alarm/volthigh.D),
- qw(set_alarm/volthigh.ALL),
- qw(set_alarm/volt2high.A set_alarm/volt2high.B set_alarm/volt2high.C set_alarm/volt2high.D),
- qw(set_alarm/volt2high.ALL),
- qw(set_alarm/voltlow.A set_alarm/voltlow.B set_alarm/voltlow.C set_alarm/voltlow.D),
- qw(set_alarm/voltlow.ALL),
- qw(set_alarm/volt2low.A set_alarm/volt2low.B set_alarm/volt2low.C set_alarm/volt2low.D),
- qw(set_alarm/volt2low.ALL),
- qw(set_alarm/unset) ],
- "poll" => [ qw(PIO.A PIO.B PIO.C PIO.D),
- qw(volt.A volt.B volt.C volt.D),
- qw(volt2.A volt2.B volt2.C volt2.D) ],
- "state" => [ qw(PIO.A PIO.B PIO.C PIO.D),
- qw(volt.A volt.B volt.C volt.D),
- qw(volt2.A volt2.B volt2.C volt2.D) ],
- "event" => { qw(0 off 1 on) },
- "interface" => "multisensor",
- };
- $owdevice{"22"} = {
- # DS1822 - Econo 1-Wire Digital Thermometer
- "read" => [ qw(temperature temperature9 temperature10 temperature11 temperature12 fasttemp),
- qw(temphigh templow),
- qw(power) ],
- "write" => [ qw(temphigh templow) ],
- "poll" => [ qw(temperature) ],
- "state" => [ qw(temperature) ],
- "alarm" => 1,
- "interface" => "temperature",
- };
- $owdevice{"23"} = {
- # DS2433 - 4kbit 1-Wire RAM
- "read" => [ qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4 pages/page.5),
- qw(pages/page.6 pages/page.7 pages/page.8 pages/page.9 pages/page.10 pages/page.11),
- qw(pages/page.12 pages/page.13 pages/page.14 pages/page.15) ],
- "write" => [ qw(memory),
- qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4 pages/page.5),
- qw(pages/page.6 pages/page.7 pages/page.8 pages/page.9 pages/page.10 pages/page.11),
- qw(pages/page.12 pages/page.13 pages/page.14 pages/page.15) ],
- "poll" => [ qw(id) ],
- "state" => [ ],
- "interface" => "multisensor",
- };
- $owdevice{"24"} = {
- # DS2415 - 1-Wire Time Chip
- # DS1904 - RTC iButton
- "read" => [ qw(date flags running udate) ],
- "write" => [ qw(date flags running udate) ],
- "poll" => [ qw(date running udate) ],
- "state" => [ qw(date running) ],
- "interface" => "timer",
- };
- $owdevice{"26"} = {
- # DS2438 - Smart Battery Monitor
- "read" => [ qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4),
- qw(pages/page.5 pages/page.6 pages/page.7 pages/page.ALL),
- qw(temperature),
- qw(VAD VDD),
- qw(vis),
- qw(CA),
- qw(EE),
- qw(IAD),
- qw(date),
- qw(disconnect/date disconnect/udate),
- qw(endcharge/date endcharge/udate),
- qw(udate),
- qw(HIH4000/humidity),
- qw(HTM1735/humidity),
- qw(DATANAB/humidity),
- qw(HIH3600/humidity),
- qw(humidity),
- qw(B1-R1-A/pressure B1-R1-A/gain B1-R1-A/offset),
- qw(S3-R1-A/current S3-R1-A/illumination S3-R1-A/illuminance S3-R1-A/gain),
- qw(MultiSensor/type),
- qw(offset) ],
- "write" => [ qw(pages/page.0 pages/page.1 pages/page.2 pages/page.3 pages/page.4),
- qw(pages/page.5 pages/page.6 pages/page.7 pages/page.ALL),
- qw(CA),
- qw(EE),
- qw(IAD),
- qw(date),
- qw(disconnect/date disconnect/udate),
- qw(endcharge/date endcharge/udate),
- qw(udate),
- qw(DATANAB/reset),
- qw(B1-R1-A/gain B1-R1-A/offset),
- qw(S3-R1-A/gain),
- qw(offset) ],
- "poll" => [ qw(temperature VAD VDD) ],
- "state" => [ qw(temperature VAD VDD) ],
- "interface" => "multisensor",
- };
- $owdevice{"27"} = {
- # DS2417 - 1-Wire Time Chip with Interrupt
- "read" => [ qw(date enable interval itime running udate) ],
- "write" => [ qw(date enable interval itime running udate) ],
- "poll" => [ qw(date enable running udate) ],
- "state" => [ qw(date enable running) ],
- "interface" => "timer",
- };
- $owdevice{"28"} = {
- # DS18B20 - Programmable Resolution 1-Wire Digital Thermometer
- "read" => [ qw(temperature temperature9 temperature10 temperature11 temperature12 fasttemp),
- qw(temphigh templow) ],
- "write" => [ qw(temphigh templow) ],
- "poll" => [ qw(temperature) ],
- "state" => [ qw(temperature) ],
- "alarm" => 1,
- "interface" => "temperature",
- };
- $owdevice{"29"} = {
- # DS2408 - 1-Wire 8 Channel Addressable Switch
- "read" => [ qw(latch.0 latch.1 latch.2 latch.3 latch.4 latch.5 latch.6 latch.7 latch.ALL latch.BYTE),
- qw(PIO.0 PIO.1 PIO.2 PIO.3 PIO.4 PIO.5 PIO.6 PIO.7 PIO.ALL PIO.BYTE),
- qw(power),
- qw(sensed.0 sensed.1 sensed.2 sensed.3 sensed.4 sensed.5 sensed.6 sensed.7 sensed.ALL),
- qw(strobe),
- qw(por),
- qw(set_alarm) ],
- "write" => [ qw(latch.0 latch.1 latch.2 latch.3 latch.4 latch.5 latch.6 latch.7 latch.ALL latch.BYTE),
- qw(PIO.0 PIO.1 PIO.2 PIO.3 PIO.4 PIO.5 PIO.6 PIO.7 PIO.ALL PIO.BYTE),
- qw(strobe),
- qw(por),
- qw(set_alarm),
- qw(LCD_H/clear LCD_H/home LCD_H/screen LCD_H/screenyc LCD_H/onoff LCD_H/message),
- qw(LCD_M/clear LCD_M/home LCD_M/screen LCD_M/screenyc LCD_M/onoff LCD_M/message) ],
- "poll" => [ qw(sensed.0 sensed.1 sensed.2 sensed.3 sensed.4 sensed.5 sensed.6 sensed.7) ],
- "state" => [ qw(sensed.0 sensed.1 sensed.2 sensed.3 sensed.4 sensed.5 sensed.6 sensed.7) ],
- "alarm" => 1,
- "event" => { qw(0 off 1 on) },
- "interface" => "state",
- };
- $owdevice{"3A"} = {
- # DS2413 - Dual Channel Addressable Switch
- "read" => [ qw(PIO.A PIO.B PIO.ALL PIO.BYTE),
- qw(sensed.A sensed.B sensed.ALL sensed.BYTE) ],
- "write" => [ qw(PIO.A PIO.B PIO.ALL PIO.BYTE) ],
- "poll" => [ qw(sensed.A sensed.B) ],
- "state" => [ qw(sensed.A sensed.B) ],
- "event" => { qw(0 off 1 on) },
- "interface" => "state",
- };
- $owdevice{"3B"} = {
- # DS1825 - Programmable Resolution 1-Wire Digital Thermometer with ID
- "read" => [ qw(prog_addr temperature temperature9 temperature10 temperature11 temperature12 fasttemp) ],
- "write" => [ qw(temphigh templow) ],
- "poll" => [ qw(temperature) ],
- "state" => [ qw(temperature) ],
- "alarm" => 1,
- "interface" => "temperature",
- };
- $owdevice{"7E"} = {
- # EDS0066 - Multisensor temperature Pressure
- "read" => [ qw(EDS0066/temperature EDS0066/pressure),
- qw(EDS0068/temperature EDS0068/pressure EDS0068/dew_point EDS0068/humidity EDS0068/light) ],
- "write" => [],
- "poll" => [ qw(EDS0066/temperature EDS0066/pressure),
- qw(EDS0068/temperature EDS0068/pressure EDS0068/dew_point EDS0068/humidity EDS0068/light) ],
- "state" => [ qw(EDS0066/temperature EDS0066/pressure),
- qw(EDS0068/temperature EDS0068/pressure EDS0068/dew_point EDS0068/humidity EDS0068/light) ],
- "interface" => "multisensor",
- };
- $owdevice{"81"} = {
- # USB id - ID found in DS2490R and DS2490B USB adapters
- "read" => [],
- "write" => [],
- "poll" => [ qw(id) ],
- "state" => [],
- "interface" => "id",
- };
- $owdevice{"FF"} = {
- # LCD - LCD controller by Louis Swart
- "read" => [ qw(counters.0 counters.1 counters.2 counters.3 counters.ALL),
- qw(cumulative.0 cumulative.1 cumulative.2 cumulative.3 cumulative.ALL),
- qw(data),
- qw(memory),
- qw(register),
- qw(version) ],
- "write" => [ qw(backlight),
- qw(cumulative.0 cumulative.1 cumulative.2 cumulative.3 cumulative.ALL),
- qw(data),
- qw(LCDon),
- qw(line16.0 line16.1 line16.2 line16.3 line16.ALL),
- qw(line20.0 line20.1 line20.2 line20.3 line20.ALL),
- qw(line40.0 line40.1 line40.2 line40.3 line40.ALL),
- qw(memory),
- qw(register),
- qw(screen16 screen20 screen40) ],
- "poll" => [ qw(counters.0 counters.1 counters.2 counters.3) ],
- "state" => [ qw(counters.0 counters.1 counters.2 counters.3) ],
- "interface" => "display",
- };
- # add default properties to each owdevice
- foreach my $f (sort keys %owdevice) {
- push(@{$owdevice{$f}{"read"}},qw(address crc8 family id locator r_address r_id r_locator type));
- @{$owdevice{$f}{"read"}} = sort(@{$owdevice{$f}{"read"}});
- if(defined($owdevice{$f}{"write"}) && @{$owdevice{$f}{"write"}}) {
- @{$owdevice{$f}{"write"}} = sort(@{$owdevice{$f}{"write"}});
- }
- if(defined($owdevice{$f}{"poll"}) && @{$owdevice{$f}{"poll"}}) {
- @{$owdevice{$f}{"poll"}} = sort(@{$owdevice{$f}{"poll"}});
- }
- if(defined($owdevice{$f}{"state"}) && @{$owdevice{$f}{"state"}}) {
- @{$owdevice{$f}{"state"}} = sort(@{$owdevice{$f}{"state"}});
- }
- }
- ###################################
- sub
- OWDevice_Initialize($)
- {
- my ($hash) = @_;
- $hash->{GetFn} = "OWDevice_Get";
- $hash->{SetFn} = "OWDevice_Set";
- $hash->{DefFn} = "OWDevice_Define";
- $hash->{NotifyFn} = "OWDevice_Notify";
- $hash->{NotifyOrderPrefix}= "50b-";
- $hash->{UndefFn} = "OWDevice_Undef";
- $hash->{AttrFn} = "OWDevice_Attr";
- $hash->{AttrList} = "IODev uncached trimvalues polls interfaces model cstrings ".
- "resolution:9,10,11,12 ".
- $readingFnAttributes;
- }
- ###################################
- # return array
- # 1st element: interface
- # 2nd element: array of getters/readings
- # 3rd element: array of setters/readings
- # 4th element: array of readings to be periodically updated
- # 5th element: array of readings to be written to state
- # 6th element: alerting device support
- sub
- OWDevice_GetDetails($) {
- my ($hash)= @_;
- my @path= split('/', $hash->{fhem}{address});
- my $address= $path[-1];
- #main::Debug "address is $address";
- my $family= substr($address, 0, 2);
- my @getters= @{$owdevice{$family}{"read"}};
- my @setters= @{$owdevice{$family}{"write"}};
- my @polls= @{$owdevice{$family}{"poll"}};
- my @state= @{$owdevice{$family}{"state"}};
- my $alerting= ($owdevice{$family}{"alarm"}) ? 1 : 0;
-
- my $interface= $owdevice{$family}{"interface"};
- # http://perl-seiten.homepage.t-online.de/html/perl_array.html
- return ($interface, \@getters, \@setters, \@polls, \@state, $alerting);
- }
- ###################################
- # This could be IORead in fhem, But there is none.
- # Read http://forum.fhem.de/index.php?t=tree&goto=54027&rid=10#msg_54027
- # to find out why.
- sub
- OWDevice_ReadFromServer($$@)
- {
- my ($hash,$cmd,@a) = @_;
- my $dev = $hash->{NAME};
- return if(IsDummy($dev) || IsIgnored($dev));
- my $iohash = $hash->{IODev};
- if(!$iohash ||
- !$iohash->{TYPE} ||
- !$modules{$iohash->{TYPE}} ||
- !$modules{$iohash->{TYPE}}{ReadFn}) {
- Log3 $hash, 5, "No I/O device or ReadFn found for $dev";
- return;
- }
- no strict "refs";
- my $ret;
- if($cmd eq "read") {
- $ret = &{$modules{$iohash->{TYPE}}{ReadFn}}($iohash, @a);
- }
- if($cmd eq "dir") {
- $ret = &{$modules{$iohash->{TYPE}}{DirFn}}($iohash, @a);
- }
- if($cmd eq "find") {
- $ret = &{$modules{$iohash->{TYPE}}{FindFn}}($iohash, @a);
- }
- use strict "refs";
- if( $iohash->{LAST_READ_FAILED} ) {
- $hash->{NR_READ_FAILED} = 0 if( !$hash->{NR_READ_FAILED} );
- $hash->{NR_READ_FAILED}++;
- $hash->{LAST_READ_FAILED} = 1;
- } else {
- $hash->{LAST_READ_FAILED} = 0;
- }
- return $ret;
- }
- ###################################
- sub
- OWDevice_ReadValue($$) {
- my ($hash,$reading)= @_;
-
- my $address= $hash->{fhem}{address};
- my $interface= $hash->{fhem}{interfaces};
- my $cache= (AttrVal($hash->{NAME},"uncached","")) ? "/uncached" : "";
- my $path = "$cache/$address/$reading";
- $path .= AttrVal($hash->{NAME},"resolution","") if( $reading eq "temperature" );
- #my ($seconds, $microseconds) = gettimeofday();
- #main::Debug "OWDevice_ReadValue NAME=" . $hash->{NAME} . " path=$path";
- my $value= OWDevice_ReadFromServer($hash,"read",$path);
- #my ($seconds2, $microseconds2) = gettimeofday();
- #my $msec = sprintf( "%03d msec", (($seconds2-$seconds)*1000000 + $microseconds2-$microseconds)/1000 );
- #Debug "$path => $value; $msec";
- if($interface ne "id") {
- if(defined($value)) {
- $value=~ s/\0.*$//g if(AttrVal($hash->{NAME},"cstrings",0));
- $value= trim($value) if(AttrVal($hash->{NAME},"trimvalues",1));
- } else {
- Log3 $hash, 3, $hash->{NAME} . ": reading $reading did not return a value";
- }
- }
-
- return $value;
- }
- ###################################
- sub OWDevice_WriteValue($$$) {
- my ($hash,$reading,$value)= @_;
- my $cache= (AttrVal($hash->{NAME},"uncached","")) ? "/uncached" : "";
- my $address= $hash->{fhem}{address};
- my $path = "$cache/$address/$reading";
- IOWrite($hash, $path, $value);
- return $value;
- }
- ###################################
- sub
- OWDevice_UpdateValues($) {
- my ($hash)= @_;
- my @polls= @{$hash->{fhem}{polls}};
- my @getters= @{$hash->{fhem}{getters}};
- my @state= @{$hash->{fhem}{state}};
- my $alerting= $hash->{fhem}{alerting};
- my $interface= $hash->{fhem}{interfaces};
- my $state;
- if($#polls>=0) {
- my $address= $hash->{fhem}{address};
- readingsBeginUpdate($hash);
- foreach my $reading (@polls) {
- my $value= OWDevice_ReadValue($hash,$reading);
- readingsBulkUpdate($hash,$reading,$value) if(defined($value));
- }
- if(@state) {
- foreach my $reading (@state) {
- my $value= ReadingsVal($hash->{NAME},$reading,undef);
- if(defined($value)) {
- $state .= "$reading: $value ";
- } else {
- $state .= "$reading: n/a ";
- }
- }
- }
- if($alerting
- && !$hash->{LAST_READ_FAILED}) {
- my $dir= OWDevice_ReadFromServer($hash,"dir","/alarm/");
- my $alarm= (defined($dir) && $dir =~ m/$address/) ? 1 :0;
- readingsBulkUpdate($hash,"alarm",$alarm);
- $state .= "alarm: $alarm";
- }
- if($interface eq "id"
- && !$hash->{LAST_READ_FAILED}) {
- my $dir= OWDevice_ReadFromServer($hash,"dir","/");
- my $present= (defined($dir) && $dir =~ m/$address/) ? 1 :0;
- readingsBulkUpdate($hash,"present",$present);
- $state .= "present: $present";
- my $bus= OWDevice_ReadFromServer($hash,"find",$address);
- my $location= (defined($bus)) ? $bus :"absent";
- readingsBulkUpdate($hash,"location",$location);
- }
- $state =~ s/\s+$//;
- readingsBulkUpdate($hash,"state",$state,0);
- readingsEndUpdate($hash,1);
- }
- RemoveInternalTimer($hash);
- InternalTimer(int(gettimeofday()) + $hash->{fhem}{interval}, "OWDevice_UpdateValues", $hash, 0)
- if(defined($hash->{fhem}{interval}));
- }
- ###################################
- sub
- OWDevice_Attr($@)
- {
- my ($cmd, $name, $attrName, $attrVal) = @_;
- my $hash = $defs{$name};
- $attrVal= "" unless defined($attrVal);
- $attrVal= "" if($cmd eq "del");
-
- if($attrName eq "polls") {
- my @polls= split(",", $attrVal);
- $hash->{fhem}{polls}= \@polls;
- Log3 $name, 5, "$name: polls: " . join(" ", @polls);
- } elsif($attrName eq "interfaces") {
- if($attrVal ne "") {
- $hash->{fhem}{interfaces}= join(";",split(",",$attrVal));
- Log3 $name, 5, "$name: interfaces: " . $hash->{fhem}{interfaces};
- } else {
- delete $hash->{fhem}{interfaces} if(defined($hash->{fhem}{interfaces}));
- Log3 $name, 5, "$name: no interfaces";
- }
- }
- }
- ###################################
- sub
- OWDevice_Get($@)
- {
- my ($hash, @a)= @_;
- my $name= $hash->{NAME};
- return "get $name needs one argument" if(int(@a) != 2);
- my $cmdname= $a[1];
- my @getters= @{$hash->{fhem}{getters}};
- if($cmdname ~~ @getters) {
- my $value= OWDevice_ReadValue($hash, $cmdname);
- readingsSingleUpdate($hash,$cmdname,$value,1);
- return $value;
- } else {
- return "Unknown argument $cmdname, choose one of " . join(" ", @getters);
- }
- }
- #############################
- sub
- OWDevice_Set($@)
- {
- my ($hash, @a)= @_;
- my $name= $hash->{NAME};
- my $cmdname= $a[1];
- my $value= $a[2];
- my @setters= @{$hash->{fhem}{setters}};
- if($cmdname ~~ @setters) {
- # LCD Display need more than two arguments, to display text
- # added by m.fischer
- if($cmdname =~ /(line16.0|line16.1|line16.2|line16.3|screen16)/ ||
- $cmdname =~ /(line20.0|line20.1|line20.2|line20.3|screen20)/ ||
- $cmdname =~ /(line40.0|line40.1|line40.2|line40.3|screen40)/) {
- shift @a;
- shift @a;
- $value= "@a";
- } else {
- return "set $name needs two arguments" if(int(@a) != 3);
- }
- OWDevice_WriteValue($hash,$cmdname,$value);
- readingsSingleUpdate($hash,$cmdname,$value,1);
- return undef;
- } elsif ($cmdname eq "interval") {
- return "Wrong interval format: Only digits are allowed!"
- if($value !~ m/^\d+$/);
- if($value == $hash->{fhem}{interval}) {
- return "new interval is equal to old interval.";
- } else {
- RemoveInternalTimer($hash);
- $hash->{fhem}{interval}= $value;
- InternalTimer(int(gettimeofday())+$hash->{fhem}{interval}, "OWDevice_UpdateValues", $hash, 0);
- return undef;
- }
- } else {
- return "Unknown argument $cmdname, choose one of interval " . join(" ", @setters);
- }
- }
- #############################
- sub
- OWDevice_Undef($$)
- {
- my ($hash, $name) = @_;
- delete($modules{OWDevice}{defptr}{$hash->{NAME}});
- RemoveInternalTimer($hash);
- return undef;
- }
- #############################
- sub
- OWDevice_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t]+", $def);
- return "Usage: define <name> OWDevice <address> [interval]" if($#a < 2|| $#a > 3);
- my $name= $a[0];
- AssignIoPort($hash) if(!defined($hash->{IODev}->{NAME}));
- if(defined($hash->{IODev}->{NAME})) {
- Log3 $name, 4, "$name: I/O device is " . $hash->{IODev}->{NAME};
- } else {
- Log3 $name, 1, "$name: no I/O device";
- }
- $hash->{fhem}{address}= $a[2];
- if($#a == 3) {
- $hash->{fhem}{interval}= $a[3];
- Log3 $name, 5, "$name: polling every $a[3] seconds";
- }
- my ($interface, $gettersref, $settersref, $pollsref, $stateref, $alerting)= OWDevice_GetDetails($hash);
- my @getters= @{$gettersref};
- my @setters= @{$settersref};
- my @polls= @{$pollsref};
- my @state= @{$stateref};
- if($interface ne "") {
- $hash->{fhem}{interfaces}= $interface;
- Log3 $name, 5, "$name: interfaces: $interface";
- }
- $hash->{fhem}{getters}= $gettersref;
- Log3 $name, 5, "$name: getters: " . join(" ", @getters);
- $hash->{fhem}{setters}= $settersref;
- Log3 $name, 5, "$name: setters: " . join(" ", @setters);
- $hash->{fhem}{polls}= $pollsref;
- Log3 $name, 5, "$name: polls: " . join(" ", @polls);
- $hash->{fhem}{state}= $stateref;
- Log3 $name, 5, "$name: state: " . join(" ", @state);
- $hash->{fhem}{alerting}= $alerting;
- Log3 $name, 5, "$name: alerting: $alerting";
- $hash->{NOTIFYDEV} = "global";
-
- if( $init_done ) {
- OWDevice_InitValues($hash);
- OWDevice_UpdateValues($hash) if(defined($hash->{fhem}{interval}));
- }
- return undef;
- }
- sub
- OWDevice_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});
- OWDevice_InitValues($hash);
- RemoveInternalTimer($hash);
- # http://forum.fhem.de/index.php/topic,16945.0/topicseen.html#msg110673
- my $delay = int(rand(20));
- Log3 $name, 5, "$name: initial delay: $delay";
- InternalTimer(int(gettimeofday())+$delay, "OWDevice_UpdateValues", $hash, 0) if(defined($hash->{fhem}{interval}));
- return undef;
- }
- sub
- OWDevice_InitValues($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my $model;
- $hash->{fhem}{bus}= OWDevice_ReadFromServer($hash,"find",$hash->{fhem}{address});
- $model= OWDevice_ReadValue($hash, "type");
- if(defined($model)) {
- $attr{$name}{model}= $model if($model ne "");
- }
- if($hash->{fhem}{interfaces} eq "id" && !defined($hash->{fhem}{interval})) {
- my $dir= OWDevice_ReadFromServer($hash,"dir","/");
- my $present= ($dir =~ m/$hash->{fhem}{address}/) ? 1 :0;
- my $bus= OWDevice_ReadFromServer($hash,"find",$hash->{fhem}{address});
- my $location= (defined($bus)) ? $bus :"absent";
- my $id= OWDevice_Get($hash, $name, "id");
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,"id",$id);
- readingsBulkUpdate($hash,"present",$present);
- readingsBulkUpdate($hash,"state","present: $present",0);
- readingsBulkUpdate($hash,"location",$location);
- readingsEndUpdate($hash,1);
- }
- }
- ###################################
- 1;
- ###################################
- =pod
- =item device
- =item summary controls a One-Wire (1Wire) device
- =item summary_DE steuert ein One-Wire- (1Wire-) Gerät
- =begin html
- <a name="OWDevice"></a>
- <h3>OWDevice</h3>
- <ul>
- <br>
- <a name="OWDevicedefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> OWDevice <address> [<interval>]</code>
- <br><br>
- Defines a 1-wire device. The 1-wire device is identified by its <address>. It is
- served by the most recently defined <a href="#OWServer">OWServer</a>.
- <br><br>
- Devices beyond 1-wire hubs (DS2409, address family 1F) need to be addressed by the full path, e.g.
- <code>1F.0AC004000000/main/26.A157B6000000</code> (no leading slash). They are
- not automatically detected.
- <br><br>
- If <interval> is given, the OWServer is polled every <interval> seconds for
- a subset of readings.
- <br><br>
- OWDevice is a generic device. Its characteristics are retrieved at the time of the device's
- definition. The available readings that you can get or set as well as those that are
- regularly retrieved by polling can be seen when issuing the
- <code><a href="#list">list</a> <name></code> command.
- <br><br>
- The following devices are currently supported:
- <ul>
- <li>DS2401 - Silicon Serial Number</li>
- <li>DS1990A - Serial Number iButton</li>
- <li>DS2405 - Addressable Switch</li>
- <li>DS18S20 - High-Precision 1-Wire Digital Thermometer</li>
- <li>DS1920 - iButton version of the thermometer</li>
- <li>DS2406, DS2407 - Dual Addressable Switch with 1kbit Memory</li>
- <li>DS2436 - Battery ID/Monitor Chip</li>
- <li>DS2423 - 4kbit 1-Wire RAM with Counter</li>
- <li>DS2450 - Quad A/D Converter</li>
- <li>DS1822 - Econo 1-Wire Digital Thermometer</li>
- <li>DS2433 - 4kbit 1-Wire RAM</li>
- <li>DS2415 - 1-Wire Time Chip</li>
- <li>DS1904 - RTC iButton</li>
- <li>DS2438 - Smart Battery Monitor</li>
- <li>DS2417 - 1-Wire Time Chip with Interrupt</li>
- <li>DS18B20 - Programmable Resolution 1-Wire Digital Thermometer</li>
- <li>DS2408 - 1-Wire 8 Channel Addressable Switch</li>
- <li>DS2413 - Dual Channel Addressable Switch</li>
- <li>DS1825 - Programmable Resolution 1-Wire Digital Thermometer with ID</li>
- <li>DS2409 - Microlan Coupler (no function implemented)</li>
- <li>EDS0066 - Multisensor for temperature and pressure</li>
- <li>LCD - LCD controller by Louis Swart</li>
- </ul>
- <br><br>
- Adding more devices is simple. Look at the code (subroutine <code>OWDevice_GetDetails</code>).
- <br><br>
- This module is completely unrelated to the 1-wire modules with names all in uppercase.
- <br><br>
- <b>Note:</b>The state reading never triggers events to avoid confusion.<br><br>
- Example:
- <ul>
- <code>
- define myOWServer OWServer localhost:4304<br><br>
- get myOWServer devices<br>
- 10.487653020800 DS18S20<br><br>
- define myT1 OWDevice 10.487653020800<br><br>
- list myT1 10.487653020800<br>
- Internals:<br>
- ...<br>
- Readings:<br>
- 2012-12-22 20:30:07 temperature 23.1875<br>
- Fhem:<br>
- ...<br>
- getters:<br>
- address<br>
- family<br>
- id<br>
- power<br>
- type<br>
- temperature<br>
- templow<br>
- temphigh<br>
- polls:<br>
- temperature<br>
- setters:<br>
- alias<br>
- templow<br>
- temphigh<br>
- ...<br>
- </code>
- </ul>
- <br>
- </ul>
- <a name="OWDeviceset"></a>
- <b>Set</b>
- <ul>
- <li><code>set <name> interval <value></code>
- <br><br>
- <code>value</code> modifies the interval for polling data. The unit is in seconds.
- </li>
- <li><code>set <name> <reading> <value></code>
- <br><br>
- Sets <reading> to <value> for the 1-wire device <name>. The permitted values are defined by the underlying
- 1-wire device type.
- <br><br>
- Example:
- <ul>
- <code>set myT1 templow 5</code><br>
- </ul>
- <br>
- </li>
- </ul>
- <a name="OWDeviceget"></a>
- <b>Get</b>
- <ul>
- <code>get <name> <reading> <value></code>
- <br><br>
- Gets <reading> for the 1-wire device <name>. The permitted values are defined by the underlying
- 1-wire device type.
- <br><br>
- Example:
- <ul>
- <code>get myT1 temperature</code><br>
- </ul>
- <br>
- </ul>
- <a name="OWDeviceattr"></a>
- <b>Attributes</b>
- <ul>
- <a name="IODev"></a>
- <li>IODev:
- Set the OWServer device which should be used for sending and receiving data
- for this OWDevice. Note: Upon startup fhem assigns each OWDevice
- to the last previously defined OWServer. Thus it is best if you define OWServer
- and OWDevices in blocks: first define the first OWServer and the OWDevices that
- belong to it, then continue with the next OWServer and the attached OWDevices, and so on.
- </li>
- <li>trimvalues: removes leading and trailing whitespace from readings. Default is 1 (on).</li>
- <li>cstrings: interprets reading as C-style string, i.e. stops reading on the first zero byte. Default is 0 (off).</li>
- <li>polls: a comma-separated list of readings to poll. This supersedes the list of default readings to poll.</li>
- <li>interfaces: supersedes the interfaces exposed by that device.</li>
- <li>model: preset with device type, e.g. DS18S20.</li>
- <li>resolution: resolution of temperature reading in bits, can be 9, 10, 11 or 12.
- Lower resolutions allow for faster retrieval of values from the bus.
- Particularly reasonable for large 1-wire installations to reduce busy times for FHEM.</li>
- <li><a href="#eventMap">eventMap</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- <br><br>
- </ul>
- =end html
- =begin html_DE
- <a name="OWDevice"></a>
- <h3>OWDevice</h3>
- <ul>
- <br>
- <a name="OWDevicedefine"></a>
- <b>Definition</b>
- <ul>
- <code>define <name> OWDevice <address> [<interval>]</code>
- <br><br>
- Definiert ein 1-Wire- Gerät. 1-Wire- Geräte werden anhand ihrer Adresse <address> definiert. Diese wird
- durch den zuvor eingerichteten <a href="#OWServer">OWServer</a> bereitgestellt.
- <br><br>
- Geräte hinter 1-wire-Hubs (DS2409, Adressfamilie 1F) müssen über den vollen Pfad adressiert werden, z.B.
- <code>1F.0AC004000000/main/26.A157B6000000</code> (kein führender Schrägstrich). Sie werden nicht
- automatisch erkannt.
- <br><br>
- Wird zusätzlich <interval> angegeben, ruft OWServer alle <interval> Sekunden
- einen Datensatz des Gerätes ab.
- <br><br>
- Jedes OWDevice ist ein eigenständiges Gerät. Seine Eigenschaften werden erstmals zum Zeitpunkt der Definition
- abgefragt. Die durch "get" oder "set" erzeugten, sowie durch den zyklischen Abruf gelieferten readings,
- können mit dem Kommando <code><a href="#list">list</a> <name></code> angezeigt werden.
- <br><br>
- Folgende 1-Wire- und iButton- Komponenten werden aktuell unterstützt:
- <ul>
- <li>DS2401 - Im Chip integrierte Seriennummer</li>
- <li>DS1990A - iButton mit fester Seriennummer</li>
- <li>DS2405 - Adressierbarer Schalter</li>
- <li>DS18S20 - Hochpräzisions-Digital-Thermosensor</li>
- <li>DS1920 - iButton-Thermosensor</li>
- <li>DS2406, DS2407 - Dualer adressierbarer Schalter mit 1 kbit Speicher</li>
- <li>DS2436 - Batterie-ID/Monitor- Schaltkreis</li>
- <li>DS2423 - Dual-Zählerbaustein mit Speicherfunktion</li>
- <li>DS2450 - Vierfach-A/D Umsetzer</li>
- <li>DS1822 - Econo-Thermosensor</li>
- <li>DS2433 - 4kbit 1-Wire RAM</li>
- <li>DS2415 - Zeitgeber- Schaltkreis </li>
- <li>DS1904 - iButton-Echtzeituhr</li>
- <li>DS2438 - Smart-Batterie-Monitor</li>
- <li>DS2417 - Zeitgeber-Schaltkreis mit Interrupt</li>
- <li>DS18B20 - Thermosensor mit programmierbarer Auflösung</li>
- <li>DS2408 - 8-kanaliger adressierbarer Schalter</li>
- <li>DS2413 - 2-kanaliger adressierbarer Schalter</li>
- <li>DS1825 - Thermosensor mit programmierbarer Auflösung und ID</li>
- <li>EDS0066 - Vielfachsensor für Temperatur und Luftdruck</li>
- <li>LCD - LCD-Ansteuerung von Louis Swart</li>
- </ul>
- <br>
- Das Hinzufügen weiterer Geräte ist im Modulcode (subroutine <code>OWDevice_GetDetails</code>) sehr einfach möglich.
- <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>
- <b>Bitte beachten:</b> Um einer Verwechselung entgegenzuwirken, stößt das reading "state" der Geräte keine Events an.<br><br>
- Beispiele zur Einrichtung:
- <ul>
- <code>
- define myOWServer OWServer localhost:4304<br><br>
- get myOWServer devices<br>
- 10.487653020800 DS18S20<br><br>
- define myT1 10.487653020800<br><br>
- list myT1 10.487653020800<br>
- Internals:<br>
- ...<br>
- Readings:<br>
- 2012-12-22 20:30:07 temperature 23.1875<br>
- Fhem:<br>
- ...<br>
- getters:<br>
- address<br>
- family<br>
- id<br>
- power<br>
- type<br>
- temperature<br>
- templow<br>
- temphigh<br>
- polls:<br>
- temperature<br>
- setters:<br>
- alias<br>
- templow<br>
- temphigh<br>
- ...<br>
- </code>
- </ul>
- <br>
- </ul>
- <a name="OWDeviceset"></a>
- <b>Set-Befehle</b>
- <ul>
- <li><code>set <name> interval <value></code>
- <br>
- <code>value</code> überschreibt das Abrufintervall der Datensätze. Der Wert ist in Sekunden anzugeben.
- </li><br>
- <li><code>set <name> <reading> <value></code>
- <br>
- Setzt das <reading> auf <value> für das 1-Wire-Gerät <name>. Die verwendbaren Werte werden durch die
- jeweiligen 1-wire-Geräte bestimmt.
- <br><br>
- Beispiel:
- <ul>
- <code>set myT1 templow 5</code><br>
- </ul>
- <br>
- </li>
- </ul>
- <a name="OWDeviceget"></a>
- <b>Get-Befehle</b>
- <ul>
- <code>get <name> <reading> <value></code>
- <br>
- Holt das <reading> des 1- Wire Geräte- <name>. Die verwendbaren Werte werden durch die
- jeweiligen 1-wire-Geräte bestimmt.
- <br><br>
- Beispiel:
- <ul>
- <code>get myT1 temperature</code><br>
- </ul>
- <br>
- </ul>
- <a name="OWDeviceattr"></a>
- <b>Attribute</b>
- <ul>
- <a name="IODev"></a>
- <li>IODev:
- Bestimmt die OWServer-Instanz, welche für das Senden und Abrufen der Daten
- eines OWDevice-Gerätes genutzt werden soll. Hinweis: Während des Starts
- ordnet FHEM die neuen OWDevice-Geräte der jeweils zuletzt definierten OWServer-Instanz zu.
- Deshalb verfährt man idealerweise so, dass man zuerst eine OWServer-Instanz und
- anschließend die zugehörigen OWDevice-Geräte definiert. Danach definiert man die
- nächste OWServer-Instanz, gefolgt von den zugehörigen OWDevice-Geräten, usw.
- </li>
- <li>trimvalues: Entfernt voran- und nachgestellte Leerzeichen aus den readings. Standartwert ist 1 (ein).</li>
- <li>cstrings: Interpretiert die readings als C-String, d.h. hört mit dem ersten 0-Byte zu lesen auf. Standardwert ist 0 (off).</li>
- <li>polls: Eine per Komma getrennte Liste der abzurufenden readings. Mit diesem Attribut unterdrückt man alle standartmäßig abgerufenen readings und ersetzt sie durch die eigene Zusammenstellung.</li>
- <li>interfaces: Ersetzt die durch dieses Gerät erzeugten Interfaces.</li>
- <li>model: Angabe des Gerätetyps, z.B.: DS18S20.</li>
- <li>resolution: Angabe der Auflösung für die Temperaturmessung in bits, zur Verfügung stehen: 9, 10, 11 oder 12.
- Hinweis: Geringere Auflösungen bewirken schnellere Reaktionen des Busses. Dies kann z.B. bei umfangreichen 1-Wire- Installationen hilfreich sein,
- um eventuelle Stillstände von FHEM zu vermindern.</li>
- <li><a href="#eventMap">eventMap</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- <br><br>
- </ul>
- =end html_DE
- =cut
|