2020-01-21 09:32:14 +00:00
##############################################
2021-07-15 16:20:04 +00:00
# $Id$
2020-01-21 09:32:14 +00:00
#
2021-07-15 16:18:11 +00:00
package FHEM::aTm2u_ebus ; ## no critic 'Package declaration'
2020-01-21 09:32:14 +00:00
use strict ;
use warnings ;
2021-07-15 16:18:11 +00:00
use JSON qw( decode_json ) ;
use Scalar::Util qw( looks_like_number ) ;
2021-07-22 06:29:50 +00:00
use List::Util 1.45 qw( uniq ) ;
2021-07-15 16:18:11 +00:00
use GPUtils qw( GP_Import ) ;
#-- Run before package compilation
BEGIN {
# Import from main context
GP_Import (
qw(
json2nameValue
2021-07-20 05:37:30 +00:00
toJSON
2021-07-15 16:18:11 +00:00
AttrVal
InternalVal
CommandGet
CommandSet
2021-07-22 06:29:50 +00:00
CommandAttr
CommandDefine
CommandDeleteReading
2021-07-23 05:21:24 +00:00
FileRead
2021-07-22 06:29:50 +00:00
FmtDateTime
2021-07-15 16:18:11 +00:00
readingsSingleUpdate
readingsBulkUpdate
readingsBeginUpdate
readingsEndUpdate
ReadingsVal
ReadingsNum
ReadingsAge
json2nameValue
2021-07-22 06:29:50 +00:00
addToDevAttrList
2021-07-15 16:18:11 +00:00
defs
2021-07-23 05:21:24 +00:00
attr
2021-07-15 16:18:11 +00:00
Log3
2021-07-22 06:29:50 +00:00
trim
2021-07-15 16:18:11 +00:00
)
) ;
2020-01-21 09:32:14 +00:00
}
2021-07-15 16:18:11 +00:00
sub ::attrTmqtt2_ebus_Utils_Initialize { goto & Initialize }
sub ::attrTmqtt2_ebus_createBarView { goto & createBarView }
# initialize ##################################################################
sub Initialize {
my $ hash = shift ;
return ;
}
2020-01-21 09:32:14 +00:00
# Enter you functions below _this_ line.
2021-07-15 16:18:11 +00:00
sub j2nv {
my $ EVENT = shift // return ;
my $ pre = shift ;
my $ filt = shift ;
my $ not = shift ;
2021-07-20 05:37:30 +00:00
return if ! length $ EVENT ;
$ EVENT =~ s , [ { ] "value" : \ s("?[^"}]+"?) [}] , $ 1 , g ;
2021-07-15 16:18:11 +00:00
return json2nameValue ( $ EVENT , $ pre , $ filt , $ not ) ;
}
2021-07-22 06:29:50 +00:00
sub j2singleReading {
my $ rName = shift // return ;
my $ EVENT = shift // return ;
my $ pre = shift ;
my $ filt = shift ;
my $ not = shift ;
return if ! length $ EVENT ;
$ EVENT =~ s , [ { ] "value" : \ s("?[^"}]+"?) [}] , $ 1 , g ;
my $ values = json2nameValue ( $ EVENT , $ pre , $ filt , $ not ) ;
my @ all ;
for my $ item ( sort keys % { $ values } ) {
2021-08-06 06:03:27 +00:00
push @ all , qq{ $item: $values-> { $item } } if defined $ values - > { $ item } ;
2021-07-22 06:29:50 +00:00
}
return { $ rName = > join q{ - } , @ all } ;
}
2021-07-15 16:18:11 +00:00
sub send_weekprofile {
2021-07-18 06:20:20 +00:00
my $ name = shift // return ;
my $ wp_name = shift // return ;
2021-07-15 16:18:11 +00:00
my $ wp_profile = shift // return ;
2021-07-20 05:37:30 +00:00
my $ model = shift // ReadingsVal ( $ name , 'week' , 'unknown' ) ; #selected,Mo-Fr,Mo-So,Sa-So? holiday to set actual $wday to sunday program?
2021-07-18 06:20:20 +00:00
#[quote author=Reinhart link=topic=97989.msg925644#msg925644 date=1554057312]
#"daysel" nicht. Für mich bedeutet dies, das das Csv mit der Feldbeschreibung nicht überein stimmt. Ich kann aber nirgends einen Fehler sichten (timerhc.inc oder _templates.csv). [code]daysel,UCH,0=selected;1=Mo-Fr;2=Sa-So;3=Mo-So,,Tage[/code]
#Ebenfalls getestet mit numerischem daysel (0,1,2,3), auch ohne Erfolg.
2021-07-15 16:18:11 +00:00
my $ onLimit = shift // '20' ;
2021-07-18 06:20:20 +00:00
my $ hash = $ defs { $ name } // return ;
2021-07-15 16:18:11 +00:00
my $ wp_profile_data = CommandGet ( undef , "$wp_name profile_data $wp_profile 0" ) ;
if ( $ wp_profile_data =~ m {(profile.*not.found|usage..profile_data..name)}xms ) {
Log3 ( $ hash , 3 , "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available" ) ;
return ;
}
my @ Dl = ( "Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" ) ;
my @ D = ( "Sun" , "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ) ;
my $ payload ;
2021-07-20 05:37:30 +00:00
#my @days = (0..6);
2021-07-15 16:18:11 +00:00
my $ text = decode_json ( $ wp_profile_data ) ;
2021-07-20 05:37:30 +00:00
( $ model , my @ days ) = split m {:}xms , $ model ;
2021-07-15 16:18:11 +00:00
( my $ sec , my $ min , my $ hour , my $ mday , my $ mon , my $ year , my $ wday , my $ yday , my $ isdst ) = localtime ;
2021-07-20 05:37:30 +00:00
my @ models ;
if ( $ model eq 'unknown' ) {
my $ monday = toJSON ( $ text - > { $ D [ 1 ] } { time } ) . toJSON ( $ text - > { $ D [ 1 ] } { temp } ) ;
my $ satday = toJSON ( $ text - > { $ D [ 6 ] } { time } ) . toJSON ( $ text - > { $ D [ 6 ] } { temp } ) ;
my $ sunday = toJSON ( $ text - > { $ D [ 0 ] } { time } ) . toJSON ( $ text - > { $ D [ 0 ] } { temp } ) ;
$ models [ 0 ] = $ satday eq $ sunday && $ sunday eq $ monday ? '3' : $ satday eq $ sunday ? 2 : 0 ;
$ models [ 1 ] = 1 ;
for my $ i ( 2 .. 5 ) {
my $ othday = toJSON ( $ text - > { $ D [ $ i ] } { time } ) . toJSON ( $ text - > { $ D [ $ i ] } { temp } ) ;
next if $ othday eq $ monday ;
$ models [ 1 ] = 0 ;
last ;
}
@ days = $ models [ 0 ] == 3 ? ( 1 ) :
$ models [ 1 ] == 1 && $ models [ 0 ] == 2 ? ( 0 , 1 ) :
$ models [ 1 ] == 1 ? ( 0 , 1 , 6 ) :
$ models [ 1 ] == 0 && $ models [ 0 ] == 2 ? ( 0 .. 5 ) : ( 0 .. 6 )
}
if ( ! @ days ) {
if ( $ model eq 'Mo-Fr' ) {
@ days = ( 1 ) ;
$ models [ 1 ] = 1 ;
} elsif ( $ model eq 'Mo-So' ) {
@ days = ( 1 ) ;
$ models [ 1 ] = 1 ;
$ models [ 0 ] = 3 ;
} elsif ( $ model eq 'holiday' ) {
@ days = ( 0 ) ;
} elsif ( $ model eq 'selected' ) {
@ days = ( 0 .. 6 ) ;
$ models [ 1 ] = 0 ;
$ models [ 0 ] = 0 ;
} elsif ( $ model eq 'Sa-So' ) {
@ days = ( 0 ) ;
$ models [ 0 ] = 2 ;
}
}
2021-07-15 16:18:11 +00:00
for my $ i ( @ days ) {
$ payload = q{ } ;
my $ pairs = 0 ;
my $ onOff = 'off' ;
for my $ j ( 0 .. 20 ) {
my $ time = '00:00' ;
if ( defined $ text - > { $ D [ $ i ] } { time } [ $ j ] ) {
$ time = $ text - > { $ D [ $ i ] } { time } [ $ j - 1 ] // '00:00' ;
my $ val = $ text - > { $ D [ $ i ] } { temp } [ $ j ] ;
if ( $ val eq $ onOff || ( looks_like_number ( $ val ) && _compareOnOff ( $ val , $ onOff , $ onLimit ) ) ) {
$ time = '00:00' if ! $ j ;
2021-07-18 06:20:20 +00:00
$ payload . = qq{ $time;$text-> { $D[$i] } { time } [$j]; } ;
2021-07-15 16:18:11 +00:00
$ pairs + + ;
$ val = $ val eq 'on' ? 'off' : 'on' ;
}
}
while ( $ pairs < 3 && ! defined $ text - > { $ D [ $ i ] } { time } [ $ j ] ) {
#fill up the three pairs with last time
$ pairs + + ;
2021-07-18 06:20:20 +00:00
$ payload . = qq{ -,-;-,-; } ;
2021-07-15 16:18:11 +00:00
}
last if $ pairs == 3 ;
}
if ( $ model eq 'holiday' ) {
$ payload . = 'selected' ;
2021-07-18 06:20:20 +00:00
CommandSet ( $ defs { $ name } , "$name $Dl[$wday] $payload" ) if ReadingsVal ( $ name , $ Dl [ $ wday ] , '' ) ne $ payload ;
2021-07-20 05:37:30 +00:00
} elsif ( $ model eq 'selected' ) {
$ payload . = 'selected' ;
CommandSet ( $ defs { $ name } , "$name $Dl[$i] $payload" ) if ReadingsVal ( $ name , $ Dl [ $ i ] , '' ) ne $ payload ;
} elsif ( $ i == 1 ) {
$ payload . = defined $ models [ 0 ] && $ models [ 0 ] == 3 ? 'Mo-So' : defined $ models [ 1 ] && $ models [ 1 ] ? 'Mo-Fr' : 'selected' ;
2021-07-22 06:29:50 +00:00
CommandSet ( $ defs { $ name } , "$name $Dl[$i] $payload" ) if defined $ models [ 0 ] && $ models [ 0 ] == 3 || defined $ models [ 1 ] && $ models [ 1 ] ;
2021-07-20 05:37:30 +00:00
CommandSet ( $ defs { $ name } , "$name $Dl[$i] $payload" ) if ReadingsVal ( $ name , $ Dl [ $ i ] , '' ) ne $ payload ;
} elsif ( $ i == 0 || $ i == 6 ) {
my $ united = defined $ models [ 0 ] && $ models [ 0 ] == 2 ;
$ payload . = $ united ? 'Sa-So' : 'selected' ;
2021-07-22 06:29:50 +00:00
CommandSet ( $ defs { $ name } , "$name $Dl[$united ? 6 : $i] $payload" ) if ReadingsVal ( $ name , $ Dl [ $ united ? 6 : $ i ] , '' ) ne $ payload || $ united ;
2021-07-15 16:18:11 +00:00
} else {
2021-07-20 05:37:30 +00:00
$ payload . = 'selected' ;
2021-07-18 06:20:20 +00:00
CommandSet ( $ defs { $ name } , "$name $Dl[$i] $payload" ) if ReadingsVal ( $ name , $ Dl [ $ i ] , '' ) ne $ payload ;
2021-07-15 16:18:11 +00:00
}
}
readingsSingleUpdate ( $ defs { $ name } , 'weekprofile' , "$wp_name $wp_profile" , 1 ) ;
return ;
}
sub _compareOnOff {
my $ val = shift // return ;
my $ onOff = shift // return ;
my $ lim = shift ;
if ( $ onOff eq 'on' ) {
return $ val < $ lim ;
} else {
return $ val >= $ lim ;
}
return ;
}
2021-07-22 06:29:50 +00:00
sub analyzeReadingList {
my $ name = shift // return ;
my $ setpre = shift // 0 ;
my $ hash = $ defs { $ name } // return ;
my $ cid = $ defs { $ name } { CID } ;
my $ dt = $ defs { $ name } { DEVICETOPIC } ;
2021-07-23 05:21:24 +00:00
my $ revsn = _getVersion ( ) ;
2021-07-22 06:29:50 +00:00
$ revsn = FmtDateTime ( time ) . " $revsn" ;
my $ attrTemplt = q{ ebus_analyzeReadingList } ;
my $ rList_old = AttrVal ( $ name , 'readingList' , '' ) ;
2021-08-26 03:08:44 +00:00
my $ sList_old = AttrVal ( $ name , 'setList' , '' ) ;
my $ gList_old = AttrVal ( $ name , 'getList' , '' ) ;
2021-07-22 06:29:50 +00:00
my $ rList_new = q{ } ;
2021-08-26 03:08:44 +00:00
my $ sList_new = q{ } ;
my $ gList_new = q{ } ;
2021-07-22 06:29:50 +00:00
my $ firstprofile = 0 ;
my $ dylist = 0 ;
my @ need_prefix ;
my @ readings = keys % { $ defs { $ name } - > { READINGS } } ;
for my $ m ( @ readings ) {
if ( $ m =~ m {\A([^_]+_)_} ) {
push @ need_prefix , $ 1 ;
}
}
@ need_prefix = uniq @ need_prefix ;
my $ needs_prefix = join q{ | } , @ need_prefix ;
#Log3(undef,3,"präfix regex: $needs_prefix");
my $ newline ;
for my $ line ( split q{ \ n } , $ rList_old ) {
$ line = trim ( $ line ) ;
next if $ line eq '' ;
my $ func ;
my $ prefix ;
if ( $ line =~ m {FHEM::aTm2u_ebus::}xm ) {
$ rList_new . = $ rList_new ? qq{ \ n$line } : $ line ;
next ;
}
my ( $ re , $ code ) = split q{ } , $ line , 2 ;
if ( ! defined $ code ) {
Log3 ( $ name , 3 , "ERROR: deleted empty code in existing readingList line >$line< for $name" ) ;
next ;
}
$ re =~ s{\$DEVICETOPIC} {$dt}g ;
$ re =~ s{\A$cid:} {}g ;
$ code = trim ( $ code ) ;
#not Perl?
if ( $ code !~ m {\A[{].*[} ] \ z } s ) {
$ rList_new . = $ rList_new ? qq{ \ n$re $code } : qq{ $re $code } ;
next ;
}
my $ newtop ;
my $ short ;
#weekprofile type rL element?
if ( $ re =~ m {(?<start>.+[/])(?<short>[^/:.]+)(?:[.]|\\x2e)(?<dy>[^.]+)(?:[.]|\\x2e)[1-3]:}xm ) {
$ newtop = qq{ $+ { start } $+ { short } .*:.* } ;
my $ sLtop = qq{ $+ { start } $+ { short } } ;
$ short = $+ { short } ;
my $ dy = $+ { dy } ;
next if $ firstprofile eq $ short ;
my @ Dl = ( "Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" ) ;
my @ dylists = qw( Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday Sonntag|Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag Sun|Mon|Tue|Wed|Thu|Fri|Sat Son|Mon|Die|Mit|Don|Fre|Sam Su|Mo|Tu|We|Th|Fr|Sa So|Mo|Di|Mi|Do|Fr|Sa ) ;
for my $ daylist ( @ dylists ) {
if ( $ dylist ) {
$ func = "{ FHEM::aTm2u_ebus::upd_day_profile( \$NAME, \$TOPIC, \$EVENT, '" . $ dylist . "' ) }" ;
} elsif ( $ dy =~ m {$daylist}xms ) {
$ func = "{ FHEM::aTm2u_ebus::upd_day_profile( \$NAME, \$TOPIC, \$EVENT, '" . $ daylist . "' ) }" ;
$ dylist = $ daylist ;
}
}
if ( ! defined $ func ) {
Log3 ( undef , 1 , "error evaluating daylist, day is $dy" ) ;
next ;
}
$ newline = qq{ $newtop $func } ;
#Log3(undef, 3, "topic: $newtop, function $func");
my @ shD = split m {\|}xms , $ dylist ;
if ( ! $ firstprofile ) {
$ rList_new . = $ rList_new ? qq{ \ n$newline } : qq{ $newline } ;
$ firstprofile = $ short ;
2021-08-26 03:08:44 +00:00
#my $sList_old = AttrVal( $name, 'setList', '');
#my $sList_new = $sList_old;
2021-07-22 06:29:50 +00:00
for my $ i ( 0 .. 6 ) {
my $ sLline = qq{ $Dl[$i] $sLtop.$shD[$i]/set } ;
if ( index ( $ sList_new , $ sLline ) == - 1 ) {
$ sList_new . = $ sList_new ? qq{ \ n$sLline } : $ sLline ;
}
}
2021-08-26 03:08:44 +00:00
#CommandAttr(undef, "$name setList $sList_new") if $sList_new ne $sList_old;
2021-07-22 06:29:50 +00:00
addToDevAttrList ( $ name , 'weekprofile' , 'weekprofile' ) ;
CommandAttr ( undef , "$name weekprofile $name" ) if ! defined AttrVal ( $ name , 'weekprofile' , undef ) ;
next ;
}
my $ newdev = qq{ $ { name } _$ { short } } ;
if ( ! defined $ defs { $ newdev } ) {
CommandDefine ( $ defs { $ name } , "$newdev MQTT2_DEVICE" ) ;
readingsBeginUpdate ( $ defs { $ newdev } ) ;
readingsBulkUpdate ( $ defs { $ newdev } , 'associatedWith' , $ name ) ;
readingsBulkUpdate ( $ defs { $ newdev } , 'IODev' , InternalVal ( $ name , 'IODev' , undef ) - > { NAME } ) ;
readingsBulkUpdate ( $ defs { $ newdev } , 'attrTemplateVersion' , $ revsn ) ;
readingsEndUpdate ( $ defs { $ newdev } , 0 ) ;
my $ nroom = AttrVal ( $ name , 'room' , 'MQTT2_DEVICE' ) ;
CommandAttr ( undef , "$newdev room $nroom" ) ;
my $ sList ;
for my $ i ( 0 .. 6 ) {
my $ sLlin = qq{ $Dl[$i] $sLtop.$shD[$i]/set } ;
$ sList . = $ sList ? qq{ \ n$sLlin } : $ sLlin ;
}
CommandAttr ( undef , "$newdev setList $sList" ) ;
CommandAttr ( undef , "$newdev model $attrTemplt" ) ;
addToDevAttrList ( $ newdev , 'weekprofile' , 'weekprofile' ) ;
CommandAttr ( undef , "$newdev weekprofile $newdev" ) ;
my $ ac = ReadingsVal ( $ name , 'associatedWith' , '' ) ;
$ ac . = $ ac ? qq{ ,$newdev } : $ newdev ;
readingsSingleUpdate ( $ defs { $ name } , 'associatedWith' , $ ac , 0 ) ;
}
my $ rl2 = AttrVal ( $ newdev , 'readingList' , "" ) ;
$ rl2 . = q{ \ n } if $ rl2 ;
CommandAttr ( undef , "$newdev readingList $rl2$newline" ) if index ( $ rl2 , $ newtop ) == - 1 ;
next ;
}
#json2nameValue type rL element with dot?
if ( $ re =~ m {(?<start>.+[/])(?<short>[^/:]+)(?:[.]|\\x2e)(?<item>[^.:123]+):}xm ) {
2021-08-26 03:08:44 +00:00
$ newtop = qq{ $+ { start } $+ { short } .$+ { item } } ;
2021-07-22 06:29:50 +00:00
$ prefix = qq{ $+ { short } _$+ { item } _ } ;
$ func = '{ FHEM::aTm2u_ebus::j2nv( $EVENT, ' . qq{ '$prefix', } . '$JSONMAP ) }' ;
2021-08-26 03:08:44 +00:00
$ newline = qq{ $newtop:.* $func } ;
$ rList_new . = $ rList_new ? qq{ \ n$newline } : qq{ $newline } ;
$ newline = qq{ $+ { short } _$+ { item } $newtop/set \ $EVTPART1 } ;
$ sList_new . = $ sList_new ? qq{ \ n$newline } : qq{ $newline } ;
next ;
}
#json2nameValue type rL element with StartOf or EndOf?
if ( $ re =~ m {(?<start>.+[/])(?<short>(?:StartOf|EndOf)[^/:]+):}xm ) {
$ newtop = qq{ $+ { start } $+ { short } } ;
$ prefix = qq{ $+ { short } _ } ;
$ func = '{ FHEM::aTm2u_ebus::j2nv( $EVENT, ' . qq{ '$prefix', } . '$JSONMAP ) }' ;
$ newline = qq{ $newtop:.* $func } ;
2021-07-22 06:29:50 +00:00
$ rList_new . = $ rList_new ? qq{ \ n$newline } : qq{ $newline } ;
2021-08-26 03:08:44 +00:00
$ newline = qq{ $+ { short } :noArg $+ { short } $ { newtop } /get } ;
$ gList_new . = $ gList_new ? qq{ \ n$newline } : qq{ $newline } ;
2021-07-22 06:29:50 +00:00
next ;
}
#json2nameValue type rL element with Error content? ebusd/sc/ErrorHistory
if ( $ re =~ m {(?<start>.+[/])(?<short>ErrorHistory):}xm ) {
$ newtop = $ re ;
$ short = $+ { short } ;
$ func = q< { FHEM::aTm2u_ebus::j2singleReading( > . qq{ '$short', } . q< $EVENT, '', $JSONMAP ) } > ;
$ newline = qq{ $newtop $func } ;
$ rList_new . = $ rList_new ? qq{ \ n$newline } : qq{ $newline } ;
2021-07-23 05:21:24 +00:00
CommandDeleteReading ( undef , "$name ${short}_.*" ) ;
2021-07-22 06:29:50 +00:00
next ;
}
#json2nameValue type rL element w/o dot?
if ( $ code =~ m {\A[{]\s+json2nameValue.*[} ] \ z } s ) {
$ func = q< { FHEM::aTm2u_ebus::j2nv( $EVENT, ' > ;
my $ funcb = q< ', $JSONMAP ) } > ;
my $ mid = q{ } ;
$ re =~ m {(?<start>.+[/])(?<pre>[^/:]+):}xm ;
my $ mid2 = qq{ $+ { pre } _ } ;
$ mid = $ mid2 if $ setpre || $ mid2 =~ m {$needs_prefix}xms ;
$ newline = qq{ $re $func$ { mid } $ { funcb } } ;
$ rList_new . = $ rList_new ? qq{ \ n$newline } : qq{ $newline } ;
next ;
}
}
#Log3(undef,3,"readingList new: $rList_new");
CommandAttr ( undef , "$name readingList $rList_new" ) if index ( $ rList_old , $ rList_new ) == - 1 ;
2021-08-26 03:08:44 +00:00
CommandAttr ( undef , "$name getList $gList_new" ) if index ( $ gList_old , $ gList_new ) == - 1 ;
CommandAttr ( undef , "$name setList $sList_new" ) if index ( $ sList_old , $ sList_new ) == - 1 ;
2021-07-22 06:29:50 +00:00
CommandAttr ( undef , "$name model $attrTemplt" ) if AttrVal ( $ name , 'model' , '' ) ne $ attrTemplt ;
CommandDeleteReading ( undef , "$name .*_value" ) ;
readingsSingleUpdate ( $ defs { $ name } , 'attrTemplateVersion' , $ revsn , 0 ) ;
return ;
}
2021-07-18 06:20:20 +00:00
#ebusd/hc1/HP1.Mo.1:.* { json2nameValue($EVENT) }
#zwei Readings "Start_value" und "End_value"
# Vermutung: { "Start": {"value": "10:00"}, "End": {"value": "11:00"}}
#ebusd/hc1/HP1\x2eMo\x2e2:.* { json2nameValue($EVENT) }
sub upd_day_profile {
my $ name = shift // return ;
my $ topic = shift // return ;
my $ payload = shift // return ;
my $ daylist = shift // q( Su|Mo|Tu|We|Th|Fr|Sa ) ;
my $ hash = $ defs { $ name } // return ;
2021-07-20 05:37:30 +00:00
return if ! length $ payload ;
2021-07-18 06:20:20 +00:00
my @ Dl = ( "Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" ) ;
my $ data = decode_json ( $ payload ) ;
$ topic =~ m {[.](?<dayshort>$daylist)[.](?<pair>[1-3])\z}xms ;
my $ shday = $+ { dayshort } // return ;
my $ pairNr = $+ { pair } // return ;
$ pairNr - - ;
my @ days = split m {\|}xms , $ daylist ;
my % days_index = map { $ days [ $ _ ] = > $ _ } ( 0 .. 6 ) ;
my $ index = $ days_index { $ shday } ;
#Log3(undef,3, "[$name] day $shday, pair $pairNr, index $index days @days");
return if ! defined $ index ;
my $ rVal = ReadingsVal ( $ name , $ Dl [ $ index ] , '-,-;-,-;-,-;-,-;-,-;-,-;Mo-So' ) ;
my @ times = split m {;}xms , $ rVal ;
$ times [ $ pairNr * 2 ] = $ data - > { Start } - > { value } ;
$ times [ $ pairNr * 2 + 1 ] = $ data - > { End } - > { value } ;
$ rVal = join q{ ; } , @ times ;
readingsSingleUpdate ( $ defs { $ name } , $ Dl [ $ index ] , $ rVal , 1 ) ;
return ;
}
2021-07-15 16:18:11 +00:00
sub createBarView {
2020-01-21 09:32:14 +00:00
my ( $ val , $ maxValue , $ color ) = @ _ ;
$ maxValue = $ maxValue // 100 ;
$ color = $ color // "red" ;
my $ percent = $ val / $ maxValue * 100 ;
# Definition des valueStyles
my $ stylestring = 'style="' .
'width: 200px; ' .
'text-align:center; ' .
'border: 1px solid #ccc ;' .
"background-image: -webkit-linear-gradient(left,$color $percent" . '%, rgba(0,0,0,0) ' . $ percent . '%); ' .
"background-image: -moz-linear-gradient(left,$color $percent" . '%, rgba(0,0,0,0) ' . $ percent . '%); ' .
"background-image: -ms-linear-gradient(left,$color $percent" . '%, rgba(0,0,0,0) ' . $ percent . '%); ' .
"background-image: -o-linear-gradient(left,$color $percent" . '%, rgba(0,0,0,0) ' . $ percent . '%); ' .
"background-image: linear-gradient(left,$color $percent" . '%, rgba(0,0,0,0) ' . $ percent . '%);"' ;
# Rückgabe des definierten Strings
return $ stylestring ;
}
2021-07-23 05:21:24 +00:00
sub _getVersion {
my $ modpath = ( exists ( $ attr { global } { modpath } ) ? $ attr { global } { modpath } : "" ) ;
2021-08-06 06:03:27 +00:00
my $ fn = "$modpath/FHEM/99_attrTmqtt2_ebus_Utils.pm" ; # configDB
2021-07-23 05:21:24 +00:00
my ( $ ret , @ content ) = FileRead ( $ fn ) ;
if ( $ ret ) {
Log3 ( undef , 1 , "Error reading file $fn!" ) ;
return 'unknown' ;
}
for ( @ content ) {
chomp ;
2021-08-30 17:39:44 +00:00
if ( m {#.*(\$Id\:[^\$\n\r].+)\$} ) {
return $ 1 ;
2021-07-23 05:21:24 +00:00
}
}
return 'unknown' ;
}
2020-01-21 09:32:14 +00:00
1 ;
2021-07-15 16:18:11 +00:00
__END__
2020-01-21 09:32:14 +00:00
= pod
2021-08-29 17:01:19 +00:00
= item summary helper functions needed for ebus MQTT2_DEVICE
= item summary_DE needed Hilfsfunktionen für ebus MQTT2_DEVICE
2020-01-21 09:32:14 +00:00
= begin html
2021-07-18 06:20:20 +00:00
< a id = "attrTmqtt2_ebus_Utils" > </a>
2020-01-21 09:32:14 +00:00
<h3> attrTmqtt2_ebus_Utils </h3>
2021-08-29 17:01:19 +00:00
There may be room for improvement , please adress any issues in https: // forum . fhem . de /index.php/ topic , 97989.0 . html .
2020-01-21 09:32:14 +00:00
<ul>
<b> Functions to support attrTemplates for ebusd </b> <br>
</ul>
<ul>
2021-07-22 06:29:50 +00:00
<li> <b> FHEM::aTm2u_ebus:: j2nv </b> <br>
<code> FHEM::aTm2u_ebus:: j2nv ( $, $$ $ ) </code> <br>
2021-07-20 05:37:30 +00:00
This is just a wrapper to fhem . pl json2nameValue ( ) to prevent the "_value" postfix . It will first clean the first argument by applying <code> $ EVENT =~ s , [ { ] "value" : \ s("?[^"}]+"?) [}] , $ 1 , g </code> .
</li>
2021-07-23 05:21:24 +00:00
<li> <b> FHEM::aTm2u_ebus:: j2singleReading </b> <br>
<code> FHEM::aTm2u_ebus:: j2singleReading ( $$ , $$ $ ) </code> <br>
This is another wrapper to fhem . pl json2nameValue ( ) , that will write all key /value pairs to a single reading. the name of the reading has to be handed over as first argument, the others (starting with JSON string ($EVENT) are identical to json2nameValue/ j2nv .
</li>
2021-07-22 06:29:50 +00:00
<li> <b> FHEM::aTm2u_ebus:: upd_day_profile </b> <br>
<code> FHEM::aTm2u_ebus:: upd_day_profile ( $$ $, $ ) </code> <br>
2021-07-20 05:37:30 +00:00
Helper function to collect weekprofile info received over different topics . $ NAME , $ TOPIC and $ EVENT are obligatory to be handed over , additionally you may provide a <i> daylist </i> as 4 th argument . <i> daylist </i> defaults to Su | Mo | Tu | We | Th | Fr | Sa . Generated readings will be named Sunday , Monday , ... , so make sure to use different MQTT2 - devices for each topic - group , if there ' s more than one item attached to your ebus capable to use weekly profiles .
</li>
2021-07-23 05:21:24 +00:00
<li> <b> FHEM::aTm2u_ebus:: analyzeReadingList </b> <br>
<code> FHEM::aTm2u_ebus:: ( $ ) </code> <br>
This is a helper function . It analyzes a reading list of a given FHEM device ( and the existing reading names ) and tries to assign one of the above mentionned special functions to each line instead of json2nameValue ( ) . Lines without Perl statements or already using these functions are ignored . This works best , if autocreate in "complex" mode had been used to automatically build the readingList .
</li>
2021-07-22 06:29:50 +00:00
<li> <b> FHEM::aTm2u_ebus:: send_weekprofile </b> <br>
<code> FHEM::aTm2u_ebus:: send_weekprofile ( $$ $, $$ ) </code> <br>
2021-07-20 05:37:30 +00:00
Helper function that may be capable to translate a ( temperature ) <i> weekly profile <i> provided by a <i> weekprofile <i> TYPE device to the ebus format ( max . three pairs of on / off switching times ) .
2021-07-15 16:18:11 +00:00
</li>
2021-07-22 06:29:50 +00:00
<li> <b> FHEM::aTm2u_ebus:: createBarView </b> <br>
<code> FHEM::aTm2u_ebus:: createBarView ( $, $$ ) </code> <br>
2020-01-21 09:32:14 +00:00
Parameters are
<ul>
<li> $ value ( required ) </li>
<li> $ maxvalue ( optional ) , defaults to 100 </li>
<li> $ color , ( optional ) , defaults to red </li>
</ul>
2021-07-15 16:18:11 +00:00
For compability reasons , function will also be exported as attrTmqtt2_ebus_createBarView ( ) . Better use package version to call it ...
</li>
2020-01-21 09:32:14 +00:00
</ul> <br>
= end html
= cut