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

46_SmartPi: add decimal Attr

git-svn-id: https://svn.fhem.de/fhem/trunk@15530 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
LeonGaultier 2017-11-30 20:39:05 +00:00
parent ca9afe4f53
commit 46447dd1cc
3 changed files with 94 additions and 64 deletions

View File

@ -1,14 +1,16 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # 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. # Do not insert empty lines here, update check depends on it.
- change: backup is always started in the background (Forum #80237) - feature: 46_SmartPi: add decimal Attr, fix Notify bug
- bugfix: 72_FB_CALLMONITOR: fix not working reverse-search-phonebook - bugfix: 74_XiaomiFlowerSens: fix many Notify bugs
file import - change: backup is always started in the background (Forum #80237)
- change: 93_DbLog: V2.22.15, some Log verbose level adapted/added - bugfix: 72_FB_CALLMONITOR: fix not working reverse-search-phonebook
- bugfix: 44_S7_ARead: event-on-change-reading file import
- bugfix: 44_S7_AWrite: event-on-change-reading - change: 93_DbLog: V2.22.15, some Log verbose level adapted/added
- bugfix: 44_S7_DRead: event-on-change-reading - bugfix: 44_S7_ARead: event-on-change-reading
- bugfix: 44_S7_DWrite: event-on-change-reading - bugfix: 44_S7_AWrite: event-on-change-reading
- bugfix: 44_S7_S5Client.pm: loading serial modul - bugfix: 44_S7_DRead: event-on-change-reading
- bugfix: 44_S7_DWrite: event-on-change-reading
- bugfix: 44_S7_S5Client.pm: loading serial modul
- change: 89_FULLY: on-timer implemented - change: 89_FULLY: on-timer implemented
- change: 77_SMAEM: V3.0.1, use abort cause of BlockingCall - change: 77_SMAEM: V3.0.1, use abort cause of BlockingCall
- change: 93_Log2Syslog: V3.2.0, add NOTIFYDEV (if possible) - change: 93_Log2Syslog: V3.2.0, add NOTIFYDEV (if possible)

View File

@ -60,7 +60,7 @@ use HttpUtils;
eval "use JSON;1" or $missingModul .= "JSON "; eval "use JSON;1" or $missingModul .= "JSON ";
my $version = "1.0.0"; my $version = "1.2.0";
@ -69,6 +69,7 @@ my $version = "1.0.0";
sub SmartPi_Attr(@); sub SmartPi_Attr(@);
sub SmartPi_Define($$); sub SmartPi_Define($$);
sub SmartPi_Initialize($); sub SmartPi_Initialize($);
sub SmartPi_Notify($$);
sub SmartPi_Get($@); sub SmartPi_Get($@);
sub SmartPi_GetData($@); sub SmartPi_GetData($@);
sub SmartPi_Undef($$); sub SmartPi_Undef($$);
@ -88,10 +89,13 @@ sub SmartPi_Initialize($) {
$hash->{GetFn} = "SmartPi_Get"; $hash->{GetFn} = "SmartPi_Get";
$hash->{DefFn} = "SmartPi_Define"; $hash->{DefFn} = "SmartPi_Define";
$hash->{UndefFn} = "SmartPi_Undef"; $hash->{UndefFn} = "SmartPi_Undef";
$hash->{NotifyFn} = "SmartPi_Notify";
$hash->{AttrFn} = "SmartPi_Attr"; $hash->{AttrFn} = "SmartPi_Attr";
$hash->{AttrList} = "interval ". $hash->{AttrList} = "interval ".
"disable:1 ". "disable:1 ".
"decimalPlace:0,1,2,3,4,5 ".
"disabledForIntervals ".
$readingFnAttributes; $readingFnAttributes;
foreach my $d(sort keys %{$modules{SmartPi}{defptr}}) { foreach my $d(sort keys %{$modules{SmartPi}{defptr}}) {
@ -115,6 +119,7 @@ sub SmartPi_Define($$) {
my $host = $a[2]; my $host = $a[2];
$hash->{HOST} = $host; $hash->{HOST} = $host;
$hash->{NOTIFYDEV} = "global";
$hash->{INTERVAL} = 300; $hash->{INTERVAL} = 300;
$hash->{PORT} = 1080; $hash->{PORT} = 1080;
$hash->{VERSION} = $version; $hash->{VERSION} = $version;
@ -124,16 +129,6 @@ sub SmartPi_Define($$) {
Log3 $name, 3, "SmartPi ($name) - defined SmartPi Device with Host $host, Port $hash->{PORT} and Interval $hash->{INTERVAL}"; Log3 $name, 3, "SmartPi ($name) - defined SmartPi Device with Host $host, Port $hash->{PORT} and Interval $hash->{INTERVAL}";
if( $init_done ) {
SmartPi_Timer_GetData($hash);
} else {
InternalTimer( gettimeofday()+15, "SmartPi_Timer_GetData", $hash, 0 );
}
$modules{SmartPi}{defptr}{HOST} = $hash; $modules{SmartPi}{defptr}{HOST} = $hash;
return undef; return undef;
@ -162,28 +157,38 @@ sub SmartPi_Attr(@) {
if( $attrName eq "disable" ) { if( $attrName eq "disable" ) {
if( $cmd eq "set" ) { if( $cmd eq "set" ) {
if( $attrVal eq "0" ) { if( $attrVal eq "0" ) {
readingsSingleUpdate ( $hash, "state", "enabled", 1 ); readingsSingleUpdate ( $hash, "state", "enabled", 1 );
Log3 $name, 3, "SmartPi ($name) - enabled"; Log3 $name, 3, "SmartPi ($name) - enabled";
} else { } else {
RemoveInternalTimer($hash);
readingsSingleUpdate ( $hash, "state", "disabled", 1 ); readingsSingleUpdate ( $hash, "state", "disabled", 1 );
Log3 $name, 3, "SmartPi ($name) - disabled"; Log3 $name, 3, "SmartPi ($name) - disabled";
} }
} else { } else {
readingsSingleUpdate ( $hash, "state", "enabled", 1 ); readingsSingleUpdate ( $hash, "state", "enabled", 1 );
Log3 $name, 3, "SmartPi ($name) - enabled"; Log3 $name, 3, "SmartPi ($name) - enabled";
} }
elsif( $attrName eq "disabledForIntervals" ) {
if( $cmd eq "set" ) {
return "check disabledForIntervals Syntax HH:MM-HH:MM or 'HH:MM-HH:MM HH:MM-HH:MM ...'"
unless($attrVal =~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/);
Log3 $name, 3, "SmartPi ($name) - disabledForIntervals";
readingsSingleUpdate ( $hash, "state", "disabled", 1 );
}
elsif( $cmd eq "del" ) {
Log3 $name, 3, "SmartPi ($name) - enabled";
readingsSingleUpdate ( $hash, "state", "active", 1 );
}
}
} elsif( $attrName eq "interval" ) { } elsif( $attrName eq "interval" ) {
if( $cmd eq "set" ) { if( $cmd eq "set" ) {
$hash->{INTERVAL} = $attrVal; $hash->{INTERVAL} = $attrVal;
} else { } else {
$hash->{INTERVAL} = 300; $hash->{INTERVAL} = 300;
} }
} }
@ -191,6 +196,31 @@ sub SmartPi_Attr(@) {
return undef; return undef;
} }
sub SmartPi_Notify($$) {
my ($hash,$dev) = @_;
my $name = $hash->{NAME};
return if (IsDisabled($name));
my $devname = $dev->{NAME};
my $devtype = $dev->{TYPE};
my $events = deviceEvents($dev,1);
return if (!$events);
SmartPi_Timer_GetData($hash) if( (grep /^DEFINED.$name$/,@{$events}
or grep /^INITIALIZED$/,@{$events}
or grep /^MODIFIED.$name$/,@{$events}
or grep /^DELETEATTR.$name.interval$/,@{$events}
or grep /^ATTR.$name.interval.[0-9]+/,@{$events}
or grep /^DELETEATTR.$name.disable$/,@{$events}
or grep /^ATTR.$name.disable.0$/,@{$events}
or grep /^DELETEATTR.$name.decimalPlace$/,@{$events}
or grep /^ATTR.$name.decimalPlace.[0-9]+/,@{$events}) and $init_done );
return;
}
sub SmartPi_Get($@) { sub SmartPi_Get($@) {
my ($hash, $name, $cmd, @args) = @_; my ($hash, $name, $cmd, @args) = @_;
@ -244,7 +274,11 @@ sub SmartPi_Get($@) {
} }
SmartPi_GetData($hash,$phaseId,$valueId); if( not IsDisabled($name) ) {
SmartPi_GetData($hash,$phaseId,$valueId);
} else {
readingsSingleUpdate($hash,'state','disabled',1);
}
return undef; return undef;
} }
@ -255,12 +289,11 @@ sub SmartPi_Timer_GetData($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
RemoveInternalTimer($hash);
if( not IsDisabled($name) ) { if( not IsDisabled($name) ) {
SmartPi_GetData($hash,'all','all'); SmartPi_GetData($hash,'all','all');
} else { } else {
readingsSingleUpdate($hash,'state','disabled',1); readingsSingleUpdate($hash,'state','disabled',1);
} }
@ -367,6 +400,8 @@ sub SmartPi_ResponseProcessing($$) {
#$json = '{"serial":"smartpi160812345","name":"House","lat":52.3667,"lng":9.7167,"time":"2017-05-30 19:52:11","softwareversion":"","ipaddress":"169.254.3.10","datasets":[{"time":"2017-05-30 19:52:08","phases":[{"phase":1,"name":"phase 1","values":[{"type":"current","unity":"A","info":"","data":0.24830514},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":57.110184},{"type":"cosphi","unity":"","info":"","data":0.70275474},{"type":"frequency","unity":"Hz","info":"","data":120.413925}]},{"phase":2,"name":"phase 2","values":[{"type":"current","unity":"A","info":"","data":0.86874366},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":199.81104},{"type":"cosphi","unity":"","info":"","data":0.99155134},{"type":"frequency","unity":"Hz","info":"","data":386.1237}]},{"phase":3,"name":"phase 3","values":[{"type":"current","unity":"A","info":"","data":1.3195294},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":303.49176},{"type":"cosphi","unity":"","info":"","data":-0.25960922},{"type":"frequency","unity":"Hz","info":"","data":153.38525}]},{"phase":4,"name":"phase 4","values":[{"type":"current","unity":"A","info":"","data":1.0668689}]}]}]}';
$decode_json = eval{decode_json($json)}; $decode_json = eval{decode_json($json)};
if($@){ if($@){
@ -389,28 +424,6 @@ sub SmartPi_WriteReadings($$) {
Log3 $name, 4, "SmartPi ($name) - Write Readings"; Log3 $name, 4, "SmartPi ($name) - Write Readings";
#{"serial":"smartpi160812345","name":"House","lat":52.3667,"lng":9.7167,"time":"2017-05-30 19:52:11","softwareversion":"","ipaddress":"169.254.3.10",
#"datasets":[{"time":"2017-05-30 19:52:08","phases":[
#{"phase":1,"name":"phase 1","values":[
# {"type":"current","unity":"A","info":"","data":0.24830514},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":57.110184},{"type":"cosphi","unity":"","info":"","data":0.70275474},{"type":"frequency","unity":"Hz","info":"","data":120.413925}]},
#{"phase":2,"name":"phase 2","values":[
#{"type":"current","unity":"A","info":"","data":0.86874366},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":199.81104},{"type":"cosphi","unity":"","info":"","data":0.99155134},{"type":"frequency","unity":"Hz","info":"","data":386.1237}]},
#{"phase":3,"name":"phase 3","values":[
#{"type":"current","unity":"A","info":"","data":1.3195294},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":303.49176},{"type":"cosphi","unity":"","info":"","data":-0.25960922},{"type":"frequency","unity":"Hz","info":"","data":153.38525}]},
#{"phase":4,"name":"phase 4","values":[
#{"type":"current","unity":"A","info":"","data":1.0668689}]}]}]}
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdateIfChanged($hash,'serialNumber',$decode_json->{serial},1); readingsBulkUpdateIfChanged($hash,'serialNumber',$decode_json->{serial},1);
@ -425,6 +438,7 @@ sub SmartPi_WriteReadings($$) {
my $dataset; my $dataset;
my $phase; my $phase;
my $value; my $value;
my $decimal = AttrVal($name,'decimalPlace',2);
foreach $dataset (@{$decode_json->{datasets}}) { foreach $dataset (@{$decode_json->{datasets}}) {
@ -436,11 +450,11 @@ sub SmartPi_WriteReadings($$) {
if( ref($phase->{values}) eq "ARRAY" and scalar(@{$phase->{values}}) > 0 ) { if( ref($phase->{values}) eq "ARRAY" and scalar(@{$phase->{values}}) > 0 ) {
foreach $value (@{$phase->{values}}) { foreach $value (@{$phase->{values}}) {
readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Current", $value->{data}, 1 ) if( $value->{type} eq 'current' ); readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Current", sprintf("%.${decimal}f",$value->{data}), 1 ) if( $value->{type} eq 'current' );
readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Voltage", $value->{data}, 1 ) if( $value->{type} eq 'voltage' ); readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Voltage", sprintf("%.${decimal}f",$value->{data}), 1 ) if( $value->{type} eq 'voltage' );
readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Power", $value->{data}, 1 ) if( $value->{type} eq 'power' ); readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Power", sprintf("%.${decimal}f",$value->{data}), 1 ) if( $value->{type} eq 'power' );
readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Cosphi", $value->{data}, 1 ) if( $value->{type} eq 'cosphi' ); readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Cosphi", sprintf("%.${decimal}f",$value->{data}), 1 ) if( $value->{type} eq 'cosphi' );
readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Frequency", $value->{data}, 1 ) if( $value->{type} eq 'frequency' ); readingsBulkUpdateIfChanged( $hash, "phase$phase->{phase}_Frequency", sprintf("%.${decimal}f",$value->{data}), 1 ) if( $value->{type} eq 'frequency' );
} }
} }
} }
@ -489,6 +503,14 @@ sub SmartPi_WriteReadings($$) {
<ul> <ul>
<li>phaseX Y - get new Y (Voltage or Current or so)data about phaseX</li> <li>phaseX Y - get new Y (Voltage or Current or so)data about phaseX</li>
</ul> </ul>
<a name="SmartPiattribut"></a>
<b>get</b>
<ul>
<li>disable - disables the device</li>
<li>disabledForIntervals - disable device for interval time (13:00-18:30 or 13:00-18:30 22:00-23:00)</li>
<li>interval - interval in seconds for statusRequest</li>
<li></li>
</ul>
</ul> </ul>
=end html =end html

View File

@ -47,7 +47,7 @@ use JSON;
use Blocking; use Blocking;
my $version = "1.2.3"; my $version = "1.2.4";
my %CallBatteryFirmwareAge = ( '8h' => 28800, my %CallBatteryFirmwareAge = ( '8h' => 28800,
'16h' => 57600, '16h' => 57600,
'24h' => 86400, '24h' => 86400,
@ -246,11 +246,13 @@ sub XiaomiFlowerSens_Notify($$) {
return if (!$events); return if (!$events);
XiaomiFlowerSens_stateRequestTimer($hash) if( grep /^INITIALIZED$/,@{$events} XiaomiFlowerSens_stateRequestTimer($hash) if( (grep /^DEFINED.$name$/,@{$events}
or grep /^DELETEATTR.$name.disable$/,@{$events} or grep /^INITIALIZED$/,@{$events}
or grep /^DELETEATTR.$name.interval$/,@{$events} or grep /^MODIFIED.$name$/,@{$events}
or grep /^ATTR.$name.interval.[0-9]+/,@{$events} or grep /^DELETEATTR.$name.disable$/,@{$events}
or (grep /^DEFINED.$name$/,@{$events} and $init_done) ); or grep /^ATTR.$name.disable.0$/,@{$events}
or grep /^DELETEATTR.$name.interval$/,@{$events}
or grep /^ATTR.$name.interval.[0-9]+/,@{$events} ) and $init_done );
return; return;
} }
@ -302,6 +304,8 @@ sub XiaomiFlowerSens_stateRequestTimer($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
RemoveInternalTimer($hash);
if( $init_done and not IsDisabled($name) ) { if( $init_done and not IsDisabled($name) ) {
XiaomiFlowerSens_stateRequest($hash); XiaomiFlowerSens_stateRequest($hash);
@ -769,6 +773,7 @@ sub XiaomiFlowerSens_CallBatteryFirmware_IsUpdateTimeAgeToOld($$) {
<b>Attributes</b> <b>Attributes</b>
<ul> <ul>
<li>disable - disables the device</li> <li>disable - disables the device</li>
<li>disabledForIntervals - disable device for interval time (13:00-18:30 or 13:00-18:30 22:00-23:00)</li>
<li>interval - interval in seconds for statusRequest</li> <li>interval - interval in seconds for statusRequest</li>
<li>minFertility - min fertility value for low warn event</li> <li>minFertility - min fertility value for low warn event</li>
<li>maxFertility - max fertility value for High warn event</li> <li>maxFertility - max fertility value for High warn event</li>
@ -809,8 +814,8 @@ sub XiaomiFlowerSens_CallBatteryFirmware_IsUpdateTimeAgeToOld($$) {
<code>define Weihnachtskaktus XiaomiFlowerSens C4:7C:8D:62:42:6F</code><br /> <code>define Weihnachtskaktus XiaomiFlowerSens C4:7C:8D:62:42:6F</code><br />
</ul> </ul>
<br /> <br />
Der Befehl legt ein Device vom Typ XiaomiFlowerSens an mit dem Namen Weihnachtskaktus und der Bluetooth MAC C4:7C:8D:62:42:6F.<br /> Der Befehl legt ein Device vom Typ XiaomiFlowerSens an mit dem Namen Weihnachtskaktus und der Bluetooth MAC C4:7C:8D:62:42:6F.<br />
Nach dem Anlegen des Device werden umgehend und automatisch die aktuellen Daten vom betroffenen Xiaomi Flower Monitor gelesen. Nach dem Anlegen des Device werden umgehend und automatisch die aktuellen Daten vom betroffenen Xiaomi Flower Monitor gelesen.
</ul> </ul>
<br /><br /> <br /><br />
<a name="XiaomiFlowerSensreadings"></a> <a name="XiaomiFlowerSensreadings"></a>
@ -845,6 +850,7 @@ sub XiaomiFlowerSens_CallBatteryFirmware_IsUpdateTimeAgeToOld($$) {
<ul> <ul>
<li>disable - deaktiviert das Device</li> <li>disable - deaktiviert das Device</li>
<li>interval - Interval in Sekunden zwischen zwei Abfragen</li> <li>interval - Interval in Sekunden zwischen zwei Abfragen</li>
<li>disabledForIntervals - deaktiviert das Gerät für den angegebenen Zeitinterval (13:00-18:30 or 13:00-18:30 22:00-23:00)</li>
<li>minFertility - min Fruchtbarkeits-Grenzwert f&uuml;r ein Ereignis minFertility low </li> <li>minFertility - min Fruchtbarkeits-Grenzwert f&uuml;r ein Ereignis minFertility low </li>
<li>maxFertility - max Fruchtbarkeits-Grenzwert f&uuml;r ein Ereignis maxFertility high </li> <li>maxFertility - max Fruchtbarkeits-Grenzwert f&uuml;r ein Ereignis maxFertility high </li>
<li>minMoisture - min Feuchtigkeits-Grenzwert f&uuml;r ein Ereignis minMoisture low </li> <li>minMoisture - min Feuchtigkeits-Grenzwert f&uuml;r ein Ereignis minMoisture low </li>