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

98_weekprofile: new: custom temperature keywords

git-svn-id: https://svn.fhem.de/fhem/trunk@23704 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Risiko 2021-02-08 18:33:45 +00:00
parent 9e16fbde2e
commit c364a8cfd3
3 changed files with 304 additions and 196 deletions

View File

@ -1,5 +1,6 @@
# 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.
- feature: 98_weekprofile: custom temperature keywords
- change: 72_TA_CMI_JSON: introduced module package
- bugfix: 73_ElectricityCalculator: Use Time::Local added for compatibility
- bugfix: 73_WaterCalculator: Use Time::Local added for compatibility

View File

@ -15,12 +15,17 @@ use JSON; #libjson-perl
use Data::Dumper;
use Time::HiRes qw(gettimeofday);
use Storable qw(dclone);
use List::Util qw[min max];
use vars qw(%defs);
use vars qw($FW_ME);
use vars qw($FW_wname);
use vars qw($FW_subdir);
use vars qw($init_done);
use vars qw($readingFnAttributes);
use vars qw(%attr);
use vars qw(%FW_hiddenroom);
my @shortDays = ("Mon","Tue","Wed","Thu","Fri","Sat","Sun");
@ -95,14 +100,9 @@ sub weekprofile_timeToMinutes($)
return $hours * 60 + $minutes;
}
##############################################
sub myAttrVal($$$)
{
my ($me,$name,$def) = @_;
my $val = AttrVal($me, $name, $def);
if (defined($val) && ($name eq 'tempON' || $name eq 'tempOFF')) {
$val = sprintf("%.1f", $val);
}
sub tempValue($) {
my ($in) = @_;
my $val = sprintf("%.1f", $in);
return $val;
}
##############################################
@ -111,12 +111,12 @@ sub weekprofile_getDeviceType($$;$)
my ($me,$device,$sndrcv) = @_;
if (IsDummy($device)){
Log3 $me, 4, "$me(getDeviceType): $device is dummy - ignored";
Log3($me, 4, "$me(getDeviceType): $device is dummy - ignored");
return undef;
}
if (IsIgnored($device)){
Log3 $me, 4, "$me(getDeviceType): $device is ignored";
Log3($me, 4, "$me(getDeviceType): $device is ignored");
return undef;
}
@ -132,36 +132,36 @@ sub weekprofile_getDeviceType($$;$)
my $devType = $devHash->{TYPE};
$devType = $devHash->{wt_type} if ($devType =~ /dummyWT/); #special dummy fake WT for testing
Log3 $me, 5, "$me(getDeviceType): type: $devType";
Log3($me, 5, "$me(getDeviceType): type: $devType");
if ($devType =~ /CUL_HM/){
my $model = AttrVal($device,"model","");
my $readonly = AttrVal($device,"readOnly",0);
if ($readonly) {
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME} is readonly - ignored";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME} is readonly - ignored");
return undef;
}
#models: HM-TC-IT-WM-W-EU, HM-CC-RT-DN, HM-CC-TC
unless ($model =~ m/.*HM-[C|T]C-.*/) {
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME}, model $model is not supported";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME}, model $model is not supported");
return undef;
}
if (!defined($devHash->{chanNo})) { #no channel device
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME}, model $model has no chanNo";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME}, model $model has no chanNo");
return undef;
}
my $channel = $devHash->{chanNo};
unless ($channel =~ /^\d+?$/) {
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME}, model $model chanNo $channel is no number";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME}, model $model chanNo $channel is no number");
return undef;
}
$channel += 0;
Log3 $me, 5, "$me(getDeviceType): $devHash->{NAME}, $model, $channel";
Log3($me, 5, "$me(getDeviceType): $devHash->{NAME}, $model, $channel");
$type = "CUL_HM" if ( ($model =~ m/.*HM-CC-RT.*/) && ($channel == 4) );
$type = "CUL_HM" if ( ($model =~ m/.*HM-TC.*/) && ($channel == 2) );
@ -174,16 +174,16 @@ sub weekprofile_getDeviceType($$;$)
elsif ( $devType =~ /HMCCUDEV/){
my $readonly = AttrVal($device,"readOnly",0);
if ($readonly) {
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME} is readonly - ignored";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME} is readonly - ignored");
return undef;
}
my $model = $devHash->{ccutype};
if (!defined($model)) {
Log3 $me, 4, "$me(getDeviceType): ccutype not defined for device $device - take NAME";
Log3($me, 4, "$me(getDeviceType): ccutype not defined for device $device - take NAME");
$model = $devHash->{NAME};
return undef if (!defined($model));
}
Log3 $me, 5, "$me(getDeviceType): $devHash->{NAME}, $model";
Log3($me, 5, "$me(getDeviceType): $devHash->{NAME}, $model");
$type = "HMCCU_IP" if ( $model =~ m/HmIP.*/ );
$type = "HMCCU_HM" if ( $model =~ m/HM-.*/ );
}
@ -195,30 +195,30 @@ sub weekprofile_getDeviceType($$;$)
}
elsif ($devType =~ /WeekdayTimer/){
my $def = $defs{$device}{DEF};
Log3 $me, 5, "$me(getDeviceType): def WDT $def";
Log3($me, 5, "$me(getDeviceType): def WDT $def");
#if (index($def, $me) != -1) {
if ($def =~ m/.*weekprofile.*/) {
$type = "WDT";
}
else {
Log3 $me, 4, "$me(getDeviceType): found WDT but not configured for weekprofile";
Log3($me, 4, "$me(getDeviceType): found WDT but not configured for weekprofile");
}
}
elsif ($devType eq 'MQTT2_DEVICE'){
my $attr = AttrVal($device,'weekprofile','');
Log3 $me, 5, "$me(getDeviceType): attr MQTT2_DEVICE $attr";
Log3($me, 5, "$me(getDeviceType): attr MQTT2_DEVICE $attr");
if ($attr ne "") {
$type = "MQTT2_DEVICE";
}
else {
Log3 $me, 4, "$me(getDeviceType): found MQTT2_DEVICE but not configured for weekprofile";
Log3($me, 4, "$me(getDeviceType): found MQTT2_DEVICE but not configured for weekprofile");
}
}
if (defined($type)) {
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME} is type $type";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME} is type $type");
} else {
Log3 $me, 4, "$me(getDeviceType): $devHash->{NAME} is not supported";
Log3($me, 4, "$me(getDeviceType): $devHash->{NAME} is not supported");
}
return $type;
}
@ -233,7 +233,7 @@ sub weekprofile_get_prefix_HM($@)
foreach (@prefix_lst) {
my $reading = "$_"."$base_name";
my $time = ReadingsVal($device, $reading, "");
Log3 $me, 5, "$me(weekprofile_get_prefix_HM): check: $reading $time";
Log3($me, 5, "$me(weekprofile_get_prefix_HM): check: $reading $time");
if ($time ne "") {
$prefix = $_;
last;
@ -253,11 +253,11 @@ sub weekprofile_readDayProfile($@)
$type = weekprofile_getDeviceType($me,$device) if (!defined($type));
return if (!defined($type));
Log3 $me, 5, "$me(readDayProfile): read from type $type";
Log3($me, 5, "$me(readDayProfile): read from type $type");
my $reading = $DEV_READINGS{$day}{$type};
#Log3 $me, 5, "$me(ReadDayProfile): $reading";
#Log3($me, 5, "$me(ReadDayProfile): $reading");
if($type eq "MAX") {
@temps = split('/',ReadingsVal($device,"$reading-temp",""));
@ -286,21 +286,21 @@ sub weekprofile_readDayProfile($@)
my $lastTime = "";
my $prefix = weekprofile_get_prefix_HM($device,"ENDTIME_$reading"."_1",$me);
if (!defined($prefix)) {
Log3 $me, 2, "$me(readDayProfile): no readings for $reading found";
Log3($me, 2, "$me(readDayProfile): no readings for $reading found");
return (\@times, \@temps);
}
Log3 $me, 5, "$me(readDayProfile): HM-Prefix is $prefix";
Log3($me, 5, "$me(readDayProfile): HM-Prefix is $prefix");
for (my $i = 1; $i < 14; $i+=1){
my $prfTime = ReadingsVal($device, "$prefix"."ENDTIME_$reading"."_$i", "");
my $prfTemp = ReadingsVal($device, "$prefix"."TEMPERATURE_$reading"."_$i", "");
if ($prfTime eq "" or $prfTemp eq ""){
Log3 $me, 2, "$me(readDayProfile): no readings for $reading found ($i)";
Log3($me, 2, "$me(readDayProfile): no readings for $reading found ($i)");
return (\@times, \@temps);
}
else{
Log3 $me, 5, "$me(readDayProfile): $reading"."_$i $prfTime $prfTemp";
Log3($me, 5, "$me(readDayProfile): $reading"."_$i $prfTime $prfTemp");
}
$prfTime = weekprofile_minutesToTime($prfTime);
@ -314,17 +314,18 @@ sub weekprofile_readDayProfile($@)
}
}
else {
Log3 $me, 3, "$me(readDayProfile): unsupported device type $type";
Log3($me, 3, "$me(readDayProfile): unsupported device type $type");
}
for(my $i = 0; $i < scalar(@temps); $i+=1){
Log3 $me, 5, "$me(ReadDayProfile): temp $i $temps[$i]";
$temps[$i] =~s/[^\d.]//g; #only numbers
my $tempON = myAttrVal($me, "tempON", undef);
my $tempOFF = myAttrVal($me, "tempOFF", undef);
my $hash = $defs{$me};
$temps[$i] =~s/$tempOFF/off/g if (defined($tempOFF)); # temp off
$temps[$i] =~s/$tempON/on/g if (defined($tempON)); # temp on
for(my $i = 0; $i < scalar(@temps); $i+=1) {
Log3($me, 5, "$me(ReadDayProfile): temp $i $temps[$i]");
my $tv = "\"".$temps[$i]."\"";
$tv = weekprofile_replaceKeywords($hash, $tv, 'toValue');
$tv =~s/\"//g;
$tv =~s/[^\d.]//g; #only numbers
$temps[$i] = tempValue($tv);
}
for(my $i = 0; $i < scalar(@times); $i+=1){
@ -356,10 +357,10 @@ sub weekprofile_readDevProfile(@)
}
if ( ($logDaysCnt>0) && ($logDaysCnt<(@shortDays)) ) {
Log3 $me, 3, $logDaysWarning;
Log3($me, 3, $logDaysWarning);
} else {
if ($logDaysCnt == (@shortDays)) {
Log3 $me, 3, "WARNING master device $device has no week profile - create default";
Log3($me, 3, "WARNING master device $device has no week profile - create default");
}
}
@ -400,12 +401,12 @@ sub weekprofile_sendDevProfile(@)
}
elsif ($type eq "WDT") {
my $cmd = "set $device weekprofile $me:$prf->{TOPIC}:$prf->{NAME}";
Log3 $me, 4, "$me(sendDevProfile): send to WDT $cmd";
Log3($me, 4, "$me(sendDevProfile): send to WDT $cmd");
return fhem("$cmd",1);
}
elsif ($type eq "MQTT2_DEVICE") {
my $cmd = "set $device weekprofile $me $prf->{TOPIC}:$prf->{NAME}";
Log3 $me, 4, "$me(sendDevProfile): send to MQTT2_DEVICE $cmd";
Log3($me, 4, "$me(sendDevProfile): send to MQTT2_DEVICE $cmd");
return fhem("$cmd",1);
}
@ -440,22 +441,22 @@ sub weekprofile_sendDevProfile(@)
}
if (scalar(@dayToTransfer) <=0) {
Log3 $me, 4, "$me(sendDevProfile): nothing to do";
Log3($me, 4, "$me(sendDevProfile): nothing to do");
return undef;
}
#make a copy because of replacements
my $prfData= dclone($prf->{DATA});
my $tempON = myAttrVal($me, "tempON", "30.5");
my $tempOFF = myAttrVal($me, "tempOFF", "4.5");
# make a copy to manipulate temps to keywords
my $prfData = dclone($prf->{DATA});
#replace variables with values
foreach my $day (@dayToTransfer){
my $tmpCnt = scalar(@{$prfData->{$day}->{"temp"}});
for (my $i = 0; $i < $tmpCnt; $i++) {
$prfData->{$day}->{"temp"}[$i] = $tempON if ($prfData->{$day}->{"temp"}[$i] =~/on/i);
$prfData->{$day}->{"temp"}[$i] = $tempOFF if ($prfData->{$day}->{"temp"}[$i] =~/off/i);
}
# send keywords to device if attr 'sendKeywordsToDevices' is set
my $useKeywords = AttrVal($me, "sendKeywordsToDevices", 0);
if ($useKeywords) {
my $hash = $defs{$me};
my $json = JSON->new->allow_nonref;
my $json_text = undef;
eval { $json_text = $json->encode($prfData) };
$json_text = weekprofile_replaceKeywords($hash, $json_text, 'toKey');
eval { $prfData = $json->decode($json_text) };
}
my $cmd;
@ -497,7 +498,7 @@ sub weekprofile_sendDevProfile(@)
$prefix = "" if ($type eq "HMCCU_HM"); # no prefix by set see topic,46117.msg1104569.html#msg1104569
$prefix = ""; # TEST always no prefix by set #msg1113658
if (!defined($prefix)) {
Log3 $me, 3, "$me(sendDevProfile): no prefix found";
Log3($me, 3, "$me(sendDevProfile): no prefix found");
$prefix = "";
}
foreach my $day (@dayToTransfer){
@ -528,7 +529,7 @@ sub weekprofile_sendDevProfile(@)
$last_profile_send = $datetimenow - $snd_delay;
} else {
my $last_profile_send_fmt = FmtDateTime($last_profile_send);
Log3 $me, 4, "$me(sendDevProfile): last profile to device type $type wars or will be at ($last_profile_send_fmt)";
Log3($me, 4, "$me(sendDevProfile): last profile to device type $type wars or will be at ($last_profile_send_fmt)");
}
if ($last_profile_send <= $datetimenow - $snd_delay) {
@ -540,16 +541,16 @@ sub weekprofile_sendDevProfile(@)
my $last_profile_send_fmt = FmtDateTime($last_profile_send);
my $sleepTime = $last_profile_send - $datetimenow;
Log3 $me, 4, "$me(sendDevProfile): profile data to $device ($type) will be sent $sleepTime seconds delayed at ($last_profile_send_fmt)";
Log3($me, 4, "$me(sendDevProfile): profile data to $device ($type) will be sent $sleepTime seconds delayed at ($last_profile_send_fmt)");
$LAST_SEND{$type} = $last_profile_send;
$cmd=$cmd.";trigger $me PROFILE_TRANSFERED $device";
Log3 $me, 4, "$me(sendDevProfile): sleep $sleepTime; $cmd";
Log3($me, 4, "$me(sendDevProfile): sleep $sleepTime; $cmd");
$ret = fhem("sleep $sleepTime; $cmd",1);
}
else {
Log3 $me, 4, "$me(sendDevProfile): $cmd";
Log3($me, 4, "$me(sendDevProfile): $cmd");
$ret = fhem($cmd,1);
DoTrigger($me,"PROFILE_TRANSFERED $device",1);
}
@ -585,7 +586,7 @@ sub weekprofile_refreshSendDevList($)
push @{$hash->{SNDDEVLIST}} , $dev;
}
my $cnt = scalar(@{$hash->{SNDDEVLIST}});
Log3 $me, 5, "$me(weekprofile_refreshSendDevList): $cnt devices in list";
Log3($me, 5, "$me(weekprofile_refreshSendDevList): $cnt devices in list");
return undef;
}
@ -624,11 +625,11 @@ sub weekprofile_assignDev($)
my $prf = undef;
if (defined($hash->{MASTERDEV})) {
Log3 $me, 5, "$me(assignDev): assign to device $hash->{MASTERDEV}->{NAME}";
Log3($me, 5, "$me(assignDev): assign to device $hash->{MASTERDEV}->{NAME}");
my $type = weekprofile_getDeviceType($me, $hash->{MASTERDEV}->{NAME});
if (!defined($type)) {
Log3 $me, 2, "$me(assignDev): device $hash->{MASTERDEV}->{NAME} not supported or defined";
Log3($me, 2, "$me(assignDev): device $hash->{MASTERDEV}->{NAME} not supported or defined");
} else {
$hash->{MASTERDEV}->{TYPE} = $type;
@ -641,7 +642,7 @@ sub weekprofile_assignDev($)
if(defined($prfDev)) {
$prf->{DATA} = $prfDev;
} else {
Log3 $me, 3, "WARNING master device $hash->{MASTERDEV}->{NAME} has no week profile - create default profile";
Log3($me, 3, "WARNING master device $hash->{MASTERDEV}->{NAME} has no week profile - create default profile");
$prf->{DATA} = weekprofile_createDefaultProfile($hash);
}
$hash->{STATE} = "assigned";
@ -649,7 +650,7 @@ sub weekprofile_assignDev($)
}
if (!defined($prf)) {
Log3 $me, 5, "create default profile";
Log3($me, 5, "create default profile");
my $prfDev = weekprofile_createDefaultProfile($hash);
if(defined($prfDev)) {
$prf = {};
@ -717,8 +718,8 @@ sub weekprofile_Initialize($)
$hash->{StateFn} = "weekprofile_State";
$hash->{NotifyFn} = "weekprofile_Notify";
$hash->{AttrFn} = "weekprofile_Attr";
$hash->{AttrList} = "useTopics:0,1 widgetTranslations widgetWeekdays widgetEditOnNewPage:0,1 widgetEditDaysInRow:1,2,3,4,5,6,7 \
sendDelay tempON tempOFF configFile forceCompleteProfile:0,1 ".$readingFnAttributes;
$hash->{AttrList} = "useTopics:0,1 widgetTranslations widgetWeekdays widgetTempRange widgetEditOnNewPage:0,1 widgetEditDaysInRow:1,2,3,4,5,6,7 \
sendDelay tempON tempOFF configFile forceCompleteProfile:0,1 tempMap sendKeywordsToDevices:0,1 ".$readingFnAttributes;
$hash->{FW_summaryFn} = "weekprofile_SummaryFn";
@ -732,7 +733,7 @@ sub weekprofile_Define($$)
if(@a < 1) {
my $msg = "wrong syntax: define <name> weekprofile [device]";
Log3 undef, 2, $msg;
Log3(undef, 2, $msg);
return $msg;
}
@ -754,6 +755,7 @@ sub weekprofile_Define($$)
$hash->{PROFILES} = \@profiles;
$hash->{SNDDEVLIST} = \@sendDevList;
$hash->{TOPICS} = \@topics;
$hash->{TEMPMAP} = {};
#$attr{$me}{verbose} = 5;
@ -780,9 +782,9 @@ sub dumpData($$$)
$dmp =~ s/^\s+|\s+$//g; #trim whitespace both ends
if (AttrVal($me,"verbose",3) < 4) {
Log3 $me, 1, "$me$prefix - set verbose to 4 to see the data";
Log3($me, 1, "$me$prefix - set verbose to 4 to see the data");
} else {
Log3 $me, 4, "$me$prefix $dmp";
Log3($me, 4, "$me$prefix $dmp");
}
}
##############################################
@ -801,14 +803,15 @@ sub weekprofile_Get($$@)
$list.= 'profile_data:' if ($prfCnt > 0);
foreach my $prf (sort sort_by_name @{$hash->{PROFILES}}){
$list.= $prf->{TOPIC}.":" if ($useTopics);
$list.= $prf->{NAME}."," if ($useTopics || (!$useTopics && ($prf->{TOPIC} eq 'default')));
$list.= $prf->{NAME} if ($useTopics || (!$useTopics && ($prf->{TOPIC} eq 'default')));
$list.= ',';
}
$list = substr($list, 0, -1) if ($prfCnt > 0);
#-----------------------------------------------------------------------------
if($cmd eq "profile_data") {
return 'usage: profile_data <name>' if(@params < 1);
return 'usage: profile_data <name> [usekeywords]' if(@params < 1);
return "no profile" if ($prfCnt <= 0);
my ($topic, $name) = weekprofile_splitName($me, $params[0]);
@ -823,6 +826,18 @@ sub weekprofile_Get($$@)
eval { $json_text = $json->encode($prf->{DATA}) };
dumpData($hash,"(Get): invalid profile data",$prf->{DATA}) if (!defined($json_text));
my $useKeywords = 1;
# 1 - return data with keywords
# 0 - depending on attr
# -1 - return data with values instead of keywords
Log3($me, 5, "$me(weekprofile_Get): params: @params");
if(@params >= 2) {
$useKeywords = AttrVal($me, "sendKeywordsToDevices", 1) if ($params[1] == 0);
$useKeywords = 0 if ($params[1] < 0);
}
my $direction = -1;
$direction = 1 if ($useKeywords <=0);
$json_text = weekprofile_replaceKeywords($hash, $json_text, $direction);
return $json_text;
}
#-----------------------------------------------------------------------------
@ -931,6 +946,8 @@ sub weekprofile_Get($$@)
return $ret;
}
# hidden functions
#-----------------------------------------------------------------------------
if($cmd eq "sndDevList") {
my $json = JSON->new->allow_nonref;
my @sortDevList = sort {lc($a->{ALIAS}) cmp lc($b->{ALIAS})} @{$hash->{SNDDEVLIST}};
@ -940,6 +957,12 @@ sub weekprofile_Get($$@)
return $json_text;
}
#-----------------------------------------------------------------------------
if($cmd eq "tempList") {
my $tempList = weekprofile_createTempList($hash);
return $tempList;
}
$list =~ s/ $//;
return "Unknown argument $cmd choose one of $list";
}
@ -952,7 +975,7 @@ sub weekprofile_findPRF($$$$)
if (!$topic) {
$topic = ReadingsVal($me, "active_topic", "default");
Log3 $me, 3, "$me(weekprofile_findPRF): use topic $topic";
Log3($me, 3, "$me(weekprofile_findPRF): use topic $topic");
}
$followRef = '0' if (!$followRef);
@ -1001,7 +1024,7 @@ sub weekprofile_splitName($$)
return ($parts[0],$parts[1]) if (@parts == 2);
my $topic = ReadingsVal($me, "active_topic", "default");
Log3 $me, 5, "$me(weekprofile_splitName): use topic $topic";
Log3($me, 5, "$me(weekprofile_splitName): use topic $topic");
return ($topic,$in);
}
##############################################
@ -1027,9 +1050,11 @@ sub weekprofile_Set($$@)
my $json = JSON->new->allow_nonref;
my $data = undef;
$jsonData = weekprofile_replaceKeywords($hash, $jsonData, 'toValue');
eval { $data = $json->decode($jsonData); };
if (!defined($data)) {
Log3 $me, 1, "$me(Set): Error parsing profile data.";
Log3($me, 1, "$me(Set): Error parsing profile data.");
return "Error parsing profile data. No valid json format";
};
@ -1075,7 +1100,7 @@ sub weekprofile_Set($$@)
my ($found,$idx) = weekprofile_findPRF($hash,$name,$topic,1);
if (!defined($found)) {
Log3 $me, 1, "$me(Set): Error unknown profile $params[0]";
Log3($me, 1, "$me(Set): Error unknown profile $params[0]");
return "Error unknown profile $params[0]";
}
@ -1083,7 +1108,7 @@ sub weekprofile_Set($$@)
foreach my $device (@devices){
my $ret = weekprofile_sendDevProfile($device,$found,$me);
if ($ret) {
Log3 $me, 1, "$me(Set): $ret" if ($ret);
Log3($me, 1, "$me(Set): $ret") if ($ret);
$err .= $ret . "\n";
}
}
@ -1106,7 +1131,7 @@ sub weekprofile_Set($$@)
$prfDest = $prf if ( ($prf->{NAME} eq $destName) && ($prf->{TOPIC} eq $destTopic) );
}
return "Error unknown profile $srcName" unless($prfSrc);
Log3 $me, 4, "$me(Set): override profile $destName" if ($prfDest);
Log3($me, 4, "$me(Set): override profile $destName") if ($prfDest);
if ($prfDest){
$prfDest->{DATA} = $prfSrc->{DATA};
@ -1140,7 +1165,7 @@ sub weekprofile_Set($$@)
$prfDest = $prf if ( ($prf->{NAME} eq $destName) && ($prf->{TOPIC} eq $destTopic) );
}
return "Error unknown profile $srcName" unless($prfSrc);
Log3 $me, 4, "$me(Set): override profile $destName" if ($prfDest);
Log3($me, 4, "$me(Set): override profile $destName") if ($prfDest);
if ($prfDest){
$prfDest->{DATA} = undef;
@ -1191,16 +1216,16 @@ sub weekprofile_Set($$@)
my $prfName = AttrVal($dev->{NAME},"weekprofile",undef);
next if (!defined($prfName));
Log3 $me, 5, "$me(Set): found device $dev->{NAME}";
Log3($me, 5, "$me(Set): found device $dev->{NAME}");
my ($prf,$idx) = weekprofile_findPRF($hash,$prfName,$topic,1);
next if (!defined($prf));
Log3 $me, 4, "$me(Set): Send profile $topic:$prfName to $dev->{NAME}";
Log3($me, 4, "$me(Set): Send profile $topic:$prfName to $dev->{NAME}");
my $ret = weekprofile_sendDevProfile($dev->{NAME},$prf,$me);
if ($ret) {
Log3 $me, 1, "$me(Set): $ret" if ($ret);
Log3($me, 1, "$me(Set): $ret") if ($ret);
$err .= $ret . "\n";
}
}
@ -1214,7 +1239,7 @@ sub weekprofile_Set($$@)
if ($cmd eq 'reread_master') {
return "Error no master device assigned" if (!defined($hash->{MASTERDEV}));
my $devName = $hash->{MASTERDEV}->{NAME};
Log3 $me, 4, "$me(Set): reread master profile from $devName";
Log3($me, 4, "$me(Set): reread master profile from $devName");
my $prfDev = weekprofile_readDevProfile($hash->{MASTERDEV}->{NAME},$hash->{MASTERDEV}->{TYPE}, $me);
if(defined($prfDev)) {
$hash->{PROFILES}[0]->{DATA} = $prfDev;
@ -1237,7 +1262,7 @@ sub weekprofile_Set($$@)
my $device = $params[0];
my $type = weekprofile_getDeviceType($me, $device);
if (!defined($type)) {
Log3 $me, 2, "$me(Set): device $device not supported or defined";
Log3($me, 2, "$me(Set): device $device not supported or defined");
return "Error device $device not supported or defined";
}
my ($topic, $name) = ('default', $device);
@ -1252,11 +1277,11 @@ sub weekprofile_Set($$@)
if(defined($devPrf)) {
$prf->{DATA} = $devPrf;
} else {
Log3 $me, 2, "device $device has no week profile";
Log3($me, 2, "device $device has no week profile");
return "Error device $device has no week profile";
}
Log3 $me, 3, "profile $topic:$name from $device imported";
Log3($me, 3, "profile $topic:$name from $device imported");
push @{$hash->{PROFILES}} , $prf;
weekprofile_updateReadings($hash);
return undef;
@ -1289,12 +1314,13 @@ sub weekprofile_Notify($$)
next if(!defined($s));
my ($what,$who) = split(' ',$s);
Log3 $me, 5, "$me(Notify): $devName, $what";
Log3($me, 5, "$me(Notify): $devName, $what");
if ($what =~ m/^INITIALIZED$/ || $what =~ m/REREADCFG/) {
delete $own->{PROFILES};
weekprofile_refreshSendDevList($own);
weekprofile_assignDev($own);
weekprofile_createTempMap($own);
weekprofile_readProfilesFromFile($own);
weekprofile_updateReadings($own);
}
@ -1317,7 +1343,7 @@ sub weekprofile_Notify($$)
next if(!defined($s));
my ($what,$who) = split(' ',$s);
Log3 $me, 5, "$me(Notify): $devName, $what";
Log3($me, 5, "$me(Notify): $devName, $what");
if ($own->{MASTERDEV}->{NAME} eq 'MAX') {
$readprf =1 if ($what=~m/weekprofile/); #reading weekprofile
@ -1330,7 +1356,7 @@ sub weekprofile_Notify($$)
}
if ($readprf) {
Log3 $me, 4, "$me(Notify): reread master profile from $devName";
Log3($me, 4, "$me(Notify): reread master profile from $devName");
my $prfDev = weekprofile_readDevProfile($own->{MASTERDEV}->{NAME},$own->{MASTERDEV}->{TYPE}, $me);
if(defined($prfDev)) {
$own->{PROFILES}[0]->{DATA} = $prfDev;
@ -1349,28 +1375,52 @@ sub weekprofile_Attr($$$)
return if (!defined($attrVal));
Log3 $me, 5, "$me(weekprofile_Attr): $cmd, $attrName, $attrVal";
Log3($me, 5, "$me(weekprofile_Attr): $cmd, $attrName, $attrVal");
$attr{$me}{$attrName} = $attrVal;
weekprofile_writeProfilesToFile($hash) if ($attrName eq 'configFile');
if ($attrName eq 'tempON') {
my $tempOFF = myAttrVal($me, "tempOFF", $attrVal);
if ($tempOFF > $attrVal) {
Log3 $me, 2, "$me(weekprofile_Attr): warning: tempON must be bigger than tempOFF";
}
if ($attrName eq 'tempON'|| $attrName eq 'tempOFF') {
return "$attrName is deprecated and will be removed in a next version. Please use tempMap and\\or widgetTempRange";
}
if ($attrName eq 'tempOFF') {
my $tempON = myAttrVal($me, "tempON", $attrVal);
if ($tempON < $attrVal) {
Log3 $me, 2, "$me(weekprofile_Attr): warning: tempOFF must be smaller than tempON";
if ($attrName eq 'tempMap') {
weekprofile_createTempMap($hash, $attrVal);
}
}
return undef;
}
##############################################
sub weekprofile_createTempMap($) {
my ($hash, $attrMap) = @_;
my $me = $hash->{NAME};
my $tempOn = AttrVal($me,"tempON", undef);
if (defined($tempOn)) {
$hash->{TEMPMAP}->{'on'} = tempValue($tempOn);
Log3($me, 2, "$me(weekprofile_createTempMap): tempON is deprecated, please remove it");
}
my $tempOff = AttrVal($me,"tempOFF", undef);
if (defined($tempOn)) {
$hash->{TEMPMAP}->{'off'} = tempValue($tempOff);
Log3($me, 2, "$me(weekprofile_createTempMap): tempOFF is deprecated, please remove it");
}
my $tempMap = AttrVal($me,"tempMap", $attrMap);
return if (!defined($tempMap));
Log3($me, 2, "$me(weekprofile_createTempMap): create map from $attrMap");
$tempMap .= ',';
my @data = split(',',$tempMap);
foreach (@data) {
my @pair = split(':',$_);
if(@pair<2){
Log3($me, 1, "$me(weekprofile_Attr): incorrect data $_");
next;
}
$hash->{TEMPMAP}->{$pair[0]} = tempValue($pair[1]);
}
}
##############################################
sub weekprofile_writeProfilesToFile(@)
@ -1379,7 +1429,7 @@ sub weekprofile_writeProfilesToFile(@)
my $me = $hash->{NAME};
if (!defined($hash->{PROFILES})) {
Log3 $me, 4, "$me(writeProfileToFile): no profiles to save";
Log3($me, 4, "$me(writeProfileToFile): no profiles to save");
return;
}
@ -1397,11 +1447,11 @@ sub weekprofile_writeProfilesToFile(@)
my $dbused = configDBUsed();
my $filename = weekprofile_getDataFile($hash);
Log3 $me, 5, "$me(writeProfileToFile): write profiles to $filename [DB: $dbused]";
Log3($me, 5, "$me(writeProfileToFile): write profiles to $filename [DB: $dbused]");
my $ret = FileWrite($filename,@content);
if ($ret){
Log3 $me, 1, "$me(writeProfileToFile): write profiles to $filename [DB: $dbused] failed $ret";
Log3($me, 1, "$me(writeProfileToFile): write profiles to $filename [DB: $dbused] failed $ret");
} else {
DoTrigger($me,"PROFILES_SAVED",1);
weekprofile_updateReadings($hash);
@ -1423,6 +1473,67 @@ sub weekprofile_getDataFile(@)
return $filename;
}
##############################################
sub weekprofile_replaceKeywords(@)
{
my ($hash, $data, $direction) = @_;
my $me = $hash->{NAME};
return undef if (!defined($data));
$direction = -1 if ($direction=~m/toKey/i);
$direction = 1 if ($direction=~m/toValue/i);
Log3($me, 5, "$me(weekprofile_replaceKeywords): replacing keywords in $data");
foreach my $key (keys %{$hash->{TEMPMAP}}){
my $value = $hash->{TEMPMAP}->{$key};
#Log3($me, 5, "$me(weekprofile_replaceKeywords): $key $value");
$direction == 1 ? $data =~s/"$key"/"$value"/g : $data =~s/"$value"/"$key"/g;
}
Log3($me, 5, "$me(weekprofile_replaceKeywords): replaced result: $data");
return $data;
}
##############################################
sub weekprofile_createTempList($) {
my ($hash) = @_;
my $me = $hash->{NAME};
my $min=5;
my $max=30;
my @values = ();
my $defMin = 5;
my $defMax = 30;
my $defStep = 0.5;
foreach my $key (keys %{$hash->{TEMPMAP}}){
my $value = $hash->{TEMPMAP}->{$key};
push @values, $value;
}
if (scalar(@values)>0) {
$defMin = min(@values);
$defMax = max(@values);
}
my $attrRange = AttrVal($me, "widgetTempRange", "$defMin:$defMax:$defStep");
my @rangV = split(':',$attrRange);
Log3($me, 5, "$me(weekprofile_createTempList): range $attrRange, @rangV");
if (scalar(@rangV) >= 2) {
$defMin = $rangV[0];
$defMax = $rangV[1];
}
if (scalar(@rangV) == 3) {
$defStep = $rangV[2];
}
my @tempList = ();
for (my $temp = $defMin; $temp <= $defMax; $temp+=$defStep){
push @tempList, "\"".tempValue($temp)."\"";
}
my $strList = weekprofile_replaceKeywords($hash, join(',', @tempList), 'toKey');
$strList =~s/\"//g;
return $strList;
}
##############################################
sub weekprofile_readProfilesFromFile(@)
{
my ($hash) = @_;
@ -1431,17 +1542,17 @@ sub weekprofile_readProfilesFromFile(@)
my $useTopics = AttrVal($me,"useTopics",0);
my $filename = weekprofile_getDataFile($hash);
Log3 $me, 5, "$me(readProfilesFromFile): read profiles from $filename";
Log3($me, 5, "$me(readProfilesFromFile): read profiles from $filename");
my ($ret, @content) = FileRead($filename);
if ($ret) {
if (configDBUsed()){
Log3 $me, 1, "$me(readProfilesFromFile): please import your config file $filename into configDB!";
Log3($me, 1, "$me(readProfilesFromFile): please import your config file $filename into configDB!");
} else {
if ($ret =~ m/.*Can't open.*/) {
defined($hash->{MASTERDEV}) ? Log3 $me, 4, "$me(readProfilesFromFile): $ret" : Log3 $me, 3, "$me(readProfilesFromFile): $ret - save profil(s) at least one time";
defined($hash->{MASTERDEV}) ? Log3($me, 4, "$me(readProfilesFromFile): $ret") : Log3($me, 3, "$me(readProfilesFromFile): $ret - save profil(s) at least one time");
} else {
Log3 $me, 1, "$me(readProfilesFromFile): $ret";
Log3($me, 1, "$me(readProfilesFromFile): $ret");
}
}
return;
@ -1453,24 +1564,25 @@ sub weekprofile_readProfilesFromFile(@)
foreach (@content) {
my $row = $_;
chomp $row;
Log3 $me, 5, "$me(readProfilesFromFile): data row $row";
Log3($me, 5, "$me(readProfilesFromFile): data row $row");
my @data = split('=',$row);
if(@data<2){
Log3 $me, 1, "$me(readProfilesFromFile): incorrect data row";
Log3($me, 1, "$me(readProfilesFromFile): incorrect data row");
next;
}
if ($rowCnt == 0 && $data[0]=~/__version__/) {
$version=$data[1] * 1;
Log3 $me, 5, "$me(readProfilesFromFile): detect version $version";
Log3($me, 5, "$me(readProfilesFromFile): detect version $version");
next;
}
if (!$version || $version < 1.1) {
my $prfData=undef;
eval { $prfData = $json->decode($data[1]); };
my $strData = weekprofile_replaceKeywords($hash,$data[1],'toValue');
eval { $prfData = $json->decode($strData); };
if (!defined($prfData)) {
Log3 $me, 1, "$me(readProfilesFromFile): Error parsing profile data $data[1]";
Log3($me, 1, "$me(readProfilesFromFile): Error parsing profile data $data[1]");
next;
};
@ -1488,9 +1600,10 @@ sub weekprofile_readProfilesFromFile(@)
} #----------------------------------------------------- 1.1
elsif ($version = 1.1) {
my $prfNew=undef;
eval { $prfNew = $json->decode($data[1]); };
my $strData = weekprofile_replaceKeywords($hash,$data[1],'toValue');
eval { $prfNew = $json->decode($strData); };
if (!defined($prfNew)) {
Log3 $me, 1, "$me(readProfilesFromFile): Error parsing profile data $data[1]";
Log3($me, 1, "$me(readProfilesFromFile): Error parsing profile data $data[1]");
next;
};
@ -1503,7 +1616,7 @@ sub weekprofile_readProfilesFromFile(@)
}
$rowCnt++;
} else {
Log3 $me, 1, "$me(readProfilesFromFile): Error unknown version $version";
Log3($me, 1, "$me(readProfilesFromFile): Error unknown version $version");
return;
}
}
@ -1524,8 +1637,6 @@ sub weekprofile_SummaryFn()
my $editNewpage = AttrVal($d, "widgetEditOnNewPage", 0);
my $useTopics = AttrVal($d, "useTopics", 0);
my $editDaysInRow = AttrVal($d, "widgetEditDaysInRow", undef);
my $tempON = AttrVal($d, "tempON", undef);
my $tempOFF = AttrVal($d, "tempOFF", undef);
my $editIcon = FW_iconName($iconName) ? FW_makeImage($iconName,$iconName,"icon") : "";
$editIcon = "<a name=\"$d.edit\" onclick=\"weekprofile_DoEditWeek('$d','$editNewpage')\" href=\"javascript:void(0)\">$editIcon</a>";
@ -1539,8 +1650,6 @@ sub weekprofile_SummaryFn()
$args .= ",USETOPICS:$useTopics";
$args .= ",MASTERDEV:$masterDev" if (defined($masterDev));
$args .= ",DAYINROW:$editDaysInRow" if (defined($editDaysInRow));
$args .= ",TEMP_ON:$tempON" if (defined($tempON));
$args .= ",TEMP_OFF:$tempOFF" if (defined($tempOFF));
my $curr = "";
if (@{$hash->{PROFILES}} > 0)
@ -1581,14 +1690,8 @@ sub weekprofile_editOnNewpage(@)
my $editDaysInRow = AttrVal($device, "widgetEditDaysInRow", undef);
$editDaysInRow = $daysInRow if (defined($daysInRow));
my $tempON = AttrVal($device, "tempON", undef);
my $tempOFF = AttrVal($device, "tempOFF", undef);
my $args = "weekprofile,MODE:EDIT,JMPBACK:1";
$args .= ",DAYINROW:$editDaysInRow" if (defined($editDaysInRow));
$args .= ",TEMP_ON:$tempON" if (defined($tempON));
$args .= ",TEMP_OFF:$tempOFF" if (defined($tempOFF));
my $html;
$html .= "<html>";
@ -1816,6 +1919,19 @@ sub weekprofile_getEditLNK_MasterDev($$)
<li>widgetEditDaysInRow<br>
Count of visible days in on row during Edit. Default 2.<br>
</li>
<li>widgetTempRange<br>
Set the temperature range of the dropdown list in the FHEM widget
Syntax: min:max:step e.g. 5:30:0.5
</li>
<li>tempMap<br>
Temperature key value pair
Syntax: <key_1>:<value 1>,<key_2>:<value 2><br>
e.g. off:5.0,on:30.0
</li>
<li>sendKeywordsToDevices<br>
Send temperatur keywords instead of temparture values to device
Default: 0
</li>
<li>configFile<br>
Path and filename of the configuration file where the profiles will be stored
Default: ./log/weekprofile-<name>.cfg
@ -1828,12 +1944,6 @@ sub weekprofile_getEditLNK_MasterDev($$)
Enable topics.<br>
Default: 0
</li>
<li>tempON<br>
Temperature for 'on'. e.g. 30
</li>
<li>tempOFF<br>
Temperature for 'off'. e.g. 4
</li>
<li>sendDelay<br>
Default: 0
Delay in seconds between sending profile data the same type of device.
@ -2010,6 +2120,19 @@ sub weekprofile_getEditLNK_MasterDev($$)
<li>widgetEditOnNewPage<br>
Wenn gesetzt ('1'), dann wird die Bearbeitung auf einer separaten\neuen Webseite gestartet.
</li>
<li>widgetTempRange<br>
Bereich der Temperatur Dropdown-Box im FHEM widget
Syntax: min:max:step z.B. 5:30:0.5
</li>
<li>tempMap<br>
Temperatur Schlüssel-Werte-Paare
Syntax: <schlüsselwort_1>:<wert_1>,<schlüsselwort_2>:<wert_2><br>
z.B. off:5.0,on:30.0
</li>
<li>sendKeywordsToDevices<br>
Sende Temperatur-Schlüsselwort zum Gerät anstatt der Werte
Default: 0
</li>
<li>configFile<br>
Pfad und Dateiname wo die Profile gespeichert werden sollen.
Default: ./log/weekprofile-<name>.cfg
@ -2021,12 +2144,6 @@ sub weekprofile_getEditLNK_MasterDev($$)
<li>useTopics<br>
Verwendung von Topic aktivieren.
</li>
<li>tempON<br>
Temperature für 'on'. z.B. 30
</li>
<li>tempOFF<br>
Temperature für 'off'. z.B. 4
</li>
<li>sendDelay<br>
Default: 0
Verzögerungszweit in Sekunden zwischen dem Senden von Profildaten an ein Thermostat gleichen Typs.

View File

@ -168,7 +168,7 @@ function FW_weekprofilePRF_chached(devName,select)
var prfName = select.options[select.selectedIndex].value;
widget.CURPRF = prfName;
widget.PROFILE = null;
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF+' 1', widget);
}
function FW_weekprofileTOPIC_chached(devName,select)
@ -535,6 +535,9 @@ function FW_weekprofileTemp_chached(select)
function FW_weekprofileEditDay(widget,day)
{
if (widget.PROFILE == null) {
return "";
}
var div = $("<div>").get(0);
var html= '';
html += "<div style=\"padding:5px;\">";
@ -548,8 +551,9 @@ function FW_weekprofileEditDay(widget,day)
$(table).attr('class',"block wide weekprofile");
html = '';
var times = widget.PROFILE[shortDays[day]]['time'];
var temps = widget.PROFILE[shortDays[day]]['temp'];
var sday = shortDays[day];
var times = widget.PROFILE[sday]['time'];
var temps = widget.PROFILE[sday]['temp'];
for (var i = 0; i < times.length; ++i) {
var startTime = (i>0) ? times[i-1] : "00:00";
@ -563,39 +567,18 @@ function FW_weekprofileEditDay(widget,day)
//to
html += "<td><input type=\"text\" name=\"ENDTIME\" size=\"5\" maxlength=\"5\" align=\"center\" value=\""+endTime+"\" onblur=\"FW_weekprofileEditTime_changed(this)\"/></td>";
//temp
var tempOn = widget.TEMP_ON;
var tempOff = widget.TEMP_OFF;
if (tempOn == null)
tempOn = 30;
if (tempOff == null)
tempOff = 5;
if (tempOff > tempOn)
{
var tmp = tempOn;
tempOn = tempOff;
tempOff = tmp;
// temp
if (widget.TEMPLIST == null) {
widget.TEMPLIST = new Array();
for (var k=5; k <= 30; k+=0.5) {
widget.TEMPLIST.push(k);
}
}
html += "<td><select name=\"TEMP\" size=\"1\" onchange=\"FW_weekprofileTemp_chached(this)\">";
for (var k=tempOff; k <= tempOn; k+=.5)
for (var k=0; k < widget.TEMPLIST.length; ++k)
{
var selected = (k == temps[i]) ? "selected " : "";
if (k == widget.TEMP_OFF) {
// currently weekprofile save on|off into json data
selected = (temps[i] == "off") ? "selected " : "";
html += "<option "+selected+"value=\"off\">off</option>";
}
else if (k == widget.TEMP_ON) {
// currently weekprofile save on|off into json data
selected = (temps[i] == "on") ? "selected " : "";
html += "<option "+selected+"value=\"on\">on</option>";
}
else
html += "<option "+selected+"value=\""+k.toFixed(1)+"\">"+k.toFixed(1)+"</option>";
var selected = (widget.TEMPLIST[k] == temps[i]) ? "selected " : "";
html += "<option "+selected+"value=\""+widget.TEMPLIST[k]+"\">"+widget.TEMPLIST[k]+"</option>";
}
html += "</select></td>";
//ADD-Button
@ -783,7 +766,7 @@ function FW_weekprofileGetValues(devName,what,data)
if (widget.CURPRF == null && widget.PROFILENAMES) {
widget.CURPRF = widget.PROFILENAMES[0];
}
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF+' 1', widget);
} else {
widget.setValueFn("REUSEPRF");
}
@ -808,6 +791,14 @@ function FW_weekprofileGetValues(devName,what,data)
if (trans.length == 2)
widget.TRANSLATIONS[trans[0].trim()] = trans[1].trim();
}
} else if (what == "TEMPLIST") {
console.log(devName+" TEMPLIST '" +data+"'");
var arr = data.split(',');
widget.TEMPLIST = new Array();
var i = -1;
while (++i < arr.length) {
widget.TEMPLIST[i] = arr[i];
}
}
}
@ -846,8 +837,7 @@ FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
widget.JMPBACK = null;
widget.MODE = 'SHOW';
widget.USETOPICS = 0;
widget.TEMP_ON = null;
widget.TEMP_OFF = null;
widget.TEMPLIST = null;
for (var i = 1; i < vArr.length; ++i) {
var arg = vArr[i].split(':');
@ -857,8 +847,6 @@ FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
case "MASTERDEV": widget.MASTERDEV = arg[1]; break;
case "USETOPICS": widget.USETOPICS = arg[1]; break;
case "DAYINROW": widget.EDIT_DAYSINROW = arg[1]; break;
case "TEMP_ON": widget.TEMP_ON = parseFloat(arg[1]); break;
case "TEMP_OFF": widget.TEMP_OFF = parseFloat(arg[1]);break;
}
}
@ -871,7 +859,8 @@ FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
widget.setValueFn = function(arg){FW_weekprofileGetProfileData(devName,arg);}
widget.activateFn = function(arg){
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
FW_cmd(FW_root+'?cmd=get '+devName+' tempList&XHR=1',function(data){FW_weekprofileGetValues(devName,"TEMPLIST",data);});
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF+' 1', widget); // use keywords
FW_cmd(FW_root+'?cmd={AttrVal("'+devName+'","widgetWeekdays","")}&XHR=1',function(data){FW_weekprofileGetValues(devName,"WEEKDAYS",data);});
FW_cmd(FW_root+'?cmd={AttrVal("'+devName+'","widgetTranslations","")}&XHR=1',function(data){FW_weekprofileGetValues(devName,"TRANSLATE",data);});
if (widget.USETOPICS == 1) {
@ -888,6 +877,7 @@ FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
// do not update profile data in edit mode
return;
}
FW_cmd(FW_root+'?cmd=get '+devName+' tempList&XHR=1',function(data){FW_weekprofileGetValues(devName,"TEMPLIST",data);});
if (widget.USETOPICS == 1) {
FW_cmd(FW_root+'?cmd=get '+devName+' topic_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"TOPICNAMES",data);});
} else {