2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-15 22:26:04 +00:00

added new modules 36_JeeLink.pm and 36_PCA301.pm and arduino sketch contrib/arduino/36_PCA301-pcaSerial.zip

git-svn-id: https://svn.fhem.de/fhem/trunk@3805 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
justme-1968 2013-08-27 11:08:47 +00:00
parent 3c4eee652a
commit b6ef098110
5 changed files with 874 additions and 0 deletions

View File

@ -1,5 +1,9 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
- SVN
- feature: new modules JeeLink and PCA301 and for the ELV PCA 301 power
meter with a JeeLabs JeeLink as RF modem. The matching JeeNode
sketch can be found in .../contrib/36_PCA301-pcaSerial.zip
(by justme1968)
- change: PRESENCE: changing ping method for Windows systems to "tcp"
- feature: install FHEM as Windows service by T.E., see docs/HOWTO_Windows.txt
- feature: new module 33_readingsGroup to display a collection of readings

558
fhem/FHEM/36_JeeLink.pm Normal file
View File

@ -0,0 +1,558 @@
# $Id$
package main;
use strict;
use warnings;
use Time::HiRes qw(gettimeofday);
sub JeeLink_Attr(@);
sub JeeLink_Clear($);
sub JeeLink_HandleWriteQueue($);
sub JeeLink_Parse($$$$);
sub JeeLink_Read($);
sub JeeLink_ReadAnswer($$$$);
sub JeeLink_Ready($);
sub JeeLink_Write($$);
sub JeeLink_SimpleWrite(@);
my $clientsJeeLink = ":PCA301:EC3000:RoomNode:";
my %matchListPCA301 = (
"1:PCA301" => "^\\S+\\s+24",
"2:EC3000" => "^\\S+\\s+22",
"3:RoomNode" => "^\\S+\\s+11",
);
sub
JeeLink_Initialize($)
{
my ($hash) = @_;
require "$attr{global}{modpath}/FHEM/DevIo.pm";
# Provider
$hash->{ReadFn} = "JeeLink_Read";
$hash->{WriteFn} = "JeeLink_Write";
$hash->{ReadyFn} = "JeeLink_Ready";
# Normal devices
$hash->{DefFn} = "JeeLink_Define";
$hash->{FingerprintFn} = "JeeLink_Fingerprint";
$hash->{UndefFn} = "JeeLink_Undef";
$hash->{GetFn} = "JeeLink_Get";
$hash->{SetFn} = "JeeLink_Set";
#$hash->{AttrFn} = "JeeLink_Attr";
#$hash->{AttrList}= "";
$hash->{ShutdownFn} = "JeeLink_Shutdown";
}
sub
JeeLink_Fingerprint($$)
{
}
#####################################
sub
JeeLink_Define($$)
{
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
if(@a != 3) {
my $msg = "wrong syntax: define <name> JeeLink {devicename[\@baudrate] ".
"| devicename\@directio}";
Log3 undef, 2, $msg;
return $msg;
}
DevIo_CloseDev($hash);
my $name = $a[0];
my $dev = $a[2];
$dev .= "\@57600" if( $dev !~ m/\@/ );
$hash->{Clients} = $clientsJeeLink;
$hash->{MatchList} = \%matchListPCA301;
$hash->{DeviceName} = $dev;
$hash->{nonce} = 0;
my $ret = DevIo_OpenDev($hash, 0, "JeeLink_DoInit");
return $ret;
}
#####################################
sub
JeeLink_Undef($$)
{
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
foreach my $d (sort keys %defs) {
if(defined($defs{$d}) &&
defined($defs{$d}{IODev}) &&
$defs{$d}{IODev} == $hash)
{
my $lev = ($reread_active ? 4 : 2);
Log3 $name, $lev, "deleting port for $d";
delete $defs{$d}{IODev};
}
}
JeeLink_Shutdown($hash);
DevIo_CloseDev($hash);
return undef;
}
#####################################
sub
JeeLink_Shutdown($)
{
my ($hash) = @_;
###JeeLink_SimpleWrite($hash, "X00");
return undef;
}
#####################################
sub
JeeLink_Set($@)
{
my ($hash, @a) = @_;
my $name = shift @a;
my $cmd = shift @a;
my $arg = join("", @a);
my $list = "raw:noArg";
return $list if( $cmd eq '?' );
if($cmd eq "raw") {
return "\"set JeeLink $cmd\" needs exactly one parameter" if(@_ != 4);
return "Expecting a even length hex number" if((length($arg)&1) == 1 || $arg !~ m/^[\dA-F]{12,}$/ );
Log3 $name, 4, "set $name $cmd $arg";
JeeLink_SimpleWrite($hash, $arg);
} else {
return "Unknown argument $cmd, choose one of ".$list;
}
return undef;
}
#####################################
sub
JeeLink_Get($@)
{
my ($hash, $name, $cmd ) = @_;
my $list = "devices:noArg initJeeLink:noArg";
if( $cmd eq "devices" ) {
JeeLink_SimpleWrite($hash, "l");
} elsif( $cmd eq "initJeeLink" ) {
JeeLink_SimpleWrite($hash, "0c");
JeeLink_SimpleWrite($hash, "2c");
} else {
return "Unknown argument $cmd, choose one of ".$list;
}
return undef;
}
sub
JeeLink_Clear($)
{
my $hash = shift;
# Clear the pipe
$hash->{RA_Timeout} = 0.1;
for(;;) {
my ($err, undef) = JeeLink_ReadAnswer($hash, "Clear", 0, undef);
last if($err && $err =~ m/^Timeout/);
}
delete($hash->{RA_Timeout});
}
#####################################
sub
JeeLink_DoInit($)
{
my $hash = shift;
my $name = $hash->{NAME};
my $err;
my $msg = undef;
my $val;
#JeeLink_Clear($hash);
JeeLink_SimpleWrite($hash, "1a" ); # led on
JeeLink_SimpleWrite($hash, "1q" ); # quiet mode
JeeLink_SimpleWrite($hash, "0x" ); # hex mode
JeeLink_SimpleWrite($hash, "0a" ); # led off
JeeLink_SimpleWrite($hash, "l"); # list known devices
$hash->{STATE} = "Initialized";
# Reset the counter
delete($hash->{XMIT_TIME});
delete($hash->{NR_CMD_LAST_H});
return undef;
}
#####################################
# This is a direct read for commands like get
# Anydata is used by read file to get the filesize
sub
JeeLink_ReadAnswer($$$$)
{
my ($hash, $arg, $anydata, $regexp) = @_;
my $type = $hash->{TYPE};
return ("No FD", undef)
if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD})));
my ($mpandata, $rin) = ("", '');
my $buf;
my $to = 3; # 3 seconds timeout
$to = $hash->{RA_Timeout} if($hash->{RA_Timeout}); # ...or less
for(;;) {
if($^O =~ m/Win/ && $hash->{USBDev}) {
$hash->{USBDev}->read_const_time($to*1000); # set timeout (ms)
# Read anstatt input sonst funzt read_const_time nicht.
$buf = $hash->{USBDev}->read(999);
return ("Timeout reading answer for get $arg", undef)
if(length($buf) == 0);
} else {
return ("Device lost when reading answer for get $arg", undef)
if(!$hash->{FD});
vec($rin, $hash->{FD}, 1) = 1;
my $nfound = select($rin, undef, undef, $to);
if($nfound < 0) {
next if ($! == EAGAIN() || $! == EINTR() || $! == 0);
my $err = $!;
DevIo_Disconnected($hash);
return("JeeLink_ReadAnswer $arg: $err", undef);
}
return ("Timeout reading answer for get $arg", undef)
if($nfound == 0);
$buf = DevIo_SimpleRead($hash);
return ("No data", undef) if(!defined($buf));
}
if($buf) {
Log3 $hash->{NAME}, 5, "JeeLink/RAW (ReadAnswer): $buf";
$mpandata .= $buf;
}
chop($mpandata);
chop($mpandata);
return (undef, $mpandata)
}
}
#####################################
# Check if the 1% limit is reached and trigger notifies
sub
JeeLink_XmitLimitCheck($$)
{
my ($hash,$fn) = @_;
my $now = time();
if(!$hash->{XMIT_TIME}) {
$hash->{XMIT_TIME}[0] = $now;
$hash->{NR_CMD_LAST_H} = 1;
return;
}
my $nowM1h = $now-3600;
my @b = grep { $_ > $nowM1h } @{$hash->{XMIT_TIME}};
if(@b > 163) { # 163 comes from fs20. todo: verify if correct for JeeLink modulation
my $name = $hash->{NAME};
Log3 $name, 2, "JeeLink TRANSMIT LIMIT EXCEEDED";
DoTrigger($name, "TRANSMIT LIMIT EXCEEDED");
} else {
push(@b, $now);
}
$hash->{XMIT_TIME} = \@b;
$hash->{NR_CMD_LAST_H} = int(@b);
}
#####################################
sub
JeeLink_Write($$)
{
my ($hash,$msg) = @_;
my $name = $hash->{NAME};
Log3 $name, 5, "$name sending $msg";
JeeLink_AddQueue($hash, $msg);
#JeeLink_SimpleWrite($hash, $msg);
}
sub
JeeLink_SendFromQueue($$)
{
my ($hash, $bstring) = @_;
my $name = $hash->{NAME};
my $to = 0.05;
if($bstring ne "") {
my $sp = AttrVal($name, "sendpool", undef);
if($sp) { # Is one of the JeeLink-fellows sending data?
my @fellows = split(",", $sp);
foreach my $f (@fellows) {
if($f ne $name &&
$defs{$f} &&
$defs{$f}{QUEUE} &&
$defs{$f}{QUEUE}->[0] ne "")
{
unshift(@{$hash->{QUEUE}}, "");
InternalTimer(gettimeofday()+$to, "JeeLink_HandleWriteQueue", $hash, 1);
return;
}
}
}
JeeLink_XmitLimitCheck($hash,$bstring);
JeeLink_SimpleWrite($hash, $bstring);
}
InternalTimer(gettimeofday()+$to, "JeeLink_HandleWriteQueue", $hash, 1);
}
sub
JeeLink_AddQueue($$)
{
my ($hash, $bstring) = @_;
if(!$hash->{QUEUE}) {
$hash->{QUEUE} = [ $bstring ];
JeeLink_SendFromQueue($hash, $bstring);
} else {
push(@{$hash->{QUEUE}}, $bstring);
}
}
#####################################
sub
JeeLink_HandleWriteQueue($)
{
my $hash = shift;
my $arr = $hash->{QUEUE};
if(defined($arr) && @{$arr} > 0) {
shift(@{$arr});
if(@{$arr} == 0) {
delete($hash->{QUEUE});
return;
}
my $bstring = $arr->[0];
if($bstring eq "") {
JeeLink_HandleWriteQueue($hash);
} else {
JeeLink_SendFromQueue($hash, $bstring);
}
}
}
#####################################
# called from the global loop, when the select for hash->{FD} reports data
sub
JeeLink_Read($)
{
my ($hash) = @_;
my $buf = DevIo_SimpleRead($hash);
return "" if(!defined($buf));
my $name = $hash->{NAME};
my $pandata = $hash->{PARTIAL};
Log3 $name, 5, "JeeLink/RAW: $pandata/$buf";
$pandata .= $buf;
while($pandata =~ m/\n/) {
my $rmsg;
($rmsg,$pandata) = split("\n", $pandata, 2);
$rmsg =~ s/\r//;
JeeLink_Parse($hash, $hash, $name, $rmsg) if($rmsg);
}
$hash->{PARTIAL} = $pandata;
}
sub
JeeLink_Parse($$$$)
{
my ($hash, $iohash, $name, $rmsg) = @_;
my $dmsg = $rmsg;
#my $l = length($dmsg);
my $rssi;
#my $rssi = hex(substr($dmsg, 1, 2));
#$rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74));
my $lqi;
#my $lqi = hex(substr($dmsg, 3, 2));
#$dmsg = substr($dmsg, 6, $l-6);
#Log3, $name, 5, "$name: $dmsg $rssi $lqi";
next if(!$dmsg || length($dmsg) < 1); # Bogus messages
next if($dmsg =~ m/^-> ack/ ); # ignore send ack
$hash->{"${name}_MSGCNT"}++;
$hash->{"${name}_TIME"} = TimeNow();
$hash->{RAWMSG} = $rmsg;
my %addvals = (RAWMSG => $rmsg);
if(defined($rssi)) {
$hash->{RSSI} = $rssi;
$addvals{RSSI} = $rssi;
}
if(defined($lqi)) {
$hash->{LQI} = $lqi;
$addvals{LQI} = $lqi;
}
if( $rmsg =~ m/(\S* )(\d+)(.*)/ ) {
my $node = $2 & 0x1F; #mask HDR -> it is handled by the skech
$dmsg = $1.$node.$3;
}
Dispatch($hash, $dmsg, \%addvals);
}
#####################################
sub
JeeLink_Ready($)
{
my ($hash) = @_;
return DevIo_OpenDev($hash, 1, "JeeLink_DoInit")
if($hash->{STATE} eq "disconnected");
# This is relevant for windows/USB only
my $po = $hash->{USBDev};
my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags);
if($po) {
($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
}
return ($InBytes && $InBytes>0);
}
########################
sub
JeeLink_SimpleWrite(@)
{
my ($hash, $msg, $nocr) = @_;
return if(!$hash);
my $name = $hash->{NAME};
Log3 $name, 5, "SW: $msg";
$msg .= "\n" unless($nocr);
$hash->{USBDev}->write($msg) if($hash->{USBDev});
syswrite($hash->{DIODev}, $msg) if($hash->{DIODev});
# Some linux installations are broken with 0.001, T01 returns no answer
select(undef, undef, undef, 0.01);
}
sub
JeeLink_Attr(@)
{
my @a = @_;
return undef;
}
1;
=pod
=begin html
<a name="JeeLink"></a>
<h3>JeeLink</h3>
<ul>
The JeeLink is a family of RF devices sold by <a href="http://jeelabs.com">jeelabs.com</a>.
It is possible to attach more than one device in order to get better
reception, fhem will filter out duplicate messages.<br><br>
This module provides the IODevice for the <a href="#PCA301">PCA301</a> modules that implements the PCA301 protocoll.<br><br>
In the future other RF devices like the Energy Controll 3000, JeeLabs room nodes, fs20 or kaku devices will be supportet.<br><br>
Note: this module may require the Device::SerialPort or Win32::SerialPort
module if you attach the device via USB and the OS sets strange default
parameters for serial devices.
<br><br>
<a name="JeeLink_Define"></a>
<b>Define</b>
<ul>
<code>define &lt;name&gt; JeeLink &lt;device&gt;</code> <br>
<br>
USB-connected devices:<br><ul>
&lt;device&gt; specifies the serial port to communicate with the JeeLink.
The name of the serial-device depends on your distribution, under
linux the cdc_acm kernel module is responsible, and usually a
/dev/ttyACM0 device will be created. If your distribution does not have a
cdc_acm module, you can force usbserial to handle the JeeLink by the
following command:<ul>modprobe usbserial vendor=0x0403
product=0x6001</ul>In this case the device is most probably
/dev/ttyUSB0.<br><br>
You can also specify a baudrate if the device name contains the @
character, e.g.: /dev/ttyACM0@57600<br><br>
If the baudrate is "directio" (e.g.: /dev/ttyACM0@directio), then the
perl module Device::SerialPort is not needed, and fhem opens the device
with simple file io. This might work if the operating system uses sane
defaults for the serial parameters, e.g. some Linux distributions and
OSX. <br><br>
</ul>
<br>
</ul>
<br>
<a name="JeeLink_Set"></a>
<b>Set</b>
<ul>
<li>raw &lt;datar&gt;<br>
send &lt;data&gt; as a raw message to the JeeLink to be transmitted over the RF link.
</li><br>
</ul>
<a name="JeeLink_Get"></a>
<b>Get</b>
<ul>
</ul>
<a name="JeeLink_Attr"></a>
<b>Attributes</b>
<ul>
</ul>
<br>
</ul>
=end html
=cut

310
fhem/FHEM/36_PCA301.pm Normal file
View File

@ -0,0 +1,310 @@
# $Id: 34_PCA301.pm 3515 2013-07-28 09:00:56Z justme1968 $
#
# TODO:
package main;
use strict;
use warnings;
use SetExtensions;
sub PCA301_Parse($$);
sub PCA301_Send($$@);
sub
PCA301_Initialize($)
{
my ($hash) = @_;
$hash->{Match} = "^\\S+\\s+24";
$hash->{SetFn} = "PCA301_Set";
#$hash->{GetFn} = "PCA301_Get";
$hash->{DefFn} = "PCA301_Define";
$hash->{UndefFn} = "PCA301_Undef";
$hash->{FingerprintFn} = "PCA301_Fingerprint";
$hash->{ParseFn} = "PCA301_Parse";
$hash->{AttrFn} = "PCA301_Attr";
$hash->{AttrList} = "IODev".
" $readingFnAttributes";
}
sub
PCA301_Define($$)
{
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
if(@a != 4 ) {
my $msg = "wrong syntax: define <name> PCA301 <addr> <channel>";
Log3 undef, 2, $msg;
return $msg;
}
$a[2] =~ m/^([\da-f]{6})$/i;
return "$a[2] is not a valid PCA301 address" if( !defined($1) );
$a[3] =~ m/^([\da-f]{2})$/i;
return "$a[3] is not a valid PCA301 channel" if( !defined($1) );
my $name = $a[0];
my $addr = $a[2];
my $channel = $a[3];
#return "$addr is not a 1 byte hex value" if( $addr !~ /^[\da-f]{2}$/i );
#return "$addr is not an allowed address" if( $addr eq "00" );
return "PCA301 device $addr already used for $modules{PCA301}{defptr}{$addr}->{NAME}." if( $modules{PCA301}{defptr}{$addr}
&& $modules{PCA301}{defptr}{$addr}->{NAME} ne $name );
$hash->{addr} = $addr;
$hash->{channel} = $channel;
$modules{PCA301}{defptr}{$addr} = $hash;
AssignIoPort($hash);
if(defined($hash->{IODev}->{NAME})) {
Log3 $name, 3, "$name: I/O device is " . $hash->{IODev}->{NAME};
} else {
Log3 $name, 1, "$name: no I/O device";
}
$attr{$name}{devStateIcon} = 'on:on:toggle off:off:toggle .*:light_question:off' if( !defined( $attr{$name}{devStateIcon} ) );
$attr{$name}{webCmd} = 'on:off:toggle:statusRequest' if( !defined( $attr{$name}{webCmd} ) );
CommandAttr( undef, "$name userReadings consumptionTotal:consumption monotonic {ReadingsVal(\$name,'consumption',0)}" ) if( !defined( $attr{$name}{userReadings} ) );
#PCA301_Send($hash, $addr, "00" );
return undef;
}
#####################################
sub
PCA301_Undef($$)
{
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
my $addr = $hash->{addr};
delete( $modules{PCA301}{defptr}{$addr} );
return undef;
}
#####################################
sub
PCA301_Set($@)
{
my ($hash, $name, @aa) = @_;
my $cnt = @aa;
return "\"set $name\" needs at least one parameter" if($cnt < 1);
my $cmd = $aa[0];
my $arg = $aa[1];
my $arg2 = $aa[2];
my $arg3 = $aa[3];
my $list = "identify:noArg off:noArg on:noArg toggle:noArg reset:noArg statusRequest:noArg";
if( $cmd eq 'toggle' ) {
$cmd = ReadingsVal($name,"state","on") eq "off" ? "on" :"off";
}
if( $cmd eq 'off' ) {
readingsSingleUpdate($hash, "state", "set-$cmd", 1);
PCA301_Send( $hash, 0x05, 0x00 );
} elsif( $cmd eq 'on' ) {
readingsSingleUpdate($hash, "state", "set-$cmd", 1);
PCA301_Send( $hash, 0x05, 0x01 );
} elsif( $cmd eq 'statusRequest' ) {
readingsSingleUpdate($hash, "state", "set-$cmd", 1);
PCA301_Send( $hash, 0x04, 0x00 );
} elsif( $cmd eq 'reset' ) {
readingsSingleUpdate($hash, "state", "set-$cmd", 1);
PCA301_Send( $hash, 0x04, 0x01 );
} elsif( $cmd eq 'identify' ) {
PCA301_Send( $hash, 0x06, 0x00 );
} else {
return SetExtensions($hash, $list, $name, @aa);
}
return undef;
}
#####################################
sub
PCA301_Get($@)
{
my ($hash, $name, $cmd, @args) = @_;
return "\"get $name\" needs at least one parameter" if(@_ < 3);
my $list = "";
return "Unknown argument $cmd, choose one of $list";
}
sub
PCA301_Fingerprint($$)
{
my ($name, $msg) = @_;
return ( "", $msg );
}
sub
PCA301_Parse($$)
{
my ($hash, $msg) = @_;
my $name = $hash->{NAME};
#return undef if( $msg !~ m/^[\dA-F]{12,}$/ );
if( $msg =~ m/^L/ ) {
my @parts = split( ' ', substr($msg, 5), 4 );
$msg = "OK 24 $parts[3]";
}
my( @bytes, $channel,$cmd,$addr,$data,$power,$consumption );
if( $msg =~ m/^OK/ ) {
@bytes = split( ' ', substr($msg, 6) );
$channel = sprintf( "%02X", $bytes[0] );
$cmd = $bytes[1];
$addr = sprintf( "%02X%02X%02X", $bytes[2], $bytes[3], $bytes[4] );
$data = $bytes[5];
return "" if( $cmd == 0x04 && $bytes[6] == 170 && $bytes[7] == 170 && $bytes[8] == 170 && $bytes[9] == 170 ); # ignore commands from display unit
return "" if( $cmd == 0x05 && ( $bytes[6] != 170 || $bytes[7] != 170 || $bytes[8] != 170 || $bytes[9] != 170 ) ); # ignore commands not from the plug
} elsif ( $msg =~ m/^TX/ ) {
# ignore TX
return "";
} else {
DoTrigger($name, "UNKNOWNCODE $msg");
Log3 $name, 3, "$name: Unknown code $msg, help me!";
return undef;
}
my $raddr = $addr;
my $rhash = $modules{PCA301}{defptr}{$raddr};
my $rname = $rhash?$rhash->{NAME}:$raddr;
if( !$modules{PCA301}{defptr}{$raddr} ) {
Log3 $name, 3, "PCA301 Unknown device $rname, please define it";
return "UNDEFINED PCA301_$rname PCA301 $raddr $channel";
}
#CommandAttr( undef, "$rname userReadings consumptionTotal:consumption monotonic {ReadingsVal($rname,'consumption',0)}" ) if( !defined( $attr{$rname}{userReadings} ) );
my @list;
push(@list, $rname);
$rhash->{PCA301_lastRcv} = TimeNow();
if( $cmd eq 0x04 ) {
my $state = $data==0x00?"off":"on";
my $power = ($bytes[6]*256 + $bytes[7]) / 10.0;
my $consumption = ($bytes[8]*256 + $bytes[9]) / 100.0;
readingsBeginUpdate($rhash);
readingsBulkUpdate($rhash, "power", $power) if( $data != 0x00 );
readingsBulkUpdate($rhash, "consumption", $consumption) if( $data != 0x00 );
readingsBulkUpdate($rhash, "state", $state) if( Value($rname) ne $state );
readingsEndUpdate($rhash,1);
} elsif( $cmd eq 0x05 ) {
my $state = $data==00?"off":"on";
readingsSingleUpdate($rhash, "state", $state, 1)
}
return @list;
}
sub
PCA301_Send($$@)
{
my ($hash, $cmd, $data) = @_;
$hash->{PCA301_lastSend} = TimeNow();
my $msg = sprintf( "%i,%i,%i,%i,%i,%i,255,255,255,255s", hex($hash->{channel}),
$cmd,
hex(substr($hash->{addr},0,2)), hex(substr($hash->{addr},2,2)), hex(substr($hash->{addr},4,2)),
$data );
IOWrite( $hash, $msg );
}
sub
PCA301_Attr(@)
{
my ($cmd, $name, $attrName, $attrVal) = @_;
return undef;
}
1;
=pod
=begin html
<a name="PCA301"></a>
<h3>PCA301</h3>
<ul>
<tr><td>
The PCA301 is a RF controlled AC mains plug with integrated power meter functionality from ELV.<br><br>
It can be integrated in to FHEM via a <a href="#JeeLink">JeeLink</a> as the IODevice.<br><br>
The JeeNode sketch required for this module can be found in .../contrib/36_PCA301-pcaSerial.zip.<br><br>
<a name="PCA301Define"></a>
<b>Define</b>
<ul>
<code>define &lt;name&gt; PCA301 &lt;addr&gt; &lt;channel&gt;</code> <br>
<br>
addr is a 6 digit hex number to identify the PCA301 device.
channel is a 2 digit hex number to identify the PCA301 device.<br><br>
Note: devices are autocreated on reception of the first message.<br>
</ul>
<br>
<a name="PCA301_Set"></a>
<b>Set</b>
<ul>
<li>on</li>
<li>off</li>
<li>identify<br>
Blink the status led for ~5 seconds.</li>
<li>reset<br>
Reset consumption counters</li>
<li>statusRequest<br>
Request device status update.</li>
<li><a href="#setExtensions"> set extensions</a> are supported.</li>
</ul><br>
<a name="PCA301_Get"></a>
<b>Get</b>
<ul>
</ul><br>
<a name="PCA301_Readings"></a>
<b>Readings</b>
<ul>
<li>power</li>
<li>consumption</li>
<li>consumptionTotal<br>
will be created as a default user reading to have a continous consumption value that is not influenced
by the regualar reset or overflow of the normal consumption reading</li>
</ul><br>
<a name="PCA301_Attr"></a>
<b>Attributes</b>
<ul>
</ul><br>
</ul>
=end html
=cut

View File

@ -89,6 +89,8 @@ FHEM/32_speedtest.pm justme1968 http://forum.fhem.de Sonstiges
FHEM/34_panStamp.pm justme1968 http://forum.fhem.de Sonstiges Systeme
FHEM/34_SWAP.pm justme1968 http://forum.fhem.de Sonstiges Systeme
FHEM/35_SWAP_0000002200000003.pm justme1968 http://forum.fhem.de Sonstiges Systeme
FHEM/36_JeeLink.pm justme1968 http://forum.fhem.de Sonstiges Systeme
FHEM/36_PCA301.pm justme1968 http://forum.fhem.de Sonstiges Systeme
FHEM/40_RFXCOM.pm wherzig http://forum.fhem.de RFXTRX
FHEM/41_OREGON.pm wherzig http://forum.fhem.de Sonstiges
FHEM/42_RFXMETER.pm wherzig http://forum.fhem.de RFXTRX

Binary file not shown.