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

1471 lines
80 KiB
Perl
Raw Normal View History

# $Id: 73_UpsPico.pm 15394 2017-11-05 15:29:05Z Sailor $
########################################################################################################################
#
# 73_UpsPico.pm
# Creates the possibility to access the UPS PIco Uninterrupteable Power Supply
#
# Author : Matthias Deeke
# e-mail : matthias.deeke(AT)deeke(PUNKT)eu
# Fhem Forum : https://forum.fhem.de/index.php/topic,77000.0.html
# Fhem Wiki :
#
# This file is part of fhem.
#
# Fhem is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Fhem is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
#
# fhem.cfg: define <devicename> UpsPico <IPv4-address> <UpsOnPiUser> <UpsOnPiPassword>
#
# Example 1 - Bare Credentials:
# define myUpsPico UpsPico 192.168.178.200 User Geheim
#
# Example 2 - base64 encoded Credentials: Both, username and password, may be pre-encode with base64 if attribute CredentialsEncrypted is set
# define myUpsPico UpsPico 192.168.178.200 VXNlcm5hbWU= UGFzc3dvcmQ=
#
########################################################################################################################
########################################################################################################################
# List of open Problems:
#
# Set - command not yet implemented
#
########################################################################################################################
package main;
use strict;
use warnings;
use Net::OpenSSH;
use Data::Dumper qw(Dumper);
use Math::Expression::Evaluator;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use constant false => 0;
use constant true => 1;
sub UpsPico_Attr(@);
sub UpsPico_Get($@);
sub UpsPico_Set($@);
sub UpsPico_Define($$);
sub UpsPico_Undefine($$);
sub UpsPico_Initialize($);
sub UpsPico_GetAllData($@);
sub UpsPico_DbLog_splitFn($$);
sub UpsPico_CheckConnection($@);
###START###### Initialize module ##############################################################################START####
sub UpsPico_Initialize($)
{
my ($hash) = @_;
$hash->{STATE} = "Init";
$hash->{DefFn} = "UpsPico_Define";
$hash->{UndefFn} = "UpsPico_Undefine";
$hash->{SetFn} = "UpsPico_Set";
$hash->{GetFn} = "UpsPico_Get";
$hash->{AttrFn} = "UpsPico_Attr";
$hash->{DbLog_splitFn} = "UpsPico_DbLog_splitFn";
$hash->{AttrList} = "do_not_notify:0,1 " .
"header " .
"Port " .
"WriteCritical:0,1 " .
"disable:1,0 " .
"loglevel:0,1,2,3,4,5 " .
"PollingInterval " .
"CredentialsEncrypted:0,1 " .
$readingFnAttributes;
}
####END####### Initialize module ###############################################################################END#####
###START###### Activate module after module has been used via fhem command "define" ##########################START####
sub UpsPico_Define($$)
{
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
my $name = $a[0];
#$a[1] just contains the "UpsPico" module name and we already know that! :-)
my $url = $a[2];
my $RemotePiUser = $a[3];
my $RemotePiPass = $a[4];
$hash->{NAME} = $name;
$hash->{STATE} = "define";
Log3 $name, 4, $name. " : UpsPico_Define - Starting to define module";
###START###### Reset fullResponse error message ############################################################START####
readingsSingleUpdate( $hash, "fullResponse", "Initialising...", 1);
####END####### Reset fullResponse error message #############################################################END#####
### Stop the current timer if one exists errornous
RemoveInternalTimer($hash);
Log3 $name, 4, $name. " : UpsPico_Define - InternalTimer has been removed.";
###START### Check whether all variables are available #####################################################START####
if (int(@a) == 5)
{
###START### Check whether IPv4 address is valid
if ($url =~ m/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/)
{
Log3 $name, 4, $name. " : UpsPico_Define - IPv4-address is valid : " . $url;
}
else
{
return $name .": Error - IPv4 address is not valid \n Please use \"define <devicename> UpsPico <IPv4-address> <interval/[s]> <Username> <Password>\" instead";
}
####END#### Check whether IPv4 address is valid
}
else
{
return $name .": UpsPico - Error - Not enough or too much parameter provided." . "\n" . "Gateway IPv4 address, Username and Password must be provided" ."\n". "Please use \"define <devicename> UpsPico <IPv4-address> <Username> <Password>\" instead";
}
####END#### Check whether all variables are available ######################################################END#####
###START### Decode Username and Password if base 64 coded #################################################START####
if (defined($attr{$name}{CredentialsEncrypted}))
{
if ($attr{$name}{CredentialsEncrypted} == 1)
{
$RemotePiUser = decode_base64($RemotePiUser);
$RemotePiPass = decode_base64($RemotePiPass);
}
}
####END#### Decode Username and Password if base 64 coded ##################################################END#####
###START###### Provide basic Information for all register #################################################START####
my %RegisterInfo;
$RegisterInfo{"mode"} = {RegisterBlockName => "Status", RegisterAddress => 0x00, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x01 => "RPI_MODE", 0x02 => "BAT_MODE", Default => "ERROR"} };
$RegisterInfo{"batlevel"} = {RegisterBlockName => "Status", RegisterAddress => 0x08, DataType => "WordBCD", Writeable => false, Reset => false, Critical => false, Factor => 0.01, Unit => "V", SelectionList => undef };
$RegisterInfo{"rpilevel"} = {RegisterBlockName => "Status", RegisterAddress => 0x0a, DataType => "WordBCD", Writeable => false, Reset => false, Critical => false, Factor => 0.01, Unit => "V", SelectionList => undef };
$RegisterInfo{"eprlevel"} = {RegisterBlockName => "Status", RegisterAddress => 0x0c, DataType => "WordBCD", Writeable => false, Reset => false, Critical => false, Factor => 0.01, Unit => "V", SelectionList => undef };
$RegisterInfo{"aEXT0level"} = {RegisterBlockName => "Status", RegisterAddress => 0x14, DataType => "WordBCD", Writeable => false, Reset => false, Critical => false, Factor => 0.01, Unit => "V", SelectionList => undef };
$RegisterInfo{"aEXT1level"} = {RegisterBlockName => "Status", RegisterAddress => 0x16, DataType => "WordBCD", Writeable => false, Reset => false, Critical => false, Factor => 0.01, Unit => "V", SelectionList => undef };
$RegisterInfo{"aEXT2level"} = {RegisterBlockName => "Status", RegisterAddress => 0x18, DataType => "WordBCD", Writeable => false, Reset => false, Critical => false, Factor => 0.01, Unit => "V", SelectionList => undef };
$RegisterInfo{"key"} = {RegisterBlockName => "Status", RegisterAddress => 0x1a, DataType => "Byte", Writeable => true, Reset => true, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "No Key pressed", 0x01 => "Key A pressed", 0x02 => "Key B pressed", 0x03 => "Key C pressed", Default => "ERROR"} };
$RegisterInfo{"ntc"} = {RegisterBlockName => "Status", RegisterAddress => 0x1b, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => "&deg;C", SelectionList => undef };
$RegisterInfo{"TO92"} = {RegisterBlockName => "Status", RegisterAddress => 0x1c, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => "&deg;C", SelectionList => undef };
$RegisterInfo{"charger"} = {RegisterBlockName => "Status", RegisterAddress => 0x20, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Charger OFF", 0x01 => "Charging Batt", Default => "ERROR"} };
$RegisterInfo{"pico_is_running"} = {RegisterBlockName => "Status", RegisterAddress => 0x22, DataType => "WordHex", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => "ms", SelectionList => undef };
$RegisterInfo{"pv"} = {RegisterBlockName => "Status", RegisterAddress => 0x24, DataType => "ASCII", Writeable => false, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => undef };
$RegisterInfo{"bv"} = {RegisterBlockName => "Status", RegisterAddress => 0x25, DataType => "ASCII", Writeable => false, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => undef };
$RegisterInfo{"fv"} = {RegisterBlockName => "Status", RegisterAddress => 0x26, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => undef };
$RegisterInfo{"RTC_seconds"} = {RegisterBlockName => "RTC", RegisterAddress => 0x00, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => "s", SelectionList => undef };
$RegisterInfo{"RTC_minutes"} = {RegisterBlockName => "RTC", RegisterAddress => 0x01, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => "min", SelectionList => undef };
$RegisterInfo{"RTC_hours"} = {RegisterBlockName => "RTC", RegisterAddress => 0x02, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => "h", SelectionList => undef };
$RegisterInfo{"RTC_wday"} = {RegisterBlockName => "RTC", RegisterAddress => 0x03, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => " ", SelectionList => undef };
$RegisterInfo{"RTC_mday"} = {RegisterBlockName => "RTC", RegisterAddress => 0x04, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => " ", SelectionList => undef };
$RegisterInfo{"RTC_month"} = {RegisterBlockName => "RTC", RegisterAddress => 0x05, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => " ", SelectionList => undef };
$RegisterInfo{"RTC_year"} = {RegisterBlockName => "RTC", RegisterAddress => 0x06, DataType => "Byte", Writeable => false, Reset => false, Critical => false, Factor => 1.00, Unit => " ", SelectionList => undef };
$RegisterInfo{"pico_state"} = {RegisterBlockName => "Command", RegisterAddress => 0x00, DataType => "Byte", Writeable => true, Reset => false, Critical => true, Factor => undef, Unit => undef, SelectionList => {0x00 => "OK", 0x80 => "OK", 0xcc => "Shutdown", 0xdd => "Factory Reset", 0xee => "CPU Reset", 0xff => "Bootloader", 0xa0 => "DEFAULT", 0xa1 => "NO_RTC", 0xa2 => "ALTERNATE", Default => "ERROR"}};
$RegisterInfo{"bat_run_time"} = {RegisterBlockName => "Command", RegisterAddress => 0x01, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "s", SelectionList => {0xff => "BattLive", Default => "Function: 60+RegisterValue*60"} };
$RegisterInfo{"rs232_rate"} = {RegisterBlockName => "Command", RegisterAddress => 0x02, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Disabled", 0x01 => "4800bps", 0x02 => "9600bps", 0x03 => "19200bps", 0x04 => "34600bps", 0x05 => "57600bps", 0x0f => "115200bps",Default => "ERROR"} };
$RegisterInfo{"STA_timer"} = {RegisterBlockName => "Command", RegisterAddress => 0x05, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "s", SelectionList => {0xff => "Disabled", Default => "Function: RegisterValue"} };
$RegisterInfo{"enable5V"} = {RegisterBlockName => "Command", RegisterAddress => 0x06, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Disabled", 0x01 => "Enabled", Default => "ERROR"} };
$RegisterInfo{"battype"} = {RegisterBlockName => "Command", RegisterAddress => 0x07, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x46 => "LiFePO4 - F", 0x51 => "LiFePO4 - Q", 0x53 => "LiPO - S", 0x50 => "LiPO - P", Default => "ERROR"} };
$RegisterInfo{"setA_D"} = {RegisterBlockName => "Command", RegisterAddress => 0x08, DataType => "Byte", Writeable => true, Reset => false, Critical => true, Factor => undef, Unit => undef, SelectionList => {0x00 => "AEXT1: 05.2V; AEXT2: 05.2V;", 0x01 => "AEXT1: 05.2V; AEXT2: 10.0V;", 0x02 => "AEXT1: 05.2V; AEXT2: 20.0V;", 0x03 => "AEXT1: 05.2V; AEXT2: 30.0V;", 0x10 => "AEXT1: 10.0V; AEXT2: 05.2V;", 0x11 => "AEXT1: 10.0V; AEXT2: 10.0V;", 0x12 => "AEXT1: 10.0V; AEXT2: 20.0V;", 0x13 => "AEXT1: 10.0V; AEXT2: 30.0V;", 0x20 => "AEXT1: 20.0V; AEXT2: 05.2V;", 0x21 => "AEXT1: 20.0V; AEXT2: 10.0V;", 0x22 => "AEXT1: 20.0V; AEXT2: 20.0V;", 0x23 => "AEXT1: 20.0V; AEXT2: 30.0V;", 0x30 => "AEXT1: 30.0V; AEXT2: 05.2V;", 0x31 => "AEXT1: 30.0V; AEXT2: 10.0V;", 0x32 => "AEXT1: 30.0V; AEXT2: 20.0V;", 0x33 => "AEXT1: 30.0V; AEXT2: 30.0V;", Default => "ERROR"} };
$RegisterInfo{"User_LED_Orange"} = {RegisterBlockName => "Command", RegisterAddress => 0x09, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "OFF", 0x01 => "ON", Default => "ERROR"} };
$RegisterInfo{"User_LED_Green"} = {RegisterBlockName => "Command", RegisterAddress => 0x0a, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "OFF", 0x01 => "ON", Default => "ERROR"} };
$RegisterInfo{"User_LED_Blue"} = {RegisterBlockName => "Command", RegisterAddress => 0x0b, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "OFF", 0x01 => "ON", Default => "ERROR"} };
$RegisterInfo{"brelay"} = {RegisterBlockName => "Command", RegisterAddress => 0x0c, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Reset", 0x01 => "Set", Default => "ERROR"} };
$RegisterInfo{"bmode"} = {RegisterBlockName => "Command", RegisterAddress => 0x0d, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Disabled", 0x01 => "Enabled", Default => "ERROR"} };
$RegisterInfo{"bfreq"} = {RegisterBlockName => "Command", RegisterAddress => 0x0e, DataType => "WordBCD", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "Hz", SelectionList => undef };
$RegisterInfo{"bdur"} = {RegisterBlockName => "Command", RegisterAddress => 0x10, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 10, Unit => "ms", SelectionList => undef };
$RegisterInfo{"fmode"} = {RegisterBlockName => "Command", RegisterAddress => 0x11, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Disabled", 0x01 => "Enabled", 0x02 => "Auto", Default => "ERROR"} };
$RegisterInfo{"fspeed"} = {RegisterBlockName => "Command", RegisterAddress => 0x12, DataType => "Hex", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "%", SelectionList => undef };
$RegisterInfo{"fstat"} = {RegisterBlockName => "Command", RegisterAddress => 0x13, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "OFF", 0x01 => "ON", Default => "ERROR"} };
$RegisterInfo{"fttemp"} = {RegisterBlockName => "Command", RegisterAddress => 0x14, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "&deg;C", SelectionList => undef };
$RegisterInfo{"LED_OFF"} = {RegisterBlockName => "Command", RegisterAddress => 0x15, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "All LEDs forced OFF", 0x01 => "All LED manual", Default => "ERROR"} };
$RegisterInfo{"STS_active"} = {RegisterBlockName => "StartTS", RegisterAddress => 0x00, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => {0x00 => "Inactive", 0xff => "Active", Default => "ERROR"} };
$RegisterInfo{"STS_minute"} = {RegisterBlockName => "StartTS", RegisterAddress => 0x01, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "min", SelectionList => undef };
$RegisterInfo{"STS_hour"} = {RegisterBlockName => "StartTS", RegisterAddress => 0x02, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "h", SelectionList => undef };
$RegisterInfo{"STS_mday"} = {RegisterBlockName => "StartTS", RegisterAddress => 0x03, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "d", SelectionList => undef };
$RegisterInfo{"STS_month"} = {RegisterBlockName => "StartTS", RegisterAddress => 0x04, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "m", SelectionList => undef };
$RegisterInfo{"STS_year"} = {RegisterBlockName => "StartTS", RegisterAddress => 0x05, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "y", SelectionList => undef };
$RegisterInfo{"D_repetition"} = {RegisterBlockName => "RunTS", RegisterAddress => 0x00, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "d", SelectionList => {0xff => "Disabled", Default => "Function: RegisterValue"} };
$RegisterInfo{"H_repetition"} = {RegisterBlockName => "RunTS", RegisterAddress => 0x01, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "h", SelectionList => {0xff => "Disabled", Default => "Function: RegisterValue"} };
$RegisterInfo{"M_repetition"} = {RegisterBlockName => "RunTS", RegisterAddress => 0x02, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "min", SelectionList => {0xff => "Disabled", Default => "Function: RegisterValue"} };
$RegisterInfo{"H_duration"} = {RegisterBlockName => "RunTS", RegisterAddress => 0x03, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "h", SelectionList => {0xff => "Disabled", Default => "Function: RegisterValue"} };
$RegisterInfo{"M_duration"} = {RegisterBlockName => "RunTS", RegisterAddress => 0x04, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => 1.00, Unit => "min", SelectionList => {0xff => "Disabled", Default => "Function: RegisterValue"} };
# $RegisterInfo{"??????????"} = {RegisterBlockName => "EventS", RegisterAddress => 0x00, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => undef };
# $RegisterInfo{"??????????"} = {RegisterBlockName => "ActionS", RegisterAddress => 0x00, DataType => "Byte", Writeable => true, Reset => false, Critical => false, Factor => undef, Unit => undef, SelectionList => undef };
####END####### Provide basic Information for all register ##################################################END#####
###START###### Provide charging information for batteries #################################################START####
my %BattChargingInfo;
$BattChargingInfo{"LiFePO4 - F"} = {Volt0Percent => 2.9, Volt100Percent => 3.6};
$BattChargingInfo{"LiFePO4 - Q"} = {Volt0Percent => 2.9, Volt100Percent => 3.6};
$BattChargingInfo{"LiPO - S"} = {Volt0Percent => 3.4, Volt100Percent => 4.3};
$BattChargingInfo{"LiPO - P"} = {Volt0Percent => 3.4, Volt100Percent => 4.3};
####END####### Provide charging information for batteries ##################################################END#####
###START###### Writing values to global hash ##############################################################START####
$hash->{NAME} = $name;
$hash->{URL} = $url;
$hash->{temp}{FIRSTTIME} = true;
$hash->{temp}{RemotePiUser} = $RemotePiUser;
$hash->{temp}{RemotePiPass} = $RemotePiPass;
%{$hash->{temp}{RegisterInfo}} = %RegisterInfo;
%{$hash->{temp}{BattChargingInfo}} = %BattChargingInfo;
####END####### Writing values to global hash ###############################################################END#####
###START###### For Debugging purpose only #################################################################START####
Log3 $name, 4, $name. " : UpsPico_Define Hash : " . $hash;
Log3 $name, 4, $name. " : UpsPico_Define Def : " . $def;
Log3 $name, 4, $name. " : UpsPico_Define Array : " . @a;
Log3 $name, 4, $name. " : UpsPico_Define Name : " . $name;
Log3 $name, 4, $name. " : UpsPico_Define Address : " . $url;
Log3 $name, 5, $name. " : UpsPico -----------------------------------------------------------------------------";
Log3 $name, 5, $name. " : UpsPico - RegisterInfo in fhem-hash : \n" . Dumper \%$hash;
Log3 $name, 5, $name. " : UpsPico -----------------------------------------------------------------------------";
####END####### For Debugging purpose only ##################################################################END#####
###Initiate the timer for first check of connection towards RasPi with UpsPico but wait 30s
InternalTimer(gettimeofday()+30, "UpsPico_CheckConnection", $hash, 0);
return undef;
}
####END####### Activate module after module has been used via fhem command "define" ############################END#####
###START###### To bind unit of value to DbLog entries #########################################################START####
sub UpsPico_DbLog_splitFn($$)
{
my ($event, $name) = @_;
my $hash = $defs{$name};
my %RegisterInfo = %{$hash->{temp}{RegisterInfo}};
my @argument = split("[ \t][ \t]*", $event);
#### Delete ":" and everything behind in readings name
$argument[0] =~ s/:.*//;
### Pre-Define variables
my $reading = $argument[0];
my $value = $argument[1];
my $unit = undef;
### Log entries for debugging
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of event : " . $event;
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of argument[0] : " . $argument[0];
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of argument[1] : " . $argument[1];
### Split Reading in RegisterI2CBlock and RegisterName
my @SplitRegisterReading = split(/\//,$argument[0]);
# $SplitRegisterReading[0] is an empty field
my $RegisterI2CBlockNameEvent = $SplitRegisterReading[1];
my $RegisterNameEvent = $SplitRegisterReading[2];
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of RegisterI2CBlockNameEvent : " . $RegisterI2CBlockNameEvent;
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of RegisterNameEvent : " . $RegisterNameEvent;
### Set I2CBlockAddressnames
my %I2CAddress;
$I2CAddress{Status} = undef;
$I2CAddress{RTC} = undef;
$I2CAddress{Command} = undef;
$I2CAddress{StartTS} = undef;
$I2CAddress{RunTS} = undef;
$I2CAddress{EventS} = undef;
$I2CAddress{ActionS} = undef;
### For all specified RegisterI2CBlocks and registers: Search for unit
SearchLoop:
{
foreach my $RegisterI2CBlock (keys %I2CAddress)
{
### If the RegisterI2CBlock to be changed is identical to the RegisterI2CBlock in the loop
if ($RegisterI2CBlockNameEvent eq $RegisterI2CBlock)
{
### For all specified Register
foreach my $RegisterName (keys %RegisterInfo)
{
### If the RegisterName to be changed is identical to the RegisterName in the loop
if ($RegisterNameEvent eq $RegisterName)
{
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Found Register for reading : " . $reading;
### Extract value and unit
$unit = $RegisterInfo{$RegisterName}{Unit};
last SearchLoop;
}
}
}
}
}
### Log entries for debugging
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of reading : " . $reading;
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of value : " . $value;
Log3 $name, 5, $name. " : UpsPico_DbLog_splitFn - Content of unit : " . $unit;
return ($reading, $value, $unit);
}
####END####### To bind unit of value to DbLog entries ##########################################################END#####
###START###### Deactivate module module after "undefine" command by fhem ######################################START####
sub UpsPico_Undefine($$)
{
my ($hash, $def) = @_;
my $name = $hash->{NAME};
my $url = $hash->{URL};
### Stop the internal timer for this module
RemoveInternalTimer($hash);
Log3 $name, 3, $name. " - UpsPico has been undefined. The KM unit at $url will no longer polled.";
return undef;
}
####END####### Deactivate module module after "undefine" command by fhem #######################################END#####
###START###### Handle attributes after changes via fhem GUI ###################################################START####
sub UpsPico_Attr(@)
{
my @a = @_;
my $name = $a[1];
my $hash = $defs{$name};
### Check whether disable attribute has been provided
if ($a[2] eq "disable")
{
###START### Check whether device shall be disabled
if ($a[3] == 1)
{
### Set new status
$hash->{STATE} = "Disabled";
### Stop the current timer
RemoveInternalTimer($hash);
Log3 $name, 4, $name. " : UpsPico_Attr - InternalTimer has been removed.";
### Delete all Readings
fhem( "deletereading $name .*" );
Log3 $name, 3, $name. " : UpsPico_Attr - Device disabled as per attribute.";
}
else
{
### Initiate the timer for first time polling of values from UpsPico but wait 10s
$hash->{temp}{FIRSTTIME} = true;
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+180, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 4, $name. " : UpsPico_Attr - Internal timer for Initialisation of services re-started.";
Log3 $name, 4, $name. " : UpsPico_Attr - Device enabled as per attribute.";
}
####END#### Check whether device shall be disabled
}
### Check whether polling interval attribute for all data has been provided
elsif ($a[2] eq "PollingInterval")
{
my $PollingInterval = $a[3];
###START### Check whether polling interval is not too short
if ($PollingInterval > 19)
{
### Initiate the timer for first time polling of values from UpsPico but wait 10s
$hash->{temp}{FIRSTTIME} = true;
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+180, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 4, $name. " : UpsPico_Attr - Interval for all data set to attribute value :" . $PollingInterval ." s";
Log3 $name, 4, $name. " : UpsPico_Attr - Internal timer for Initialisation of services re-started.";
}
else
{
return $name .": Error - Polling interval too small - server response time greater than defined interval, please use something >=20, default is 90";
}
####END#### Check whether polling interval is not too short
}
### If no attributes of the above mentioned ones have been selected
else
{
# Do nothing
}
return undef;
}
####END####### Handle attributes after changes via fhem GUI ####################################################END#####
###START###### Obtain value after "get" command by fhem #######################################################START####
sub UpsPico_Get($@)
{
my ( $hash, @a ) = @_;
### If not enough arguments have been provided
if ( @a < 2 )
{
return "\"UpsPico_Get\" needs at least one argument";
}
my $name = shift @a;
my $reading = shift @a;
my $host = $hash->{URL};
my $user = $hash->{temp}{RemotePiUser};
my $pass = $hash->{temp}{RemotePiPass};
my %RegisterInfo = %{$hash->{temp}{RegisterInfo}};
### Pre-Define variables
my $ReturnMessage;
### Log entries for debugging
Log3 $name, 5, $name. " : UpsPico_Get ------------------- Definition ----------------------------------------------";
Log3 $name, 5, $name. " : UpsPico_Get - name : " . $name;
Log3 $name, 5, $name. " : UpsPico_Get - reading : " . $reading;
### Prepare list of readings to be selected
if(!$hash->{READINGS}{$reading})
{
my @cList = sort keys %{$hash->{READINGS}};
return "Unknown argument $reading, choose one of " . join(" ", @cList);
}
### Split Reading in RegisterI2CBlock and RegisterName
my @SplitRegisterReading = split(/\//,$reading);
# $SplitRegisterReading[0] is an empty field
my $RegisterI2CBlockNameEvent = $SplitRegisterReading[1];
my $RegisterNameEvent = $SplitRegisterReading[2];
Log3 $name, 5, $name. " : UpsPico_Get - Content of RegisterI2CBlockNameEvent : " . $RegisterI2CBlockNameEvent;
Log3 $name, 5, $name. " : UpsPico_Get - Content of RegisterNameEvent : " . $RegisterNameEvent;
### Set I2C address block hash
my %I2CAddress;
$I2CAddress{Status} = undef;
$I2CAddress{RTC} = undef;
$I2CAddress{Command} = undef;
$I2CAddress{StartTS} = undef;
$I2CAddress{RunTS} = undef;
$I2CAddress{EventS} = undef;
$I2CAddress{ActionS} = undef;
### For all specified RegisterI2CBlocks and registers: Search for unit and register address
SearchLoop:
{
foreach my $RegisterI2CBlock (keys %I2CAddress)
{
### If the RegisterI2CBlock to be changed is identical to the RegisterI2CBlock in the loop
if ($RegisterI2CBlockNameEvent eq $RegisterI2CBlock)
{
### For all specified Register
foreach my $RegisterName (keys %RegisterInfo)
{
### If the RegisterName to be changed is identical to the RegisterName in the loop
if ($RegisterNameEvent eq $RegisterName)
{
Log3 $name, 5, $name. " : UpsPico_Get - Found Register for reading : " . $reading;
### Call Download
UpsPico_GetAllData($hash, @a);
### Log entries for debugging
Log3 $name, 5, $name. " : UpsPico_Get ------------------- Final Handover ------------------------------------------";
Log3 $name, 5, $name. " : UpsPico_Get - reading : " . $reading;
Log3 $name, 5, $name. " : UpsPico_Get - RegisterName : " . $RegisterName;
Log3 $name, 5, $name. " : UpsPico_Get - RegisterInfo{RegisterName}{Value} : " . $RegisterInfo{$RegisterName}{Value};
Log3 $name, 5, $name. " : UpsPico_Get - RegisterInfo{RegisterName}{Unit} : " . $RegisterInfo{$RegisterName}{Unit};
Log3 $name, 5, $name. " : UpsPico_Get ==============================================================================";
### Prepare the message
$ReturnMessage = $reading . " = " . $RegisterInfo{$RegisterName}{Value} . " " . $RegisterInfo{$RegisterName}{Unit};
### Break the loop since the job is done
last SearchLoop;
}
}
}
}
}
### Return value
return($ReturnMessage);
}
####END####### Obtain value after "get" command by fhem ########################################################END#####
###START###### Manipulate service after "set" command by fhem #################################################START####
sub UpsPico_Set($@)
{
my ( $hash, @a ) = @_;
### If not enough arguments have been provided
if ( @a < 2 )
{
return "\"set UpsPico\" needs at least one argument";
}
my $name = shift @a;
my $register = shift @a;
my $value = join(" ", @a);
my %UpsPico_sets;
my $ReturnMessage;
return($ReturnMessage);
### DO NOT FORGET TO CHECK ATTRIBUTE "WriteCritical"!!!
### DO NOT FORGET TO RESET ATTRIBUTE "WriteCritical" after every single reading!!! Use fhem command "save"
}
####END####### Manipulate service after "Set" command by fhem ##################################################END#####
###START###### Check connection towards remote RasPi via SSH ##################################################START####
sub UpsPico_CheckConnection($@)
{
my ($hash, $def) = @_;
my $name = $hash->{NAME};
my $url = $hash->{URL};
Log3 $name, 5, $name. " : UpsPico - CheckConnection-------------------------------------------------------------------------------------------------";
### Stop the internal timer for this module
RemoveInternalTimer($hash);
Log3 $name, 4, $name. " : UpsPico - CheckConnection - Internal Timer has been removed";
###START###### Try to access UpsPIco to get I2C address range ##############################################START####
my $port = $attr{$name}{Port};
my $stderr = 0;
my $RemotePiUser = $hash->{temp}{RemotePiUser};
my $RemotePiPass = $hash->{temp}{RemotePiPass};
my $stdout;
my $exit;
my $cmd;
my $ssh;
###START###### Reset fullResponse error message ############################################################START####
readingsSingleUpdate( $hash, "fullResponse", "Checking Connection...", 1);
####END####### Reset fullResponse error message #############################################################END#####
eval {$ssh = Net::SSH::Perl->new($url);};
if( $@ )
{
###Set warning for log file
Log3 $name, 1, $name. " : UpsPico - CheckConnection - SSH Connection to RasPi with UPS-PIco could not be established since network connection failed. Retrying in 300s";
### Stop the internal timer for this module and re-initiate the timer for another check of connection towards RasPi with UpsPico but wait 300s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+30, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 4, $name. " : UpsPico - CheckConnection - Internal Timer has been removed and restarted to check connection again in 300s";
undef $ssh;
return undef;
}
else
{
eval {$ssh->login($RemotePiUser, $RemotePiPass);};
if( $@ )
{
###Set warning for log file
Log3 $name, 1, $name. " : UpsPico - CheckConnection - SSH Login to RasPi with UPS-PIco could not be established due to wrong credentials. Retrying in 300s";
### Stop the internal timer for this module and re-initiate the timer for another check of connection towards RasPi with UpsPico but wait 10s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+30, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 4, $name. " : UpsPico - CheckConnection - Internal Timer has been removed and restarted to check connection again in 300s";
undef $ssh;
return undef;
}
else
{
#### Try out with factory default address
$cmd = "sudo i2cget -y 1 0x69 0x00 b";
($stdout, $stderr, $exit) = $ssh->cmd($cmd);
if(defined($stderr)) { Log3 $name, 2, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x69 - stderr : " . $stderr;}
if(defined($exit)) { Log3 $name, 5, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x69 - exit : " . $exit; }
if(defined($stdout)) { Log3 $name, 5, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x69 - stdout : " . $stdout;}
Log3 $name, 5, $name. " : UpsPico - CheckConnection ----------------------------------------------------------";
### If connection with status register on I2C address 0x69 was successfully
if ($stdout ne "")
{
#### Try out whether RTC register are available
$cmd = "sudo i2cget -y 1 0x6A 0x00 b";
($stdout, $stderr, $exit) = $ssh->cmd($cmd);
if(defined($stderr)) { Log3 $name, 2, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x6A - stderr : " . $stderr;}
if(defined($exit)) { Log3 $name, 5, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x6A - exit : " . $exit; }
if(defined($stdout)) { Log3 $name, 5, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x6A - stdout : " . $stdout;}
Log3 $name, 5, $name. " : UpsPico - CheckConnection ----------------------------------------------------------";
### If connection with RTC register on I2C address 0x6A was successfully
if ($stdout ne "")
{
### Set I2CRegisterRange to "NORMAL"
$hash->{I2cRegisterRange} = "NORMAL";
}
else
{
### Set I2CRegisterRange to "NO_RTC"
$hash->{I2cRegisterRange} = "NO_RTC";
}
###Initiate the timer for first time polling of values from UpsPico but wait 10s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+10, "UpsPico_GetAllData", $hash, 0);
Log3 $name, 3, $name. " : UpsPico - CheckConnection - I2C range has been set to : " . $hash->{I2cRegisterRange};
Log3 $name, 4, $name. " : UpsPico - CheckConnection - Internal timer for Initialisation of services started for the first time.";
###Set fullResponse error message
readingsSingleUpdate( $hash, "fullResponse", "OK", 1);
}
### If connection was not successfully
else
{
#### Try out with alternate address
$cmd = "sudo i2cget -y 1 0x59 0x00 b";
($stdout, $stderr, $exit) = $ssh->cmd($cmd);
if(defined($stderr)) { Log3 $name, 2, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x5A - stderr : " . $stderr;}
if(defined($exit)) { Log3 $name, 5, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x5A - exit : " . $exit; }
if(defined($stdout)) { Log3 $name, 5, $name. " : UpsPico - CheckConnection - Obtain I2C range with 0x5A - stdout : " . $stdout;}
Log3 $name, 5, $name. " : UpsPico - CheckConnection ----------------------------------------------------------";
### If connection with status register on I2C address 0x59 was successfully
if ($stdout ne "")
{
$hash->{I2cRegisterRange} = "ALTERNATE";
###Initiate the timer for first time polling of values from UpsPico but wait 10s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+10, "UpsPico_GetAllData", $hash, 0);
Log3 $name, 3, $name. " : UpsPico - CheckConnection - I2C range has been set to : " . $hash->{I2cRegisterRange};
Log3 $name, 4, $name. " : UpsPico - CheckConnection - Internal timer for Initialisation of services started for the first time.";
###Set fullResponse error message
readingsSingleUpdate( $hash, "fullResponse", "OK", 1);
}
### Otherwise there is no UpsPIco connection available
else
{
Log3 $name, 2, $name. " : UpsPico - CheckConnection - Connection to UPS-PIco could not be established. Terminating Initialisation!";
###Set fullResponse error message
readingsSingleUpdate( $hash, "fullResponse", "Error I2C-connection failed. Check connection and re-define device.", 1);
### Stop the internal timer for this module and re-initiate the timer for another check of connection towards RasPi with UpsPico but wait 10s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+10, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 4, $name. " : UpsPico - CheckConnection - Internal Timer has been removed and restarted to check connection again in 10s";
return undef;
}
}
}
}
Log3 $name, 5, $name. " : UpsPico ----------------------------------------------------------------------------------------------------------------";
return undef;
}
####END####### Check connection towards remote RasPi via SSH ###################################################END#####
###START###### Download all register ##########################################################################START####
sub UpsPico_GetAllData($@)
{
my ($hash, $def) = @_;
my $host = $hash->{URL};
my $name = $hash->{NAME} ;
my $user = $hash->{temp}{RemotePiUser};
my $pass = $hash->{temp}{RemotePiPass};
my $PollingInterval = $attr{$name}{PollingInterval};
my %RegisterInfo = %{$hash->{temp}{RegisterInfo}};
my %BattChargingInfo = %{$hash->{temp}{BattChargingInfo}};
my $port = $attr{$name}{Port};
my $ssh;
my $ReturnMessage;
### Stop the current timer
RemoveInternalTimer($hash);
###START###### Reset fullResponse error message ############################################################START####
readingsSingleUpdate( $hash, "fullResponse", "Downloading...", 1);
####END####### Reset fullResponse error message #############################################################END#####
###START###### Set I2C address accordingly ###############################################################START####
my %I2CAddress;
if ($hash->{I2cRegisterRange} eq "NORMAL")
{
Log3 $name, 4, $name. " : UpsPico_GetAllData - I2CRegisterRange has been set to NORMAL";
$I2CAddress{Status} = 0x69;
$I2CAddress{RTC} = 0x6a;
$I2CAddress{Command} = 0x6b;
$I2CAddress{StartTS} = 0x6c;
$I2CAddress{RunTS} = 0x6d;
$I2CAddress{EventS} = 0x6e;
$I2CAddress{ActionS} = 0x6f;
}
elsif ($hash->{I2cRegisterRange} eq "NO_RTC")
{
Log3 $name, 4, $name. " : UpsPico_GetAllData - I2CRegisterRange has been set to NO_RTC";
$I2CAddress{Status} = 0x69;
$I2CAddress{RTC} = undef;
$I2CAddress{Command} = 0x6b;
$I2CAddress{StartTS} = undef;
$I2CAddress{RunTS} = undef;
$I2CAddress{EventS} = undef;
$I2CAddress{ActionS} = undef;
}
elsif ($hash->{I2cRegisterRange} eq "ALTERNATE")
{
Log3 $name, 4, $name. " : UpsPico_GetAllData - I2CRegisterRange has been set to ALTERNATE";
$I2CAddress{Status} = 0x59;
$I2CAddress{RTC} = 0x5a;
$I2CAddress{Command} = 0x5b;
$I2CAddress{StartTS} = 0x5c;
$I2CAddress{RunTS} = 0x5d;
$I2CAddress{EventS} = 0x5e;
$I2CAddress{ActionS} = 0x5f;
}
####END####### Set I2C address accordingly #################################################################END#####
###START###### Check whether all required attributes exists otherwise create them with standard values ###BEGIN####
if(!defined($attr{$name}{Port}))
{
### Set attribute with standard value since it is not available
$attr{$name}{Port} = 22;
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute SSH-Port was missing and has been set to " . $attr{$name}{Port};
}
if(!defined($attr{$name}{PollingInterval}))
{
### Set attribute with standard value since it is not available
$attr{$name}{PollingInterval} = 300;
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute PollingInterval was missing and has been set to " . $attr{$name}{PollingInterval};
}
if(!defined($attr{$name}{room}))
{
### Set attribute with standard value since it is not available
$attr{$name}{room} = "UpsPIco";
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute for room was missing and has been set to " . $attr{$name}{room};
}
if(!defined($attr{$name}{WriteCritical}))
{
### Set attribute with standard value since it is not available
$attr{$name}{WriteCritical} = 0;
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute for allowing to write critical register was missing and has been set to " . $attr{$name}{WriteCritical};
}
if(!defined($attr{$name}{CredentialsEncrypted}))
{
### Set attribute with standard value since it is not available
$attr{$name}{CredentialsEncrypted} = 0;
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute for the Credentials being encrypted has been set to " . $attr{$name}{CredentialsEncrypted};
}
if(!defined($attr{$name}{DbLogExclude}))
{
### Set attribute with standard value since it is not available
$attr{$name}{DbLogExclude} = "/Status/pico_is_running";
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute for excluding the logging of the pico_is_running - status has been set.";
}
if(!defined($attr{$name}{"event-on-change-reading"}))
{
### Set attribute with standard value since it is not available
$attr{$name}{"event-on-change-reading"} = ".*";
### Writing log entry
Log3 $name, 3, $name. " : UpsPico - The attribute for logging only on changed values has been set to all readings.";
}
####END####### Check whether all required attributes exists otherwise create them with standard values ####END#####
###START###### Check connection ###########################################################################START####
### Check whether the network connection still exists
eval {$ssh = Net::SSH::Perl->new($host);};
if( $@ )
{
###Set warning for log file
Log3 $name, 1, $name. " : UpsPico_GetAllData - SSH Connection to RasPi with UPS-PIco could not be established. Terminating Initialisation!";
###Set fullResponse error message
readingsSingleUpdate( $hash, "fullResponse", "Error: SSH-connection failed", 1);
### Stop the internal timer for this module and re-initiate the timer for another check of connection towards RasPi with UpsPico but wait 10s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+10, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 4, $name. " : UpsPico_GetAllData - Error SSH-connection failed.";
undef $ssh;
return undef;
}
### Check whether the credentials are still valid
eval {$ssh->login($user, $pass);};
if( $@ )
{
###Set warning for log file
Log3 $name, 1, $name. " : UpsPico_GetAllData - SSH Login to RasPi with UPS-PIco could not be established. Terminating Initialisation!";
###Set fullResponse error message
readingsSingleUpdate( $hash, "fullResponse", "Error SSH-Login failed - Check Credentials", 1);
### Stop the internal timer for this module and re-initiate the timer for another check of connection towards RasPi with UpsPico but wait 10s
RemoveInternalTimer($hash);
$hash->{temp}{FIRSTTIME} = true;
InternalTimer(gettimeofday()+10, "UpsPico_CheckConnection", $hash, 0);
Log3 $name, 1, $name. " : UpsPico_GetAllData - Error SSH-Login failed - Check Credentials";
undef $ssh;
return undef;
}
####END####### Check connection ############################################################################END#####
###START###### Download register block from UPS PIco via ssh command ######################################START####
foreach my $RegisterI2CBlock (keys %I2CAddress)
{
###START##### Download Register #######################################################################START####
if (defined($I2CAddress{$RegisterI2CBlock}))
{
Log3 $name, 4, $name. " : UpsPico_GetAllData - working on Registerblock: " . $RegisterI2CBlock;
my @RegisterBlock;
my $stdout;
my $stderr = 0;
my $exit;
my $SshCmd = "sudo i2cdump -y -r 0-255 1 " . int($I2CAddress{$RegisterI2CBlock}) . " b";
($stdout, $stderr, $exit) = $ssh->cmd($SshCmd);
### For debugging purposes only
if(defined($stderr)) { Log3 $name, 2, $name. " : UpsPico_GetAllData - stderr " . $RegisterI2CBlock . " : " . $stderr; }
if(defined($exit)) { Log3 $name, 5, $name. " : UpsPico_GetAllData - exit " . $RegisterI2CBlock . " : " . $exit; }
if(defined($stdout)) { Log3 $name, 5, $name. " : UpsPico_GetAllData - stdout " . $RegisterI2CBlock . " : \n" . $stdout; }
Log3 $name, 5, $name. " : UpsPico_GetAllData ------------------------------------------------------------------------------------";
my @BlockRegister = split(/ /, $stdout);
Log3 $name, 5, $name. " : UpsPico_GetAllData - BlockRegister" . $RegisterI2CBlock . " : \n" . Dumper \@BlockRegister;
Log3 $name, 5, $name. " : UpsPico_GetAllData ------------------------------------------------------------------------------------";
my $LineNumber;
for ($LineNumber = 19; $LineNumber < 530; $LineNumber = $LineNumber + 2)
{
my @TempRegister = split(/ /, $BlockRegister[$LineNumber]);
splice(@TempRegister, 0, 1);
push(@RegisterBlock,@TempRegister);
}
Log3 $name, 4, $name. " : UpsPico_GetAllData - RegisterBlock " . $RegisterI2CBlock . " successfully downloaded";
Log3 $name, 5, $name. " : UpsPico_GetAllData - RegisterBlock " . $RegisterI2CBlock . " : \n" . Dumper \@RegisterBlock;
Log3 $name, 5, $name. " : UpsPico_GetAllData ------------------------------------------------------------------------------------";
foreach my $RegisterName (keys %RegisterInfo)
{
### If the Register-Information belongs to the current Register
if ($RegisterInfo{$RegisterName}{RegisterBlockName} eq $RegisterI2CBlock)
{
if ($RegisterInfo{$RegisterName}{DataType} eq "Byte")
{
### Mark SelectionList Item as not yet found
my $FoundSelectionListItem = false;
### If SelectionList exists for this Register
if ($RegisterInfo{$RegisterName}{SelectionList} ne undef)
{
### Extract Selectionlist from hash
my %SelectionList = %{$RegisterInfo{$RegisterName}{SelectionList}};
### For debugging purposes only
Log3 $name, 5, $name. " : UpsPico_GetAllData -----------------Finding the Selection List entries for " . $RegisterName . "--------------------------------------------------------";
Log3 $name, 5, $name. " : UpsPico_GetAllData - Register to be searched in SeletionListEntry : " . ($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]);
Log3 $name, 5, $name. " : UpsPico_GetAllData - Register to be searched in SeletionListEntry hex : " . hex($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]);
### Search for the correct alias in the SelectionList
foreach my $SeletionListEntry (keys %SelectionList)
{
Log3 $name, 5, $name. " : UpsPico_GetAllData - SeletionListEntry : " . ($SeletionListEntry);
### If the RegisterValue matches with the Key of the Selectionlist
if ((($SeletionListEntry) eq hex($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}])) && ($SeletionListEntry ne "Default"))
{
Log3 $name, 5, $name. " : UpsPico_GetAllData - Found matching SeletionListEntry for : " . $SeletionListEntry . ". The value is: " . $SelectionList{$SeletionListEntry};
### Save the alias as value into the Register - hash
$RegisterInfo{$RegisterName}{Value} = $SelectionList{$SeletionListEntry};
Log3 $name, 4, $name. " : UpsPico_GetAllData - SelectionList Alias from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
### Mark SelectionList Item as bein already found
$FoundSelectionListItem = true;
}
### If there is no match
else
{
Log3 $name, 5, $name. " : UpsPico_GetAllData - Found NO matching SeletionListEntry for : " . $SeletionListEntry;
### Only set default value if the SelectionList item has not been found yet
if ($FoundSelectionListItem == false)
{
### Save the default value as value into the Register - hash
$RegisterInfo{$RegisterName}{Value} = $SelectionList{Default};
Log3 $name, 4, $name. " : UpsPico_GetAllData - SelectionList Default from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
}
}
}
Log3 $name, 4, $name. " : UpsPico_GetAllData - Byte Value with SelectionList formation from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
### If the SelectionList Vaulue is a mathematical function which needs to be calculated
if (index($RegisterInfo{$RegisterName}{Value}, "Function: ") != -1)
{
### Transform RegisterValue from hex into integer
my $RegisterValue = hex($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]);
### Extract formula from SelectionList
my $MathExpression = $RegisterInfo{$RegisterName}{Value};
### Remove the keyword "Function " from the function string
$MathExpression =~ s/Function: //;
### Create Parsing object for mathematical expression
my $MathParsingObject = Math::Expression::Evaluator->new;
### Perform parsing and do calculation
my $TempCalcResult = $MathParsingObject->parse("RegisterValue = " . $RegisterValue . "; " . $MathExpression)->val();
### Save the default value as value into the Register - hash
$RegisterInfo{$RegisterName}{Value} = $TempCalcResult;
### For debugging purposes only
Log3 $name, 5, $name. " : UpsPico_GetAllData - A mathematical formula has been found in the selection list.";
Log3 $name, 5, $name. " : UpsPico_GetAllData - RegisterValue : " . $RegisterValue;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Expression of formula in SeletctionList : " . $MathExpression;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Result of formula in TempCalcResult : " . $TempCalcResult;
}
}
### If SelectionList does not exists for this Register
else
{
### If the Byte Value is bound to a unit and shown as hex corresponds to BCD
if ($RegisterInfo{$RegisterName}{Unit} ne undef)
{
### Just write Register-Value into Hash
$RegisterInfo{$RegisterName}{Value} = $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}];
Log3 $name, 4, $name. " : UpsPico_GetAllData - Byte Value as BCD from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
}
### If the Byte Value is not bound to a unit so do not transform it
else
{
### Just write Register-Value into Hash
$RegisterInfo{$RegisterName}{Value} = "0x" . sprintf("%02d", $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]);
Log3 $name, 4, $name. " : UpsPico_GetAllData - Byte Value as hex from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
}
}
}
elsif ($RegisterInfo{$RegisterName}{DataType} eq "WordBCD")
{
$RegisterInfo{$RegisterName}{Value} = int($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} + 1] . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]) * $RegisterInfo{$RegisterName}{Factor};
Log3 $name, 4, $name. " : UpsPico_GetAllData - Word Value from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterBlock[RegisterInfo{RegisterName}{RegisterAddress} + 0 : " . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} ] ;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterBlock[RegisterInfo{RegisterName}{RegisterAddress} + 1 : " . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} + 1] ;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterBlock[RegisterInfo{RegisterName}{RegisterAddress} + 1 & +0 : " . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} + 1] . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}];
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterInfo{RegisterName}{Factor} : " . $RegisterInfo{$RegisterName}{Factor};
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterInfo{RegisterName}{Value} : " . $RegisterInfo{$RegisterName}{Value};
}
elsif ($RegisterInfo{$RegisterName}{DataType} eq "WordHex")
{
$RegisterInfo{$RegisterName}{Value} = hex($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} + 1] . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]) * $RegisterInfo{$RegisterName}{Factor};
Log3 $name, 4, $name. " : UpsPico_GetAllData - Word Value from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterBlock[RegisterInfo{RegisterName}{RegisterAddress} + 0 : " . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} ] ;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterBlock[RegisterInfo{RegisterName}{RegisterAddress} + 1 : " . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} + 1] ;
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterBlock[RegisterInfo{RegisterName}{RegisterAddress} + 1 & +0 : " . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress} + 1] . $RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}];
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterInfo{RegisterName}{Factor} : " . $RegisterInfo{$RegisterName}{Factor};
Log3 $name, 5, $name. " : UpsPico_GetAllData - Word Value - RegisterInfo{RegisterName}{Value} : " . $RegisterInfo{$RegisterName}{Value};
}
elsif ($RegisterInfo{$RegisterName}{DataType} eq "ASCII")
{
$RegisterInfo{$RegisterName}{Value} = chr(hex($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]));
Log3 $name, 4, $name. " : UpsPico_GetAllData - ASCII Value from " . $RegisterI2CBlock . " Register stored in Register-Hash for " . $RegisterName;
}
elsif ($RegisterInfo{$RegisterName}{DataType} eq "Hex")
{
$RegisterInfo{$RegisterName}{Value} = hex($RegisterBlock[$RegisterInfo{$RegisterName}{RegisterAddress}]);
Log3 $name, 4, $name. " : UpsPico_GetAllData - Hex Value from " . $RegisterI2CBlock . " Register transformed into Integer and stored in Register-Hash for " . $RegisterName;
}
else
{
$RegisterInfo{$RegisterName}{Value} = "ERROR";
Log3 $name, 2, $name. " : UpsPico_GetAllData - ERROR - No Data Type found in Register-Hash for " . $RegisterName;
}
### If the Register needs to be reset after reading, write 0x00 into register.
if(($RegisterInfo{$RegisterName}{Reset} == true))
{
my $SshCmdStatus = "sudo i2cset -y 1 " . $I2CAddress{$RegisterI2CBlock} . " " . $RegisterInfo{$RegisterName}{RegisterAddress} . " 0";
($stdout, $stderr, $exit) = $ssh->cmd($SshCmdStatus);
Log3 $name, 4, $name. " : UpsPico_GetAllData - Resetting Register to 0x00 for : " . $RegisterName;
Log3 $name, 5, $name. " : UpsPico_GetAllData - SshCmdStatus : " . $SshCmdStatus;
if(defined($stderr)) { Log3 $name, 2, $name. " : UpsPico_GetAllData - stderr Reset : " . $stderr; }
if(defined($exit)) { Log3 $name, 5, $name. " : UpsPico_GetAllData - exit Reset : " . $exit; }
if(defined($stdout)) { Log3 $name, 5, $name. " : UpsPico_GetAllData - stdout Reset : \n" . $stdout; }
Log3 $name, 5, $name. " : UpsPico_GetAllData ------------------------------------------------------------------------------------";
}
### Write current value
readingsSingleUpdate($hash, "/" . $RegisterI2CBlock . "/" . $RegisterName, $RegisterInfo{$RegisterName}{Value},1);
}
}
}
####END###### Download Register ########################################################################END#####
}
####END####### Download register block from UPS PIco via ssh command #######################################END#####
###START###### Calculate and save Battery charging status #################################################START####
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - battype value : " . $RegisterInfo{"battype"}{Value};
if ($RegisterInfo{"battype"}{Value} ne undef)
{
my $ChargeState;
my $BattType = $RegisterInfo{"battype"}{Value};
my $FoundBatteryItem = false;
my $BattChargingState = "ERROR - No Battery found";
### Search for the correct alias in the SelectionList
foreach my $BattInfoEntry (keys %BattChargingInfo)
{
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - BattInfoEntry : " . $RegisterInfo{"battype"}{Value};
### If the entry has been found
if ($BattInfoEntry eq $BattType)
{
### For debugging purpose only
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - Found battype! ";
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - BattType : " . $BattInfoEntry;
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - 0 Percent Voltage : " . $BattChargingInfo{$BattInfoEntry}{Volt0Percent};
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - 100 Percent Voltage : " . $BattChargingInfo{$BattInfoEntry}{Volt100Percent};
Log3 $name, 5, $name. " : UpsPico_GetAllData - charge status - Measured Voltage : " . $RegisterInfo{"batlevel"}{Value};
my $BatVoltageLevel = $RegisterInfo{"batlevel"}{Value};
### Limit Voltagelevel to maximum to avoid indication of temporary overcharging
if ($BatVoltageLevel > $BattChargingInfo{$BattInfoEntry}{Volt100Percent})
{
$BatVoltageLevel = $BattChargingInfo{$BattInfoEntry}{Volt100Percent}
}
### Calculate Battery state of charging
$BattChargingState = sprintf("%02d", ((($BatVoltageLevel - $BattChargingInfo{$BattInfoEntry}{Volt0Percent}) / ($BattChargingInfo{$BattInfoEntry}{Volt100Percent} - $BattChargingInfo{$BattInfoEntry}{Volt0Percent})) * 100));
}
}
### Write current value to reading and STATE
readingsSingleUpdate($hash, "BattCharge", $BattChargingState,1);
$hash->{STATE} = $BattChargingState;
Log3 $name, 4, $name. " : UpsPico_GetAllData - charge status - BattChargingState : " . $BattChargingState;
}
####END####### Calculate and save Battery charging status ##################################################END#####
### For Debugging purpose only
Log3 $name, 5, $name. " : UpsPico_GetAllData - RegisterInfo in fhem-hash : \n" . Dumper \$hash->{temp}{RegisterInfo};
Log3 $name, 5, $name. " : UpsPico_GetAllData -----------------------------------------------------------------";
### Close SSH session
undef $ssh;
Log3 $name, 4, $name. " : UpsPico_GetAllData - SSH session closed";
Log3 $name, 5, $name. " : UpsPico_GetAllData ----------------------------------------------------------------------------------------------------------------";
####END####### Download register block from UPS PIco via ssh command #######################################END#####
#### Initiate the timer for continuous polling of all data from UpsPico
InternalTimer(gettimeofday()+$PollingInterval, "UpsPico_GetAllData", $hash, 0);
Log3 $name, 4, $name. " : UpsPico_GetAllData - Define: InternalTimer for GettAllData re-started with interval of: " . $PollingInterval . " s";
###START###### Reset fullResponse error message ############################################################START####
readingsSingleUpdate( $hash, "fullResponse", "Standby", 1);
####END####### Reset fullResponse error message #############################################################END#####
}
####END####### Download all register ###########################################################################END#####
1;
=pod
=item device
=item summary Connects fhem to UpsPIco on remote RasPi
=item summary_DE Verbindet fhem mit einem UpsPIco auf einem entfernten RasPi
=begin html
<a name="UpsPico"></a>
<h3>UpsPico</h3>
<ul>
<table>
<tr>
<td>
The UpsPIco is an interruptible Power Supply for the Raspberry Pi from PiModules. This module is written for the Firmware Version 0x38 and above and has been tested on the "UPS PIco HV3.0A Stack Plus" only.<BR>
This module provides all the internal data written in the UpsPIco register which are accessible via I2C - Bus. The set command is able to change the values in accordance to the specifications.<BR>
For details to the Information contained in the register, please consult the internal register specification published in the latest manual. (See below)<BR>
<BR>
<u>References:</u><BR>
<a href="http://www.pimodulescart.com/shop/item.aspx?itemid=29">UPS PIco HV3.0A Stack Plus</a><BR>
<a href="http://www.forum.pimodules.com/viewforum.php?f=25">UPS PIco HV3.0A : Internal Register Specification, Manuals and Firmware Updates</a><BR>
<BR>
</td>
</tr>
</table>
<table>
<tr><td><a name="UpsPicodefine"></a><b>Define</b></td></tr>
</table>
<table><tr><td><ul><code>define &lt;name&gt; UpsPico &lt;IPv4-address&gt; &lt;Username&gt; &lt;Password&gt;</code></ul></td></tr></table>
<ul><ul>
<table>
<tr><td><code>&lt;name&gt;</code> : </td><td>The name of the device. Recommendation: "myUpsPico".</td></tr>
<tr><td><code>&lt;IPv4-address&gt;</code> : </td><td>A valid IPv4 address of the Raspberry Pi with UpsPIco. You might look into your router which DHCP address has been given to the RasPi.</td></tr>
<tr><td><code>&lt;GatewayPassword&gt;</code> : </td><td>The username of the remote Raspberry Pi.</td></tr>
<tr><td><code>&lt;PrivatePassword&gt;</code> : </td><td>The password of the remote Raspberry Pi.</td></tr>
</table>
</ul></ul>
<BR>
<table>
<tr><td><a name="UpsPicoSet"></a><b>Set</b></td></tr>
<tr><td>
<ul>
The set function is able to change a value which is marked as writeable.<BR>
If the register is considered as a critical setting (e.g. a wrong value might result in permanent damage), the attribute "WriteCritical" must be set to "1" = yes beforehand.
</ul>
</td></tr>
</table>
<table><tr><td><ul><code>set &lt;name&gt; &lt;register&gt; &lt;value&gt;</code></ul></td></tr></table>
<ul><ul>
<table>
<tr><td><code>&lt;name&gt;</code> : </td><td>The name of the defined UpsPico device<BR></td></tr>
<tr><td><code>&lt;register&gt;</code> : </td><td>The name of the register which value shall be set. E.g.: "<code>/Status/key</code>"<BR></td></tr>
<tr><td><code>&lt;value&gt;</code> : </td><td>A valid value for this register.<BR></td></tr>
</table>
</ul></ul>
<BR>
<table>
<tr><td><a name="UpsPicoGet"></a><b>Get</b></td></tr>
<tr><td>
<ul>
The get function is able to obtain a value of a register.<BR>
It returns only the value but not the unit or the range or list of allowed values possible.<BR>
</ul>
</td></tr>
</table>
<table><tr><td><ul><code>get &lt;name&gt; &lt;register&gt;</code></ul></td></tr></table>
<ul><ul>
<table>
<tr><td><code>&lt;name&gt;</code> : </td><td>The name of the defined UpsPico device<BR></td></tr>
<tr><td><code>&lt;register&gt;</code> : </td><td>The name of the register which value shall be obtained. E.g.: "<code>/Status/key</code>"<BR></td></tr>
</td>
</tr>
</table>
</ul></ul>
<BR>
<table>
<tr><td><a name="UpsPicoAttr"></a><b>Attributes</b></td></tr>
<tr><td>
<ul>
<BR>
The following user attributes can be used with the UpsPico module in addition to the general ones e.g. <a href="#room">room</a>.<BR>
</ul>
</td></tr>
</table>
<table>
<td>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>PollingInterval</code> : </li></td><td>A valid polling interval for the values of the UPS PIco. The value must be >=20s to allow the UpsPico module to perform a full polling procedure. <BR>
The default value is 300s.<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>WriteCritical</code> : </li></td><td>Prevents acidential damaging of the UpsPico hardware by change of critical register with wrong values.<BR>
The attribute must be re-activated for every single set-command.<BR>
The default value is 0 = deactivated<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>Port</code> : </li></td><td>The port number for the SSH access on the remote system.<BR>
The default value is 22 = Standard SSH port<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>CredentialsEncrypted</code> : </li></td><td>This attributes will swap from plain text to base64 encrypted credentials in the definition.<BR>
The default value is 0 = Plain Text Credentials<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>DbLogExclude</code> : </li></td><td>This general attribute will be set automatically to the reading "/Status/pico_is_running" which is a continously counting WatchDog register.<BR>
It makes no sense to log this reading.<BR>
The default exclusion from logging is "/Status/pico_is_running" <BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>event-on-change-reading</code> : </li></td><td>This general attribute will be set automatically to ".*" which prevents unchanged but updated readings to be logged.<BR>
The default value is ".*" = Apply to all readings.<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>room</code> : </li></td><td>This general attribute will be set automatically to "UpsPIco" which prevents the device getting lost in the "Everything" room.<BR>
The default value is "UpsPIco".<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
</td>
</table>
</ul>
=end html
=begin html_DE
<a name="UpsPico"></a>
<h3>UpsPico</h3>
<ul>
<table>
<tr>
<td>
Der UpsPIco ist eine unterbrechungsfreie Stroimversorgung f&uuml;r den Raspberry Pi von PiModules. Dieses Modul wurde f&uuml;r die Firmware ab Version 0x38 und h&ouml;her geschrieben und wurde nur auf dem "UPS PIco HV3.0A Stack Plus" getestet.<BR>
Dieses Modul stellt alle internen Daten zur Verf&uuml;gung, welche in die UpsPIco Register geschrieben und &uuml;ber den I2C - Bus ausgelesen werden. Der set-Befehl ist dar&uuml;ber hinaus in der Lage die Werte der Register entsprechend Ihrer Spezifikation zu &auml;ndern.<BR>
Detailierte Informationen zu den einzelnen Registern stehen in den Register Spezifikationen in der letzten ver&ouml;ffentlichten Anleitung. (Siehe unten)<BR>
<BR>
<u>Referenzen:</u><BR>
<a href="http://www.pimodulescart.com/shop/item.aspx?itemid=29">UPS PIco HV3.0A Stack Plus</a><BR>
<a href="http://www.forum.pimodules.com/viewforum.php?f=25">UPS PIco HV3.0A : Interne Register Spezification, Anleitung and Firmware Updates</a><BR>
<BR>
</td>
</tr>
</table>
<table>
<tr><td><a name="UpsPicodefine"></a><b>Define</b></td></tr>
</table>
<table><tr><td><ul><code>define &lt;name&gt; UpsPico &lt;IPv4-address&gt; &lt;Username&gt; &lt;Password&gt;</code></ul></td></tr></table>
<ul><ul>
<table>
<tr><td><code>&lt;name&gt;</code> : </td><td>Der Name des Device. Empfehlung: "myUpsPico".</td></tr>
<tr><td><code>&lt;IPv4-address&gt;</code> : </td><td>Eine g&uuml;ltige IPv4 Adresse des Raspberry Pi mit UpsPIco. Gegebenenfalls muss der Router f&uuml;r die an den Raspberry Pi vergebene DHCP Adresse konsultiert werden.</td></tr>
<tr><td><code>&lt;GatewayPassword&gt;</code> : </td><td>Der Username des entfernten Raspberry Pi.</td></tr>
<tr><td><code>&lt;PrivatePassword&gt;</code> : </td><td>Das Passwort des entfernten Raspberry Pi.</td></tr>
</table>
</ul></ul>
<BR>
<table>
<tr><td><a name="UpsPicoSet"></a><b>Set</b></td></tr>
<tr><td>
<ul>
Diese Funktion ver&auml;ndert die Werte der register, welche als beschreibbar definiert sind.<BR>
Sind die entsprechenden Register als kritisch (critical) spezifiziert (Ein falscher Wert k&ouml;nnte zur Besch&auml;digung des UpsPIco f&uuml;hren), muss das Atttribut "WriteCritical" vorher auf "1" gesetzt werden.
</ul>
</td></tr>
</table>
<table><tr><td><ul><code>set &lt;name&gt; &lt;register&gt; &lt;value&gt;</code></ul></td></tr></table>
<ul><ul>
<table>
<tr><td><code>&lt;name&gt;</code> : </td><td>Der name des definierten UpsPico Device<BR></td></tr>
<tr><td><code>&lt;register&gt;</code> : </td><td>Der name des Registers welches ver&auml;ndert werden soll. E.g.: "<code>/Status/key</code>"<BR></td></tr>
<tr><td><code>&lt;value&gt;</code> : </td><td>Ein g&uuml;ltiger Wert f&uuml;r das Register.<BR></td></tr>
</table>
</ul></ul>
<BR>
<table>
<tr><td><a name="UpsPicoGet"></a><b>Get</b></td></tr>
<tr><td>
<ul>
Die get Funktion liest einzelne Register aus und schreibt sie in das entsprechende Reading.<BR>
Es wird nur der Wert, aber nicht die Einheit oder der g&uuml;ltige Wertebereich zur&uuml;ckgegeben.<BR>
</ul>
</td></tr>
</table>
<table><tr><td><ul><code>get &lt;name&gt; &lt;register&gt;</code></ul></td></tr></table>
<ul><ul>
<table>
<tr><td><code>&lt;name&gt;</code> : </td><td>Der name des definierten UpsPico Device<BR></td></tr>
<tr><td><code>&lt;register&gt;</code> : </td><td>Der name des Registers welches ausgelesen werden soll. E.g.: "<code>/Status/key</code>"<BR></td></tr>
</td>
</tr>
</table>
</ul></ul>
<BR>
<table>
<tr><td><a name="UpsPicoAttr"></a><b>Attributes</b></td></tr>
<tr><td>
<ul>
<BR>
Die folgenden Attribute k&ouml;nnen neben den allgemeinen Attributen wie <a href="#room">room</a> vergeben werden.<BR>
</ul>
</td></tr>
</table>
<table>
<td>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>PollingInterval</code> : </li></td><td>Abrageinterval f&uuml;r den UPS PIco. Der Wert muss >=20s sein um einen vollen Polling Zyklus zu erlauben.<BR>
Der Defaul Wert ist 300s.<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>WriteCritical</code> : </li></td><td>Verhindert versehentliche Besch&auml;digungen durch Beschreiben der kritischen Register mit falschen Werten.<BR>
Musz f&uuml;r jeden einzelnen Schreibvorgang erneut gesetzt werden da dieser zur&uuml;ckgesetzt wird..<BR>
Der Default Wert ist 0 = Deaktiviert.<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>Port</code> : </li></td><td>Port Nummer f&uuml;r den SSH Zugang am entfernten Raspberry Pi.<BR>
Der Default Wert ist 22 = Standard SSH Port<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>CredentialsEncrypted</code> : </li></td><td>Definiert ob die Anmeldedaten in lesbarer Form (PlainText) oder als base64 verschl&uuml;sselt vorliegen.<BR>
Der Default Wert ist 0 = Anmeldedaten liegen in PlainText vor.<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>DbLogExclude</code> : </li></td><td>Generelles Attribut um Readings von Loggen auszuschließen. Das Attribut wird automatisch auf "/Status/pico_is_running" gesetzt welchen den kontinuierlichen Watchdog Z&auml;hler vom loggen ausnimmt.<BR>
Es ergibt keinen Sinn dieses Reading zu loggen.<BR>
Der Default Wert f&uuml;r die Ausnahme vom loggen liegt auf dem Reading "/Status/pico_is_running" <BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>event-on-change-reading</code> : </li></td><td>Generelles Attribut um Events nur bei &auml;nderungen von Readings zu erzeugen. Das Attribut wird automatisch auf ".*" gesetzt, was alle Readings nur bei &auml;nderungen loggt.<BR>
Der Default Wert ist ".*" = Alle Readings.<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
<ul><ul>
<tr>
<td>
<BR>
<tr><td><ul><li><code>room</code> : </li></td><td>Generelles Attribut zum setzen des Raumes. Das Attribut wird automatisch auf "UpsPIco" gesetzt, damit das device nicht im "Everthing" Raum verschwindet.<BR>
Der Default Wert ist "UpsPIco".<BR>
</ul></td></tr>
</td>
</tr>
</ul></ul>
</td>
</table>
</ul>
=end html_DE