################################################################################ # # $Id$ # # 66_EseraMulti.pm # # Copyright (C) 2018 pizmus # # This program 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 3 of the License, or # (at your option) any later version. # # This program 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 this program. If not, see . # ################################################################################ # # This FHEM module supports an Esera multi sensor connected via # an Esera 1-wire Controller and the 66_EseraOneWire module. # ################################################################################ package main; use strict; use warnings; use SetExtensions; sub EseraMulti_Initialize($) { my ($hash) = @_; $hash->{Match} = "DS2438|11112|11121|11132|11133|11134|11135"; $hash->{DefFn} = "EseraMulti_Define"; $hash->{UndefFn} = "EseraMulti_Undef"; $hash->{ParseFn} = "EseraMulti_Parse"; $hash->{SetFn} = "EseraMulti_Set"; $hash->{GetFn} = "EseraMulti_Get"; $hash->{AttrFn} = "EseraMulti_Attr"; $hash->{AttrList} = "$readingFnAttributes"; } sub EseraMulti_Define($$) { my ($hash, $def) = @_; my @a = split( "[ \t][ \t]*", $def); return "Usage: define EseraMulti <1-wire-ID> " if(@a < 5); my $devName = $a[0]; my $type = $a[1]; my $physicalDevice = $a[2]; my $oneWireId = $a[3]; my $deviceType = uc($a[4]); $hash->{STATE} = 'Initialized'; $hash->{NAME} = $devName; $hash->{TYPE} = $type; $hash->{ONEWIREID} = $oneWireId; $hash->{ESERAID} = undef; # We will get this from the first reading. $hash->{DEVICE_TYPE} = $deviceType; $modules{EseraMulti}{defptr}{$oneWireId} = $hash; AssignIoPort($hash, $physicalDevice); if (defined($hash->{IODev}->{NAME})) { Log3 $devName, 4, "$devName: I/O device is " . $hash->{IODev}->{NAME}; } else { Log3 $devName, 1, "$devName: no I/O device"; } # program the the device type into the controller via the physical module if ($deviceType =~ m/^DS([0-9A-F]+)/) { # for the DS* devices types the "DS" has to be omitted IOWrite($hash, "assign;$oneWireId;$1"); } else { IOWrite($hash, "assign;$oneWireId;$deviceType"); } return undef; } sub EseraMulti_Undef($$) { my ($hash, $arg) = @_; my $oneWireId = $hash->{ONEWIREID}; RemoveInternalTimer($hash); delete( $modules{EseraMulti}{defptr}{$oneWireId} ); return undef; } sub EseraMulti_Get($@) { return undef; } sub EseraMulti_Set($$) { return undef; } sub EseraMulti_Parse($$) { my ($ioHash, $msg) = @_; my $ioName = $ioHash->{NAME}; my $buffer = $msg; # expected message format: $deviceType."_".$oneWireId."_".$eseraId."_".$readingId."_".$value my @fields = split(/_/, $buffer); if (scalar(@fields) != 5) { return undef; } my $deviceType = uc($fields[0]); my $oneWireId = $fields[1]; my $eseraId = $fields[2]; my $readingId = $fields[3]; my $value = $fields[4]; # search for logical device my $rhash = undef; foreach my $d (keys %defs) { my $h = $defs{$d}; my $type = $h->{TYPE}; if($type eq "EseraMulti") { if (defined($h->{IODev}->{NAME})) { my $ioDev = $h->{IODev}->{NAME}; my $def = $h->{DEF}; # $def has the whole definition, extract the oneWireId (which is expected as 2nd parameter) my @parts = split(/ /, $def); my $oneWireIdFromDef = $parts[1]; if (($ioDev eq $ioName) && ($oneWireIdFromDef eq $oneWireId)) { $rhash = $h; last; } } } } if($rhash) { my $rname = $rhash->{NAME}; Log3 $rname, 4, "EseraMulti ($rname) - parse - device found: ".$rname; # capture the Esera ID for later use $rhash->{ESERAID} = $eseraId; # consistency check of device type if (!($rhash->{DEVICE_TYPE} eq uc($deviceType))) { Log3 $rname, 1, "EseraMulti ($rname) - unexpected device type ".$deviceType; # program the the device type into the controller via the physical module if ($rhash->{DEVICE_TYPE} =~ m/^DS([0-9A-F]+)/) { # for the DS* devices types the "DS" has to be omitted IOWrite($rhash, "assign;$oneWireId;$1"); } else { IOWrite($rhash, "assign;$oneWireId;".$rhash->{DEVICE_TYPE}); } } if ($readingId eq "ERROR") { Log3 $rname, 1, "EseraMulti ($rname) - error message from physical device: ".$value; } elsif ($readingId eq "STATISTIC") { Log3 $rname, 1, "EseraMulti ($rname) - statistics message not supported yet: ".$value; } else { my $nameOfReading; if ($deviceType eq "DS2438") { if ($readingId == 1) { $nameOfReading = "temperature"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 2) { $nameOfReading = "VCC"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 3) { $nameOfReading = "VAD"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 4) { $nameOfReading = "VSense"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100000.0, 1); } } elsif (($deviceType eq "11121") || ($deviceType eq "11132") || ($deviceType eq "11133") || ($deviceType eq "11134") || ($deviceType eq "11135")) { if ($readingId == 1) { $nameOfReading = "temperature"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 2) { $nameOfReading = "voltage"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 3) { $nameOfReading = "humidity"; if ($value != 10000) # Esera 11133 sporadically reports 100% by mistake { readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } } elsif ($readingId == 4) { $nameOfReading = "dewpoint"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 5) { $nameOfReading = "brightness"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } } elsif (($deviceType eq "11112")) { if ($readingId == 1) { $nameOfReading = "temperature"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 2) { $nameOfReading = "voltage"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 3) { $nameOfReading = "brightness"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } elsif ($readingId == 4) { $nameOfReading = "radiation"; readingsSingleUpdate($rhash, $nameOfReading, $value / 100.0, 1); } } } my @list; push(@list, $rname); return @list; } elsif (($deviceType eq "DS2438") || ($deviceType eq "11112") || ($deviceType eq "11121") || ($deviceType eq "11132") || ($deviceType eq "11133") || ($deviceType eq "11134") || ($deviceType eq "11135")) { return "UNDEFINED EseraMulti_".$ioName."_".$oneWireId." EseraMulti ".$ioName." ".$oneWireId." ".$deviceType; } return undef; } sub EseraMulti_Attr(@) { } 1; =pod =item summary Represents an Esera 1-wire multi sensor. =item summary_DE Repraesentiert einen Esera 1-wire Multi-Sensor. =begin html

EseraMulti

    This module supports an Esera 1-wire multi sensor or a DS2438 1-wire IC.
    It uses 66_EseraOneWire as I/O device.

    Define
      define <name> EseraMulti <ioDevice> <oneWireId> <deviceType>
      <oneWireId> specifies the 1-wire ID of the sensor. Use the "get devices"
      query of EseraOneWire to get a list of 1-wire IDs, or simply rely on autocreate.
      Supported values for deviceType:
      • DS2438
      • 11112 (Esera product number, multi sensor Solar)
      • 11121 (Esera product number)
      • 11132 (Esera product number, multi sensor Unterputz)
      • 11133 (Esera product number, multi sensor Unterputz)
      • 11134 (Esera product number, multi sensor Aufputz)
      • 11135 (Esera product number, multi sensor Outdoor)
      With deviceType DS2438 this device generates readings with un-interpreted data
      from DS2438. This can be used with any DS2438 device, independent of an Esera
      product. With deviceType 11112/11121/11132/11133/11134/11135 this module provides interpreted
      readings like humidity or dew point.
    Set
    • no get functionality

    Get
    • no get functionality

    Attributes
    • no attributes

    Readings
      readings for DS2438:
      • VAD
      • VCC
      • VSense
      • temperature
      readings for Esera 11121/11132/11133/11134/11135:
      • temperature
      • humidity
      • dewpoint
      • brightness
      • voltage
      readings for Esera 11112:
      • temperature (°C)
      • radiation (W/m²)
      • brightness (Lux)
      • voltage (V)

=end html =cut