From b7ba66d44d72d53a704c48913c55b1f72fa249a5 Mon Sep 17 00:00:00 2001 From: breaker27 Date: Wed, 28 Sep 2022 19:51:36 +0000 Subject: [PATCH] 37_SHC.pm: Updated for current smarthomatic v0.12.0 (Forum #129298) git-svn-id: https://svn.fhem.de/fhem/trunk@26451 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 3 ++ fhem/FHEM/37_SHC.pm | 58 ++++++++++++++------ fhem/FHEM/37_SHCdev.pm | 83 +++++++++++++++++++++++------ fhem/FHEM/SHC_datafields.pm | 70 ++++++++++++++++++++---- fhem/FHEM/SHC_parser.pm | 54 ++++++++++++++----- fhem/FHEM/lib/SHC_packet_layout.xml | 73 +++++++++++++++++++++++++ 6 files changed, 288 insertions(+), 53 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 597de19ae..93b768aae 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - change: 37_SHC: Support current smarthomatic version. + Basestation uses 115200 Baud by default and CRC. + EnvSensor supports particulate matter sensor. - bugfix: 73_NUKIBridge: Fix 503 Unavailable message - change: 88_HMCCU: Switched close to closed - bugfix: 70_Klafs: package main was removed from source code diff --git a/fhem/FHEM/37_SHC.pm b/fhem/FHEM/37_SHC.pm index 7d6678a29..cae031475 100644 --- a/fhem/FHEM/37_SHC.pm +++ b/fhem/FHEM/37_SHC.pm @@ -2,6 +2,7 @@ # This file is part of the smarthomatic module for FHEM. # # Copyright (c) 2014 Stefan Baumann +# 2015, 2022 Uwe Freese # # You can find smarthomatic at www.smarthomatic.org. # You can find FHEM at www.fhem.de. @@ -26,6 +27,8 @@ package main; use strict; use warnings; use Time::HiRes qw(gettimeofday); +use Digest::CRC qw(crc32); # linux packet libdigest-crc-perl +use DevIo; sub SHC_Parse($$$$); sub SHC_Read($); @@ -37,7 +40,7 @@ sub SHC_SimpleWrite(@); my $clientsSHC = ":SHCdev:BASE:xxx:"; my %matchListSHC = ( - "1:SHCdev" => "^Packet Data: SenderID=[1-9]|0[1-9]|[1-9][0-9]|[0-9][0-9][0-9]|[0-3][0-9][0-9][0-9]|40[0-8][0-9]|409[0-6]", #1-4096 with leading zeros + "1:SHCdev" => "^PKT:SID=([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-3][0-9][0-9][0-9]|40[0-8][0-9]|409[0-6]);", #1-4096 "2:xxx" => "^\\S+\\s+22", "3:xxx" => "^\\S+\\s+11", "4:xxx" => "^\\S+\\s+9 ", @@ -47,8 +50,6 @@ sub SHC_Initialize($) { my ($hash) = @_; - require "$attr{global}{modpath}/FHEM/DevIo.pm"; - # Provider $hash->{ReadFn} = "SHC_Read"; $hash->{WriteFn} = "SHC_Write"; @@ -69,7 +70,7 @@ sub SHC_Define($$) my @a = split("[ \t][ \t]*", $def); if (@a != 3) { - my $msg = "wrong syntax: define SHC {devicename[\@baudrate] " . "| devicename\@directio}"; + my $msg = "wrong syntax: define SHC {devicename[\@baudrate]}"; Log3 undef, 2, $msg; return $msg; } @@ -78,7 +79,7 @@ sub SHC_Define($$) my $name = $a[0]; my $dev = $a[2]; - $dev .= "\@19200" if ($dev !~ m/\@/); + $dev .= "\@115200" if ($dev !~ m/\@/); $hash->{Clients} = $clientsSHC; $hash->{MatchList} = \%matchListSHC; @@ -221,7 +222,6 @@ sub SHC_ReadAnswer($$$$) undef, $mpandata ); } - } ##################################### @@ -269,11 +269,15 @@ sub SHC_Parse($$$$) next if (!$dmsg || length($dmsg) < 1); # Bogus messages - if ($dmsg !~ m/^Packet Data: SenderID=/) { + if ($dmsg =~ m/^PKT:SID=0;/) { # "echo" from message sent by FHEM itself + return; + } + + if ($dmsg !~ m/^PKT:SID=/) { # Messages just to dipose - if ( $dmsg =~ m/^\*\*\* Enter AES key nr/ - || $dmsg =~ m/^\*\*\* Received character/) + if ( $dmsg =~ m/^\*\*\* Enter data/ + || $dmsg =~ m/^\*\*\* 0x/) { return; } @@ -294,17 +298,34 @@ sub SHC_Parse($$$$) # -Verbosity level 4 if ( $dmsg =~ m/^Request added to queue/ || $dmsg =~ m/^Request Buffer/ - || $dmsg =~ m/^Request (q|Q)ueue/) + || $dmsg =~ m/^Request Queue/) { Log3 $name, 4, "$name: $dmsg"; return; } + # -Verbosity level 1 + if ( $dmsg =~ m/^CRC Error/ ) + { + Log3 $name, 1, "$name: $dmsg"; + return; + } + # Anything else in verbosity level 3 Log3 $name, 3, "$name: $dmsg"; return; } + # check CRC of "PKT:..." message and ignore message if necessary + my $crc = crc32(substr($dmsg, 4, length($dmsg) - 12)); + $crc = sprintf("%08x", $crc); + + if ($crc ne substr($dmsg, length($dmsg) - 8)) + { + Log3 $name, 1, "$name: CRC Error (" . $crc . ") $dmsg"; + return; + } + $hash->{"${name}_MSGCNT"}++; $hash->{"${name}_TIME"} = TimeNow(); $hash->{RAWMSG} = $rmsg; @@ -345,26 +366,33 @@ sub SHC_SimpleWrite(@) syswrite($hash->{DIODev}, $msg) if ($hash->{DIODev}); # Some linux installations are broken with 0.001, T01 returns no answer - select(undef, undef, undef, 0.01); + #select(undef, undef, undef, 0.01); + + # Sleep for 250 milliseconds to make sure the base station can process the command before the next is sent + select(undef, undef, undef, 0.25); } 1; =pod +=item summary support the basestation of smarthomatic (www.smarthomatic.org) +=item summary_DE Unterstützung der Basisstation von smarthomatic (www.smarthomatic.org) =begin html

SHC

    - SHC is the basestation module that supports a family of RF devices available + SHC is the basestation module that supports a family of RF devices available at www.smarthomatic.org. - This module provides the IODevice for the SHCdev + This module provides the IODevice for the SHCdev modules that implement the SHCdev protocol.

    Note: this module may require the Device::SerialPort or Win32::SerialPort module if you attach the device via USB and the OS sets strange default - parameters for serial devices.

    + parameters for serial devices.
    + It also requires Digest::CRC because the communication to the basestation + is secured by a CRC.

    Define @@ -377,7 +405,7 @@ sub SHC_SimpleWrite(@) You can also specify a baudrate if the device name contains the @ character, e.g.: /dev/ttyUSB0@57600. Please note that the default - baudrate for the SHC base station is 19200 baud.

    + baudrate for the SHC base station is 115200 baud.

    Example:
      diff --git a/fhem/FHEM/37_SHCdev.pm b/fhem/FHEM/37_SHCdev.pm index 5b95b6ed4..6f5fee816 100644 --- a/fhem/FHEM/37_SHCdev.pm +++ b/fhem/FHEM/37_SHCdev.pm @@ -1,7 +1,8 @@ ########################################################################## # This file is part of the smarthomatic module for FHEM. # -# Copyright (c) 2014 Stefan Baumann, Uwe Freese +# Copyright (c) 2014 Stefan Baumann +# 2014, 2015, 2019 Uwe Freese # # You can find smarthomatic at www.smarthomatic.org. # You can find FHEM at www.fhem.de. @@ -63,7 +64,10 @@ my %dev_state_format = ( "port", "Port: ", "ains", "Ain: " ], - "RGBDimmer" => ["color", "Color: "], + "RGBDimmer" => [ + "color", "Color: ", + "brightness", "Brightness: " + ], "SoilMoistureMeter" => ["humidity", "H: "] ); @@ -78,13 +82,14 @@ my %sets = ( "DigitalPort " . "DigitalPortTimeout " . "DigitalPin " . - "DigitalPinTimeout ", + "DigitalPinTimeout", "Dimmer" => "on:noArg off:noArg toggle:noArg statusRequest:noArg pct:slider,0,1,100 ani " . # Used from SetExtensions.pm "blink on-for-timer on-till off-for-timer off-till intervals", "EnvSensor" => "", "RGBDimmer" => "Color " . - "ColorAnimation", + "ColorAnimation " . + "Dimmer.Brightness:slider,0,1,100", "SoilMoistureMeter" => "", "Custom" => "Dimmer.Brightness " . "Dimmer.Animation" @@ -107,13 +112,13 @@ sub SHCdev_Initialize($) { my ($hash) = @_; - $hash->{Match} = "^Packet Data: SenderID=[1-9]|0[1-9]|[1-9][0-9]|[0-9][0-9][0-9]|[0-3][0-9][0-9][0-9]|40[0-8][0-9]|409[0-6]"; + $hash->{Match} = "^PKT:SID=([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-3][0-9][0-9][0-9]|40[0-8][0-9]|409[0-6]);"; $hash->{SetFn} = "SHCdev_Set"; $hash->{GetFn} = "SHCdev_Get"; $hash->{DefFn} = "SHCdev_Define"; $hash->{UndefFn} = "SHCdev_Undef"; $hash->{ParseFn} = "SHCdev_Parse"; - $hash->{AttrList} = "IODev" + $hash->{AttrList} = "IODev" ." readonly:1" ." forceOn:1" ." $readingFnAttributes" @@ -185,19 +190,20 @@ sub SHCdev_Parse($$) my $name = $hash->{NAME}; if (!$parser->parse($msg)) { - Log3 $hash, 4, "SHC_TEMP: parser error: $msg"; + Log3 $name, 1, "$name: Parser error: $msg"; return ""; } - my $msgtypename = $parser->getMessageTypeName(); - my $msggroupname = $parser->getMessageGroupName(); - my $msgname = $parser->getMessageName(); - my $raddr = $parser->getSenderID(); - my $rhash = $modules{SHCdev}{defptr}{$raddr}; - my $rname = $rhash ? $rhash->{NAME} : $raddr; + my $msgtypename = $parser->getMessageTypeName(); + my $msggroupname = $parser->getMessageGroupName(); + my $msgname = $parser->getMessageName(); + my $packetcounter = $parser->getPacketCounter(); + my $raddr = $parser->getSenderID(); + my $rhash = $modules{SHCdev}{defptr}{$raddr}; + my $rname = $rhash ? $rhash->{NAME} : $raddr; if (!$modules{SHCdev}{defptr}{$raddr}) { - Log3 $name, 3, "SHC_TEMP: Unknown device $rname, please define it"; + Log3 $name, 3, "$name: Unknown device $rname, please define it"; return "UNDEFINED SHCdev_$rname SHCdev $raddr"; } @@ -218,6 +224,9 @@ sub SHCdev_Parse($$) readingsBeginUpdate($rhash); + # remember PacketCounter (which every message provides) + readingsBulkUpdate($rhash, "packetCounter", $packetcounter); + given ($msggroupname) { when ('Generic') { given ($msgname) { @@ -244,6 +253,9 @@ sub SHCdev_Parse($$) } readingsBulkUpdate($rhash, "version", "$major.$minor.$patch-$vhash"); + } + when ('HardwareError') { + readingsBulkUpdate($rhash, "hardwareErrorCode", $parser->getField("ErrorCode")); } when ('BatteryStatus') { readingsBulkUpdate($rhash, "battery", $parser->getField("Percentage")); @@ -334,6 +346,35 @@ sub SHCdev_Parse($$) my $brt = $parser->getField("Distance"); readingsBulkUpdate($rhash, "distance", $brt); } + when ('ParticulateMatter') { + my $size = $parser->getField("TypicalParticleSize"); + + if ($size != 1023) # 1023 means invalid + { + readingsBulkUpdate($rhash, "typicalParticleSize", $size / 100); # value was in 1/100 µm + } + + for (my $i = 0 ; $i < 5 ; $i++) { + $size = $parser->getField("Size", $i); + + if ($size) # 0 means array element not used + { + my $pmStr = int($size / 10) . "." . ($size % 10); + my $massConcentration = $parser->getField("MassConcentration", $i); + my $numberConcentration = $parser->getField("NumberConcentration", $i); + + if ($massConcentration != 1023) # 1023 means invalid + { + readingsBulkUpdate($rhash, "massConcentration_PM" . $pmStr, $massConcentration / 10); # value was in 1/10 µm + } + + if ($numberConcentration != 4095) # 4095 means invalid + { + readingsBulkUpdate($rhash, "numberConcentration_PM" . $pmStr, $numberConcentration / 10); # value was in 1/10 µm + } + } + } + } } } when ('Dimmer') { @@ -605,6 +646,16 @@ sub SHCdev_Set($@) } readingsSingleUpdate($hash, "state", "set-coloranimation", 1); SHCdev_Send($hash); + } elsif ($cmd eq 'Dimmer.Brightness') { + my $brightness = $arg; + + # DEBUG + # Log3 $name, 3, "$name: Args: $arg, $arg2, $arg3, $brightness"; + + readingsSingleUpdate($hash, "state", "set-brightness:$brightness", 1); + $parser->initPacket("Dimmer", "Brightness", "SetGet"); + $parser->setField("Dimmer", "Brightness", "Brightness", $brightness); + SHCdev_Send($hash); } else { return SetExtensions($hash, "", $name, @aa); } @@ -713,12 +764,14 @@ sub SHCdev_Send($) 1; =pod +=item summary support of several smarthomatic devices (www.smarthomatic.org) +=item summary_DE Unterstützung verschiedener smarthomatic-Geräte (www.smarthomatic.org) =begin html

      SHCdev

        - SHC is the device module that supports several device types available + SHC is the device module that supports several device types available at www.smarthomatic.org.

        These device are connected to the FHEM server through the SHC base station (SHC).

        diff --git a/fhem/FHEM/SHC_datafields.pm b/fhem/FHEM/SHC_datafields.pm index 1eb465703..c0f7c9667 100644 --- a/fhem/FHEM/SHC_datafields.pm +++ b/fhem/FHEM/SHC_datafields.pm @@ -1,9 +1,9 @@ -#!/usr/bin/perl +#!/usr/bin/perl ########################################################################## # This file is part of the smarthomatic module for FHEM. # -# Copyright (c) 2014 Uwe Freese +# Copyright (c) 2014, 2019 Uwe Freese # # You can find smarthomatic at www.smarthomatic.org. # You can find FHEM at www.fhem.de. @@ -226,6 +226,56 @@ sub setValue SHC_util::setInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value); } +# ----------- FloatValue class ----------- + +package FloatValue; + +sub new +{ + my $class = shift; + my $self = { + _id => shift, + _offset => shift, + _length => shift, + _arrayElementBits => shift + }; + bless $self, $class; + return $self; +} + +# reinterpret a float value as a 4-byte unsigned int which can be stored into a message +sub floatToUint32($) +{ + my $b = pack 'f', shift(); + my $str = reverse unpack "h*", $b; + return hex($str); +} + +# reinterpret a 4-byte unsigned int received from a device as a float value +sub uintToFloat($) +{ + my $u = shift(); + my @bytes = ( $u >> 24, ($u >> 16) & 0xff, ($u >> 8) & 0xff, $u & 0xff); + return unpack 'f', pack 'C4', reverse @bytes; +} + +sub getValue +{ + my ($self, $byteArrayRef, $index) = @_; + + my $uint32 = SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, 32); + my $float = uintToFloat($uint32); + return $float; +} + +sub setValue +{ + my ($self, $byteArrayRef, $value, $index) = @_; + + my $uint32 = floatToUint32($value); + SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, 32, $uint32); +} + # ----------- BoolValue class ----------- package BoolValue; @@ -262,8 +312,8 @@ sub setValue package EnumValue; -my %name2value = (); -my %value2name = (); +# my %name2value = (); +# my %value2name = (); sub new { @@ -273,7 +323,9 @@ sub new _offset => shift, _bits => shift, _length => shift, - _arrayElementBits => shift + _arrayElementBits => shift, + _name2value => {}, + _value2name => {} }; bless $self, $class; return $self; @@ -283,8 +335,8 @@ sub addValue { my ($self, $name, $value) = @_; - $name2value{$name} = $value; - $value2name{$value} = $name; + $self->{_name2value}{$name} = $value; + $self->{_value2name}{$value} = $name; } sub getValue @@ -292,14 +344,14 @@ sub getValue my ($self, $byteArrayRef, $index) = @_; my $value = SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}); - return $value2name{$value}; + return $self->{_value2name}{$value}; } sub setValue { my ($self, $byteArrayRef, $name, $index) = @_; - my $value = $name2value{$name}; + my $value = $self->{_name2value}{$name}; SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value); } diff --git a/fhem/FHEM/SHC_parser.pm b/fhem/FHEM/SHC_parser.pm index 4e960f1b3..96771b702 100644 --- a/fhem/FHEM/SHC_parser.pm +++ b/fhem/FHEM/SHC_parser.pm @@ -3,7 +3,7 @@ ########################################################################## # This file is part of the smarthomatic module for FHEM. # -# Copyright (c) 2014 Uwe Freese +# Copyright (c) 2014, 2015, 2019 Uwe Freese # # You can find smarthomatic at www.smarthomatic.org. # You can find FHEM at www.fhem.de. @@ -30,11 +30,12 @@ # Receiving packets: # ------------------ # 1.) Receive string from base station (over UART). -# 2.) Parse received string: -# $parser->parse("Packet Data: SenderID=22;..."); -# 3.) Get MessageGroupName: my $grp = $parser->getMessageGroupName(); -# 4.) Get MessageName: my $msg = $parser->getMessageName(); -# 5.) Get data fields depending on MessageGroupName and MessageName, e.g. +# 2.) Check CRC (last 8 characters, optional). +# 3.) Parse received string: +# $parser->parse("PKT:SID=22;..."); +# 4.) Get MessageGroupName: my $grp = $parser->getMessageGroupName(); +# 5.) Get MessageName: my $msg = $parser->getMessageName(); +# 6.) Get data fields depending on MessageGroupName and MessageName, e.g. # $val = $parser->getField("Temperature"); # # Sending packets: @@ -44,6 +45,7 @@ # 2.) Set fields: # $parser->setField("PowerSwitch", "SwitchState", "TimeoutSec", 8); # 3.) Get send string: $str = $parser->getSendString($receiverID); +# It includes a CRC32 as last 8 characters. # 4.) Send string to base station (over UART). ########################################################################## # $Id$ @@ -54,6 +56,7 @@ use strict; use feature qw(switch); use XML::LibXML; use SHC_datafields; +use Digest::CRC qw(crc32); # linux packet libdigest-crc-perl # Hash for data field definitions. my %dataFields = (); @@ -123,6 +126,18 @@ sub init_datafield_positions_noarray($$$$$) $offset += $bits; } + when ('FloatValue') { + my $id = ($field->findnodes("ID"))[0]->textContent; + my $bits = 32; + + # print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n"; + + $dataFields{$messageGroupID . "-" . $messageID . "-" . $id} = + new FloatValue($id, $offset, $arrayLength, $arrayElementBits); + + $offset += $bits; + } + when ('BoolValue') { my $id = ($field->findnodes("ID"))[0]->textContent; my $bits = 1; @@ -149,6 +164,8 @@ sub init_datafield_positions_noarray($$$$$) my $name = ($element->findnodes("Name"))[0]->textContent; $object->addValue($name, $value); + + # print "Enum value " . $value . " -> " . $name . "\n"; } $offset += $bits; @@ -167,7 +184,7 @@ sub init_datafield_positions_array($$$) calc_array_bits_ovr($field); # number of bits for one struct ("set of sub-elements") in a structured array # print "Next field is an array with " . $arrayLength . " elements (" . $arrayElementBits . " ovr bits per array element)!\n"; - for my $subfield ($field->findnodes("UIntValue|IntValue|BoolValue|EnumValue")) { + for my $subfield ($field->findnodes("UIntValue|IntValue|FloatValue|BoolValue|EnumValue")) { my $bits = init_datafield_positions_noarray($messageGroupID, $messageID, $subfield, $arrayLength, $arrayElementBits); } @@ -189,6 +206,10 @@ sub calc_array_bits_ovr($) $bits += ($subfield->findnodes("Bits"))[0]->textContent; } + for my $subfield ($field->findnodes("FloatValue")) { + $bits += 32; + } + return $bits; } @@ -223,7 +244,7 @@ sub init_datafield_positions() $offset = 0; - for my $field ($message->findnodes("Array|UIntValue|IntValue|BoolValue|EnumValue")) { + for my $field ($message->findnodes("Array|UIntValue|IntValue|FloatValue|BoolValue|EnumValue")) { # When an array is detected, remember the array length and change the current field node # to the inner node for further processing. @@ -250,10 +271,10 @@ sub parse if ( ( $msg =~ -/^Packet Data: SenderID=(\d*);PacketCounter=(\d*);MessageType=(\d*);MessageGroupID=(\d*);MessageID=(\d*);MessageData=([^;]*);.*/ +/^PKT:SID=(\d+);PC=(\d+);MT=(\d+);MGID=(\d+);MID=(\d+);MD=([^;]+);.*/ ) || ($msg =~ -/^Packet Data: SenderID=(\d*);PacketCounter=(\d*);MessageType=(\d*);AckSenderID=\d*;AckPacketCounter=\d*;Error=\d*;MessageGroupID=(\d*);MessageID=(\d*);MessageData=([^;]*);.*/ +/^PKT:SID=(\d+);PC=(\d+);MT=(\d+);ASID=\d+;APC=\d+;E=\d+;MGID=(\d+);MID=(\d+);MD=([^;]+);.*/ ) ) { @@ -311,6 +332,9 @@ sub getMessageData $res .= sprintf("%02X", $_); } + # strip trailing zeros (pairwise) + $res =~ s/(00)+$//; + return $res; } else { return $self->{_messageData}; @@ -326,7 +350,7 @@ sub getField } my $obj = $dataFields{$self->{_messageGroupID} . "-" . $self->{_messageID} . "-" . $fieldName}; - + # add 256 "empty" bytes to have enough data in the array because the message may be truncated my @tmpArray = map hex("0x$_"), ($self->{_messageData} . ("00" x 256)) =~ /(..)/g; @@ -365,8 +389,8 @@ sub setField $obj->setValue(\@msgData, $value, $index); } -# sKK01RRRRGGMMDD -# s0001003D3C0164 = SET Dimmer Switch Brightness 50% +# cKK01RRRRGGMMDD{CRC32} +# c0001003D3C0164 = SET Dimmer Switch Brightness 50% sub getSendString { my ($self, $receiverID, $aesKeyNr) = @_; @@ -382,13 +406,15 @@ sub getSendString $aesKeyNr = 0; } - my $s = "s" + my $s = "c" . sprintf("%02X", $aesKeyNr) . sprintf("%02X", $self->{_messageTypeID}) . sprintf("%04X", $receiverID) . sprintf("%02X", $self->{_messageGroupID}) . sprintf("%02X", $self->{_messageID}) . getMessageData(); + + return $s . sprintf("%08x", crc32($s)); } 1; diff --git a/fhem/FHEM/lib/SHC_packet_layout.xml b/fhem/FHEM/lib/SHC_packet_layout.xml index fed42fcc3..fa7953d32 100644 --- a/fhem/FHEM/lib/SHC_packet_layout.xml +++ b/fhem/FHEM/lib/SHC_packet_layout.xml @@ -260,6 +260,10 @@ 80 Thermostat + + 90 + TeaMaker + VersionMajor @@ -290,6 +294,34 @@ 4294967295 + + HardwareError + Reports detected problems with the hardware. + 3 + 8 + test + + ErrorCode + Lists the type of error that occurred. + 8 + + 0 + ExternalReset + + + 1 + BrownOutReset + + + 2 + WatchdogReset + + + 3 + TransceiverWatchdogReset + + + BatteryStatus Tells the current battery status in percent. Please note that the "Get" may not be answered because a device does not listen to requests. @@ -555,6 +587,47 @@ 16383 + + ParticulateMatter + + 3 + 0 + 8 + 10 + test + + TypicalParticleSize + Typical Particle Size [1/100 μm]. Use 1023 when value invalid. + 10 + 0 + 1023 + + + 5 + + Size + Maximum particle size [1/10 µm] which is considered in the MassConcentration and NumberConcentration. Use 0 when the array element is not used. + 8 + 0 + 255 + 0 + + + MassConcentration + Mass concentration [1/10 μg/m3], considering the defined size. Use 1023 when the value is invalid. + 10 + 0 + 1023 + + + NumberConcentration + Number concentration [1/10 #/cm3], considering the defined size. Use 4095 when the value is invalid. + 12 + 0 + 4095 + + + PowerSwitch