mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
37_SHC: now add all files for the previous commit (rr2000)
git-svn-id: https://svn.fhem.de/fhem/trunk@8182 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
8443d9b4bb
commit
b7f5a515d2
@ -1,5 +1,6 @@
|
||||
# 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.
|
||||
- changed: 37_SHC: now add all files for the previous commit (rr2000)
|
||||
- feature: 37_SHC: add new support for SoilMoistureMeter and add
|
||||
support for DigPort and DigPin in Powerswitch (rr2000)
|
||||
- feature: 02_HTTPSRV: query string sets readings (Stefan Strobel)
|
||||
|
@ -2,6 +2,7 @@
|
||||
# This file is part of the smarthomatic module for FHEM.
|
||||
#
|
||||
# Copyright (c) 2014 Stefan Baumann
|
||||
# 2015 Uwe Freese
|
||||
#
|
||||
# You can find smarthomatic at www.smarthomatic.org.
|
||||
# You can find FHEM at www.fhem.de.
|
||||
@ -26,6 +27,7 @@ package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
use Digest::CRC qw(crc32); # linux packet libdigest-crc-perl
|
||||
|
||||
sub SHC_Parse($$$$);
|
||||
sub SHC_Read($);
|
||||
@ -37,7 +39,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 ",
|
||||
@ -269,11 +271,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 +300,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;
|
||||
|
@ -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 Uwe Freese
|
||||
#
|
||||
# You can find smarthomatic at www.smarthomatic.org.
|
||||
# You can find FHEM at www.fhem.de.
|
||||
@ -33,37 +34,41 @@ use SHC_parser;
|
||||
my $parser = new SHC_parser();
|
||||
|
||||
my %dev_state_icons = (
|
||||
"PowerSwitch" => "on:on:toggle off:off:toggle set.*:light_question:off",
|
||||
"Dimmer" => "on:on off:off set.*:light_question:off",
|
||||
"EnvSensor" => undef,
|
||||
"RGB_Dimmer" => undef
|
||||
"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,
|
||||
"RGBDimmer" => undef,
|
||||
"SoilMoistureMeter" => ".*H:\\s\\d\\..*:ampel_rot"
|
||||
);
|
||||
|
||||
my %web_cmds = (
|
||||
"PowerSwitch" => "on:off:toggle:statusRequest",
|
||||
"Dimmer" => "on:off:statusRequest",
|
||||
"EnvSensor" => undef,
|
||||
"RGB_Dimmer" => undef
|
||||
"PowerSwitch" => "on:off:toggle:statusRequest",
|
||||
"Dimmer" => "on:off:statusRequest",
|
||||
"EnvSensor" => undef,
|
||||
"RGBDimmer" => undef,
|
||||
"SoilMoistureMeter" => undef
|
||||
);
|
||||
|
||||
# Array format: [ reading1, str_format1, reading2, str_format2 ... ]
|
||||
# "on" reading translates 0 -> "off"
|
||||
# 1 -> "on"
|
||||
my %dev_state_format = (
|
||||
"PowerSwitch" => ["on", ""],
|
||||
"Dimmer" => ["on", "", "brightness", "B: "],
|
||||
"EnvSensor" => [ # Results in "T: 23.4 H: 27.3 Baro: 978.34 B: 45"
|
||||
"PowerSwitch" => ["port", "Port: "],
|
||||
"Dimmer" => ["on", "", "brightness", "B: "],
|
||||
"EnvSensor" => [ # Results in "T: 23.4 H: 27.3 Baro: 978.34 B: 45"
|
||||
"temperature", "T: ",
|
||||
"humidity", "H: ",
|
||||
"barometric_pressure", "Baro: ",
|
||||
"brightness", "B: ",
|
||||
"distance", "D: ",
|
||||
"dins", "Din: ",
|
||||
"port", "Port: ",
|
||||
"ains", "Ain: "
|
||||
],
|
||||
"RGB_Dimmer" => [
|
||||
"color", "Color: "
|
||||
]
|
||||
"RGBDimmer" => [
|
||||
"color", "Color: ",
|
||||
"brightness", "Brightness: "
|
||||
],
|
||||
"SoilMoistureMeter" => ["humidity", "H: "]
|
||||
);
|
||||
|
||||
# Supported set commands
|
||||
@ -71,19 +76,23 @@ my %dev_state_format = (
|
||||
# use "cmd_name:cmd_additional_info"
|
||||
# cmd_additional_info: Description available at http://www.fhemwiki.de/wiki/DevelopmentModuleIntro#X_Set
|
||||
my %sets = (
|
||||
"PowerSwitch" => "on:noArg off:noArg toggle:noArg statusRequest:noArg " .
|
||||
# Used from SetExtensions.pm
|
||||
"blink on-for-timer on-till off-for-timer off-till intervals",
|
||||
"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" => "",
|
||||
"RGB_Dimmer" => "Color " .
|
||||
"ColorAnimation",
|
||||
"Custom" => "PowerSwitch.SwitchState " .
|
||||
"PowerSwitch.SwitchStateExt " .
|
||||
"Dimmer.Brightness " .
|
||||
"Dimmer.Animation"
|
||||
"PowerSwitch" => "on:noArg off:noArg toggle:noArg statusRequest:noArg " .
|
||||
# Used from SetExtensions.pm
|
||||
"blink on-for-timer on-till off-for-timer off-till intervals " .
|
||||
"DigitalPort " .
|
||||
"DigitalPortTimeout " .
|
||||
"DigitalPin " .
|
||||
"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 " .
|
||||
"Dimmer.Brightness:slider,0,1,100",
|
||||
"SoilMoistureMeter" => "",
|
||||
"Custom" => "Dimmer.Brightness " .
|
||||
"Dimmer.Animation"
|
||||
);
|
||||
|
||||
# Supported get commands
|
||||
@ -92,27 +101,10 @@ 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",
|
||||
"RGB_Dimmer" => "",
|
||||
"RGBDimmer" => "",
|
||||
"Custom" => ""
|
||||
);
|
||||
|
||||
# Hashtable for automatic device type assignment
|
||||
# Format:
|
||||
# "MessageGroupName:MessageName" => "Auto Device Type"
|
||||
my %auto_devtype = (
|
||||
"Weather.Temperature" => "EnvSensor",
|
||||
"Weather.HumidityTemperature" => "EnvSensor",
|
||||
"Weather.BarometricPressureTemperature" => "EnvSensor",
|
||||
"Environment.Brightness" => "EnvSensor",
|
||||
"Environment.Distance" => "EnvSensor",
|
||||
"GPIO.DigitalPin" => "EnvSensor",
|
||||
"GPIO.AnalogPin" => "EnvSensor",
|
||||
"PowerSwitch.SwitchState" => "PowerSwitch",
|
||||
"Dimmer.Brightness" => "Dimmer",
|
||||
"Dimmer.Color" => "RGB_Dimmer",
|
||||
"Dimmer.ColorAnimation" => "RGB_Dimmer"
|
||||
);
|
||||
|
||||
sub SHCdev_Parse($$);
|
||||
|
||||
#####################################
|
||||
@ -120,7 +112,7 @@ 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";
|
||||
@ -130,7 +122,7 @@ sub SHCdev_Initialize($)
|
||||
." readonly:1"
|
||||
." forceOn:1"
|
||||
." $readingFnAttributes"
|
||||
." devtype:EnvSensor,Dimmer,PowerSwitch,RGB_Dimmer";
|
||||
." devtype:EnvSensor,Dimmer,PowerSwitch,RGBDimmer,SoilMoistureMeter";
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -198,7 +190,7 @@ 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 "";
|
||||
}
|
||||
|
||||
@ -210,7 +202,7 @@ sub SHCdev_Parse($$)
|
||||
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";
|
||||
}
|
||||
|
||||
@ -234,9 +226,6 @@ sub SHCdev_Parse($$)
|
||||
given ($msggroupname) {
|
||||
when ('Generic') {
|
||||
given ($msgname) {
|
||||
when ('BatteryStatus') {
|
||||
readingsBulkUpdate($rhash, "battery", $parser->getField("Percentage"));
|
||||
}
|
||||
when ('Version') {
|
||||
my $major = $parser->getField("Major");
|
||||
my $minor = $parser->getField("Minor");
|
||||
@ -244,22 +233,61 @@ sub SHCdev_Parse($$)
|
||||
my $vhash = $parser->getField("Hash");
|
||||
|
||||
readingsBulkUpdate($rhash, "version", "$major.$minor.$patch-$vhash");
|
||||
}
|
||||
when ('DeviceInfo') {
|
||||
my $devtype = $parser->getField("DeviceType");
|
||||
my $major = $parser->getField("VersionMajor");
|
||||
my $minor = $parser->getField("VersionMinor");
|
||||
my $patch = $parser->getField("VersionPatch");
|
||||
my $vhash = $parser->getField("VersionHash");
|
||||
|
||||
# Assign device type
|
||||
my $devtypeOld = AttrVal( $rname, "devtype", undef );
|
||||
if (!defined($devtypeOld)) {
|
||||
$attr{$rname}{devtype} = $devtype;
|
||||
Log3 $name, 3, "$rname: Assign device type = " . $attr{$rname}{devtype};
|
||||
}
|
||||
|
||||
readingsBulkUpdate($rhash, "version", "$major.$minor.$patch-$vhash");
|
||||
}
|
||||
when ('BatteryStatus') {
|
||||
readingsBulkUpdate($rhash, "battery", $parser->getField("Percentage"));
|
||||
}
|
||||
}
|
||||
}
|
||||
when ('GPIO') {
|
||||
given ($msgname) {
|
||||
when ('DigitalPin') {
|
||||
when ('DigitalPortTimeout') {
|
||||
my $pins = "";
|
||||
for (my $i = 0 ; $i < 8 ; $i++) {
|
||||
my $pinx = $parser->getField("On", $i);
|
||||
my $timeoutx = $parser->getField("TimeoutSec", $i);
|
||||
my $channel = $i + 1;
|
||||
if ($channel == 1)
|
||||
{
|
||||
readingsBulkUpdate($rhash, "on", $pinx);
|
||||
}
|
||||
readingsBulkUpdate($rhash, "pin" . $channel, $pinx);
|
||||
readingsBulkUpdate($rhash, "timeout" . $channel, $timeoutx);
|
||||
$pins .= $pinx;
|
||||
}
|
||||
readingsBulkUpdate($rhash, "port", $pins);
|
||||
}
|
||||
when ('DigitalPort') {
|
||||
my $pins = "";
|
||||
for (my $i = 0 ; $i < 8 ; $i++) {
|
||||
my $pinx = $parser->getField("On", $i);
|
||||
my $channel = $i + 1;
|
||||
readingsBulkUpdate($rhash, "din" . $channel, $pinx);
|
||||
if ($channel == 1)
|
||||
{
|
||||
readingsBulkUpdate($rhash, "on", $pinx);
|
||||
}
|
||||
readingsBulkUpdate($rhash, "pin" . $channel, $pinx);
|
||||
$pins .= $pinx;
|
||||
}
|
||||
readingsBulkUpdate($rhash, "dins", $pins);
|
||||
readingsBulkUpdate($rhash, "port", $pins);
|
||||
}
|
||||
when ('AnalogPin') {
|
||||
when ('AnalogPort') {
|
||||
my $pins = "";
|
||||
for (my $i = 0 ; $i < 5 ; $i++) {
|
||||
my $pinx_on = $parser->getField("On", $i);
|
||||
@ -294,6 +322,11 @@ sub SHCdev_Parse($$)
|
||||
readingsBulkUpdate($rhash, "barometric_pressure", $bar);
|
||||
readingsBulkUpdate($rhash, "temperature", $tmp);
|
||||
}
|
||||
when ('Humidity') {
|
||||
my $hum = $parser->getField("Humidity") / 10; # parser returns 1/10 percent
|
||||
|
||||
readingsBulkUpdate($rhash, "humidity", $hum);
|
||||
}
|
||||
}
|
||||
}
|
||||
when ('Environment') {
|
||||
@ -308,17 +341,6 @@ sub SHCdev_Parse($$)
|
||||
}
|
||||
}
|
||||
}
|
||||
when ('PowerSwitch') {
|
||||
given ($msgname) {
|
||||
when ('SwitchState') {
|
||||
my $on = $parser->getField("On");
|
||||
my $timeout = $parser->getField("TimeoutSec");
|
||||
|
||||
readingsBulkUpdate($rhash, "on", $on);
|
||||
readingsBulkUpdate($rhash, "timeout", $timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
when ('Dimmer') {
|
||||
given ($msgname) {
|
||||
when ('Brightness') {
|
||||
@ -348,13 +370,6 @@ sub SHCdev_Parse($$)
|
||||
}
|
||||
}
|
||||
|
||||
# Autoassign device type
|
||||
my $devtype = AttrVal( $rname, "devtype", undef );
|
||||
if (!defined($devtype) && (defined($auto_devtype{"$msggroupname.$msgname"}))) {
|
||||
$attr{$rname}{devtype} = $auto_devtype{"$msggroupname.$msgname"};
|
||||
Log3 $name, 3, "$rname: Autoassign device type = " . $attr{$rname}{devtype};
|
||||
}
|
||||
|
||||
# If the devtype is defined add, if not already done, the according webCmds and devStateIcons
|
||||
my $devtype2 = AttrVal( $rname, "devtype", undef );
|
||||
if (defined($devtype2)) {
|
||||
@ -446,23 +461,56 @@ sub SHCdev_Set($@)
|
||||
# is able to do this as well. Even more it supports intervals, off-for-timer, off-till ...
|
||||
|
||||
if ($cmd eq 'toggle') {
|
||||
$cmd = ReadingsVal($name, "state", "on") eq "off" ? "on" : "off";
|
||||
$cmd = ReadingsVal($name, "on", "0") eq "0" ? "on" : "off";
|
||||
}
|
||||
|
||||
if (!$readonly && $cmd eq 'off') {
|
||||
readingsSingleUpdate($hash, "state", "set-$cmd", 1);
|
||||
$parser->initPacket("PowerSwitch", "SwitchState", "SetGet");
|
||||
$parser->setField("PowerSwitch", "SwitchState", "TimeoutSec", 0);
|
||||
$parser->setField("PowerSwitch", "SwitchState", "On", 0);
|
||||
$parser->initPacket("GPIO", "DigitalPin", "SetGet");
|
||||
$parser->setField("GPIO", "DigitalPin", "Pos", 0);
|
||||
$parser->setField("GPIO", "DigitalPin", "On", 0);
|
||||
SHCdev_Send($hash);
|
||||
} elsif (!$readonly && $cmd eq 'on') {
|
||||
readingsSingleUpdate($hash, "state", "set-$cmd", 1);
|
||||
$parser->initPacket("PowerSwitch", "SwitchState", "SetGet");
|
||||
$parser->setField("PowerSwitch", "SwitchState", "TimeoutSec", 0);
|
||||
$parser->setField("PowerSwitch", "SwitchState", "On", 1);
|
||||
$parser->initPacket("GPIO", "DigitalPin", "SetGet");
|
||||
$parser->setField("GPIO", "DigitalPin", "Pos", 0);
|
||||
$parser->setField("GPIO", "DigitalPin", "On", 1);
|
||||
SHCdev_Send($hash);
|
||||
} elsif ($cmd eq 'statusRequest') {
|
||||
$parser->initPacket("PowerSwitch", "SwitchState", "Get");
|
||||
$parser->initPacket("GPIO", "DigitalPin", "Get");
|
||||
SHCdev_Send($hash);
|
||||
} elsif ($cmd eq 'DigitalPort') {
|
||||
$parser->initPacket("GPIO", "DigitalPort", "SetGet");
|
||||
# if not enough (less than 8) pinbits are available use zero as default
|
||||
my $pinbits = $arg . "00000000";
|
||||
for (my $i = 0 ; $i < 8 ; $i = $i + 1) {
|
||||
$parser->setField("GPIO", "DigitalPort", "On", substr($pinbits, $i , 1), $i);
|
||||
}
|
||||
SHCdev_Send($hash);
|
||||
} elsif ($cmd eq 'DigitalPortTimeout') { # TODO implement correctly
|
||||
$parser->initPacket("GPIO", "DigitalPortTimeout", "SetGet");
|
||||
# if not enough (less than 8) pinbits are available use zero as default
|
||||
my $pinbits = $arg . "00000000";
|
||||
for (my $i = 0 ; $i < 8 ; $i = $i + 1) {
|
||||
my $pintimeout = "0"; # default value for timeout
|
||||
if (exists $aa[$i + 2]) {
|
||||
$pintimeout = $aa[$i + 2];
|
||||
}
|
||||
Log3 $name, 3, "$name: $i: Pin: " . substr($pinbits, $i , 1) . " Timeout: $pintimeout";
|
||||
$parser->setField("GPIO", "DigitalPortTimeout", "On", substr($pinbits, $i , 1), $i);
|
||||
$parser->setField("GPIO", "DigitalPortTimeout", "TimeoutSec", $pintimeout, $i);
|
||||
}
|
||||
SHCdev_Send($hash);
|
||||
} elsif ($cmd eq 'DigitalPin') {
|
||||
$parser->initPacket("GPIO", "DigitalPin", "SetGet");
|
||||
$parser->setField("GPIO", "DigitalPin", "Pos", $arg);
|
||||
$parser->setField("GPIO", "DigitalPin", "On", $arg2);
|
||||
SHCdev_Send($hash);
|
||||
} elsif ($cmd eq 'DigitalPinTimeout') {
|
||||
$parser->initPacket("GPIO", "DigitalPinTimeout", "SetGet");
|
||||
$parser->setField("GPIO", "DigitalPinTimeout", "Pos", $arg);
|
||||
$parser->setField("GPIO", "DigitalPinTimeout", "On", $arg2);
|
||||
$parser->setField("GPIO", "DigitalPinTimeout", "TimeoutSec", $arg3);
|
||||
SHCdev_Send($hash);
|
||||
} else {
|
||||
return SetExtensions($hash, "", $name, @aa);
|
||||
@ -519,7 +567,7 @@ sub SHCdev_Set($@)
|
||||
return SetExtensions($hash, "", $name, @aa);
|
||||
}
|
||||
}
|
||||
when ('RGB_Dimmer') {
|
||||
when ('RGBDimmer') {
|
||||
if ($cmd eq 'Color') {
|
||||
#TODO Verify argument values
|
||||
my $color = $arg;
|
||||
@ -562,6 +610,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);
|
||||
}
|
||||
@ -605,10 +663,10 @@ sub SHCdev_Get($@)
|
||||
}
|
||||
elsif ($arg eq "all")
|
||||
{
|
||||
if ( defined($hash->{READINGS}{dins})
|
||||
&& defined($hash->{READINGS}{dins}{VAL}))
|
||||
if ( defined($hash->{READINGS}{port})
|
||||
&& defined($hash->{READINGS}{port}{VAL}))
|
||||
{
|
||||
return "$name.dins => " . $hash->{READINGS}{dins}{VAL};
|
||||
return "$name.port => " . $hash->{READINGS}{port}{VAL};
|
||||
}
|
||||
return "Error: \"input all\" readings not yet available or not supported by device";
|
||||
}
|
||||
@ -676,7 +734,7 @@ sub SHCdev_Send($)
|
||||
<h3>SHCdev</h3>
|
||||
<ul>
|
||||
SHC is the device module that supports several device types available
|
||||
at <a href="http://http://www.smarthomatic.org">www.smarthomatic.org</a>.<br><br>
|
||||
at <a href="http://www.smarthomatic.org">www.smarthomatic.org</a>.<br><br>
|
||||
|
||||
These device are connected to the FHEM server through the SHC base station (<a href="#SHC">SHC</a>).<br><br>
|
||||
Currently supported are:<br>
|
||||
@ -684,6 +742,8 @@ sub SHCdev_Send($)
|
||||
<li>EnvSensor</li>
|
||||
<li>PowerSwitch</li>
|
||||
<li>Dimmer</li>
|
||||
<li>RGBDimmer</li>
|
||||
<li>SoilMoistureMeter</li>
|
||||
</ul><br>
|
||||
|
||||
<a name="SHCdev_Define"></a>
|
||||
@ -707,10 +767,10 @@ sub SHCdev_Send($)
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
<li>on<br>
|
||||
Supported by Dimmer and PowerSwitch.
|
||||
Supported by Dimmer and PowerSwitch (on always refers to pin1).
|
||||
</li><br>
|
||||
<li>off<br>
|
||||
Supported by Dimmer, PowerSwitch.
|
||||
Supported by Dimmer and PowerSwitch (off always refers to pin1).
|
||||
</li><br>
|
||||
<li>pct <0..100><br>
|
||||
Sets the brightness in percent. Supported by Dimmer.
|
||||
@ -725,12 +785,36 @@ sub SHCdev_Send($)
|
||||
<li>Color <ColorNumber><br>
|
||||
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 RGB_Dimmer.
|
||||
Supported by RGBDimmer.
|
||||
</li><br>
|
||||
<li>ColorAnimation <Repeat> <AutoReverse> <Time0> <ColorNumber0> <Time1> <ColorNumber1> ... 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>
|
||||
The color palette can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
|
||||
Supported by RGB_Dimmer.
|
||||
Supported by RGBDimmer.
|
||||
</li><br>
|
||||
<li>DigitalPin <Pos> <On><br>
|
||||
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 <Pos> <On> <Timeout><br>
|
||||
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 <On><br>
|
||||
<On><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>
|
||||
Supported by PowerSwitch.
|
||||
</li><br>
|
||||
<li>DigitalPortTimeout <On> <Timeout0> .. <Timeout7><br>
|
||||
<On><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>
|
||||
<Timeout0> .. <Timeout7><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>
|
||||
Supported by PowerSwitch.
|
||||
</li><br>
|
||||
<li><a href="#setExtensions"> set extensions</a><br>
|
||||
Supported by Dimmer and PowerSwitch.</li>
|
||||
@ -764,7 +848,7 @@ sub SHCdev_Send($)
|
||||
<ul>
|
||||
<li>devtype<br>
|
||||
The device type determines the command set, default web commands and the
|
||||
default devStateicon. Currently supported are: EnvSensor, Dimmer, PowerSwitch, RGB_Dimmer.<br><br>
|
||||
default devStateicon. Currently supported are: EnvSensor, Dimmer, PowerSwitch, RGBDimmer, SoilMoistureMeter.<br><br>
|
||||
|
||||
Note: If the device is not set manually, it will be determined automatically
|
||||
on reception of a device type specific message. For example: If a
|
||||
|
@ -150,19 +150,16 @@ sub getInt($$$)
|
||||
{
|
||||
my ($byteArrayRef, $offset, $length_bits) = @_;
|
||||
|
||||
# FIX ME! DOES NOT WORK WITH NEGATIVE VALUES!
|
||||
|
||||
$x = getUInt($byteArrayRef, $offset, $length_bits);
|
||||
|
||||
# If MSB is 1 (value is negative interpreted as signed int),
|
||||
# set all higher bits also to 1.
|
||||
if ((($x >> ($length_bits - 1)) & 1) == 1) {
|
||||
$x = $x | ~((1 << ($length_bits - 1)) - 1);
|
||||
if ($x >= 2 ** ($length_bits - 1))
|
||||
{
|
||||
$x = $x - 2 ** $length_bits;
|
||||
}
|
||||
|
||||
$y = $x;
|
||||
# DEBUG print "UInt = " . $x . ", length_bits = " . length_bits . "\r\n";
|
||||
|
||||
return $y;
|
||||
return $x;
|
||||
}
|
||||
|
||||
# ----------- UIntValue class -----------
|
||||
@ -219,14 +216,14 @@ sub getValue
|
||||
{
|
||||
my ($self, $byteArrayRef, $index) = @_;
|
||||
|
||||
return SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits});
|
||||
return SHC_util::getInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits});
|
||||
}
|
||||
|
||||
sub setValue
|
||||
{
|
||||
my ($self, $byteArrayRef, $value, $index) = @_;
|
||||
|
||||
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value);
|
||||
SHC_util::setInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value);
|
||||
}
|
||||
|
||||
# ----------- BoolValue class -----------
|
||||
|
@ -3,7 +3,7 @@
|
||||
##########################################################################
|
||||
# This file is part of the smarthomatic module for FHEM.
|
||||
#
|
||||
# Copyright (c) 2014 Uwe Freese
|
||||
# Copyright (c) 2014, 2015 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 = ();
|
||||
@ -250,10 +253,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 +314,9 @@ sub getMessageData
|
||||
$res .= sprintf("%02X", $_);
|
||||
}
|
||||
|
||||
# strip trailing zeros (pairwise)
|
||||
$res =~ s/(00)+$//;
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
return $self->{_messageData};
|
||||
@ -365,8 +371,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 +388,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;
|
||||
|
@ -190,7 +190,7 @@
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<Validity>deprecated</Validity>
|
||||
<UIntValue>
|
||||
<ID>Major</ID>
|
||||
<Description>Different major version means incompatible changes.</Description>
|
||||
@ -220,6 +220,76 @@
|
||||
<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>
|
||||
<MessageID>2</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</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>
|
||||
<Bits>8</Bits>
|
||||
<Element>
|
||||
<Value>0</Value>
|
||||
<Name>BaseStation</Name>
|
||||
</Element>
|
||||
<Element>
|
||||
<Value>20</Value>
|
||||
<Name>EnvSensor</Name>
|
||||
</Element>
|
||||
<Element>
|
||||
<Value>40</Value>
|
||||
<Name>PowerSwitch</Name>
|
||||
</Element>
|
||||
<Element>
|
||||
<Value>50</Value>
|
||||
<Name>RGBDimmer</Name>
|
||||
</Element>
|
||||
<Element>
|
||||
<Value>60</Value>
|
||||
<Name>Dimmer</Name>
|
||||
</Element>
|
||||
<Element>
|
||||
<Value>70</Value>
|
||||
<Name>SoilMoistureMeter</Name>
|
||||
</Element>
|
||||
<Element>
|
||||
<Value>80</Value>
|
||||
<Name>Thermostat</Name>
|
||||
</Element>
|
||||
</EnumValue>
|
||||
<UIntValue>
|
||||
<ID>VersionMajor</ID>
|
||||
<Description>Different major version means incompatible changes.</Description>
|
||||
<Bits>8</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>255</MaxVal>
|
||||
</UIntValue>
|
||||
<UIntValue>
|
||||
<ID>VersionMinor</ID>
|
||||
<Description>Different minor number means new functionality without breaking compatibility.</Description>
|
||||
<Bits>8</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>255</MaxVal>
|
||||
</UIntValue>
|
||||
<UIntValue>
|
||||
<ID>VersionPatch</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>VersionHash</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>BatteryStatus</Name>
|
||||
<Description>Tells the current battery status in percent. Please note that the "Get" may not be answered because a device does not listen to requests.</Description>
|
||||
@ -242,8 +312,8 @@
|
||||
<Description>This group contains messages for general I/O functions. The meaning of the values is not known to the SHC devices. It depends on the connected parts (e.g. switches). The values have to be processed by the user/server software appropriately.</Description>
|
||||
<MessageGroupID>1</MessageGroupID>
|
||||
<Message>
|
||||
<Name>DigitalPin</Name>
|
||||
<Description>This is the state of up to 8 pins.</Description>
|
||||
<Name>DigitalPort</Name>
|
||||
<Description>This is the state of the complete digital port, containing up to 8 pins.</Description>
|
||||
<MessageID>1</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>1</MessageType>
|
||||
@ -261,8 +331,8 @@
|
||||
</Array>
|
||||
</Message>
|
||||
<Message>
|
||||
<Name>AnalogPin</Name>
|
||||
<Description>This is the voltage of up to 8 ADC channels. The ATMega328 in the PDIP package has only 6 ADCs and one ADC may be blocked by the battery voltage measurement, so there may be less than 8 ADC values reported depending on the device and configuration.</Description>
|
||||
<Name>DigitalPortTimeout</Name>
|
||||
<Description>This is the state of the complete digital port, containing up to 8 pins, including a timeout value per pin.</Description>
|
||||
<MessageID>2</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>1</MessageType>
|
||||
@ -271,15 +341,91 @@
|
||||
<MessageType>9</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<Array>
|
||||
<Length>8</Length>
|
||||
<BoolValue>
|
||||
<ID>On</ID>
|
||||
<Description>Tells if the pin is on (at high level) or not (low level).</Description>
|
||||
</BoolValue>
|
||||
<UIntValue>
|
||||
<ID>TimeoutSec</ID>
|
||||
<Description>The time after which the switch is automatically toggled again. Use 0 to disable this.</Description>
|
||||
<Bits>16</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>65535</MaxVal>
|
||||
</UIntValue>
|
||||
</Array>
|
||||
</Message>
|
||||
<Message>
|
||||
<Name>DigitalPin</Name>
|
||||
<Description>This represents the state of one pin of the digital port.</Description>
|
||||
<MessageID>5</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>1</MessageType>
|
||||
<MessageType>2</MessageType>
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>9</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<UIntValue>
|
||||
<ID>Pos</ID>
|
||||
<Description>The number of the pin in the port.</Description>
|
||||
<Bits>3</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>7</MaxVal>
|
||||
</UIntValue>
|
||||
<BoolValue>
|
||||
<ID>On</ID>
|
||||
<Description>Tells if the pin is on (at high level) or not (low level).</Description>
|
||||
</BoolValue>
|
||||
</Message>
|
||||
<Message>
|
||||
<Name>DigitalPinTimeout</Name>
|
||||
<Description>This represents the state of one pin of the digital port, including a timeout value.</Description>
|
||||
<MessageID>6</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>1</MessageType>
|
||||
<MessageType>2</MessageType>
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>9</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<UIntValue>
|
||||
<ID>Pos</ID>
|
||||
<Description>The number of the pin in the port.</Description>
|
||||
<Bits>3</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>7</MaxVal>
|
||||
</UIntValue>
|
||||
<BoolValue>
|
||||
<ID>On</ID>
|
||||
<Description>Tells if the pin is on (at high level) or not (low level).</Description>
|
||||
</BoolValue>
|
||||
<UIntValue>
|
||||
<ID>TimeoutSec</ID>
|
||||
<Description>The time after which the switch is automatically toggled again. Use 0 to disable this.</Description>
|
||||
<Bits>16</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>65535</MaxVal>
|
||||
</UIntValue>
|
||||
</Message>
|
||||
<Message>
|
||||
<Name>AnalogPort</Name>
|
||||
<Description>This is the voltage of up to 8 ADC channels. The ATMega328 in the PDIP package has only 6 ADCs and one ADC may be blocked by the battery voltage measurement, so there may be less than 8 ADC values reported depending on the device and configuration.</Description>
|
||||
<MessageID>10</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>1</MessageType>
|
||||
<MessageType>2</MessageType>
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>9</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<Array>
|
||||
<Length>8</Length>
|
||||
<BoolValue>
|
||||
<ID>On</ID>
|
||||
<Description>Tells if the pin is on (voltage over trigger threshold) or not.</Description>
|
||||
</BoolValue>
|
||||
</Array>
|
||||
<Array>
|
||||
<Length>8</Length>
|
||||
<UIntValue>
|
||||
<ID>Voltage</ID>
|
||||
<Description>This is the voltage level in mV.</Description>
|
||||
@ -356,6 +502,22 @@
|
||||
<MaxVal>32767</MaxVal>
|
||||
</IntValue>
|
||||
</Message>
|
||||
<Message>
|
||||
<Name>Humidity</Name>
|
||||
<Description>This is a message containing humidity.</Description>
|
||||
<MessageID>4</MessageID>
|
||||
<MessageType>0</MessageType>
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<UIntValue>
|
||||
<ID>Humidity</ID>
|
||||
<Description>relative humidity permill, 0..1000 (other values not defined)</Description>
|
||||
<Bits>10</Bits>
|
||||
<MinVal>0</MinVal>
|
||||
<MaxVal>1000</MaxVal>
|
||||
</UIntValue>
|
||||
</Message>
|
||||
</MessageGroup>
|
||||
<MessageGroup>
|
||||
<Name>Environment</Name>
|
||||
@ -408,7 +570,7 @@
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>9</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<Validity>deprecated</Validity>
|
||||
<BoolValue>
|
||||
<ID>On</ID>
|
||||
<Description>Tells if the switch is on (active).</Description>
|
||||
@ -431,7 +593,7 @@
|
||||
<MessageType>8</MessageType>
|
||||
<MessageType>9</MessageType>
|
||||
<MessageType>10</MessageType>
|
||||
<Validity>test</Validity>
|
||||
<Validity>deprecated</Validity>
|
||||
<Array>
|
||||
<Length>8</Length>
|
||||
<BoolValue>
|
||||
|
Loading…
Reference in New Issue
Block a user