2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-14 05:46:35 +00:00

SHC: add support for analog inputs (EnvSensor) and new device RGB_Dimmer

git-svn-id: https://svn.fhem.de/fhem/trunk@6580 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rr2000 2014-09-20 09:50:45 +00:00
parent 7d86d6c032
commit 8e5254396b
6 changed files with 418 additions and 113 deletions

View File

@ -1,5 +1,7 @@
# 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.
- feature: SHC: support for analog inputs (EnvSensor) and new device
RGB_Dimmer added (rr2000)
- feature: PRESENCE: MAC address support for mode fritzbox (by Markus M.)
- bugfix: PRESENCE: fixing presence detection in mode fritzbox with new
Fritz!OS 6.20 (by Markus M.)

View File

@ -35,13 +35,15 @@ 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
"EnvSensor" => undef,
"RGB_Dimmer" => undef
);
my %web_cmds = (
"PowerSwitch" => "on:off:toggle:statusRequest",
"Dimmer" => "on:off:statusRequest",
"EnvSensor" => undef
"EnvSensor" => undef,
"RGB_Dimmer" => undef
);
# Array format: [ reading1, str_format1, reading2, str_format2 ... ]
@ -50,12 +52,17 @@ my %web_cmds = (
my %dev_state_format = (
"PowerSwitch" => ["on", ""],
"Dimmer" => ["on", "", "brightness", "B: "],
"EnvSensor" => [ # Results in "T: 23.4 H: 27.3 Baro: 978.34 B: 45"
"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: "
"distance", "D: ",
"dins", "Din: ",
"ains", "Ain: "
],
"RGB_Dimmer" => [
"color", "Color: "
]
);
@ -71,6 +78,8 @@ my %sets = (
# 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 " .
@ -82,7 +91,8 @@ my %sets = (
my %gets = (
"PowerSwitch" => "",
"Dimmer" => "",
"EnvSensor" => "input:all,1,2,3,4,5,6,7,8 ",
"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" => "",
"Custom" => ""
);
@ -96,8 +106,11 @@ my %auto_devtype = (
"Environment.Brightness" => "EnvSensor",
"Environment.Distance" => "EnvSensor",
"GPIO.DigitalPin" => "EnvSensor",
"GPIO.AnalogPin" => "EnvSensor",
"PowerSwitch.SwitchState" => "PowerSwitch",
"Dimmer.Brightness" => "Dimmer"
"Dimmer.Brightness" => "Dimmer",
"Dimmer.Color" => "RGB_Dimmer",
"Dimmer.ColorAnimation" => "RGB_Dimmer"
);
sub SHCdev_Parse($$);
@ -117,7 +130,7 @@ sub SHCdev_Initialize($)
." readonly:1"
." forceOn:1"
." $readingFnAttributes"
." devtype:EnvSensor,Dimmer,PowerSwitch";
." devtype:EnvSensor,Dimmer,PowerSwitch,RGB_Dimmer";
}
#####################################
@ -241,10 +254,22 @@ sub SHCdev_Parse($$)
for (my $i = 0 ; $i < 8 ; $i++) {
my $pinx = $parser->getField("On", $i);
my $channel = $i + 1;
readingsBulkUpdate($rhash, "pin" . $channel, $pinx);
readingsBulkUpdate($rhash, "din" . $channel, $pinx);
$pins .= $pinx;
}
readingsBulkUpdate($rhash, "pins", $pins);
readingsBulkUpdate($rhash, "dins", $pins);
}
when ('AnalogPin') {
my $pins = "";
for (my $i = 0 ; $i < 5 ; $i++) {
my $pinx_on = $parser->getField("On", $i);
my $pinx_volt = $parser->getField("Voltage", $i);
my $channel = $i + 1;
readingsBulkUpdate($rhash, "ain" . $channel, $pinx_on);
readingsBulkUpdate($rhash, "ain_volt" . $channel, $pinx_volt);
$pins .= $pinx_on;
}
readingsBulkUpdate($rhash, "ains", $pins);
}
}
}
@ -303,6 +328,22 @@ sub SHCdev_Parse($$)
readingsBulkUpdate($rhash, "on", $on);
readingsBulkUpdate($rhash, "brightness", $brightness);
}
when ('Color') {
my $color = $parser->getField("Color");
readingsBulkUpdate($rhash, "color", $color);
}
when ('ColorAnimation') {
my $repeat = $parser->getField("Repeat");
my $autoreverse = $parser->getField("AutoReverse");
readingsBulkUpdate($rhash, "repeat", $repeat);
readingsBulkUpdate($rhash, "autoreverse", $autoreverse);
for (my $i = 0 ; $i < 10 ; $i = $i + 1) {
my $time = $parser->getField("Time" , $i);
my $color = $parser->getField("Color", $i);
readingsBulkUpdate($rhash, "time$i", $time);
readingsBulkUpdate($rhash, "color$i", $color);
}
}
}
}
}
@ -478,6 +519,53 @@ sub SHCdev_Set($@)
return SetExtensions($hash, "", $name, @aa);
}
}
when ('RGB_Dimmer') {
if ($cmd eq 'Color') {
#TODO Verify argument values
my $color = $arg;
# DEBUG
# Log3 $name, 3, "$name: Color args: $arg, $arg2, $arg3, $arg4";
readingsSingleUpdate($hash, "state", "set-color:$color", 1);
$parser->initPacket("Dimmer", "Color", "SetGet");
$parser->setField("Dimmer", "Color", "Color", $color);
SHCdev_Send($hash);
} elsif ($cmd eq 'ColorAnimation') {
#TODO Verify argument values
$parser->initPacket("Dimmer", "ColorAnimation", "SetGet");
$parser->setField("Dimmer", "ColorAnimation", "Repeat", $arg);
$parser->setField("Dimmer", "ColorAnimation", "AutoReverse", $arg2);
my $curtime = 0;
my $curcolor = 0;
# Iterate over all given command line parameters and set Time and Color
# accordingly. Fill the remaining values with zero.
for (my $i = 0 ; $i < 10 ; $i = $i + 1) {
if (!defined($aa[($i * 2) + 3])) {
$curtime = 0;
} else {
$curtime = $aa[($i * 2) + 3];
}
if (!defined($aa[($i * 2) + 4])) {
$curcolor = 0;
} else {
$curcolor = $aa[($i * 2) + 4];
}
# DEBUG
# Log3 $name, 3, "$name: Nr: $i Time: $curtime Color: $curcolor";
$parser->setField("Dimmer", "ColorAnimation", "Time" , $curtime, $i);
$parser->setField("Dimmer", "ColorAnimation", "Color", $curcolor, $i);
}
readingsSingleUpdate($hash, "state", "set-coloranimation", 1);
SHCdev_Send($hash);
} else {
return SetExtensions($hash, "", $name, @aa);
}
}
}
return undef;
@ -505,9 +593,9 @@ sub SHCdev_Get($@)
given ($devtype) {
when ('EnvSensor') {
if ($cmd eq 'input') {
if ($cmd eq 'din') {
if ($arg =~ /[1-8]/) {
my $channel = "pin" . $arg;
my $channel = "din" . $arg;
if ( defined($hash->{READINGS}{$channel})
&& defined($hash->{READINGS}{$channel}{VAL}))
{
@ -517,14 +605,45 @@ sub SHCdev_Get($@)
}
elsif ($arg eq "all")
{
if ( defined($hash->{READINGS}{pins})
&& defined($hash->{READINGS}{pins}{VAL}))
if ( defined($hash->{READINGS}{dins})
&& defined($hash->{READINGS}{dins}{VAL}))
{
return "$name.pins => " . $hash->{READINGS}{pins}{VAL};
return "$name.dins => " . $hash->{READINGS}{dins}{VAL};
}
return "Error: \"input all\" readings not yet available or not supported by device";
}
}
if ($cmd eq 'ain') {
if ($arg =~ /[1-5]/) {
my $channel = "ain" . $arg;
if ( defined($hash->{READINGS}{$channel})
&& defined($hash->{READINGS}{$channel}{VAL}))
{
return "$name.$channel => " . $hash->{READINGS}{$channel}{VAL};
}
return "Error: \"input " . $channel . "\" readings not yet available or not supported by device";
}
elsif ($arg eq "all")
{
if ( defined($hash->{READINGS}{ains})
&& defined($hash->{READINGS}{ains}{VAL}))
{
return "$name.ains => " . $hash->{READINGS}{ains}{VAL};
}
return "Error: \"input all\" readings not yet available or not supported by device";
}
}
if ($cmd eq 'ain_volt') {
if ($arg =~ /[1-5]/) {
my $channel = "ain_volt" . $arg;
if ( defined($hash->{READINGS}{$channel})
&& defined($hash->{READINGS}{$channel}{VAL}))
{
return "$name.$channel => " . $hash->{READINGS}{$channel}{VAL};
}
return "Error: \"input " . $channel . "\" readings not yet available or not supported by device";
}
}
# This return is required to provide the get commands in the web interface
return "Unknown argument $cmd, choose one of " . $gets{$devtype};
@ -603,6 +722,16 @@ sub SHCdev_Send($)
<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>
The color palette can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
Supported by RGB_Dimmer.
</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>
The color palette can be found <a href="http://www.smarthomatic.org/devices/rgb_dimmer.html">here</a>
Supported by RGB_Dimmer.
</li><br>
<li><a href="#setExtensions"> set extensions</a><br>
Supported by Dimmer and PowerSwitch.</li>
</ul><br>
@ -610,8 +739,22 @@ sub SHCdev_Send($)
<a name="SHCdev_Get"></a>
<b>Get</b>
<ul>
<li>input &lt;pin&gt;<br>
Returns the state of the specified pin for pin = 1..8 or the state of all pins for pin = all.
<li>din &lt;pin&gt;<br>
Returns the state of the specified digital input pin for pin = 1..8. Or the state of all pins for pin = all.
Supported by EnvSensor.
</li><br>
<li>ain &lt;pin&gt;<br>
Returns the state of the specified analog input pin for pin = 1..5. Or the state of all pins for pin = all.
If the voltage of the pin is over the specied trigger threshold) it return 1 otherwise 0.
Supported by EnvSensor.
</li><br>
<li>ain &lt;pin&gt;<br>
Returns the state of the specified analog input pin for pin = 1..5. Or the state of all pins for pin = all.
If the voltage of the pin is over the specied trigger threshold) it return 1 otherwise 0.
Supported by EnvSensor.
</li><br>
<li>ain_volt &lt;pin&gt;<br>
Returns the voltage of the specified analog input pin for pin = 1..5 in millivolts, ranging from 0 .. 1100 mV.
Supported by EnvSensor.
</li><br>
</ul><br>
@ -621,7 +764,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.<br><br>
default devStateicon. Currently supported are: EnvSensor, Dimmer, PowerSwitch, RGB_Dimmer.<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

View File

@ -97,6 +97,7 @@ sub setUIntBits($$$$$)
# if length is smaller than 8 bits, get the old value from array
if ($length_bits < 8) {
$b = @$byteArrayRef[$byte];
$b = clear_bits($b, $bit, $length_bits);
}
@ -111,7 +112,7 @@ sub setUInt($$$$)
{
my ($byteArrayRef, $offset, $length_bits, $value) = @_;
my $byte = $offset / 8;
my $byte = int($offset / 8);
my $bit = $offset % 8;
# move bits to the left border
@ -125,7 +126,7 @@ sub setUInt($$$$)
my $len = min($length_bits, 8 - $bit);
my $val8 = get_bits($value, $src_start, $len);
# DEBUG print " Write bits to byte " . $byte . ", dst_start " . $dst_start . ", len " . $len . ", val8 " . $val8 . "\r\n";
# DEBUG print " Write value " . $val8 . " (" . $len . " bits) to byte " . $byte . ", dst_start " . $dst_start . "\r\n";
setUIntBits($byteArrayRef, $byte, $dst_start, $len, $val8);
@ -137,7 +138,7 @@ sub setUInt($$$$)
$val8 = get_bits($value, $src_start, $len);
$byte++;
# DEBUG print " Byte nr. " . $byte . ", src_start " . $src_start . ", len " . $len . ", val8 " . $val8 . "\r\n";
# DEBUG print " Write value " . $val8 . " (" . $len . " bits) from src_start " . $src_start . " to byte " . $byte . ", dst_start " . $dst_start . "\r\n";
setUIntBits($byteArrayRef, $byte, $dst_start, $len, $val8);
@ -172,9 +173,11 @@ sub new
{
my $class = shift;
my $self = {
_id => shift,
_offset => shift,
_bits => shift,
_id => shift,
_offset => shift,
_bits => shift,
_length => shift,
_arrayElementBits => shift
};
bless $self, $class;
return $self;
@ -182,16 +185,16 @@ sub new
sub getValue
{
my ($self, $byteArrayRef) = @_;
my ($self, $byteArrayRef, $index) = @_;
return SHC_util::getUInt($byteArrayRef, $self->{_offset}, $self->{_bits});
return SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits});
}
sub setValue
{
my ($self, $byteArrayRef, $value) = @_;
my ($self, $byteArrayRef, $value, $index) = @_;
SHC_util::setUInt($byteArrayRef, $self->{_offset}, $self->{_bits}, $value);
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value);
}
# ----------- IntValue class -----------
@ -202,9 +205,11 @@ sub new
{
my $class = shift;
my $self = {
_id => shift,
_offset => shift,
_bits => shift,
_id => shift,
_offset => shift,
_bits => shift,
_length => shift,
_arrayElementBits => shift
};
bless $self, $class;
return $self;
@ -212,16 +217,16 @@ sub new
sub getValue
{
my ($self, $byteArrayRef) = @_;
my ($self, $byteArrayRef, $index) = @_;
return SHC_util::getUInt($byteArrayRef, $self->{_offset}, $self->{_bits});
return SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits});
}
sub setValue
{
my ($self, $byteArrayRef, $value) = @_;
my ($self, $byteArrayRef, $value, $index) = @_;
SHC_util::setUInt($byteArrayRef, $self->{_offset}, $self->{_bits}, $value);
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value);
}
# ----------- BoolValue class -----------
@ -232,9 +237,10 @@ sub new
{
my $class = shift;
my $self = {
_id => shift,
_offset => shift,
_length => shift,
_id => shift,
_offset => shift,
_length => shift,
_arrayElementBits => shift
};
bless $self, $class;
return $self;
@ -244,14 +250,15 @@ sub getValue
{
my ($self, $byteArrayRef, $index) = @_;
return SHC_util::getUInt($byteArrayRef, $self->{_offset} + $index, 1) == 1 ? 1 : 0;
return SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, 1) == 1 ? 1 : 0;
}
sub setValue
{
my ($self, $byteArrayRef, $value) = @_;
my ($self, $byteArrayRef, $value, $index) = @_;
return SHC_util::setUInt($byteArrayRef, $self->{_offset}, 1, $value == 0 ? 0 : 1);
return SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, 1,
$value == 0 ? 0 : 1);
}
# ----------- EnumValue class -----------
@ -265,9 +272,11 @@ sub new
{
my $class = shift;
my $self = {
_id => shift,
_offset => shift,
_bits => shift,
_id => shift,
_offset => shift,
_bits => shift,
_length => shift,
_arrayElementBits => shift
};
bless $self, $class;
return $self;
@ -283,18 +292,18 @@ sub addValue
sub getValue
{
my ($self, $byteArrayRef) = @_;
my ($self, $byteArrayRef, $index) = @_;
my $value = SHC_util::getUInt($byteArrayRef, $self->{_offset}, $self->{_bits});
my $value = SHC_util::getUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits});
return $value2name{$value};
}
sub setValue
{
my ($self, $byteArrayRef, $name) = @_;
my ($self, $byteArrayRef, $name, $index) = @_;
my $value = $name2value{$name};
SHC_util::setUInt($byteArrayRef, $self->{_offset}, $self->{_bits}, $value);
SHC_util::setUInt($byteArrayRef, $self->{_offset} + $self->{_arrayElementBits} * $index, $self->{_bits}, $value);
}
1;

View File

@ -34,7 +34,7 @@
# $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.
# 5.) Get data fields depending on MessageGroupName and MessageName, e.g.
# $val = $parser->getField("Temperature");
#
# Sending packets:
@ -74,6 +74,8 @@ my %messageID2bits = ();
my @msgData = ();
my $sendMode = 0;
my $offset = 0;
sub new
{
my $class = shift;
@ -92,6 +94,104 @@ sub new
return $self;
}
sub init_datafield_positions_noarray($$$$$)
{
my ($messageGroupID, $messageID, $field, $arrayLength, $arrayElementBits) = @_;
given ($field->nodeName) {
when ('UIntValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = ($field->findnodes("Bits"))[0]->textContent;
# print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} =
new UIntValue($id, $offset, $bits, $arrayLength, $arrayElementBits);
$offset += $bits;
}
when ('IntValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = ($field->findnodes("Bits"))[0]->textContent;
# print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} =
new IntValue($id, $offset, $bits, $arrayLength, $arrayElementBits);
$offset += $bits;
}
when ('BoolValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = 1;
# print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} =
new BoolValue($id, $offset, $arrayLength, $arrayElementBits);
$offset += $bits;
}
when ('EnumValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = ($field->findnodes("Bits"))[0]->textContent;
# print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
my $object = new EnumValue($id, $offset, $bits, $arrayLength, $arrayElementBits);
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} = $object;
for my $element ($field->findnodes("Element")) {
my $value = ($element->findnodes("Value"))[0]->textContent;
my $name = ($element->findnodes("Name"))[0]->textContent;
$object->addValue($name, $value);
}
$offset += $bits;
}
}
}
sub init_datafield_positions_array($$$)
{
my ($messageGroupID, $messageID, $field) = @_;
my $offsetStartArray = $offset;
my $arrayLength = int(($field->findnodes("Length"))[0]->textContent);
my $arrayElementBits =
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")) {
my $bits =
init_datafield_positions_noarray($messageGroupID, $messageID, $subfield, $arrayLength, $arrayElementBits);
}
$offset = $offsetStartArray + $arrayLength * $arrayElementBits;
}
# Calculate the overall bits for one struct in a structured array
sub calc_array_bits_ovr($)
{
my ($field) = @_;
my $bits = 0;
for my $subfield ($field->findnodes("BoolValue")) {
$bits += 1;
}
for my $subfield ($field->findnodes("UIntValue|IntValue|EnumValue")) {
$bits += ($subfield->findnodes("Bits"))[0]->textContent;
}
return $bits;
}
# Read packet layout from XML file and remember the defined MessageGroups,
# Messages and data fields (incl. positions, length).
sub init_datafield_positions()
@ -121,75 +221,21 @@ sub init_datafield_positions()
$messageID2messageName{$messageGroupID . "-" . $messageID} = $messageName;
$messageName2messageID{$messageGroupName . "-" . $messageName} = $messageID;
my $offset = 0;
my $arrayLength = 1;
$offset = 0;
for my $field ($message->findnodes("Array|UIntValue|IntValue|BoolValue|EnumValue")) {
# When an array is detected, remember the array length and change the current field node
# to the inner node for further processing.
if ($field->nodeName eq 'Array') {
$arrayLength = int(($field->findnodes("Length"))[0]->textContent);
# DEBUG print "Next field is an array with " . $arrayLength . " elements!\n";
$field = ($field->findnodes("UIntValue|IntValue|BoolValue|EnumValue"))[0];
}
given ($field->nodeName) {
when ('UIntValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = ($field->findnodes("Bits"))[0]->textContent;
# DEBUG print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} = new UIntValue($id, $offset, $bits);
$offset += $bits * $arrayLength;
}
when ('IntValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = ($field->findnodes("Bits"))[0]->textContent;
# DEBUG print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} = new IntValue($id, $offset, $bits);
$offset += $bits * $arrayLength;
}
when ('BoolValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = 1;
# DEBUG print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} = new BoolValue($id, $offset, $arrayLength);
$offset += $bits * $arrayLength;
}
when ('EnumValue') {
my $id = ($field->findnodes("ID"))[0]->textContent;
my $bits = ($field->findnodes("Bits"))[0]->textContent;
# DEBUG print "Data field " . $id . " starts at " . $offset . " with " . $bits . " bits.\n";
my $object = new EnumValue($id, $offset, $bits);
$dataFields{$messageGroupID . "-" . $messageID . "-" . $id} = $object;
for my $element ($field->findnodes("Element")) {
my $value = ($element->findnodes("Value"))[0]->textContent;
my $name = ($element->findnodes("Name"))[0]->textContent;
$object->addValue($name, $value);
}
$offset += $bits * $arrayLength;
}
init_datafield_positions_array($messageGroupID, $messageID, $field);
} else {
init_datafield_positions_noarray($messageGroupID, $messageID, $field, 1, 0);
}
}
# DEBUG print "Remember packet length " . $offset . " bits for MessageGroupID " . $messageGroupID . ", MessageID " . $messageID . "\n";
$messageID2bits{$messageGroupID . "-" . $messageID} = $offset;
}
}
@ -275,8 +321,14 @@ sub getField
{
my ($self, $fieldName, $index) = @_;
if (!defined $index) {
$index = 0;
}
my $obj = $dataFields{$self->{_messageGroupID} . "-" . $self->{_messageID} . "-" . $fieldName};
my @tmpArray = map hex("0x$_"), $self->{_messageData} =~ /(..)/g;
# 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;
return $obj->getValue(\@tmpArray, $index);
}
@ -290,23 +342,27 @@ sub initPacket
$self->{_messageGroupID} = $messageGroupName2messageGroupID{$messageGroupName};
$self->{_messageID} = $messageName2messageID{$messageGroupName . "-" . $messageName};
my $lenBytes = $messageID2bits{$self->{_messageGroupID} . "-" . $self->{_messageID}} / 8;
my $lenBytes = int(($messageID2bits{$self->{_messageGroupID} . "-" . $self->{_messageID}} + 7) / 8);
@msgData = 0 x $lenBytes;
@msgData = (0) x $lenBytes;
$sendMode = 1;
}
sub setField
{
my ($self, $messageGroupName, $messageName, $fieldName, $value) = @_;
my ($self, $messageGroupName, $messageName, $fieldName, $value, $index) = @_;
if (!defined $index) {
$index = 0;
}
my $gID = $messageGroupName2messageGroupID{$messageGroupName};
my $mID = $messageName2messageID{$messageGroupName . "-" . $messageName};
my $obj = $dataFields{$gID . "-" . $mID . "-" . $fieldName};
$obj->setValue(\@msgData, $value);
$obj->setValue(\@msgData, $value, $index);
}
# sKK01RRRRGGMMDD
@ -322,6 +378,10 @@ sub getSendString
# Add lookup table device -> AES key?
# Automatically gather used AES key after reception from device?
if (!defined $aesKeyNr) {
$aesKeyNr = 0;
}
my $s = "s"
. sprintf("%02X", $aesKeyNr)
. sprintf("%02X", $self->{_messageTypeID})

View File

@ -260,6 +260,35 @@
</BoolValue>
</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>
<MessageID>2</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>
<Bits>11</Bits>
<MinVal>0</MinVal>
<MaxVal>1100</MaxVal>
</UIntValue>
</Array>
</Message>
</MessageGroup>
<MessageGroup>
<Name>Weather</Name>
@ -491,5 +520,64 @@
<MaxVal>100</MaxVal>
</UIntValue>
</Message>
<Message>
<Name>Color</Name>
<Description>This is to set a fixed color.</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>
<UIntValue>
<ID>Color</ID>
<Description>The color is according to the 6 bit color palette used in SHC.</Description>
<Bits>6</Bits>
<MinVal>0</MinVal>
<MaxVal>63</MaxVal>
</UIntValue>
</Message>
<Message>
<Name>ColorAnimation</Name>
<Description>This is to set a color animation.</Description>
<MessageID>11</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 animation 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 animation will be played back in the normal direction and then in reverse order.</Description>
</BoolValue>
<Array>
<Length>10</Length>
<UIntValue>
<ID>Time</ID>
<Description>The time for the animation between the current color and the next 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 animation. Further values will be ignored.</Description>
<Bits>5</Bits>
<MinVal>0</MinVal>
<MaxVal>31</MaxVal>
</UIntValue>
<UIntValue>
<ID>Color</ID>
<Description>The color is according to the 6 bit color palette used in SHC. The last color (or the first when AutoReverse is true) of the animation will remain visible after the animation is completed.</Description>
<Bits>6</Bits>
<MinVal>0</MinVal>
<MaxVal>63</MaxVal>
</UIntValue>
</Array>
</Message>
</MessageGroup>
</Packet>

View File

@ -260,8 +260,11 @@ FHEM/HttpUtils.pm rudolfkoenig http://forum.fhem.de Automatis
FHEM/MaxCommon.pm mgehre http://forum.fhem.de MAX
FHEM/ONKYOdb.pm loredo http://forum.fhem.de Multimedia
FHEM/SetExtensions.pm rudolfkoenig http://forum.fhem.de Automatisierung
FHEM/SHC_datafields.pm rr2000 http://forum.fhem.de Sonstige Systeme
FHEM/SHC_parser.pm rr2000 http://forum.fhem.de Sonstige Systeme
FHEM/TcpServerUtils.pm rudolfkoenig http://forum.fhem.de Automatisierung
FHEM/lib/Device/Firmata/* ntruchsess http://forum.fhem.de Sonstiges
FHEM/lib/SHC_packet_layout.xml rr2000 http://forum.fhem.de Sonstige Systeme
FHEM/lib/SWAP/* justme1968 http://forum.fhem.de Sonstige Systeme
FHEM/FhemUtils/* mfr69bs http://forum.fhem.de Sonstiges