2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

37_SHC.pm: Updated for current smarthomatic version v0.13.0

git-svn-id: https://svn.fhem.de/fhem/trunk@27810 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
breaker27 2023-07-30 11:58:56 +00:00
parent e4ca3bdc3c
commit efb008f802
4 changed files with 442 additions and 98 deletions

View File

@ -2,7 +2,7 @@
# This file is part of the smarthomatic module for FHEM.
#
# Copyright (c) 2014 Stefan Baumann
# 2014, 2015, 2019, 2022 Uwe Freese
# 2014, 2015, 2019, 2022, 2023 Uwe Freese
#
# You can find smarthomatic at www.smarthomatic.org.
# You can find FHEM at www.fhem.de.
@ -28,6 +28,7 @@ use strict;
use feature qw(switch);
use warnings;
use SetExtensions;
use Encode qw(encode_utf8 decode_utf8);
use SHC_parser;
@ -37,6 +38,7 @@ my %dev_state_icons = (
"PowerSwitch" => ".*1\\d{7}:on:off .*0\\d{7}:off:on set.*:light_question:off",
"Dimmer" => "on:on off:off set.*:light_question:off",
"EnvSensor" => undef,
"Controller" => undef,
"RGBDimmer" => undef,
"SoilMoistureMeter" => ".*H:\\s\\d\\..*:ampel_rot"
);
@ -45,6 +47,7 @@ my %web_cmds = (
"PowerSwitch" => "on:off:toggle:statusRequest",
"Dimmer" => "on:off:statusRequest",
"EnvSensor" => undef,
"Controller" => undef,
"RGBDimmer" => undef,
"SoilMoistureMeter" => undef
);
@ -64,6 +67,10 @@ my %dev_state_format = (
"port", "Port: ",
"ains", "Ain: "
],
"Controller" => [
"color", "Color: ",
"brightness", "Brightness: "
],
"RGBDimmer" => [
"color", "Color: ",
"brightness", "Brightness: "
@ -87,9 +94,19 @@ my %sets = (
# Used from SetExtensions.pm
"blink on-for-timer on-till off-for-timer off-till intervals",
"EnvSensor" => "",
"Controller" => "Color " .
"ColorAnimation " .
"Dimmer.Brightness:slider,0,1,100 " .
"Text " .
"MenuSelection " .
"Backlight " .
"Tone " .
"Melody",
"RGBDimmer" => "Color " .
"ColorAnimation " .
"Dimmer.Brightness:slider,0,1,100",
"Dimmer.Brightness:slider,0,1,100 " .
"Tone " .
"Melody",
"SoilMoistureMeter" => "",
"Custom" => "Dimmer.Brightness " .
"Dimmer.Animation"
@ -101,6 +118,7 @@ my %gets = (
"PowerSwitch" => "",
"Dimmer" => "",
"EnvSensor" => "din:all,1,2,3,4,5,6,7,8 ain:all,1,2,3,4,5 ain_volt:1,2,3,4,5",
"Controller" => "",
"RGBDimmer" => "",
"Custom" => ""
);
@ -122,7 +140,7 @@ sub SHCdev_Initialize($)
." readonly:1"
." forceOn:1"
." $readingFnAttributes"
." devtype:EnvSensor,Dimmer,PowerSwitch,RGBDimmer,SoilMoistureMeter";
." devtype:EnvSensor,Dimmer,PowerSwitch,Controller,RGBDimmer,SoilMoistureMeter";
}
#####################################
@ -207,7 +225,7 @@ sub SHCdev_Parse($$)
return "UNDEFINED SHCdev_$rname SHCdev $raddr";
}
if (($msgtypename ne "Status") && ($msgtypename ne "AckStatus")) {
if (($msgtypename ne "Status") && ($msgtypename ne "AckStatus") && ($msgtypename ne "Deliver")) {
Log3 $name, 3, "$rname: Ignoring MessageType $msgtypename";
return "";
}
@ -348,6 +366,42 @@ sub SHCdev_Parse($$)
}
}
}
} elsif ($msggroupname eq "Controller") {
if ($msgname eq "MenuSelection") {
my $index;
for (my $i = 0 ; $i < 16 ; $i = $i + 1) {
$index = $parser->getField("Index" , $i);
# index 0 indicates the value was not changed / doesn't exist
if ($index != 0) {
readingsBulkUpdate($rhash, sprintf("index%02d", $i), $index);
}
}
# remember delivery (= user selection)
if ($msgtypename eq "Deliver") {
readingsBulkUpdate($rhash, "menuSelectionDelivery", 1);
}
}
} elsif ($msggroupname eq "Audio") {
if ($msgname eq "Tone") {
my $tone = $parser->getField("Tone");
readingsBulkUpdate($rhash, "tone", $tone);
} elsif ($msgname eq "Melody") {
my $repeat = $parser->getField("Repeat");
my $autoreverse = $parser->getField("AutoReverse");
readingsBulkUpdate($rhash, "repeat", $repeat);
readingsBulkUpdate($rhash, "autoreverse", $autoreverse);
for (my $i = 0 ; $i < 25 ; $i = $i + 1) {
my $time = $parser->getField("Time" , $i);
my $effect = $parser->getField("Effect", $i);
my $tone = $parser->getField("Tone", $i);
readingsBulkUpdate($rhash, sprintf("time%02d", $i), $time);
readingsBulkUpdate($rhash, sprintf("effect%02d", $i), $effect);
readingsBulkUpdate($rhash, sprintf("tone%02d", $i), $tone);
}
}
} elsif ($msggroupname eq "Dimmer") {
if ($msgname eq "Brightness") {
my $brightness = $parser->getField("Brightness");
@ -370,6 +424,14 @@ sub SHCdev_Parse($$)
readingsBulkUpdate($rhash, "color$i", $color);
}
}
} elsif ($msggroupname eq "Display") {
if ($msgname eq "Backlight") {
my $mode = $parser->getField("Mode");
my $autotimeoutsec = $parser->getField("AutoTimeoutSec");
readingsBulkUpdate($rhash, "backlightMode", $mode);
readingsBulkUpdate($rhash, "backlightAutoTimeSec", $autotimeoutsec);
}
}
# If the devtype is defined add, if not already done, the according webCmds and devStateIcons
@ -566,7 +628,7 @@ sub SHCdev_Set($@)
} else {
return SetExtensions($hash, "", $name, @aa);
}
} elsif ($devtype eq "RGBDimmer") {
} elsif (($devtype eq "Controller") || ($devtype eq "RGBDimmer")) {
if ($cmd eq 'Color') {
#TODO Verify argument values
my $color = $arg;
@ -578,6 +640,17 @@ sub SHCdev_Set($@)
$parser->initPacket("Dimmer", "Color", "SetGet");
$parser->setField("Dimmer", "Color", "Color", $color);
SHCdev_Send($hash);
} elsif ($cmd eq 'Tone') {
#TODO Verify argument values
my $tone = $arg;
# DEBUG
# Log3 $name, 3, "$name: Tone args: $arg, $arg2, $arg3, $arg4";
readingsSingleUpdate($hash, "state", "set-tone:$tone", 1);
$parser->initPacket("Audio", "Tone", "SetGet");
$parser->setField("Audio", "Tone", "Tone", $tone);
SHCdev_Send($hash);
} elsif ($cmd eq 'ColorAnimation') {
#TODO Verify argument values
@ -609,6 +682,44 @@ sub SHCdev_Set($@)
}
readingsSingleUpdate($hash, "state", "set-coloranimation", 1);
SHCdev_Send($hash);
} elsif ($cmd eq 'Melody') {
#TODO Verify argument values
$parser->initPacket("Audio", "Melody", "SetGet");
$parser->setField("Audio", "Melody", "Repeat", $arg);
$parser->setField("Audio", "Melody", "AutoReverse", $arg2);
my $curtime = 0;
my $cureffect = 0;
my $curtone = 0;
# Iterate over all given command line parameters and set Time, Effect and Tone
# accordingly. Fill the remaining values with zero.
for (my $i = 0 ; $i < 25 ; $i = $i + 1) {
if (!defined($aa[($i * 3) + 3])) {
$curtime = 0;
} else {
$curtime = $aa[($i * 3) + 3];
}
if (!defined($aa[($i * 3) + 4])) {
$cureffect = 0;
} else {
$cureffect = $aa[($i * 3) + 4];
}
if (!defined($aa[($i * 3) + 5])) {
$curtone = 0;
} else {
$curtone = $aa[($i * 3) + 5];
}
# DEBUG
# Log3 $name, 3, "$name: Nr: $i Time: $curtime Effect: $cureffect Tone: $curtone";
$parser->setField("Audio", "Melody", "Time" , $curtime, $i);
$parser->setField("Audio", "Melody", "Effect", $cureffect, $i);
$parser->setField("Audio", "Melody", "Tone", $curtone, $i);
}
readingsSingleUpdate($hash, "state", "set-melody", 1);
SHCdev_Send($hash);
} elsif ($cmd eq 'Dimmer.Brightness') {
my $brightness = $arg;
@ -619,6 +730,37 @@ sub SHCdev_Set($@)
$parser->initPacket("Dimmer", "Brightness", "SetGet");
$parser->setField("Dimmer", "Brightness", "Brightness", $brightness);
SHCdev_Send($hash);
} elsif ($cmd eq 'Text') {
$parser->initPacket("Display", "Text", "Set");
$parser->setField("Display", "Text", "PosY", $arg);
$parser->setField("Display", "Text", "PosX", $arg2);
$parser->setField("Display", "Text", "Format", $arg3);
$arg4 = decode_utf8($arg4);
$arg4 =~ s/(?<!\\)_/ /g; # replace non-escaped '_' with space
$arg4 =~ s/\\_/_/g; # replace escape character from escaped '_'
$arg4 =~ s/(?<!\\)\\1/\x01/g; # replace \1 with character 1 (user character)
$arg4 =~ s/(?<!\\)\\2/\x02/g; # replace \2 with character 2 (user character)
$arg4 =~ s/(?<!\\)\\3/\x03/g; # replace \3 with character 3 (user character)
$arg4 =~ s/(?<!\\)\\4/\x04/g; # replace \4 with character 4 (user character)
$arg4 =~ s/(?<!\\)\\5/\x05/g; # replace \5 with character 5 (user character)
$arg4 =~ s/(?<!\\)\\6/\x06/g; # replace \6 with character 6 (user character)
$arg4 =~ s/(?<!\\)\\7/\x07/g; # replace \7 with character 7 (user character)
$arg4 =~ s/(?<!\\)\\8/\x08/g; # replace \8 with character 8 (user character)
$parser->setField("Display", "Text", "Text", $arg4);
SHCdev_Send($hash);
} elsif ($cmd eq 'Backlight') {
$parser->initPacket("Display", "Backlight", "SetGet");
$parser->setField("Display", "Backlight", "Mode", $arg);
$parser->setField("Display", "Backlight", "AutoTimeoutSec", $arg2);
SHCdev_Send($hash);
} elsif ($cmd eq 'MenuSelection') {
$parser->initPacket("Controller", "MenuSelection", "SetGet");
for (my $i = 0 ; $i < 16 ; $i = $i + 1) {
if (defined($aa[$i + 1])) {
$parser->setField("Controller", "MenuSelection", "Index", $aa[$i + 1], $i);
}
}
SHCdev_Send($hash);
} else {
return SetExtensions($hash, "", $name, @aa);
}
@ -740,6 +882,7 @@ sub SHCdev_Send($)
<li>EnvSensor</li>
<li>PowerSwitch</li>
<li>Dimmer</li>
<li>Controller</li>
<li>RGBDimmer</li>
<li>SoilMoistureMeter</li>
</ul><br>
@ -774,35 +917,58 @@ sub SHCdev_Send($)
Sets the brightness in percent. Supported by Dimmer.
</li><br>
<li>ani &lt;AnimationMode&gt; &lt;TimeoutSec&gt; &lt;StartBrightness&gt; &lt;EndBrightness&gt;<br>
Description and details available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Dimmer_Animation">www.smarthomatic.org</a>
Description and details available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Dimmer_Animation">www.smarthomatic.org</a>.
Supported by Dimmer.
</li><br>
<li>statusRequest<br>
Supported by Dimmer and PowerSwitch.
</li><br>
<li>Color &lt;ColorNumber&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Dimmer_Color">www.smarthomatic.org</a>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Dimmer_Color">www.smarthomatic.org</a>.
The color palette can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
Supported by RGBDimmer.
</li><br>
<li>ColorAnimation &lt;Repeat&gt; &lt;AutoReverse&gt; &lt;Time0&gt; &lt;ColorNumber0&gt; &lt;Time1&gt; &lt;ColorNumber1&gt; ... up to 10 time/color pairs<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Dimmer_ColorAnimation">www.smarthomatic.org</a>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Dimmer_ColorAnimation">www.smarthomatic.org</a>.
The color palette can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
Supported by RGBDimmer.
</li><br>
<li>Tone &lt;ToneNumber&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Audio_Tone">www.smarthomatic.org</a>.
The tone definition can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
Supported by RGBDimmer.
</li><br>
<li>Melody &lt;Repeat&gt; &lt;AutoReverse&gt; &lt;Time0&gt; &lt;Effect0&gt; &lt;ToneNumber0&gt; &lt;Time1&gt; &lt;Effect1&gt; &lt;ToneNumber1&gt; ... up to 25 time/effect/tone pairs<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Audio_Melody">www.smarthomatic.org</a>.
The tone definition can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
Supported by RGBDimmer.
</li><br>
<li>Text &lt;PosY&gt; &lt;PosX&gt; &lt;Format&gt; &lt;Text&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Display_Text">www.smarthomatic.org</a>. Supported by Controller.<br>
<b>Note:</b> Since FHEM parameters can't include spaces, there is a special form to enter them.
To add a space to the text, use the underline character (e.g. 'Hello_world').
If you want to send an underline character, escape it with the backslash (e.g. '\_test\_').
</li><br>
<li>MenuSelection &lt;Index00&gt; &lt;Index01&gt; ... &lt;Index15&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Controller_MenuSelection">www.smarthomatic.org</a>. Supported by Controller.<br>
When the MenuSelection was initiated by the user with the controller, the reading <b>menuSelectionDelivery</b> will be set additionally to the index00, ... readings. This can be used to distinguish if the menu selection was user initiated or done programmatically by a FHEM "set" command, especially to keep more than one controller with the same options in sync reacting on a change of the menuSelectionDelivery reading.
</li><br>
<li>Backlight &lt;Mode&gt; &lt;AutoTimeoutSec&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#Display_Backlight">www.smarthomatic.org</a>. Supported by Controller.
</li><br>
<li>DigitalPin &lt;Pos&gt; &lt;On&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPin">www.smarthomatic.org</a>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPin">www.smarthomatic.org</a>.
Supported by PowerSwitch.
</li><br>
<li>DigitalPinTimeout &lt;Pos&gt; &lt;On&gt; &lt;Timeout&gt;<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPinTimeout">www.smarthomatic.org</a>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPinTimeout">www.smarthomatic.org</a>.
Supported by PowerSwitch.
</li><br>
<li>DigitalPort &lt;On&gt;<br>
&lt;On&gt;<br>
is a bit array (0 or 1) describing the port state. If less than eight bits were provided zero is assumed.
Example: set SHC_device DigitalPort 10110000 will set pin0, pin2 and pin3 to 1.<br>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPort">www.smarthomatic.org</a>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPort">www.smarthomatic.org</a>.
Supported by PowerSwitch.
</li><br>
<li>DigitalPortTimeout &lt;On&gt; &lt;Timeout0&gt; .. &lt;Timeout7&gt;<br>
@ -811,7 +977,7 @@ sub SHCdev_Send($)
Example: set SHC_device DigitalPort 10110000 will set pin0, pin2 and pin3 to 1.<br>
&lt;Timeout0&gt; .. &lt;Timeout7&gt;<br>
are the timeouts for each pin. If no timeout is provided zero is assumed.
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPortTimeout">www.smarthomatic.org</a>
A detailed description is available at <a href="http://www.smarthomatic.org/basics/message_catalog.html#GPIO_DigitalPortTimeout">www.smarthomatic.org</a>.
Supported by PowerSwitch.
</li><br>
<li><a href="#setExtensions"> set extensions</a><br>

View File

@ -126,7 +126,7 @@ sub setUInt($$$$)
my $len = min($length_bits, 8 - $bit);
my $val8 = get_bits($value, $src_start, $len);
# DEBUG print " Write value " . $val8 . " (" . $len . " bits) to byte " . $byte . ", dst_start " . $dst_start . "\r\n";
# DEBUG print " Write value " . $val8 . " (" . $len . " bits) to byte " . $byte . ", start bit " . $dst_start . "\r\n";
setUIntBits($byteArrayRef, $byte, $dst_start, $len, $val8);
@ -138,7 +138,7 @@ sub setUInt($$$$)
$val8 = get_bits($value, $src_start, $len);
$byte++;
# DEBUG print " Write value " . $val8 . " (" . $len . " bits) from src_start " . $src_start . " to byte " . $byte . ", dst_start " . $dst_start . "\r\n";
# DEBUG print " Write value " . $val8 . " (" . $len . " bits) from src_start " . $src_start . " to byte " . $byte . ", start bit " . $dst_start . "\r\n";
setUIntBits($byteArrayRef, $byte, $dst_start, $len, $val8);
@ -355,4 +355,68 @@ sub setValue
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value);
}
# ----------- ByteArray class -----------
package ByteArray;
sub new
{
my $class = shift;
my $self = {
_id => shift,
_offset => shift,
_bytes => shift,
_length => shift,
_arrayElementBits => shift
};
bless $self, $class;
return $self;
}
sub getValue
{
my ($self, $byteArrayRef, $index) = @_;
my $res = "";
my ($i, $c);
for ($i = 0; $i < $self->{_bytes}; $i++)
{
$c = SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index + $i * 8, 8);
if ($c == 0)
{
last;
}
$res .= Chr($c);
}
return $res;
}
sub setValue
{
my ($self, $byteArrayRef, $value, $index) = @_;
my @chars = split("", $value);
# Set a maximum of _bytes bytes in the data array.
my $i;
my $strlen = SHC_util::min(length($value), $self->{_bytes});
for ($i = 0; $i < $strlen; $i++)
{
#print "set bit " . ($self->{_offset} + $self->{_arrayElementBits} * $index + $i * 8) . " char " . $i . " = " . $chars[$i] . " = ord " . ord($chars[$i]) . "\n";
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index + $i * 8, 8, ord($chars[$i]));
}
# Fill up the rest of the bytes with 0.
for ($i = $strlen; $i < $self->{_bytes}; $i++)
{
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index + $i * 8, 8, 0);
}
}
1;

View File

@ -160,6 +160,16 @@ sub init_datafield_positions_noarray($$$$$)
}
$offset += $bits;
} elsif ($field->nodeName eq "ByteArray") {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bytes = ($field->findnodes("Bytes"))[0]->textContent;
# print "Data field " . $id . " starts at " . $offset . " with " . $bytes . " bytes.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} =
new ByteArray($id, $offset, $bytes, $arrayLength, $arrayElementBits);
$offset += $bytes * 8;
}
}
@ -174,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|FloatValue|BoolValue|EnumValue")) {
for my $subfield ($field->findnodes("UIntValue|IntValue|FloatValue|BoolValue|EnumValue|ByteArray")) {
my $bits =
init_datafield_positions_noarray($messageGroupID, $messageID, $subfield, $arrayLength, $arrayElementBits);
}
@ -200,6 +210,10 @@ sub calc_array_bits_ovr($)
$bits += 32;
}
for my $subfield ($field->findnodes("ByteArray")) {
$bits += ($subfield->findnodes("Bytes"))[0]->textContent * 8;
}
return $bits;
}
@ -234,7 +248,7 @@ sub init_datafield_positions()
$offset = 0;
for my $field ($message->findnodes("Array|UIntValue|IntValue|FloatValue|BoolValue|EnumValue")) {
for my $field ($message->findnodes("Array|UIntValue|IntValue|FloatValue|BoolValue|EnumValue|ByteArray")) {
# When an array is detected, remember the array length and change the current field node
# to the inner node for further processing.
@ -258,12 +272,16 @@ sub parse
$sendMode = 0;
# PKT:SID=56;PC=1816;MT=3;RID=0;MGID=45;MID=1;MD=010105;efc28d5e
if (
(
$msg =~
/^PKT:SID=(\d+);PC=(\d+);MT=(\d+);MGID=(\d+);MID=(\d+);MD=([^;]+);.*/
)
|| ($msg =~
/^PKT:SID=(\d+);PC=(\d+);MT=(3);RID=0;MGID=(\d+);MID=(\d+);MD=([^;]+);.*/
)
|| ($msg =~
/^PKT:SID=(\d+);PC=(\d+);MT=(\d+);ASID=\d+;APC=\d+;E=\d+;MGID=(\d+);MID=(\d+);MD=([^;]+);.*/
)
)

View File

@ -38,6 +38,10 @@
<Value>2</Value>
<Name>SetGet</Name>
</Element>
<Element>
<Value>3</Value>
<Name>Deliver</Name>
</Element>
<Element>
<Value>8</Value>
<Name>Status</Name>
@ -80,6 +84,7 @@
<HeaderExtension>
<MessageType>1</MessageType>
<MessageType>2</MessageType>
<MessageType>3</MessageType>
<UIntValue>
<ID>ReceiverID</ID>
<Description>The ID of the device to process the request. Use 4095 for broadcasts.</Description>
@ -183,43 +188,6 @@
<Name>Generic</Name>
<Description>This group contains messages useful for different devices.</Description>
<MessageGroupID>0</MessageGroupID>
<Message>
<Name>Version</Name>
<Description>Reports the current firmware version. Version information is only available when set in source code, which is usually only done for official builds by the build robot.</Description>
<MessageID>1</MessageID>
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>deprecated</Validity>
<UIntValue>
<ID>Major</ID>
<Description>Different major version means incompatible changes.</Description>
<Bits>8</Bits>
<MinVal>0</MinVal>
<MaxVal>255</MaxVal>
</UIntValue>
<UIntValue>
<ID>Minor</ID>
<Description>Different minor number means new functionality without breaking compatibility.</Description>
<Bits>8</Bits>
<MinVal>0</MinVal>
<MaxVal>255</MaxVal>
</UIntValue>
<UIntValue>
<ID>Patch</ID>
<Description>The patch version is changed when backwards-compatible bug fixes are made.</Description>
<Bits>8</Bits>
<MinVal>0</MinVal>
<MaxVal>255</MaxVal>
</UIntValue>
<UIntValue>
<ID>Hash</ID>
<Description>The beginning of the revision ID hash (as reported by Git).</Description>
<Bits>32</Bits>
<MinVal>0</MinVal>
<MaxVal>4294967295</MaxVal>
</UIntValue>
</Message>
<Message>
<Name>DeviceInfo</Name>
<Description>Reports DeviceType and current firmware version. Version information is only available when set in source code, which is usually only done for official builds by the build robot.</Description>
@ -227,7 +195,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<EnumValue>
<ID>DeviceType</ID>
<Description>The DeviceType can be used to adapt the behavior or representation of the SHC device at the server software (e.g. FHEM).</Description>
@ -244,6 +212,10 @@
<Value>40</Value>
<Name>PowerSwitch</Name>
</Element>
<Element>
<Value>45</Value>
<Name>Controller</Name>
</Element>
<Element>
<Value>50</Value>
<Name>RGBDimmer</Name>
@ -329,7 +301,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Percentage</ID>
<Description>The remaining capacity of the battery from 0 (empty) to 100 (full).</Description>
@ -353,7 +325,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<Array>
<Length>8</Length>
<BoolValue>
@ -372,7 +344,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<Array>
<Length>8</Length>
<BoolValue>
@ -398,7 +370,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Pos</ID>
<Description>The number of the pin in the port.</Description>
@ -421,7 +393,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Pos</ID>
<Description>The number of the pin in the port.</Description>
@ -479,7 +451,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<IntValue>
<ID>Temperature</ID>
<Description>temperature [1/100 degree celsius], -50°C = -5000, 50°C = 5000</Description>
@ -495,7 +467,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Humidity</ID>
<Description>relative humidity permill, 0..1000 (other values not defined)</Description>
@ -518,7 +490,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>BarometricPressure</ID>
<Description>barometric pressure in pascal</Description>
@ -541,7 +513,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Humidity</ID>
<Description>relative humidity permill, 0..1000 (other values not defined)</Description>
@ -562,7 +534,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Brightness</ID>
<Description>brightness in percent</Description>
@ -578,7 +550,7 @@
<MessageType>0</MessageType>
<MessageType>8</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Distance</ID>
<Description>distance in cm</Description>
@ -630,12 +602,12 @@
</Message>
</MessageGroup>
<MessageGroup>
<Name>PowerSwitch</Name>
<Description/>
<MessageGroupID>20</MessageGroupID>
<Name>Display</Name>
<Description>This message group contains messages for displays.</Description>
<MessageGroupID>40</MessageGroupID>
<Message>
<Name>SwitchState</Name>
<Description>This is the state of the relais and its timeout value.</Description>
<Name>Text</Name>
<Description>This is a message to get/set text content at a specified position.</Description>
<MessageID>1</MessageID>
<MessageType>0</MessageType>
<MessageType>1</MessageType>
@ -643,22 +615,38 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>deprecated</Validity>
<BoolValue>
<ID>On</ID>
<Description>Tells if the switch is on (active).</Description>
</BoolValue>
<Validity>test</Validity>
<UIntValue>
<ID>TimeoutSec</ID>
<Description>The time after which the switch is automatically toggled again. Use 0 to disable this.</Description>
<Bits>16</Bits>
<ID>PosY</ID>
<Description>Y (line) position at which the text shall be displayed. Line numbers above 3 are for the corresponding virtual lines / pages.</Description>
<Bits>5</Bits>
<MinVal>0</MinVal>
<MaxVal>65535</MaxVal>
<MaxVal>31</MaxVal>
</UIntValue>
<UIntValue>
<ID>PosX</ID>
<Description>X (character) position at which the text shall be displayed.</Description>
<Bits>7</Bits>
<MinVal>0</MinVal>
<MaxVal>79</MaxVal>
</UIntValue>
<UIntValue>
<ID>Format</ID>
<Description>Format, font, or other value which modifies how the text is displayed. Depends on the implementation of the device.</Description>
<Bits>4</Bits>
<MinVal>0</MinVal>
<MaxVal>15</MaxVal>
<DefaultVal>0</DefaultVal>
</UIntValue>
<ByteArray>
<ID>Text</ID>
<Description>40 bytes for the text that shall be displayed. The end of the text is marked with a 0 byte if it's shorter than 40 characters.</Description>
<Bytes>40</Bytes>
</ByteArray>
</Message>
<Message>
<Name>SwitchStateExt</Name>
<Description>This is the state of up to 8 relais and its timeout values.</Description>
<Name>Backlight</Name>
<Description>This is a message to get/set the backlight mode of a display.</Description>
<MessageID>2</MessageID>
<MessageType>0</MessageType>
<MessageType>1</MessageType>
@ -666,22 +654,130 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>deprecated</Validity>
<Validity>test</Validity>
<EnumValue>
<ID>Mode</ID>
<Description>The backlight mode defines when the backlight is switched on. The setting 'Auto' means the backlight is switched on automatically after user interaction and off after a timeout.</Description>
<Bits>4</Bits>
<Element>
<Value>0</Value>
<Name>On</Name>
</Element>
<Element>
<Value>1</Value>
<Name>Off</Name>
</Element>
<Element>
<Value>2</Value>
<Name>Auto</Name>
</Element>
</EnumValue>
<UIntValue>
<ID>AutoTimeoutSec</ID>
<Description>This is the timeout in seconds after which the backlight is switched off in mode 'Auto'. The value 0 shall be treated as not to change the value when sending a request to the device.</Description>
<Bits>8</Bits>
<MinVal>0</MinVal>
<MaxVal>255</MaxVal>
</UIntValue>
</Message>
</MessageGroup>
<MessageGroup>
<Name>Controller</Name>
<Description>This message group contains messages for controller / HMI devices.</Description>
<MessageGroupID>45</MessageGroupID>
<Message>
<Name>MenuSelection</Name>
<Description>These are the value indexes of selected menu items. It depends on the configuration of a specific controller device which value each index represents. The indexes of selected menu entries should start with 1, and 0 should be treated as 'not updated' (in a Status/AckStatus/Deliver message) or 'not to be updated' (in a Set/SetGet request). This is to allow smaller (16 byte) packets when there are few menu entries.</Description>
<MessageID>1</MessageID>
<MessageType>0</MessageType>
<MessageType>1</MessageType>
<MessageType>2</MessageType>
<MessageType>3</MessageType>
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Array>
<Length>8</Length>
<BoolValue>
<ID>On</ID>
<Description/>
</BoolValue>
</Array>
<Array>
<Length>8</Length>
<Length>16</Length>
<UIntValue>
<ID>TimeoutSec</ID>
<Description>The time after which the switch is automatically toggled again. Use 0 to disable this.</Description>
<Bits>16</Bits>
<ID>Index</ID>
<Description>The index of the selected value of a menu entry.</Description>
<Bits>8</Bits>
<MinVal>0</MinVal>
<MaxVal>65535</MaxVal>
<MaxVal>255</MaxVal>
<DefaultVal>0</DefaultVal>
</UIntValue>
</Array>
</Message>
</MessageGroup>
<MessageGroup>
<Name>Audio</Name>
<Description>This message group contains messages for audio input/output.</Description>
<MessageGroupID>50</MessageGroupID>
<Message>
<Name>Tone</Name>
<Description>This is a message to get/set playback of a continuous tone which doesn't stop until another one is requested.</Description>
<MessageID>1</MessageID>
<MessageType>0</MessageType>
<MessageType>1</MessageType>
<MessageType>2</MessageType>
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<UIntValue>
<ID>Tone</ID>
<Description>Tone according frequency table. 0 means OFF.</Description>
<Bits>7</Bits>
<MinVal>0</MinVal>
<MaxVal>116</MaxVal>
</UIntValue>
</Message>
<Message>
<Name>Melody</Name>
<Description>This is a message to play a series of tones (set) or get the currently playing one.</Description>
<MessageID>2</MessageID>
<MessageType>0</MessageType>
<MessageType>1</MessageType>
<MessageType>2</MessageType>
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<UIntValue>
<ID>Repeat</ID>
<Description>The number of times the melody will be repeated. 0 means infinitely.</Description>
<Bits>4</Bits>
<MinVal>0</MinVal>
<MaxVal>15</MaxVal>
</UIntValue>
<BoolValue>
<ID>AutoReverse</ID>
<Description>If true, the melody will be played back in the normal direction and then in reverse order.</Description>
</BoolValue>
<Array>
<Length>25</Length>
<UIntValue>
<ID>Time</ID>
<Description>The playback time between the previous tone and the new one. The number of seconds used is 0.05 * 1.3 ^ Time and covers the range from 0.03s to 170s. Use 0 to mark the end of the melody. Further values will be ignored.</Description>
<Bits>5</Bits>
<MinVal>0</MinVal>
<MaxVal>31</MaxVal>
</UIntValue>
<UIntValue>
<ID>Effect</ID>
<Description>Define how the tone is played. 0: Tone is played immediately (default). 1: A sliding tone from the previous to the new one. A sliding tone from or to tone index 0 (off) is not possible. The new tone / no tone will be played back immediately in this case. Other values are free for future use.</Description>
<Bits>3</Bits>
<MinVal>0</MinVal>
<MaxVal>1</MaxVal>
<DefaultVal>0</DefaultVal>
</UIntValue>
<UIntValue>
<ID>Tone</ID>
<Description>Index according frequency table. 0 means OFF. The last index (or the first when AutoReverse is true) of the melody will remain audible after the melody is completed.</Description>
<Bits>7</Bits>
<MinVal>0</MinVal>
<MaxVal>116</MaxVal>
</UIntValue>
</Array>
</Message>
@ -700,7 +796,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Brightness</ID>
<Description>The brightness in percent. 0 = Off.</Description>
@ -719,7 +815,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<EnumValue>
<ID>AnimationMode</ID>
<Description>If a time is set, use this animation mode to change the brightness over time (none = leave at start state for the whole time and switch to end state at the end).</Description>
@ -765,7 +861,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Color</ID>
<Description>The color is according to the 6 bit color palette used in SHC.</Description>
@ -784,7 +880,7 @@
<MessageType>8</MessageType>
<MessageType>9</MessageType>
<MessageType>10</MessageType>
<Validity>test</Validity>
<Validity>released</Validity>
<UIntValue>
<ID>Repeat</ID>
<Description>The number of times the animation will be repeated. 0 means infinitely.</Description>