2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-12 02:39:57 +00:00

98_weekprofile: including topics\categories

git-svn-id: https://svn.fhem.de/fhem/trunk@10613 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
risiko79 2016-01-24 19:10:01 +00:00
parent 1d37848518
commit 958a5dc9cc
3 changed files with 409 additions and 113 deletions

View File

@ -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.
- feature: 98_weekprofile: including topics\categories
- change: 98_weekprofile: filter for homatic channel devices
- feature: YAMAHA_BD: input reading indicates now Netflix, YouTube, and all
other online apps.
- feature: 73_GasCalculator: New module for calc. around the gas consumption

View File

@ -60,7 +60,10 @@ sub weekprofile_getDeviceType($;$)
if ($devHash->{TYPE} =~ /CUL_HM/){
my $model = AttrVal($device,"model","");
$type = "CUL_HM" if ($model =~ m/.*(HM-CC|HM-TC).*/);
return undef if (!defined($devHash->{chanNo})); #no channel device
$type = "CUL_HM" if ( ($model =~ m/.*(HM-CC).*/) && ($devHash->{chanNo} == 4) );
$type = "CUL_HM" if ( ($model =~ m/.*(HM-TC).*/) && ($devHash->{chanNo} == 2) );
}
#avoid max shutter contact
elsif ( ($devHash->{TYPE} =~ /MAX/) && ($devHash->{type} =~ /.*Thermostat.*/) ){
@ -362,6 +365,13 @@ sub weekprofile_updateReadings($)
#readingsBulkUpdate($hash,$str,$prf->{NAME});
#$idx++;
#}
splice(@{$hash->{TOPICS}});
foreach my $prf (@{$hash->{PROFILES}}) {
if ( !grep( /^$prf->{TOPIC}$/, @{$hash->{TOPICS}}) ) {
push @{$hash->{TOPICS}}, $prf->{TOPIC};
}
}
readingsEndUpdate($hash, 1);
}
##############################################
@ -406,9 +416,11 @@ sub weekprofile_Define($$)
$hash->{STATE} = "defined";
my @profiles = ();
my @sendDevList = ();
my @topics = ();
$hash->{PROFILES} = \@profiles;
$hash->{PROFILES} = \@profiles;
$hash->{SNDDEVLIST} = \@sendDevList;
$hash->{TOPICS} = \@topics;
#$attr{$me}{verbose} = 5;
@ -431,14 +443,15 @@ sub weekprofile_Get($$@)
my $useTopics = AttrVal($name,"useTopics",0);
if (!$useTopics) {
$list.= 'profile_data:' if ($prfCnt > 0);
foreach my $prf (@{$hash->{PROFILES}}){
$list.= $prf->{NAME}.",";
}
$list = substr($list, 0, -1) if ($prfCnt > 0);
} else {$list.= 'profile_data' if ($prfCnt > 0);}
$list.= 'profile_data:' if ($prfCnt > 0);
foreach my $prf (@{$hash->{PROFILES}}){
$list.= $prf->{TOPIC}.":" if ($useTopics);
$list.= $prf->{NAME}."," if ($useTopics || (!$useTopics && ($prf->{TOPIC} eq 'default')));
}
$list = substr($list, 0, -1) if ($prfCnt > 0);
#-----------------------------------------------------------------------------
if($cmd eq "profile_data") {
return 'usage: profile_data <name>' if(@params < 1);
return "no profile" if ($prfCnt <= 0);
@ -457,7 +470,7 @@ sub weekprofile_Get($$@)
my $json_text = $json->encode($prf->{DATA});
return $json_text;
}
#-----------------------------------------------------------------------------
$list.= ' profile_names';
if($cmd eq "profile_names") {
my $names = '';
@ -468,22 +481,49 @@ sub weekprofile_Get($$@)
$names .=$prf->{NAME}."," if ($topic eq $prf->{TOPIC});
$names .="$prf->{TOPIC}:$prf->{NAME}," if ($topic eq '*');
}
$names = substr($names, 0, -1);
if ($names) {
$names = substr($names, 0, -1);
$names =~ s/ $//;
}
return $names;
}
$list.= ' profile_references:noArg';
#-----------------------------------------------------------------------------
$list.= ' profile_references' if ($useTopics);
if($cmd eq "profile_references") {
return 'usage: profile_references <name>' if(@params < 1);
my $refs = '';
my $topic = 'default';
foreach my $prf (@{$hash->{PROFILES}}){
next if (!defined($prf->{REF}));
$refs .= "$prf->{TOPIC}:$prf->{NAME} -> $prf->{REF},";
if ($params[0] eq '*') {
foreach my $prf (@{$hash->{PROFILES}}){
next if (!defined($prf->{REF}));
$refs .= "$prf->{TOPIC}:$prf->{NAME}>$prf->{REF},";
}
$refs = substr($refs, 0, -1);
} else {
my ($topic, $name) = weekprofile_splitName($params[0]);
my ($prf,$idx) = weekprofile_findPRF($hash,$name,$topic);
return "profile $params[0] not found" unless ($prf);
$refs = '0';
$refs = "$prf->{REF}" if ($prf->{REF});
}
$refs = substr($refs, 0, -1);
return $refs;
}
#-----------------------------------------------------------------------------
$list.= ' topic_names:noArg' if ($useTopics);
if($cmd eq "topic_names") {
my $names = '';
foreach my $topic (@{$hash->{TOPICS}}) {
$names .= "$topic,";
}
if ($names) {
$names = substr($names, 0, -1);
$names =~ s/ $//;
}
return $names;
}
if($cmd eq "sndDevList") {
my $json = JSON->new;
my $json_text = $json->encode($hash->{SNDDEVLIST});
@ -643,14 +683,14 @@ sub weekprofile_Set($$@)
Log3 $me, 4, "$me(Set): override profile $destName" if ($prfDest);
if ($prfDest){
$prfDest->{DATA} = $prfSrc->{DATA};
$prfDest->{REF} = undef;
$prfDest->{DATA} = $prfSrc->{DATA};
$prfDest->{REF} = $prfSrc->{REF};
} else {
$prfDest = {};
$prfDest->{NAME} = $destName;
$prfDest->{DATA} = $prfSrc->{DATA};
$prfDest->{TOPIC} = $destTopic;
$prfDest->{REF} = undef;
$prfDest->{REF} = $prfSrc->{REF};
push @{$hash->{PROFILES}}, $prfDest;
}
weekprofile_writeProfilesToFile($hash);
@ -659,7 +699,7 @@ sub weekprofile_Set($$@)
}
#----------------------------------------------------------
$list.= " reference_profile";
$list.= " reference_profile" if ($useTopics);
if ($cmd eq 'reference_profile') {
return 'usage: copy_profile <source> <target>' if(@params < 2);
@ -717,32 +757,28 @@ sub weekprofile_Set($$@)
#----------------------------------------------------------
$list.= " change_topic" if ($useTopics);
if ($cmd eq 'change_topic') {
return 'usage: change_topic <name>' if(@params < 1);
my $restore = 1;
$list.= " restore_topic" if ($useTopics);
if ($cmd eq 'restore_topic') {
return 'usage: restore_topic <name>' if(@params < 1);
my $topic = $params[0];
my $err = "";
my $err='';
$restore = $params[1] if(@params == 2);
if ($restore) {
foreach my $dev (@{$hash->{SNDDEVLIST}}){
my $prfName = AttrVal($dev->{NAME},"weekprofile",undef);
next if (!defined($prfName));
Log3 $me, 5, "$me(Set): found device $dev->{NAME}";
my ($prf,$idx) = weekprofile_findPRF($hash,$prfName,$topic);
next if (!defined($prf));
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);
$err .= $ret . "\n";
}
foreach my $dev (@{$hash->{SNDDEVLIST}}){
my $prfName = AttrVal($dev->{NAME},"weekprofile",undef);
next if (!defined($prfName));
Log3 $me, 5, "$me(Set): found device $dev->{NAME}";
my ($prf,$idx) = weekprofile_findPRF($hash,$prfName,$topic);
next if (!defined($prf));
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);
$err .= $ret . "\n";
}
}
readingsSingleUpdate($hash,"active_topic",$topic,1);
@ -873,6 +909,8 @@ sub weekprofile_readProfilesFromFile(@)
{
my ($hash) = @_;
my $me = $hash->{NAME};
my $useTopics = AttrVal($me,"useTopics",0);
my $filename = "./log/weekprofile-$me.cfg";
$filename = AttrVal($me,"configFile",$filename);
@ -936,6 +974,8 @@ sub weekprofile_readProfilesFromFile(@)
next;
};
next if (!$useTopics && ($prfNew->{TOPIC} ne 'default')); # remove topics!!
if (!$hash->{MASTERDEV} && $rowCnt == 0) {
$hash->{PROFILES}[0] = $prfNew; # replace default
} else {
@ -964,6 +1004,7 @@ sub weekprofile_SummaryFn()
my $iconName = AttrVal($d, "icon", "edit_settings");
my $editNewpage = AttrVal($d, "widgetEditOnNewPage", 0);
my $useTopics = AttrVal($d, "useTopics", 0);
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>";
@ -974,17 +1015,30 @@ sub weekprofile_SummaryFn()
my $masterDev = defined($hash->{MASTERDEV}) ? $hash->{MASTERDEV}->{NAME} : undef;
my $args = "weekprofile,MODE:SHOW";
$args .= ",USETOPICS:$useTopics";
$args .= ",MASTERDEV:$masterDev" if (defined($masterDev));
my $curr = "";
$curr = $hash->{PROFILES}[0]->{NAME} if (@{$hash->{PROFILES}} > 0 );
if (@{$hash->{PROFILES}} > 0)
{
$curr = "$hash->{PROFILES}[0]->{TOPIC}:$hash->{PROFILES}[0]->{NAME}";
my $currTopic = ReadingsVal($d, "active_topic", undef);
if ($currTopic) {
foreach my $prf (@{$hash->{PROFILES}}){
if ($prf->{TOPIC} eq $currTopic){
$curr = "$prf->{TOPIC}:$prf->{NAME}";
last;
}
}
}
}
$html .= "<table>";
$html .= "<tr><td>";
$html .= "<div class=\"devType\" id=\"weekprofile.$d.header\">";
$html .= "<div class=\"devType\" id=\"weekprofile.menu.base\">";
$html .= "<table style=\"padding:0\"><tr><td style=\"padding-right:0;padding-bottom:0\"><div id=\"weekprofile.menu.base\">";
$html .= $editIcon."&nbsp;".$lnkDetails;
$html .= "</di></div></td></tr>";
$html .= "</div></td></tr></table></div></td></tr>";
$html .= "<tr><td>";
$html .= "<div class=\"fhemWidget\" informId=\"$d\" cmd=\"\" arg=\"$args\" current=\"$curr\" dev=\"$d\">"; # div tag to support inform updates
$html .= "</div>";
@ -1077,7 +1131,16 @@ sub weekprofile_getEditLNK_MasterDev($$)
Im Standardfall wird das Modul mit einem Geräte = 'Master-Gerät' assoziiert,
um das Wochenprofil vom Gerät grafisch bearbeiten zu können und andere Profile auf das Gerät zu übertragen.
Wird kein 'Master-Gerät' angegeben, wird erstmalig ein Default-Profil angelegt.
<br>
Ein weiterer Anwendungsfall ist die Verwendung von Rubriken 'Topics'.
Hier sollte kein 'Master-Gerät' angegeben werden. Dieses Feature muss erst über das Attribut 'useTopics' aktiviert werden.
Topics sind z.B. Winter, Sommer, Urlaub, Party, etc.
Innerhalb einer Topic kann es mehrere Wochenprofile geben. Sinnvollerweise sollten es soviele wie Thermostate sein.
Über ein Userattribut 'weekprofile' im Thermostat wird ein Wochenprofile ohne Topicname angegeben.
Mittels 'restore_topic' wird dann das angebene Wochenprofil der Topic an das Thermostat übertragen.
Somit kann man einfach zwischen den Topics wechseln und die Thermostate bekommen das passende Wochenprofil.
<br><br>
<b>Achtung:</b> Das Übertragen von Wochenprofilen erfordet eine Menge an Credits.
Dies wird vom Modul nicht berücksichtigt. So kann es sein, dass nach dem
Setzen\Aktualisieren eines Profils das Profil im Modul nicht mit dem Profil im Gerät
@ -1125,7 +1188,11 @@ sub weekprofile_getEditLNK_MasterDev($$)
<li>reference_profile<br>
<code>set &lt;name&gt; reference_profile &lt;quelle&gt; &lt;ziel&gt; </code><br>
Referenziert das Profil 'ziel'auf 'quelle'. 'ziel' wird überschrieben oder neu angelegt.
<b>Noch in Entwicklung !!!</b>
</li>
<li>restore_topic<br>
<code>set &lt;name&gt; restore_topic &lt;topic&gt;</code><br>
Alle Wochenpläne in der Topic werden zu den entsprechenden Geräten übertragen.
Dazu muss im Gerät ein Userattribut 'weekprofile' mit dem Namen des Wochenplans <b>ohne</b> Topic gesetzt sein.
</li>
</ul>
@ -1203,10 +1270,18 @@ sub weekprofile_getEditLNK_MasterDev($$)
<li>Homatic channel _Clima or _Climate</li>
In the normal case the module is assoziated with a master device.
So a profile 'master' will be created automatically. This profile correnspond to the current active
So a profile 'master' will be created automatically. This profile corrensponds to the current active
profile on the master device.
You can also use this module without a master device. In this case a default profile will be created.
<br>
An other use case is the usage of categories 'Topics'.
To enable the feature the attribute 'useTopics' have to be set.
Topics are e.q. winter, summer, holidays, party, and so on.
A topic consists of different week profiles. Normally one profile for each thermostat.
The connection between the thermostats and the profile is an user attribute 'weekprofile' without the topic name.
With 'restore_topic' the defined profile in the attribute will be transfered to the thermostat.
So it is possible to change the topic easily and all thermostats will be updated with the correndponding profile.
<br><br>
<b>Attention:</b>
To transfer a profile to a device it needs a lot of Credits.
This is not taken into account from this module. So it could be happend that the profile in the module
@ -1256,6 +1331,11 @@ sub weekprofile_getEditLNK_MasterDev($$)
Create a reference from destination to source. The destination will be overwritten if it exits.
<b>Still under development!!!</b>
</li>
<li>restore_topic<br>
<code>set &lt;name&gt; restore_topic &lt;topic&gt;</code><br>
All weekprofiles from the topic will be transfered to the correcponding devices.
Therefore a user attribute 'weekprofile' with the weekprofile name <b>without the topic name</b> have to exist in the device.
</li>
</ul>
<a name="weekprofileget"></a>
@ -1266,14 +1346,19 @@ sub weekprofile_getEditLNK_MasterDev($$)
Get the profile date from 'profilename' in json-Format
</li>
<li>profile_names<br>
<code>set &lt;name&gt; profile_names</code><br>
Get a comma seperated list of profile names
<code>set &lt;name&gt; profile_names [topicname]</code><br>
Get a comma seperated list of weekprofile profile names from the topic 'topicname'
If topicname is not set, 'default' will be used
If topicname is '*', all weekprofile profile names are returned.
</li>
<li>profile_references<br>
Get a list of references in the following syntax
<code>
ref_topic:ref_profile -> dest_topic:dest_profile
</code>
<li>profile_references [name]<br>
If name is '*', a comma seperated list of all references in the following syntax
<code>ref_topic:ref_profile>dest_topic:dest_profile</code>
are returned
If name is 'topicname:profilename', '0' or the reference name is returned.
</li>
<li>topic_names<br>
Return a list of topic names.
</li>
</ul>
@ -1286,7 +1371,7 @@ sub weekprofile_getEditLNK_MasterDev($$)
</ul>
<ul>
<li>active_topic<br>
Aktive Topic.
Active\restored topic name
</li>
<li>profile_count<br>
Count of all profiles including references.
@ -1308,11 +1393,11 @@ sub weekprofile_getEditLNK_MasterDev($$)
Default: ./log/weekprofile-<name>.cfg
</li>
<li>icon<br>
icon for edit
icon for edit<br>
Default: edit_settings
</li>
<li>useTopics<br>
Enable topics.
Enable topics.<br>
Default: 0
</li>
</ul>

View File

@ -7,12 +7,36 @@ $(document).ready(function(){
var shortDays = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
function FW_weekprofileInputDialog(title,inp,parent,callback)
function FW_weekprofileInputDialog(title,inp,def,parent,callback)
{
var div = $("<div id='FW_weekprofileInputDiolog'>");
var content = $('<input type="'+inp+'">').get(0);
$(div).append(title);
$(div).append(content);
var table = $("<table>");
var content = [];
for(var i=0; i<title.length; i++){
var tr =
content[i] = $('<input type="'+inp[i]+'">').get(0);
if (def)
content[i].value = def[i];
var tr = $("<tr>");
var td1 = $("<td>");
$(td1).append(title[i]);
if (inp[i] == 'hidden') {
$(td1).attr("colspan","2");
$(td1).attr("align","center");
}
var td2 = $("<td>");
$(td2).append(content[i]);
$(tr).append(td1);
$(tr).append(td2);
table.append(tr);
}
$(div).append(table);
$("body").append(div);
$(div).dialog({
dialogClass:"no-close",modal:true, width:"auto", closeOnEscape:true,
@ -21,14 +45,21 @@ function FW_weekprofileInputDialog(title,inp,parent,callback)
buttons: [{text:"OK", click:function(){
$(this).dialog("close");
$(div).remove();
if(callback)
callback(content.value,1);
if(callback) {
var backCont = [];
for(var i=0; i<content.length; i++){
backCont[i] = content[i].value;
if (inp[i] == 'checkbox')
backCont[i] = content[i].checked;
}
callback(backCont,1);
}
}},{text:"CANCEL", click:function(){
$(this).dialog("close");
$(div).remove();
content.value = null;
if(callback)
callback(content.value,0);
callback(null,0);
}}]
});
@ -52,7 +83,7 @@ function FW_weekprofileMultiSelDialog(title, elementNames, elementLabels, select
var sel = 0;
if (selected && selected.indexOf(n)>=0)
sel=1;
table += '<tr><td><div class="checkbox"><input name="'+n+'" type="checkbox"';
table += (sel ? " checked" : "")+'/><label for="'+n+'"><span></span></label></div></td>';
table += '<td><label for="' +n+'">'+l+'</label></td></tr>';
@ -109,7 +140,7 @@ function weekprofile_DoEditWeek(devName,newPage)
url = url.substr(pos);
else
url='';
window.location.assign(FW_root+'?cmd={weekprofile_editOnNewpage("'+widget.DEVICE+'","'+widget.CURPRF+'","'+url+'");;}');
window.location.assign(FW_root+'?cmd={weekprofile_editOnNewpage("'+widget.DEVICE+'","'+widget.CURTOPIC+':'+widget.CURPRF+'","'+url+'");;}');
} else {
widget.MODE = 'EDIT';
$(widget.MENU.BASE).hide();
@ -117,14 +148,49 @@ function weekprofile_DoEditWeek(devName,newPage)
}
}
function FW_weekprofilePRFChached(devName,select)
function FW_weekprofilePRF_chached(devName,select)
{
var widget = $('div[informid="'+devName+'"]').get(0)
var prfName = select.options[select.selectedIndex].value;
widget.CURPRF = prfName;
widget.PROFILE = null;
FW_queryValue('get '+devName+' profile_data '+prfName, widget);
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
}
function FW_weekprofileTOPIC_chached(devName,select)
{
var widget = $('div[informid="'+devName+'"]').get(0)
var topicName = select.options[select.selectedIndex].value;
widget.CURTOPIC = topicName;
widget.CURPRF = null;
widget.PROFILE = null;
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
}
function FW_weekprofileChacheTo(devName,topicName,profileName)
{
var widget = $('div[informid="'+devName+'"]').get(0)
widget.CURTOPIC = topicName;
widget.CURPRF = profileName;
widget.PROFILE = null;
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
}
function FW_weekprofileRestoreTopic(devName,bnt)
{
var widget = $('div[informid="'+devName+'"]').get(0)
FW_weekprofileInputDialog(["<p>Restore topic: '"+widget.CURTOPIC+"'&nbsp;?</p>"],["hidden"],null,bnt,function(name,ok){
if (ok == 1)
FW_cmd(FW_root+'?cmd=set '+devName+' restore_topic '+widget.CURTOPIC+'&XHR=1',function(data){
console.log(devName+" error restore topic '" +data+"'");
FW_errmsg(devName+" error restore topic '" +data+"'",5000);
return;
});
});
}
function FW_weekprofileSendToDev(devName,bnt)
@ -143,12 +209,12 @@ function FW_weekprofileSendToDev(devName,bnt)
}
var selected = [];
if (widget.MASTERDEV)
selected.push(widget.MASTERDEV);
selected.push(widget.MASTERDEV);
FW_weekprofileMultiSelDialog("<span>Device(s):</span>",devicesNames,devicesAlias,selected,bnt,
function(sndDevs) {
if (!sndDevs || sndDevs.length==0)
return;
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" send_to_device "+widget.CURPRF+" "+sndDevs.join(',')+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" send_to_device "+widget.CURTOPIC+':'+widget.CURPRF+" "+sndDevs.join(',')+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
});
} catch(e){
@ -165,10 +231,53 @@ function FW_weekprofileCopyPrf(devName,lnk)
{
var widget = $('div[informid="'+devName+'"]').get(0)
FW_weekprofileInputDialog("<span>Name:</span>","text",lnk,function(name,ok){
if (!name || name.length <=0)
var title = [];
var inp = [];
var def = [];
var idx = 0;
var topic = '';
if (widget.USETOPICS==1) {
topic=widget.CURTOPIC+":";
}
title[idx] = "<p>Create new entry from: "+topic+widget.CURPRF+"</p>";
inp[idx] = "hidden";
def[idx] = '';
idx++;
if (widget.USETOPICS==1) {
title[idx] = "<p>Reference:</p>";
inp[idx] = "checkbox";
def[idx] = '';
idx++;
title[idx] = "<p>Topic:</p>";
inp[idx] = "text";
def[idx] = widget.CURTOPIC;
idx++;
}
title[idx] = "<p>Name:</p>";
inp[idx] = "text";
def[idx] = '';
FW_weekprofileInputDialog(title,inp,def,lnk,function(names,ok){
if (ok < 1)
return;
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" copy_profile "+widget.CURPRF+" "+name+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
var topic = widget.CURTOPIC;
var name = names[names.length-1].trim();
var ref = 0;
if (widget.USETOPICS==1) {
topic = names[names.length-2].trim();
ref = names[names.length-3];
}
if (topic.length < 1 || name.length < 1)
return;
if (ref != 0)
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" reference_profile "+widget.CURTOPIC+':'+widget.CURPRF+" "+topic+':'+name+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
else
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" copy_profile "+widget.CURTOPIC+':'+widget.CURPRF+" "+topic+':'+name+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
});
}
@ -176,10 +285,10 @@ function FW_weekprofileRemovePrf(devName,lnk)
{
var widget = $('div[informid="'+devName+'"]').get(0)
FW_weekprofileInputDialog("<p>Delete Profile: '"+widget.CURPRF+"'&nbsp;?</p>","hidden",lnk,function(name,ok){
FW_weekprofileInputDialog(["<p>Delete Profile: '"+widget.CURTOPIC+':'+widget.CURPRF+"'&nbsp;?</p>"],["hidden"],null,lnk,function(name,ok){
if (ok < 1)
return;
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" remove_profile "+widget.CURPRF+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" remove_profile "+widget.CURTOPIC+':'+widget.CURPRF+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
});
}
@ -187,42 +296,90 @@ function FW_weekprofileRemovePrf(devName,lnk)
function FW_weekprofileShow(widget)
{
$(widget.MENU.BASE).show();
var editIcon = $(widget.MENU.BASE).find('a[name="'+widget.DEVICE+'.edit"]').get(0);
$(editIcon).css("visibility", "visible"); //hide() remove the element
$(widget.MENU.CONTENT).empty();
var html='';
var selMargin=0;
var tdStyle="style=\"padding-left:0px;padding-right:0px\"";
if (widget.USETOPICS == 1) {
selMargin = 2;
tdStyle = "style=\"padding:0px\"";
}
if (widget.PROFILENAMES) {
html += "&nbsp;"
html += "<select name=\"PROFILES\" onchange=\"FW_weekprofilePRFChached('"+widget.DEVICE+"',this)\">";
for (var k=0; k < widget.PROFILENAMES.length; k++)
{
var selected = (widget.CURPRF == widget.PROFILENAMES[k]) ? "selected " : "";
html += "<option "+selected+"value=\""+widget.PROFILENAMES[k]+"\">"+widget.PROFILENAMES[k]+"</option>";
var html='';
html += '<table style="padding-bottom:0">';
html += "<tr><td style=\"padding:0px\">";
if (widget.USETOPICS == 1 && widget.TOPICNAMES) {
html += "<select style=\"margin-bottom:"+selMargin+"px\" name=\"TOPICS\" onchange=\"FW_weekprofileTOPIC_chached('"+widget.DEVICE+"',this)\">";
for (var k=0; k < widget.TOPICNAMES.length; k++)
{
var name = widget.TOPICNAMES[k].trim();
var selected = (widget.CURTOPIC == name) ? "selected " : "";
html += "<option "+selected+"value=\""+name+"\">"+name+"</option>";
}
html += "</select>";
}
html += "</select>";
html += "&nbsp;"
html += "</td>";
html += "<td rowspan=\"2\" "+tdStyle+">";
html += "<button type=\"button\"onclick=\"FW_weekprofileCopyPrf('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"copy profile\">+</button>";
html += "&nbsp;"
html += "<button type=\"button\" onclick=\"FW_weekprofileRemovePrf('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"remove profile\">-</button>";
html += "&nbsp;"
html += "<button type=\"button\" onclick=\"FW_weekprofileSendToDev('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"send to device\">--></button>";
if (widget.USETOPICS == 0) {
html += "<button type=\"button\" onclick=\"FW_weekprofileSendToDev('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"send to device\">--></button>";
} else {
html += "<button type=\"button\" onclick=\"FW_weekprofileRestoreTopic('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"restore topic\">T</button>";
}
html += "</td></tr>";
html += "<tr><td "+tdStyle+">";
html += "<select style=\"margin-top:"+selMargin+"px\" name=\"PROFILES\" onchange=\"FW_weekprofilePRF_chached('"+widget.DEVICE+"',this)\">";
for (var k=0; k < widget.PROFILENAMES.length; k++)
{
var name = widget.PROFILENAMES[k];
var selected = (widget.CURPRF == name) ? "selected " : "";
html += "<option "+selected+"value=\""+name+"\">"+name+"</option>";
}
html += "</select>";
html += "</td></tr>";
if (widget.PRFREF) {
$(editIcon).css("visibility", "hidden");
var names = widget.PRFREF.split(':');
names[0] = names[0].trim();
names[1] = names[1].trim();
html += "<tr><td colspan=\"2\" align=\"left\" "+tdStyle+">";
html += "&nbsp;"
html += "<a href=\"javascript:void(0)\" onclick=\"FW_weekprofileChacheTo('"+widget.DEVICE+"','"+names[0]+"','"+names[1]+"')\">REF: "+names[0]+":"+names[1]+"</a>";
html += "</td></tr>";
}
html += "</table>";
$(widget.MENU.CONTENT).append(html);
var select = $(widget.MENU.CONTENT).find('select[name="PROFILES"]').get(0);
var prfName = select.options[select.selectedIndex].value;
if (widget.CURPRF != prfName)
FW_weekprofilePRFChached(widget.DEVICE,select);
FW_weekprofilePRF_chached(widget.DEVICE,select);
}
if (!widget.PROFILE) {
return;
}
var table = widget.CONTENT;
var table = widget.CONTENT;
$(table).empty();
for (var i = 0; i < shortDays.length; ++i) {
$(table).append('<tr class="'+ ( (i+1)%2==0 ? 'even':'odd')+ '"><td>'+widget.WEEKDAYS[i]+'</td></tr>');
@ -242,7 +399,7 @@ function FW_weekprofileShow(widget)
}
}
function FW_weekprofileEditTimeChanged(inp)
function FW_weekprofileEditTime_changed(inp)
{
if (inp == null) {return;}
var times = inp.value.split(':');
@ -275,7 +432,7 @@ function FW_weekprofileEditRowStyle(table)
inp.removeAttr('style');
inp.removeAttr('readonly');
FW_weekprofileEditTimeChanged(inp.get(0));
FW_weekprofileEditTime_changed(inp.get(0));
if (i==0){
$(alltr[i]).find('span[name="STARTTIME"]').get(0).innerHTML = "00:00";
@ -348,7 +505,7 @@ function FW_weekprofileEditDay(widget,day)
html += "<td>-</td>";
//to
html += "<td><input type=\"text\" name=\"ENDTIME\" size=\"5\" maxlength=\"5\" align=\"center\" value=\""+endTime+"\" onblur=\"FW_weekprofileEditTimeChanged(this)\"/></td>";
html += "<td><input type=\"text\" name=\"ENDTIME\" size=\"5\" maxlength=\"5\" align=\"center\" value=\""+endTime+"\" onblur=\"FW_weekprofileEditTime_changed(this)\"/></td>";
//temp
html += "<td><select name=\"TEMP\" size=\"1\">";
@ -372,6 +529,8 @@ function FW_weekprofileEditDay(widget,day)
function FW_weekprofileEditWeek(widget)
{
$(widget.MENU.CONTENT).empty();
var table = widget.CONTENT;
var daysInRow = 2;
@ -436,7 +595,7 @@ function FW_weekprofilePrepAndSendProf(devName)
}
try {
var data=JSON.stringify(prf);
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" profile_data "+widget.CURPRF+" "+data+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" profile_data "+widget.CURTOPIC+':'+widget.CURPRF+" "+data+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
} catch(e){
FW_errmsg(devName+" Parameter "+e,5000);
return;
@ -468,14 +627,15 @@ function FW_weekprofileEditAbort(devName)
FW_weekprofileBack(widget);
}
function FW_weekprofileSetValue(devName,data)
function FW_weekprofileGetProfileData(devName,data)
{
var widget = $('div[informid="'+devName+'"]').get(0);
$(widget.CONTENT).empty();
var reuse = (data == "REUSEPRF") ? 1 : 0;
var prf={};
try {
(data == "REUSEPRF") ? prf = widget.PROFILE : prf=JSON.parse(data);
(reuse) ? prf = widget.PROFILE : prf=JSON.parse(data);
} catch(e){
console.log(devName+" error parsing json '" +data+"'");
FW_errmsg(devName+" Parameter "+e,5000);
@ -483,9 +643,25 @@ function FW_weekprofileSetValue(devName,data)
}
widget.PROFILE = prf;
widget.PRFREF = null;
if (widget.MODE == 'SHOW')
{
FW_weekprofileShow(widget);
if (reuse == 0 && widget.USETOPICS != 0) {
//check if data is a reference
FW_cmd(FW_root+'?cmd=get '+devName+' profile_references '+widget.CURTOPIC+':'+widget.CURPRF+'&XHR=1',function(data){
if (data != 0) {
var name = data.split(':');
if (name.length == 2) {
widget.PRFREF = data;
} else {
console.log(devName+" error get references '" +data+"'");
}
}
FW_weekprofileShow(widget);
});
} else {
FW_weekprofileShow(widget);
}
}
else if (widget.MODE == 'EDIT')
{
@ -499,6 +675,7 @@ function FW_weekprofileSetValue(devName,data)
function FW_weekprofileGetValues(devName,what,data)
{
data = data.trim();
if(data.match(/^[\r\n]*$/)) {return;}
var widget = $('div[informid="'+devName+'"]').get(0);
@ -507,9 +684,28 @@ function FW_weekprofileGetValues(devName,what,data)
widget.WEEKDAYS = data.split(',');
} else if (what == "PROFILENAMES") {
widget.PROFILENAMES = data.split(',');
if (widget.MODE != 'EDIT') {
widget.setValueFn("REUSEPRF");
if (widget.MODE != 'EDIT') {
if (widget.CURPRF == null && widget.PROFILENAMES) {
widget.CURPRF = widget.PROFILENAMES[0];
}
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
} else {
widget.setValueFn("REUSEPRF");
}
} else if (what == "TOPICNAMES") {
widget.TOPICNAMES = data.split(',');
var found = 0;
for (var k = 0; k < widget.TOPICNAMES.length; ++k) {
widget.TOPICNAMES[k] = widget.TOPICNAMES[k].trim();
if (widget.CURTOPIC == widget.TOPICNAMES[k]) {
found=1;
}
}
if (found==0) {
widget.CURTOPIC = widget.TOPICNAMES[0];
}
FW_weekprofileChacheTo(devName,widget.CURTOPIC,null);
}
}
@ -541,19 +737,13 @@ FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
widget.MENU = new Object();
widget.MENU.BASE = $(widget.HEADER).find('div[id*="menu.base"]').get(0);
var menu = $('<div class="devType" id="weekprofile.menu.content" style="display:inline;padding:0px;margin:0px;">').get(0);
$(widget.MENU.BASE).append(menu);
widget.MENU.CONTENT = menu;
//inform profile_count changed
var prfCnt = $('<div informid="'+devName+'-profile_count" style="display:none">').get(0);
prfCnt.setValueFn = function(arg){
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
}
$(widget.HEADER).append(prfCnt);
var menuContent = '<td style="display:inline;padding:0px;margin:0px;"><div id="weekprofile.menu.content"></td>';
$(widget.MENU.BASE.parentElement.parentElement).append(menuContent);
widget.MENU.CONTENT = $(widget.HEADER).find('div[id*="menu.content"]').get(0);
widget.SHOWURL = null;
widget.MODE = 'SHOW';
widget.USETOPICS = 0;
for (var i = 1; i < vArr.length; ++i) {
var arg = vArr[i].split(':');
@ -561,19 +751,38 @@ FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
case "MODE": widget.MODE = arg[1]; break;
case "BACKURL": widget.SHOWURL = arg[1]; break;
case "MASTERDEV": widget.MASTERDEV = arg[1]; break;
case "USETOPICS": widget.USETOPICS = arg[1]; break;
}
}
widget.DEVICE = devName;
widget.WEEKDAYS = shortDays.slice();
widget.CURPRF = currVal;
widget.setValueFn = function(arg){FW_weekprofileSetValue(devName,arg);}
var current = currVal.split(':');
widget.CURTOPIC = current[0];
widget.CURPRF = current[1];
widget.setValueFn = function(arg){FW_weekprofileGetProfileData(devName,arg);}
widget.activateFn = function(arg){
FW_queryValue('get '+devName+' profile_data '+widget.CURPRF, widget);
FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
FW_cmd(FW_root+'?cmd={AttrVal("'+devName+'","widgetWeekdays","")}&XHR=1',function(data){FW_weekprofileGetValues(devName,"WEEKDAYS",data);});
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
if (widget.USETOPICS == 1) {
FW_cmd(FW_root+'?cmd=get '+devName+' topic_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"TOPICNAMES",data);});
} else {
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
}
};
//inform profile_count changed
var prfCnt = $('<div informid="'+devName+'-profile_count" style="display:none">').get(0);
prfCnt.setValueFn = function(arg){
if (widget.USETOPICS == 1) {
FW_cmd(FW_root+'?cmd=get '+devName+' topic_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"TOPICNAMES",data);});
} else {
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
}
}
$(widget.HEADER).append(prfCnt);
return widget;
}