mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 03:06:37 +00:00
73_GardenaSmartBridge/Device: fix typo oK to ok, change to package
git-svn-id: https://svn.fhem.de/fhem/trunk@17536 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
36b95156ad
commit
4e0c1e7b30
@ -1,5 +1,7 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- bugfix: 73_GardenaSmartBridge/Device fix typo oK to ok, change to
|
||||
package System
|
||||
- change: 93_DbRep: V8.2.3, check availability of DbLog-device at
|
||||
definition time of DbRep-device
|
||||
- change: 93_Log2Syslog: send BSD-format changed, commandref revised
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,40 +53,25 @@
|
||||
##
|
||||
##
|
||||
|
||||
|
||||
|
||||
package main;
|
||||
|
||||
|
||||
my $missingModul = "";
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Time::Local;
|
||||
|
||||
eval "use JSON;1" or $missingModul .= "JSON ";
|
||||
|
||||
|
||||
my $version = "1.2.2";
|
||||
|
||||
|
||||
|
||||
|
||||
# Declare functions
|
||||
sub GardenaSmartDevice_Attr(@);
|
||||
sub GardenaSmartDevice_Define($$);
|
||||
sub GardenaSmartDevice_Initialize($);
|
||||
sub GardenaSmartDevice_Set($@);
|
||||
sub GardenaSmartDevice_Undef($$);
|
||||
sub GardenaSmartDevice_WriteReadings($$);
|
||||
sub GardenaSmartDevice_Parse($$);
|
||||
sub GardenaSmartDevice_ReadingLangGerman($$);
|
||||
sub GardenaSmartDevice_RigRadingsValue($$);
|
||||
sub GardenaSmartDevice_Zulu2LocalString($);
|
||||
sub GardenaSmartDevice_SetPredefinedStartPoints($@);
|
||||
|
||||
|
||||
# # Declare functions
|
||||
# sub GardenaSmartDevice_Attr(@);
|
||||
# sub GardenaSmartDevice_Define($$);
|
||||
# sub GardenaSmartDevice_Initialize($);
|
||||
# sub GardenaSmartDevice_Set($@);
|
||||
# sub GardenaSmartDevice_Undef($$);
|
||||
# sub GardenaSmartDevice_WriteReadings($$);
|
||||
# sub GardenaSmartDevice_Parse($$);
|
||||
# sub GardenaSmartDevice_ReadingLangGerman($$);
|
||||
# sub GardenaSmartDevice_RigRadingsValue($$);
|
||||
# sub GardenaSmartDevice_Zulu2LocalString($);
|
||||
# sub GardenaSmartDevice_SetPredefinedStartPoints($@);
|
||||
|
||||
my $version = "1.4.0";
|
||||
|
||||
sub GardenaSmartDevice_Initialize($) {
|
||||
|
||||
@ -94,32 +79,71 @@ sub GardenaSmartDevice_Initialize($) {
|
||||
|
||||
$hash->{Match} = '^{"id":".*';
|
||||
|
||||
$hash->{SetFn} = "GardenaSmartDevice_Set";
|
||||
$hash->{DefFn} = "GardenaSmartDevice_Define";
|
||||
$hash->{UndefFn} = "GardenaSmartDevice_Undef";
|
||||
$hash->{ParseFn} = "GardenaSmartDevice_Parse";
|
||||
$hash->{SetFn} = "GardenaSmartDevice::Set";
|
||||
$hash->{DefFn} = "GardenaSmartDevice::Define";
|
||||
$hash->{UndefFn} = "GardenaSmartDevice::Undef";
|
||||
$hash->{ParseFn} = "GardenaSmartDevice::Parse";
|
||||
|
||||
$hash->{AttrFn} = "GardenaSmartDevice_Attr";
|
||||
$hash->{AttrList} = "readingValueLanguage:de,en ".
|
||||
"model:watering_computer,sensor,mower,ic24 ".
|
||||
"IODev ".
|
||||
$readingFnAttributes;
|
||||
$hash->{AttrFn} = "GardenaSmartDevice::Attr";
|
||||
$hash->{AttrList} =
|
||||
"readingValueLanguage:de,en "
|
||||
. "model:watering_computer,sensor,mower,ic24 "
|
||||
. "IODev "
|
||||
. $readingFnAttributes;
|
||||
|
||||
foreach my $d(sort keys %{$modules{GardenaSmartDevice}{defptr}}) {
|
||||
foreach my $d ( sort keys %{ $modules{GardenaSmartDevice}{defptr} } ) {
|
||||
|
||||
my $hash = $modules{GardenaSmartDevice}{defptr}{$d};
|
||||
$hash->{VERSION} = $version;
|
||||
}
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_Define($$) {
|
||||
## unserer packagename
|
||||
package GardenaSmartDevice;
|
||||
|
||||
use GPUtils qw(:all)
|
||||
; # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt
|
||||
|
||||
my $missingModul = "";
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX;
|
||||
|
||||
use Time::Local;
|
||||
|
||||
eval "use JSON;1" or $missingModul .= "JSON ";
|
||||
|
||||
## Import der FHEM Funktionen
|
||||
BEGIN {
|
||||
GP_Import(
|
||||
qw(readingsSingleUpdate
|
||||
readingsBulkUpdate
|
||||
readingsBulkUpdateIfChanged
|
||||
readingsBeginUpdate
|
||||
readingsEndUpdate
|
||||
Log3
|
||||
CommandAttr
|
||||
AttrVal
|
||||
ReadingsVal
|
||||
AssignIoPort
|
||||
modules
|
||||
IOWrite
|
||||
defs)
|
||||
);
|
||||
}
|
||||
|
||||
sub Define($$) {
|
||||
|
||||
my ( $hash, $def ) = @_;
|
||||
my @a = split( "[ \t]+", $def );
|
||||
|
||||
return "too few parameters: define <NAME> GardenaSmartDevice <device_Id> <model>" if( @a < 3 ) ;
|
||||
return "Cannot define Gardena Bridge device. Perl modul $missingModul is missing." if ( $missingModul );
|
||||
|
||||
return
|
||||
"too few parameters: define <NAME> GardenaSmartDevice <device_Id> <model>"
|
||||
if ( @a < 3 );
|
||||
return
|
||||
"Cannot define Gardena Bridge device. Perl modul $missingModul is missing."
|
||||
if ($missingModul);
|
||||
|
||||
my $name = $a[0];
|
||||
my $deviceId = $a[2];
|
||||
@ -129,17 +153,19 @@ sub GardenaSmartDevice_Define($$) {
|
||||
$hash->{VERSION} = $version;
|
||||
$hash->{helper}{STARTINGPOINTID} = '';
|
||||
|
||||
CommandAttr( undef,
|
||||
"$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}" )
|
||||
if ( AttrVal( $name, 'IODev', 'none' ) eq 'none' );
|
||||
|
||||
my $iodev = AttrVal( $name, 'IODev', 'none' );
|
||||
|
||||
CommandAttr(undef,"$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}") if(AttrVal($name,'IODev','none') eq 'none');
|
||||
AssignIoPort( $hash, $iodev ) if ( !$hash->{IODev} );
|
||||
|
||||
my $iodev = AttrVal($name,'IODev','none');
|
||||
|
||||
AssignIoPort($hash,$iodev) if( !$hash->{IODev} );
|
||||
|
||||
if(defined($hash->{IODev}->{NAME})) {
|
||||
Log3 $name, 3, "GardenaSmartDevice ($name) - I/O device is " . $hash->{IODev}->{NAME};
|
||||
} else {
|
||||
if ( defined( $hash->{IODev}->{NAME} ) ) {
|
||||
Log3 $name, 3, "GardenaSmartDevice ($name) - I/O device is "
|
||||
. $hash->{IODev}->{NAME};
|
||||
}
|
||||
else {
|
||||
Log3 $name, 1, "GardenaSmartDevice ($name) - no I/O device";
|
||||
}
|
||||
|
||||
@ -147,255 +173,395 @@ sub GardenaSmartDevice_Define($$) {
|
||||
|
||||
my $d = $modules{GardenaSmartDevice}{defptr}{$deviceId};
|
||||
|
||||
return "GardenaSmartDevice device $name on GardenaSmartBridge $iodev already defined."
|
||||
if( defined($d) and $d->{IODev} == $hash->{IODev} and $d->{NAME} ne $name );
|
||||
return
|
||||
"GardenaSmartDevice device $name on GardenaSmartBridge $iodev already defined."
|
||||
if ( defined($d)
|
||||
and $d->{IODev} == $hash->{IODev}
|
||||
and $d->{NAME} ne $name );
|
||||
|
||||
#$attr{$name}{room} = "GardenaSmart" if( not defined( $attr{$name}{room} ) );
|
||||
CommandAttr( undef, $name . ' room GardenaSmart' )
|
||||
if ( AttrVal( $name, 'room', 'none' ) eq 'none' );
|
||||
|
||||
#$attr{$name}{room} = "GardenaSmart" if( not defined( $attr{$name}{room} ) );
|
||||
CommandAttr(undef,$name.' room GardenaSmart') if( AttrVal($name,'room','none') eq 'none');
|
||||
#$attr{$name}{model} = $category if( not defined( $attr{$name}{model} ) );
|
||||
CommandAttr(undef,$name.' model '.$category) if( AttrVal($name,'model','none') eq 'none');
|
||||
#$attr{$name}{model} = $category if( not defined( $attr{$name}{model} ) );
|
||||
CommandAttr( undef, $name . ' model ' . $category )
|
||||
if ( AttrVal( $name, 'model', 'none' ) eq 'none' );
|
||||
|
||||
Log3 $name, 3, "GardenaSmartDevice ($name) - defined GardenaSmartDevice with DEVICEID: $deviceId";
|
||||
readingsSingleUpdate($hash,'state','initialized',1);
|
||||
Log3 $name, 3,
|
||||
"GardenaSmartDevice ($name) - defined GardenaSmartDevice with DEVICEID: $deviceId";
|
||||
readingsSingleUpdate( $hash, 'state', 'initialized', 1 );
|
||||
|
||||
$modules{GardenaSmartDevice}{defptr}{$deviceId} = $hash;
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_Undef($$) {
|
||||
sub Undef($$) {
|
||||
|
||||
my ( $hash, $arg ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $deviceId = $hash->{DEVICEID};
|
||||
|
||||
|
||||
delete $modules{GardenaSmartDevice}{defptr}{$deviceId};
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_Attr(@) {
|
||||
sub Attr(@) {
|
||||
|
||||
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
||||
my $hash = $defs{$name};
|
||||
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_Set($@) {
|
||||
sub Set($@) {
|
||||
|
||||
my ( $hash, $name, $cmd, @args ) = @_;
|
||||
|
||||
my ($hash, $name, $cmd, @args) = @_;
|
||||
#my ($arg, @params) = @args;
|
||||
|
||||
my $payload;
|
||||
my $abilities = '';
|
||||
|
||||
|
||||
### mower
|
||||
if( lc $cmd eq 'parkuntilfurthernotice' ) {
|
||||
if ( lc $cmd eq 'parkuntilfurthernotice' ) {
|
||||
|
||||
$payload = '"name":"park_until_further_notice"';
|
||||
|
||||
} elsif( lc $cmd eq 'parkuntilnexttimer' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'parkuntilnexttimer' ) {
|
||||
|
||||
$payload = '"name":"park_until_next_timer"';
|
||||
|
||||
} elsif( lc $cmd eq 'startresumeschedule' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'startresumeschedule' ) {
|
||||
|
||||
$payload = '"name":"start_resume_schedule"';
|
||||
|
||||
} elsif( lc $cmd eq 'startoverridetimer' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'startoverridetimer' ) {
|
||||
|
||||
my $duration = join( " ", @args );
|
||||
$payload = '"name":"start_override_timer","parameters":{"duration":' . $duration . '}';
|
||||
$payload = '"name":"start_override_timer","parameters":{"duration":'
|
||||
. $duration . '}';
|
||||
|
||||
} elsif( lc $cmd eq 'startpoint' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'startpoint' ) {
|
||||
my $err;
|
||||
|
||||
($err,$payload,$abilities) = GardenaSmartDevice_SetPredefinedStartPoints($hash,@args);
|
||||
return $err if( defined($err) );
|
||||
( $err, $payload, $abilities ) =
|
||||
SetPredefinedStartPoints( $hash, @args );
|
||||
return $err if ( defined($err) );
|
||||
|
||||
### watering_computer
|
||||
} elsif( lc $cmd eq 'manualoverride' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'manualoverride' ) {
|
||||
|
||||
my $duration = join( " ", @args );
|
||||
$payload = '"name":"manual_override","parameters":{"duration":' . $duration . '}';
|
||||
$payload = '"name":"manual_override","parameters":{"duration":'
|
||||
. $duration . '}';
|
||||
|
||||
} elsif( lc $cmd eq 'canceloverride' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'canceloverride' ) {
|
||||
|
||||
$payload = '"name":"cancel_override"';
|
||||
|
||||
### Watering ic24
|
||||
} elsif( $cmd =~ /manualDurationValve/ ) {
|
||||
}
|
||||
elsif ( $cmd =~ /manualDurationValve/ ) {
|
||||
|
||||
my $valve_id;
|
||||
my $duration = join( " ", @args );
|
||||
|
||||
if( $cmd =~ m#(\d)$# ) {
|
||||
if ( $cmd =~ m#(\d)$# ) {
|
||||
$valve_id = $1;
|
||||
}
|
||||
|
||||
$payload = '"properties":{"name":"watering_timer_' . $valve_id . '","value":{"state":"manual","duration":' . $duration . ',"valve_id":' . $valve_id . '}}';
|
||||
$payload =
|
||||
'"properties":{"name":"watering_timer_'
|
||||
. $valve_id
|
||||
. '","value":{"state":"manual","duration":'
|
||||
. $duration
|
||||
. ',"valve_id":'
|
||||
. $valve_id . '}}';
|
||||
|
||||
### Sensors
|
||||
} elsif( lc $cmd eq 'refresh' ) {
|
||||
}
|
||||
elsif ( lc $cmd eq 'refresh' ) {
|
||||
|
||||
my $sensname = join( " ", @args );
|
||||
if( lc $sensname eq 'temperature' ) {
|
||||
if ( lc $sensname eq 'temperature' ) {
|
||||
$payload = '"name":"measure_ambient_temperature"';
|
||||
$abilities = 'ambient_temperature';
|
||||
|
||||
} elsif( lc $sensname eq 'light' ) {
|
||||
}
|
||||
elsif ( lc $sensname eq 'light' ) {
|
||||
$payload = '"name":"measure_light"';
|
||||
$abilities = 'light';
|
||||
|
||||
} elsif( lc $sensname eq 'humidity' ) {
|
||||
}
|
||||
elsif ( lc $sensname eq 'humidity' ) {
|
||||
$payload = '"name":"measure_soil_humidity"';
|
||||
$abilities = 'humidity';
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
my $list = '';
|
||||
$list .= 'parkUntilFurtherNotice:noArg parkUntilNextTimer:noArg startResumeSchedule:noArg startOverrideTimer:slider,0,60,1440 startpoint' if( AttrVal($name,'model','unknown') eq 'mower' );
|
||||
$list .= 'manualOverride:slider,0,1,59 cancelOverride:noArg' if( AttrVal($name,'model','unknown') eq 'watering_computer' );
|
||||
$list .= 'manualDurationValve1:slider,1,1,59 manualDurationValve2:slider,1,1,59 manualDurationValve3:slider,1,1,59 manualDurationValve4:slider,1,1,59 manualDurationValve5:slider,1,1,59 manualDurationValve6:slider,1,1,59' if( AttrVal($name,'model','unknown') eq 'ic24' );
|
||||
$list .= 'refresh:temperature,light,humidity' if( AttrVal($name,'model','unknown') eq 'sensor' );
|
||||
$list .=
|
||||
'parkUntilFurtherNotice:noArg parkUntilNextTimer:noArg startResumeSchedule:noArg startOverrideTimer:slider,0,60,1440 startpoint'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' );
|
||||
$list .= 'manualOverride:slider,0,1,59 cancelOverride:noArg'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
||||
$list .=
|
||||
'manualDurationValve1:slider,1,1,59 manualDurationValve2:slider,1,1,59 manualDurationValve3:slider,1,1,59 manualDurationValve4:slider,1,1,59 manualDurationValve5:slider,1,1,59 manualDurationValve6:slider,1,1,59'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
|
||||
$list .= 'refresh:temperature,light,humidity'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'sensor' );
|
||||
|
||||
return "Unknown argument $cmd, choose one of $list";
|
||||
}
|
||||
|
||||
$abilities = 'mower' if( AttrVal($name,'model','unknown') eq 'mower' ) and $abilities ne 'mower_settings';
|
||||
$abilities = 'outlet' if( AttrVal($name,'model','unknown') eq 'watering_computer' );
|
||||
$abilities = 'watering' if( AttrVal($name,'model','unknown') eq 'ic24' );
|
||||
|
||||
$abilities = 'mower'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' )
|
||||
and $abilities ne 'mower_settings';
|
||||
$abilities = 'outlet'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
||||
$abilities = 'watering'
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
|
||||
|
||||
$hash->{helper}{deviceAction} = $payload;
|
||||
readingsSingleUpdate( $hash, "state", "send command to gardena cloud", 1);
|
||||
readingsSingleUpdate( $hash, "state", "send command to gardena cloud", 1 );
|
||||
|
||||
IOWrite($hash,$payload,$hash->{DEVICEID},$abilities);
|
||||
Log3 $name, 4, "GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}";
|
||||
IOWrite( $hash, $payload, $hash->{DEVICEID}, $abilities );
|
||||
Log3 $name, 4,
|
||||
"GardenaSmartBridge ($name) - IOWrite: $payload $hash->{DEVICEID} $abilities IODevHash=$hash->{IODev}";
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_Parse($$) {
|
||||
sub Parse($$) {
|
||||
|
||||
my ($io_hash,$json) = @_;
|
||||
my ( $io_hash, $json ) = @_;
|
||||
|
||||
my $name = $io_hash->{NAME};
|
||||
|
||||
|
||||
|
||||
my $decode_json = eval{decode_json($json)};
|
||||
if($@){
|
||||
Log3 $name, 3, "GardenaSmartBridge ($name) - JSON error while request: $@";
|
||||
my $decode_json = eval { decode_json($json) };
|
||||
if ($@) {
|
||||
Log3 $name, 3,
|
||||
"GardenaSmartBridge ($name) - JSON error while request: $@";
|
||||
}
|
||||
|
||||
Log3 $name, 4, "GardenaSmartDevice ($name) - ParseFn was called";
|
||||
Log3 $name, 4, "GardenaSmartDevice ($name) - JSON: $json";
|
||||
|
||||
|
||||
if( defined($decode_json->{id}) ) {
|
||||
if ( defined( $decode_json->{id} ) ) {
|
||||
|
||||
my $deviceId = $decode_json->{id};
|
||||
|
||||
if( my $hash = $modules{GardenaSmartDevice}{defptr}{$deviceId} ) {
|
||||
if ( my $hash = $modules{GardenaSmartDevice}{defptr}{$deviceId} ) {
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
GardenaSmartDevice_WriteReadings($hash,$decode_json);
|
||||
Log3 $name, 4, "GardenaSmartDevice ($name) - find logical device: $hash->{NAME}";
|
||||
WriteReadings( $hash, $decode_json );
|
||||
Log3 $name, 4,
|
||||
"GardenaSmartDevice ($name) - find logical device: $hash->{NAME}";
|
||||
|
||||
return $hash->{NAME};
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
Log3 $name, 3, "GardenaSmartDevice ($name) - autocreate new device " . makeDeviceName($decode_json->{name}) . " with deviceId $decode_json->{id}, model $decode_json->{category}";
|
||||
return "UNDEFINED " . makeDeviceName($decode_json->{name}) . " GardenaSmartDevice $decode_json->{id} $decode_json->{category}";
|
||||
Log3 $name, 3,
|
||||
"GardenaSmartDevice ($name) - autocreate new device "
|
||||
. makeDeviceName( $decode_json->{name} )
|
||||
. " with deviceId $decode_json->{id}, model $decode_json->{category}";
|
||||
return
|
||||
"UNDEFINED "
|
||||
. makeDeviceName( $decode_json->{name} )
|
||||
. " GardenaSmartDevice $decode_json->{id} $decode_json->{category}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_WriteReadings($$) {
|
||||
sub WriteReadings($$) {
|
||||
|
||||
my ($hash,$decode_json) = @_;
|
||||
my ( $hash, $decode_json ) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my $abilities = scalar (@{$decode_json->{abilities}});
|
||||
my $settings = scalar (@{$decode_json->{settings}});
|
||||
|
||||
my $abilities = scalar( @{ $decode_json->{abilities} } );
|
||||
my $settings = scalar( @{ $decode_json->{settings} } );
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
do {
|
||||
|
||||
if( ref($decode_json->{abilities}[$abilities]{properties}) eq "ARRAY" and scalar(@{$decode_json->{abilities}[$abilities]{properties}}) > 0 ) {
|
||||
foreach my $propertie (@{$decode_json->{abilities}[$abilities]{properties}}) {
|
||||
readingsBulkUpdateIfChanged($hash,$decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name},GardenaSmartDevice_RigRadingsValue($hash,$propertie->{value})) if( defined($propertie->{value})
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'radio-quality'
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'battery-level'
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'internal_temperature-temperature'
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'ambient_temperature-temperature'
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'soil_temperature-temperature'
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'humidity-humidity'
|
||||
and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} ne 'light-light'
|
||||
and ref($propertie->{value}) ne "HASH" );
|
||||
if (
|
||||
ref( $decode_json->{abilities}[$abilities]{properties} ) eq "ARRAY"
|
||||
and
|
||||
scalar( @{ $decode_json->{abilities}[$abilities]{properties} } ) >
|
||||
0 )
|
||||
{
|
||||
foreach my $propertie (
|
||||
@{ $decode_json->{abilities}[$abilities]{properties} } )
|
||||
{
|
||||
readingsBulkUpdateIfChanged(
|
||||
$hash,
|
||||
$decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name},
|
||||
RigRadingsValue(
|
||||
$hash, $propertie->{value}
|
||||
)
|
||||
)
|
||||
if ( defined( $propertie->{value} )
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'radio-quality'
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'battery-level'
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'internal_temperature-temperature'
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'ambient_temperature-temperature'
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'soil_temperature-temperature'
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'humidity-humidity'
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} ne 'light-light'
|
||||
and ref( $propertie->{value} ) ne "HASH" );
|
||||
|
||||
readingsBulkUpdate($hash,$decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name},GardenaSmartDevice_RigRadingsValue($hash,$propertie->{value})) if( defined($propertie->{value})
|
||||
and ($decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'radio-quality'
|
||||
or $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'battery-level'
|
||||
or $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'internal_temperature-temperature'
|
||||
or $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'ambient_temperature-temperature'
|
||||
or $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'soil_temperature-temperature'
|
||||
or $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'humidity-humidity'
|
||||
or $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'light-light') );
|
||||
readingsBulkUpdate(
|
||||
$hash,
|
||||
$decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name},
|
||||
RigRadingsValue(
|
||||
$hash, $propertie->{value}
|
||||
)
|
||||
)
|
||||
if (
|
||||
defined( $propertie->{value} )
|
||||
and ( $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'radio-quality'
|
||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'battery-level'
|
||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq
|
||||
'internal_temperature-temperature'
|
||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq
|
||||
'ambient_temperature-temperature'
|
||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'soil_temperature-temperature'
|
||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'humidity-humidity'
|
||||
or $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'light-light' )
|
||||
);
|
||||
|
||||
readingsBulkUpdateIfChanged($hash,$decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name},join(',',@{$propertie->{value}})) if( defined($propertie->{value}) and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'ic24-valves_connected' );
|
||||
readingsBulkUpdateIfChanged(
|
||||
$hash,
|
||||
$decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name},
|
||||
join( ',', @{ $propertie->{value} } )
|
||||
)
|
||||
if ( defined( $propertie->{value} )
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'ic24-valves_connected' );
|
||||
|
||||
readingsBulkUpdateIfChanged($hash,$decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name},join(',',@{$propertie->{value}})) if( defined($propertie->{value}) and $decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name} eq 'ic24-valves_master_config' );
|
||||
readingsBulkUpdateIfChanged(
|
||||
$hash,
|
||||
$decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name},
|
||||
join( ',', @{ $propertie->{value} } )
|
||||
)
|
||||
if ( defined( $propertie->{value} )
|
||||
and $decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} eq 'ic24-valves_master_config' );
|
||||
|
||||
if( ref($propertie->{value}) eq "HASH" ) {
|
||||
while( my ($r,$v) = each %{$propertie->{value}} ) {
|
||||
readingsBulkUpdate($hash,$decode_json->{abilities}[$abilities]{name}.'-'.$propertie->{name}.'_'.$r,GardenaSmartDevice_RigRadingsValue($hash,$v));
|
||||
if ( ref( $propertie->{value} ) eq "HASH" ) {
|
||||
while ( my ( $r, $v ) = each %{ $propertie->{value} } ) {
|
||||
readingsBulkUpdate(
|
||||
$hash,
|
||||
$decode_json->{abilities}[$abilities]{name} . '-'
|
||||
. $propertie->{name} . '_'
|
||||
. $r,
|
||||
RigRadingsValue( $hash, $v )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$abilities--;
|
||||
} while ($abilities >= 0);
|
||||
|
||||
} while ( $abilities >= 0 );
|
||||
|
||||
do {
|
||||
|
||||
if( ref($decode_json->{settings}[$settings]{value}) eq "ARRAY" and $decode_json->{settings}[$settings]{name} eq 'starting_points' ) {
|
||||
if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY"
|
||||
and $decode_json->{settings}[$settings]{name} eq 'starting_points' )
|
||||
{
|
||||
#save the startingpointid needed to update the startingpoints
|
||||
if ($hash->{helper}{STARTINGPOINTID} ne $decode_json->{settings}[$settings]{id}) {
|
||||
$hash->{helper}{STARTINGPOINTID} = $decode_json->{settings}[$settings]{id};
|
||||
if ( $hash->{helper}{STARTINGPOINTID} ne
|
||||
$decode_json->{settings}[$settings]{id} )
|
||||
{
|
||||
$hash->{helper}{STARTINGPOINTID} =
|
||||
$decode_json->{settings}[$settings]{id};
|
||||
}
|
||||
|
||||
$hash->{helper}{STARTINGPOINTS} = '{ "name": "starting_points", "value": '. encode_json($decode_json->{settings}[$settings]{value}) . '}';
|
||||
$hash->{helper}{STARTINGPOINTS} =
|
||||
'{ "name": "starting_points", "value": '
|
||||
. encode_json( $decode_json->{settings}[$settings]{value} ) . '}';
|
||||
my $startpoint_cnt = 0;
|
||||
|
||||
foreach my $startingpoint (@{$decode_json->{settings}[$settings]{value}}) {
|
||||
foreach my $startingpoint (
|
||||
@{ $decode_json->{settings}[$settings]{value} } )
|
||||
{
|
||||
$startpoint_cnt++;
|
||||
readingsBulkUpdateIfChanged($hash,'startpoint-'.$startpoint_cnt.'-enabled',$startingpoint->{enabled});
|
||||
readingsBulkUpdateIfChanged(
|
||||
$hash,
|
||||
'startpoint-' . $startpoint_cnt . '-enabled',
|
||||
$startingpoint->{enabled}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$settings--;
|
||||
} while ($settings >= 0);
|
||||
} while ( $settings >= 0 );
|
||||
|
||||
readingsBulkUpdate( $hash, 'state',
|
||||
ReadingsVal( $name, 'mower-status', 'readingsValError' ) )
|
||||
if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' );
|
||||
readingsBulkUpdate(
|
||||
$hash, 'state',
|
||||
(
|
||||
ReadingsVal( $name, 'outlet-valve_open', 'readingsValError' ) == 1
|
||||
? RigRadingsValue( $hash, 'open' )
|
||||
: RigRadingsValue( $hash, 'closed' )
|
||||
)
|
||||
) if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
|
||||
|
||||
readingsBulkUpdate($hash,'state',ReadingsVal($name,'mower-status','readingsValError')) if( AttrVal($name,'model','unknown') eq 'mower' );
|
||||
readingsBulkUpdate($hash,'state',(ReadingsVal($name,'outlet-valve_open','readingsValError') == 1 ? GardenaSmartDevice_RigRadingsValue($hash,'open') : GardenaSmartDevice_RigRadingsValue($hash,'closed'))) if( AttrVal($name,'model','unknown') eq 'watering_computer' );
|
||||
readingsBulkUpdate(
|
||||
$hash, 'state',
|
||||
'T: '
|
||||
. ReadingsVal( $name, 'ambient_temperature-temperature',
|
||||
'readingsValError' )
|
||||
. '°C, H: '
|
||||
. ReadingsVal( $name, 'humidity-humidity', 'readingsValError' )
|
||||
. '%, L: '
|
||||
. ReadingsVal( $name, 'light-light', 'readingsValError' ) . 'lux'
|
||||
) if ( AttrVal( $name, 'model', 'unknown' ) eq 'sensor' );
|
||||
|
||||
readingsBulkUpdate($hash,'state','T: ' . ReadingsVal($name,'ambient_temperature-temperature','readingsValError') . '°C, H: ' . ReadingsVal($name,'humidity-humidity','readingsValError') . '%, L: ' . ReadingsVal($name,'light-light','readingsValError') . 'lux') if( AttrVal($name,'model','unknown') eq 'sensor' );
|
||||
|
||||
readingsBulkUpdate($hash,'state','scheduled watering next start: ' . (ReadingsVal($name,'scheduling-scheduled_watering_next_start','readingsValError'))) if( AttrVal($name,'model','unknown') eq 'ic24' );
|
||||
readingsBulkUpdate(
|
||||
$hash, 'state',
|
||||
'scheduled watering next start: '
|
||||
. (
|
||||
ReadingsVal(
|
||||
$name, 'scheduling-scheduled_watering_next_start',
|
||||
'readingsValError'
|
||||
)
|
||||
)
|
||||
) if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
|
||||
|
||||
readingsEndUpdate( $hash, 1 );
|
||||
|
||||
@ -406,12 +572,11 @@ sub GardenaSmartDevice_WriteReadings($$) {
|
||||
##################################
|
||||
#### my little helpers ###########
|
||||
|
||||
sub GardenaSmartDevice_ReadingLangGerman($$) {
|
||||
sub ReadingLangGerman($$) {
|
||||
|
||||
my ($hash,$readingValue) = @_;
|
||||
my ( $hash, $readingValue ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
|
||||
my %langGermanMapp = (
|
||||
'ok_cutting' => 'mähen',
|
||||
'paused' => 'pausiert',
|
||||
@ -423,7 +588,8 @@ sub GardenaSmartDevice_ReadingLangGerman($$) {
|
||||
'parked_timer' => 'geparkt nach Zeitplan',
|
||||
'parked_park_selected' => 'geparkt',
|
||||
'off_disabled' => 'der Mäher ist ausgeschaltet',
|
||||
'off_hatch_open' => 'deaktiviert. Abdeckung ist offen oder PIN-Code erforderlich',
|
||||
'off_hatch_open' =>
|
||||
'deaktiviert. Abdeckung ist offen oder PIN-Code erforderlich',
|
||||
'unknown' => 'unbekannter Status',
|
||||
'error' => 'Fehler',
|
||||
'error_at_power_up' => 'Neustart ...',
|
||||
@ -465,8 +631,10 @@ sub GardenaSmartDevice_ReadingLangGerman($$) {
|
||||
'guide_2_not_found' => 'SK 2 nicht gefunden',
|
||||
'guide_3_not_found' => 'SK 3 nicht gefunden',
|
||||
'difficult_finding_home' => 'Problem die Ladestation zu finden',
|
||||
'guide_calibration_accomplished' => 'Kalibrierung des Suchkabels beendet',
|
||||
'guide_calibration_failed' => 'Kalibrierung des Suchkabels fehlgeschlagen',
|
||||
'guide_calibration_accomplished' =>
|
||||
'Kalibrierung des Suchkabels beendet',
|
||||
'guide_calibration_failed' =>
|
||||
'Kalibrierung des Suchkabels fehlgeschlagen',
|
||||
'temporary_battery_problem' => 'kurzzeitiges Batterieproblem',
|
||||
'battery_problem' => 'Batterieproblem',
|
||||
'alarm_mower_switched_off' => 'Alarm! Mäher ausgeschalten',
|
||||
@ -480,8 +648,8 @@ sub GardenaSmartDevice_ReadingLangGerman($$) {
|
||||
'out_of_operation' => 'ausser Betrieb',
|
||||
'replace_now' => 'kritischer Batteriestand, wechseln Sie jetzt',
|
||||
'low' => 'niedrig',
|
||||
'ok' => 'oK',
|
||||
'no_source' => 'oK',
|
||||
'ok' => 'ok',
|
||||
'no_source' => 'ok',
|
||||
'mower_charging' => 'Mäher wurde geladen',
|
||||
'completed_cutting_autotimer' => 'Sensor Control erreicht',
|
||||
'week_timer' => 'Wochentimer erreicht',
|
||||
@ -509,103 +677,140 @@ sub GardenaSmartDevice_ReadingLangGerman($$) {
|
||||
'inactive' => 'nicht aktiv'
|
||||
);
|
||||
|
||||
if( defined($langGermanMapp{$readingValue}) and (AttrVal('global','language','none') eq 'DE' or AttrVal($name,'readingValueLanguage','none') eq 'de') and AttrVal($name,'readingValueLanguage','none') ne 'en') {
|
||||
if (
|
||||
defined( $langGermanMapp{$readingValue} )
|
||||
and ( AttrVal( 'global', 'language', 'none' ) eq 'DE'
|
||||
or AttrVal( $name, 'readingValueLanguage', 'none' ) eq 'de' )
|
||||
and AttrVal( $name, 'readingValueLanguage', 'none' ) ne 'en'
|
||||
)
|
||||
{
|
||||
return $langGermanMapp{$readingValue};
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return $readingValue;
|
||||
}
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_RigRadingsValue($$) {
|
||||
sub RigRadingsValue($$) {
|
||||
|
||||
my ($hash,$readingValue) = @_;
|
||||
my ( $hash, $readingValue ) = @_;
|
||||
|
||||
my $rigReadingValue;
|
||||
|
||||
|
||||
if( $readingValue =~ /^(\d+)-(\d\d)-(\d\d)T(\d\d)/ ) {
|
||||
$rigReadingValue = GardenaSmartDevice_Zulu2LocalString($readingValue);
|
||||
} else {
|
||||
$rigReadingValue = GardenaSmartDevice_ReadingLangGerman($hash,$readingValue);
|
||||
if ( $readingValue =~ /^(\d+)-(\d\d)-(\d\d)T(\d\d)/ ) {
|
||||
$rigReadingValue = Zulu2LocalString($readingValue);
|
||||
}
|
||||
else {
|
||||
$rigReadingValue =
|
||||
ReadingLangGerman( $hash, $readingValue );
|
||||
}
|
||||
|
||||
return $rigReadingValue;
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_Zulu2LocalString($) {
|
||||
sub Zulu2LocalString($) {
|
||||
|
||||
my $t = shift;
|
||||
my ($datehour,$datemin,$rest) = split(/:/,$t,3);
|
||||
my ( $datehour, $datemin, $rest ) = split( /:/, $t, 3 );
|
||||
|
||||
my ( $year, $month, $day, $hour, $min ) =
|
||||
$datehour =~ /(\d+)-(\d\d)-(\d\d)T(\d\d)/;
|
||||
my $epoch = timegm( 0, 0, $hour, $day, $month - 1, $year );
|
||||
|
||||
my ($year, $month, $day, $hour,$min) = $datehour =~ /(\d+)-(\d\d)-(\d\d)T(\d\d)/;
|
||||
my $epoch = timegm (0,0,$hour,$day,$month-1,$year);
|
||||
|
||||
my ($lyear,$lmonth,$lday,$lhour,$isdst) = (localtime($epoch))[5,4,3,2,-1];
|
||||
my ( $lyear, $lmonth, $lday, $lhour, $isdst ) =
|
||||
( localtime($epoch) )[ 5, 4, 3, 2, -1 ];
|
||||
|
||||
$lyear += 1900; # year is 1900 based
|
||||
$lmonth++; # month number is zero based
|
||||
|
||||
if( defined($rest) ) {
|
||||
return ( sprintf("%04d-%02d-%02d %02d:%02d:%s",$lyear,$lmonth,$lday,$lhour,$datemin,substr($rest,0,2)));
|
||||
} elsif( $lyear < 2000 ) {
|
||||
if ( defined($rest) ) {
|
||||
return (
|
||||
sprintf(
|
||||
"%04d-%02d-%02d %02d:%02d:%s",
|
||||
$lyear, $lmonth, $lday,
|
||||
$lhour, $datemin, substr( $rest, 0, 2 )
|
||||
)
|
||||
);
|
||||
}
|
||||
elsif ( $lyear < 2000 ) {
|
||||
return "illegal year";
|
||||
} else {
|
||||
return ( sprintf("%04d-%02d-%02d %02d:%02d",$lyear,$lmonth,$lday,$lhour,substr($datemin,0,2)));
|
||||
}
|
||||
else {
|
||||
return (
|
||||
sprintf(
|
||||
"%04d-%02d-%02d %02d:%02d",
|
||||
$lyear, $lmonth, $lday, $lhour, substr( $datemin, 0, 2 )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sub GardenaSmartDevice_SetPredefinedStartPoints($@) {
|
||||
sub SetPredefinedStartPoints($@) {
|
||||
|
||||
my ($hash,$startpoint_state,$startpoint_num,@morestartpoints) = @_;
|
||||
my ( $hash, $startpoint_state, $startpoint_num, @morestartpoints ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $payload;
|
||||
my $abilities;
|
||||
|
||||
|
||||
if (defined($startpoint_state) and defined($startpoint_num) ) {
|
||||
if (defined($hash->{helper}{STARTINGPOINTS}) and $hash->{helper}{STARTINGPOINTS} ne '') {
|
||||
# add needed parameters to saved settings config and change the value in request
|
||||
my $decode_json_settings = eval{decode_json($hash->{helper}{STARTINGPOINTS})};
|
||||
if($@){
|
||||
Log3 $name, 3, "GardenaSmartBridge ($name) - JSON error while setting startpoint: $@";
|
||||
if ( defined($startpoint_state) and defined($startpoint_num) ) {
|
||||
if ( defined( $hash->{helper}{STARTINGPOINTS} )
|
||||
and $hash->{helper}{STARTINGPOINTS} ne '' )
|
||||
{
|
||||
# add needed parameters to saved settings config and change the value in request
|
||||
my $decode_json_settings =
|
||||
eval { decode_json( $hash->{helper}{STARTINGPOINTS} ) };
|
||||
if ($@) {
|
||||
Log3 $name, 3,
|
||||
"GardenaSmartBridge ($name) - JSON error while setting startpoint: $@";
|
||||
}
|
||||
|
||||
$decode_json_settings->{device} = $hash->{DEVICEID};
|
||||
my $setval = $startpoint_state eq 'disable' ? \0 : \1;
|
||||
$decode_json_settings->{value}[$startpoint_num-1]{enabled} = $setval;
|
||||
$decode_json_settings->{value}[ $startpoint_num - 1 ]{enabled} =
|
||||
$setval;
|
||||
|
||||
#set more startpoints
|
||||
if (defined scalar(@morestartpoints) and (scalar(@morestartpoints) == 2 or scalar(@morestartpoints) == 4 )) {
|
||||
if (scalar(@morestartpoints) == 2) {
|
||||
if (
|
||||
defined scalar(@morestartpoints)
|
||||
and ( scalar(@morestartpoints) == 2
|
||||
or scalar(@morestartpoints) == 4 )
|
||||
)
|
||||
{
|
||||
if ( scalar(@morestartpoints) == 2 ) {
|
||||
$setval = $morestartpoints[0] eq 'disable' ? \0 : \1;
|
||||
$decode_json_settings->{value}[$morestartpoints[1]-1]{enabled} = $setval;
|
||||
$decode_json_settings->{value}[ $morestartpoints[1] - 1 ]
|
||||
{enabled} = $setval;
|
||||
|
||||
} elsif (scalar(@morestartpoints) == 4) {
|
||||
}
|
||||
elsif ( scalar(@morestartpoints) == 4 ) {
|
||||
$setval = $morestartpoints[0] eq 'disable' ? \0 : \1;
|
||||
$decode_json_settings->{value}[$morestartpoints[1]-1]{enabled} = $setval;
|
||||
$decode_json_settings->{value}[ $morestartpoints[1] - 1 ]
|
||||
{enabled} = $setval;
|
||||
$setval = $morestartpoints[2] eq 'disable' ? \0 : \1;
|
||||
$decode_json_settings->{value}[$morestartpoints[3]-1]{enabled} = $setval;
|
||||
$decode_json_settings->{value}[ $morestartpoints[3] - 1 ]
|
||||
{enabled} = $setval;
|
||||
}
|
||||
}
|
||||
|
||||
$payload = '"settings": '. encode_json($decode_json_settings);
|
||||
$payload = '"settings": ' . encode_json($decode_json_settings);
|
||||
$abilities = 'mower_settings';
|
||||
} else {
|
||||
return "startingpoints not loaded yet, please wait a couple of minutes",undef,undef;
|
||||
}
|
||||
} else {
|
||||
return "startpoint usage: set ".$hash->{NAME}." startpoint disable 1 [enable 2] [disable 3]",undef,undef;
|
||||
else {
|
||||
return
|
||||
"startingpoints not loaded yet, please wait a couple of minutes",
|
||||
undef, undef;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return
|
||||
"startpoint usage: set "
|
||||
. $hash->{NAME}
|
||||
. " startpoint disable 1 [enable 2] [disable 3]", undef, undef;
|
||||
}
|
||||
|
||||
return undef,$payload,$abilities;
|
||||
return undef, $payload, $abilities;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
Loading…
x
Reference in New Issue
Block a user