2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 03:06:37 +00:00

- Solved the issue that 1byte values that are short (only 1-4bits) are not sent as 1byte values.

- renamed the command "value" to "raw" (as this command takes a raw hex value
- introducing new command "value" and all given values are translated according to the defined model
- added support for sending values of dpt5,dpt7,dpt9,dpt10,dpt11 (means also that sending of current time and date is possible)

git-svn-id: https://svn.fhem.de/fhem/trunk@3146 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
hotmaz 2013-05-01 22:41:47 +00:00
parent 6c498c9f2f
commit 19a9d3c778
2 changed files with 152 additions and 15 deletions

View File

@ -336,6 +336,11 @@ TUL_SimpleWrite(@)
$eibmsg->{'dst'} = $2;
my $hexvalues = $3;
my @data = map hex($_), $hexvalues =~ /(..)/g;
# check: first byte is only allowed to contain data in the lower 6bits
# to make sure all is fine, we mask the first byte
$data[0] = $data[0] & 0x3f if(defined($data[0]));
print "SimpleWrite data: @data \n";
$eibmsg->{'data'} = \@data;
@ -701,9 +706,10 @@ sub encode_eibd($)
@msg = (
tul_hex2addr( $mref->{'dst'}), # Destination address
0x0 | ($APCI >> 2), # TPDU type, Sequence no, APCI (msb)
(($APCI & 0x3) << 6) | ($datalen ==1? $data[0] : 0),
(($APCI & 0x3) << 6) | $data[0],
);
if ($datalen > 1) {
shift(@data);
push @msg, @data;
}
return @msg;
@ -798,11 +804,12 @@ sub encode_tpuart($)
0xBC, # EIB ctrl byte
tul_hex2addr($mref->{'src'}), # src address
tul_hex2addr( $mref->{'dst'}), # Destination address
0xE0 | ($datalen + ($datalen>1?1:0)), # Routing counter + data len
0xE0 | $datalen, # Routing counter + data len
0x00,
(($APCI & 0x3) << 6) | ($datalen ==1? $data[0] : 0),
(($APCI & 0x3) << 6) | $data[0],
);
if ($datalen > 1) {
shift(@data);
push @msg, @data;
}

View File

@ -7,18 +7,15 @@ use warnings;
# Open Tasks
# - precision for model percent to 0,1
# - send time & date methods and as command
# - send 4bit values for (8bit-types)
# - allow defined groups that are only used for sending of data (no status shown)
# - add convinience method for sending dim values / allow slider
# - get should also be able to get for a given group
my %eib_c2b = (
"off" => "00",
"on" => "01",
"on-for-timer" => "01",
"on-till" => "01",
"value" => ""
"raw" => "",
"value" => "" #value must be last.. because of slider functionality in Set
);
my %codes = (
@ -39,11 +36,11 @@ my %eib_dpttypes = (
# 1-Octet unsigned value
"dpt5" => {"CODE"=>"dpt5", "UNIT"=>"", "factor"=>1},
"percent" => {"CODE"=>"dpt5", "UNIT"=>"%", "factor"=>100/255},
"percent" => {"CODE"=>"dpt5", "UNIT"=>"%", "factor"=>100/255, "slider"=>"0,1,100"},
"dpt5.003" => {"CODE"=>"dpt5", "UNIT"=>"&deg;", "factor"=>360/255},
"angle" => {"CODE"=>"dpt5", "UNIT"=>"&deg;", "factor"=>360/255}, # alias for dpt5.003
"dpt5.004" => {"CODE"=>"dpt5", "UNIT"=>"%", "factor"=>1},
"percent255" => {"CODE"=>"dpt5", "UNIT"=>"%", "factor"=>1}, #alias for dpt5.004
"percent255" => {"CODE"=>"dpt5", "UNIT"=>"%", "factor"=>1 , "slider"=>"0,1,255"}, #alias for dpt5.004
# 2-Octet unsigned Value (current, length, brightness)
"dpt7" => {"CODE"=>"dpt7", "UNIT"=>""},
@ -199,11 +196,14 @@ EIB_Set($@)
$arg1 = $a[2] if($na>2);
$arg2 = $a[3] if($na>3);
my $model = $attr{$name}{"model"};
my $sliderdef = !defined($model)?undef:$eib_dpttypes{"$model"}{"slider"};
my $c = $eib_c2b{$value};
if(!defined($c)) {
return "Unknown argument $value, choose one of " .
join(" ", sort keys %eib_c2b);
my $resp = "Unknown argument $value, choose one of " . join(" ", sort keys %eib_c2b);
$resp = $resp . ":slider,$sliderdef" if(defined $sliderdef);
return $resp;
}
# the command can be send to any of the defined groups indexed starting by 1
@ -216,10 +216,16 @@ EIB_Set($@)
Log GetLogLevel($name,2), "EIB set $v";
(undef, $v) = split(" ", $v, 2); # Not interested in the name...
if($value eq "value" && defined($arg1)) {
if($value eq "raw" && defined($arg1)) {
# complex value command.
# the additional argument is transfered alone.
$c = $arg1;
} elsif ($value eq "value" && defined($arg1)) {
# value to be translated according to datapoint type
$c = EIB_EncodeByDatapointType($hash,$name,$arg1);
# set the value to the back translated value
$v = EIB_ParseByDatapointType($hash,$name,$c);
}
my $groupcode = $hash->{CODE}{$groupnr};
@ -287,6 +293,7 @@ EIB_Set($@)
return $ret;
}
sub
EIB_Parse($$)
{
@ -357,6 +364,100 @@ EIB_Parse($$)
}
}
sub
EIB_EncodeByDatapointType($$$)
{
my ($hash, $name, $value) = @_;
my $model = $attr{$name}{"model"};
# nothing to do if no model is given
return $value if(!defined($model));
my $dpt = $eib_dpttypes{"$model"};
Log(4,"EIB encode $value for $name model: $model dpt: $dpt");
return $value if(!defined($dpt));
my $code = $eib_dpttypes{"$model"}{"CODE"};
my $unit = $eib_dpttypes{"$model"}{"UNIT"};
my $transval = undef;
Log(4,"EIB encode $value for $name model: $model dpt: $code unit: $unit");
if ($code eq "dpt5")
{
my $dpt5factor = $eib_dpttypes{"$model"}{"factor"};
my $fullval = sprintf("00%.2x",($value/$dpt5factor));
$transval = $fullval;
Log(5,"EIB $code encode $value = $fullval factor = $dpt5factor translated: $transval");
} elsif ($code eq "dpt7")
{
my $fullval = sprintf("00%.2x",$value);
$transval = $fullval;
Log(5,"EIB $code encode $value = $fullval translated: $transval");
} elsif($code eq "dpt9")
{
my $sign = $value<0?-1:1;
my $absval = abs($value);
my $exp = $absval==0?0:int(log($absval)/log(2));
my $mant = $absval / (2**$exp) *100;
$mant = ((~($mant+1))&0x07FF) if($sign<0);
my $fullval = $mant+2048*$exp;
$fullval |=0x8000 if($sign<0);
$transval = sprintf("00%.4x",$fullval);
Log(5,"EIB $code encode $value = $fullval sign: $sign mant: $mant exp: $exp translated: $transval");
} elsif ($code eq "dpt10")
{
# set current Time
my ($secs,$mins,$hours,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year+=1900;
$mon++;
my $fullval = $secs + ($mins<<8) + ($hours<<16);
$transval = sprintf("00%.6x",$fullval);
Log(5,"EIB $code encode $value = $fullval hours: $hours mins: $mins secs: $secs translated: $transval");
} elsif ($code eq "dpt11")
{
# set current Date
my ($secs,$mins,$hours,$day,$month,$year,$wday,$yday,$isdst) = localtime(time);
$year+=1900;
$month++;
my $fullval = ($year-2000) + ($month<<8) + ($day<<16);
$transval = sprintf("00%.6x",$fullval);
Log(5,"EIB $code encode $value = $fullval day: $day month: $month year: $year translated: $transval");
} elsif ($code eq "dptxx") {
}
# set state to translated value
if(defined($transval))
{
Log(4,"EIB $name translated $value $unit to $transval");
$value = "$transval";
}
else
{
Log(4,"EIB $name model $model value $value could not be translated/encoded. Just do a dec2hex translation");
$value = sprintf("00%.2x",$value);
}
return $value;
}
sub
EIB_ParseByDatapointType($$$)
{
@ -554,7 +655,8 @@ eib_name2hex($)
<li><b>off</b> switch off device
<li><b>on-for-timer</b> <secs> switch on the device for the given time. After the specified seconds a switch off command is sent.
<li><b>on-till</b> <time spec> switches the device on. The device will be switched off at the given time.
<li><b>value</b> <hexvalue> sends the given value as raw data to the device.
<li><b>raw</b> <hexvalue> sends the given value as raw data to the device.
<li><b>value</b> <decimal value> transforms the value according to the chosen model and send the result to the device.
<br>Example:
<ul><code>
@ -562,7 +664,8 @@ eib_name2hex($)
set lamp1 off<br>
set lamp1 on-for-timer 10<br>
set lamp1 on-till 13:15:00<br>
set lamp1 value 234578<br>
set lamp1 raw 234578<br>
set lamp1 value 23.44<br>
</code></ul>
</li>
@ -574,6 +677,33 @@ eib_name2hex($)
set lamp1 on g2 (will send "on" to 0/10/02)
</code></ul>
A dimmer can be used with a slider as shown in following example:
<br><ul><code>
define dim1 EIB 0/0/5
attr dim1 model percent
attr dim1 webCmd value
</code></ul>
The current date and time can be sent to the bus by the following settings:
<br><ul><code>
define timedev EIB 0/0/7
attr timedev model dpt10
attr timedev eventMap /value now:now/
attr timedev webCmd now
define datedev EIB 0/0/8
attr datedev model dpt11
attr datedev eventMap /value now:now/
attr datedev webCmd now
# send every midnight the new date
define dateset at *00:00:00 set datedev value now
# send every hour the current time
define timeset at +*01:00:00 set timedev value now
</code></ul>
</ul>
<br>