fhemweb_weekprofile.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. // $Id: fhemweb_weekprofile.js 13277 2017-01-29 18:38:12Z Risiko $
  2. var language = 'de';
  3. //for tooltip
  4. $(document).ready(function(){
  5. $('[data-toggle="tooltip"]').tooltip();
  6. language = window.navigator.userLanguage || window.navigator.language;
  7. });
  8. var shortDays = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
  9. function FW_weekprofileInputDialog(title,inp,def,parent,callback)
  10. {
  11. var div = $("<div id='FW_weekprofileInputDiolog'>");
  12. var table = $("<table>");
  13. var content = [];
  14. for(var i=0; i<title.length; i++){
  15. var tr =
  16. content[i] = $('<input type="'+inp[i]+'">').get(0);
  17. if (def)
  18. content[i].value = def[i];
  19. var tr = $("<tr>");
  20. var td1 = $("<td>");
  21. $(td1).append(title[i]);
  22. if (inp[i] == 'hidden') {
  23. $(td1).attr("colspan","2");
  24. $(td1).attr("align","center");
  25. }
  26. var td2 = $("<td>");
  27. $(td2).append(content[i]);
  28. $(tr).append(td1);
  29. $(tr).append(td2);
  30. table.append(tr);
  31. }
  32. $(div).append(table);
  33. $("body").append(div);
  34. $(div).dialog({
  35. dialogClass:"no-close",modal:true, width:"auto", closeOnEscape:true,
  36. maxWidth:$(window).width()*0.9, maxHeight:$(window).height()*0.9,
  37. title: title,
  38. buttons: [{text:"OK", click:function(){
  39. $(this).dialog("close");
  40. $(div).remove();
  41. if(callback) {
  42. var backCont = [];
  43. for(var i=0; i<content.length; i++){
  44. backCont[i] = content[i].value;
  45. if (inp[i] == 'checkbox')
  46. backCont[i] = content[i].checked;
  47. }
  48. callback(backCont,1);
  49. }
  50. }},{text:"CANCEL", click:function(){
  51. $(this).dialog("close");
  52. $(div).remove();
  53. content.value = null;
  54. if(callback)
  55. callback(null,0);
  56. }}]
  57. });
  58. if(parent)
  59. $(div).dialog( "option", "position", {
  60. my: "left top", at: "right bottom",
  61. of: parent, collision: "flipfit"
  62. });
  63. }
  64. function FW_weekprofileMultiSelDialog(title, elementNames, elementLabels, selected,freeInp,parent,callback)
  65. {
  66. var table = "<table>";
  67. if (elementNames) {
  68. for(var i1=0; i1<elementNames.length; i1++){
  69. var n = elementNames[i1];
  70. var l = n;
  71. if (elementLabels && elementLabels.length == elementNames.length)
  72. l = elementLabels[i1];
  73. var sel = 0;
  74. if (selected && selected.indexOf(n)>=0)
  75. sel=1;
  76. table += '<tr><td><div class="checkbox"><input name="'+n+'" type="checkbox"';
  77. table += (sel ? " checked" : "")+'/><label for="'+n+'"><span></span></label></div></td>';
  78. table += '<td><label for="' +n+'">'+l+'</label></td></tr>';
  79. }
  80. }
  81. table += "</table>";
  82. var div = $("<div id='FW_weekprofileMultiSelDiolog'>");
  83. $(div).append(title);
  84. $(div).append(table);
  85. if (freeInp && freeInp == 1)
  86. $(div).append('<input id="FW_weekprofileMultiSelDiologFreeText" />');
  87. $("body").append(div);
  88. $(div).dialog({
  89. dialogClass:"no-close",modal:true, width:"auto", closeOnEscape:true,
  90. maxWidth:$(window).width()*0.9, maxHeight:$(window).height()*0.9,
  91. title: title,
  92. buttons: [{text:"OK", click:function(){
  93. var res=[];
  94. if($("#FW_weekprofileMultiSelDiologFreeText").val())
  95. res.push($("#FW_weekprofileMultiSelDiologFreeText").val());
  96. $("#FW_weekprofileMultiSelDiolog table input").each(function(){
  97. if($(this).prop("checked"))
  98. res.push($(this).attr("name"));
  99. });
  100. $(this).dialog("close");
  101. $(div).remove();
  102. if(callback)
  103. callback(res);
  104. }},{text:"CANCEL", click:function(){
  105. $(this).dialog("close");
  106. $(div).remove();
  107. if(callback)
  108. callback(null);
  109. }}]
  110. });
  111. if(parent)
  112. $(div).dialog( "option", "position", {
  113. my: "left top", at: "right bottom",
  114. of: parent, collision: "flipfit"
  115. });
  116. }
  117. function weekprofile_DoEditWeek(devName,newPage)
  118. {
  119. var widget = $('div[informid="'+devName+'"]').get(0);
  120. if (newPage == 1) {
  121. window.location.assign(FW_root+'?cmd={weekprofile_editOnNewpage("'+widget.DEVICE+'","'+widget.CURTOPIC+':'+widget.CURPRF+'");;}');
  122. } else {
  123. widget.MODE = 'EDIT';
  124. $(widget.MENU.BASE).hide();
  125. widget.setValueFn("REUSEPRF");
  126. }
  127. }
  128. function FW_weekprofilePRF_chached(devName,select)
  129. {
  130. var widget = $('div[informid="'+devName+'"]').get(0)
  131. var prfName = select.options[select.selectedIndex].value;
  132. widget.CURPRF = prfName;
  133. widget.PROFILE = null;
  134. FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
  135. }
  136. function FW_weekprofileTOPIC_chached(devName,select)
  137. {
  138. var widget = $('div[informid="'+devName+'"]').get(0)
  139. var topicName = select.options[select.selectedIndex].value;
  140. widget.CURTOPIC = topicName;
  141. widget.CURPRF = null;
  142. widget.PROFILE = null;
  143. FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
  144. }
  145. function FW_weekprofileChacheTo(devName,topicName,profileName)
  146. {
  147. var widget = $('div[informid="'+devName+'"]').get(0)
  148. widget.CURTOPIC = topicName;
  149. widget.CURPRF = profileName;
  150. widget.PROFILE = null;
  151. FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
  152. }
  153. function FW_weekprofileRestoreTopic(devName,bnt)
  154. {
  155. var widget = $('div[informid="'+devName+'"]').get(0)
  156. FW_weekprofileInputDialog(["<p>Restore topic: '"+widget.CURTOPIC+"'&nbsp;?</p>"],["hidden"],null,bnt,function(name,ok){
  157. if (ok == 1)
  158. FW_cmd(FW_root+'?cmd=set '+devName+' restore_topic '+widget.CURTOPIC+'&XHR=1',function(data){
  159. console.log(devName+" error restore topic '" +data+"'");
  160. FW_errmsg(devName+" error restore topic '" +data+"'",5000);
  161. return;
  162. });
  163. });
  164. }
  165. function FW_weekprofileSendToDev(devName,bnt)
  166. {
  167. var widget = $('div[informid="'+devName+'"]').get(0)
  168. var deviceLst = null;
  169. bnt.setValueFn = function(data) {
  170. try {
  171. deviceLst=JSON.parse(data);
  172. var devicesNames = [];
  173. var devicesAlias = [];
  174. for (var k=0; k < deviceLst.length; k++) {
  175. devicesNames.push(deviceLst[k]['NAME']);
  176. devicesAlias.push(deviceLst[k]['ALIAS']);
  177. }
  178. var selected = [];
  179. if (widget.MASTERDEV)
  180. selected.push(widget.MASTERDEV);
  181. FW_weekprofileMultiSelDialog("<span>Device(s):</span>",devicesNames,devicesAlias,selected,1,bnt,
  182. function(sndDevs) {
  183. if (!sndDevs || sndDevs.length==0)
  184. return;
  185. 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);});
  186. });
  187. } catch(e){
  188. console.log(devName+" error parsing json '" +data+"'");
  189. FW_errmsg(devName+" Parameter "+e,5000);
  190. return;
  191. }
  192. }
  193. FW_queryValue('get '+devName+' sndDevList', bnt);
  194. }
  195. function FW_weekprofileCopyPrf(devName,lnk)
  196. {
  197. var widget = $('div[informid="'+devName+'"]').get(0)
  198. var title = [];
  199. var inp = [];
  200. var def = [];
  201. var idx = 0;
  202. var topic = '';
  203. if (widget.USETOPICS==1) {
  204. topic=widget.CURTOPIC+":";
  205. }
  206. title[idx] = "<p>Create new entry from: "+topic+widget.CURPRF+"</p>";
  207. inp[idx] = "hidden";
  208. def[idx] = '';
  209. idx++;
  210. if (widget.USETOPICS==1) {
  211. title[idx] = "<p>Reference:</p>";
  212. inp[idx] = "checkbox";
  213. def[idx] = '';
  214. idx++;
  215. title[idx] = "<p>Topic:</p>";
  216. inp[idx] = "text";
  217. def[idx] = widget.CURTOPIC;
  218. idx++;
  219. }
  220. title[idx] = "<p>Name:</p>";
  221. inp[idx] = "text";
  222. def[idx] = '';
  223. FW_weekprofileInputDialog(title,inp,def,lnk,function(names,ok){
  224. if (ok < 1)
  225. return;
  226. var topic = widget.CURTOPIC;
  227. var name = names[names.length-1].trim();
  228. var ref = 0;
  229. if (widget.USETOPICS==1) {
  230. topic = names[names.length-2].trim();
  231. ref = names[names.length-3];
  232. }
  233. if (topic.length < 1 || name.length < 1)
  234. return;
  235. if (ref != 0)
  236. 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);});
  237. else
  238. 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);});
  239. });
  240. }
  241. function FW_weekprofileRemovePrf(devName,lnk)
  242. {
  243. var widget = $('div[informid="'+devName+'"]').get(0)
  244. FW_weekprofileInputDialog(["<p>Delete Profile: '"+widget.CURTOPIC+':'+widget.CURPRF+"'&nbsp;?</p>"],["hidden"],null,lnk,function(name,ok){
  245. if (ok < 1)
  246. return;
  247. FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" remove_profile "+widget.CURTOPIC+':'+widget.CURPRF+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
  248. });
  249. }
  250. function FW_weekprofileShow(widget)
  251. {
  252. $(widget.MENU.BASE).show();
  253. var editIcon = $(widget.MENU.BASE).find('a[name="'+widget.DEVICE+'.edit"]').get(0);
  254. $(editIcon).css("visibility", "visible"); //hide() remove the element
  255. $(widget.MENU.CONTENT).empty();
  256. var selMargin=0;
  257. var tdStyle="style=\"padding-left:0px;padding-right:0px\"";
  258. if (widget.USETOPICS == 1) {
  259. selMargin = 2;
  260. tdStyle = "style=\"padding:0px\"";
  261. }
  262. if (widget.PROFILENAMES) {
  263. var html='';
  264. html += '<table style="padding-bottom:0">';
  265. html += "<tr><td style=\"padding:0px\">";
  266. if (widget.USETOPICS == 1 && widget.TOPICNAMES) {
  267. html += "<select style=\"margin-bottom:"+selMargin+"px\" name=\"TOPICS\" onchange=\"FW_weekprofileTOPIC_chached('"+widget.DEVICE+"',this)\">";
  268. for (var k=0; k < widget.TOPICNAMES.length; k++)
  269. {
  270. var name = widget.TOPICNAMES[k].trim();
  271. var selected = (widget.CURTOPIC == name) ? "selected " : "";
  272. html += "<option "+selected+"value=\""+name+"\">"+name+"</option>";
  273. }
  274. html += "</select>";
  275. }
  276. html += "</td>";
  277. html += "<td rowspan=\"2\" "+tdStyle+">";
  278. html += "<button type=\"button\"onclick=\"FW_weekprofileCopyPrf('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"copy profile\">+</button>";
  279. html += "&nbsp;"
  280. html += "<button type=\"button\" onclick=\"FW_weekprofileRemovePrf('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"remove profile\">-</button>";
  281. html += "&nbsp;"
  282. if (widget.USETOPICS == 0) {
  283. html += "<button type=\"button\" onclick=\"FW_weekprofileSendToDev('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"send to device\">--></button>";
  284. } else {
  285. html += "<button type=\"button\" onclick=\"FW_weekprofileRestoreTopic('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"restore topic\">T</button>";
  286. }
  287. html += "</td></tr>";
  288. html += "<tr><td "+tdStyle+">";
  289. html += "<select style=\"margin-top:"+selMargin+"px\" name=\"PROFILES\" onchange=\"FW_weekprofilePRF_chached('"+widget.DEVICE+"',this)\">";
  290. for (var k=0; k < widget.PROFILENAMES.length; k++)
  291. {
  292. var name = widget.PROFILENAMES[k];
  293. var selected = (widget.CURPRF == name) ? "selected " : "";
  294. html += "<option "+selected+"value=\""+name+"\">"+name+"</option>";
  295. }
  296. html += "</select>";
  297. html += "</td></tr>";
  298. if (widget.PRFREF) {
  299. $(editIcon).css("visibility", "hidden");
  300. var names = widget.PRFREF.split(':');
  301. names[0] = names[0].trim();
  302. names[1] = names[1].trim();
  303. html += "<tr><td colspan=\"2\" align=\"left\" "+tdStyle+">";
  304. html += "&nbsp;"
  305. html += "<a href=\"javascript:void(0)\" onclick=\"FW_weekprofileChacheTo('"+widget.DEVICE+"','"+names[0]+"','"+names[1]+"')\">REF: "+names[0]+":"+names[1]+"</a>";
  306. html += "</td></tr>";
  307. }
  308. html += "</table>";
  309. $(widget.MENU.CONTENT).append(html);
  310. var select = $(widget.MENU.CONTENT).find('select[name="PROFILES"]').get(0);
  311. var prfName = select.options[select.selectedIndex].value;
  312. if (widget.CURPRF != prfName)
  313. FW_weekprofilePRF_chached(widget.DEVICE,select);
  314. }
  315. if (!widget.PROFILE) {
  316. return;
  317. }
  318. var table = widget.CONTENT;
  319. $(table).empty();
  320. for (var i = 0; i < shortDays.length; ++i) {
  321. $(table).append('<tr class="'+ ( (i+1)%2==0 ? 'even':'odd')+ '"><td>'+widget.WEEKDAYS[i]+'</td></tr>');
  322. var tr = $(table).find("tr").get(i);
  323. for (var k = 0; k < widget.PROFILE[shortDays[i]]['temp'].length; ++k) {
  324. var str = '';
  325. k>0 ? str = widget.PROFILE[shortDays[i]]['time'][k-1] : str = '00:00';
  326. str = str + '-' + widget.PROFILE[shortDays[i]]['time'][k];
  327. $(tr).append('<td>'+str+ '</td>');
  328. str = widget.PROFILE[shortDays[i]]['temp'][k]+' °C';
  329. $(tr).append('<td>'+str+ '</td>');
  330. }
  331. }
  332. }
  333. function FW_weekprofileEditTime_changed(inp)
  334. {
  335. if (inp == null) {return;}
  336. var times = inp.value.split(':');
  337. if (times.length == 0)
  338. return;
  339. var hour = parseInt(times[0]);
  340. var min = (times.length==2) ? parseInt(times[1]): 0;
  341. inp.value = ((hour<10)?("0"+hour):hour) +":"+ ((min<10)?("0"+min):min);
  342. //set new end time as new start time for the next interval
  343. var nexttr = inp.parentNode.parentNode.nextSibling;
  344. if (nexttr!=null){
  345. nexttr.firstChild.firstChild.innerHTML=inp.value;
  346. }
  347. }
  348. function FW_weekprofileEditRowStyle(table)
  349. {
  350. var alltr = $(table).find("tr");
  351. for (var i = 0; i < alltr.length; ++i){
  352. var delButton = $(alltr[i]).find('input[name="DEL"]');
  353. var addButton = $(alltr[i]).find('input[name="ADD"]');
  354. var inp = $(alltr[i]).find('input[name="ENDTIME"]');
  355. $(alltr[i]).attr('class',(i%2==0)? "odd":"even");
  356. delButton.attr('type',"button");
  357. addButton.attr('type',"button");
  358. inp.removeAttr('style');
  359. inp.removeAttr('readonly');
  360. FW_weekprofileEditTime_changed(inp.get(0));
  361. if (i==0){
  362. $(alltr[i]).find('span[name="STARTTIME"]').get(0).innerHTML = "00:00";
  363. if (alltr.length == 1){
  364. delButton.attr('type',"hidden");
  365. }
  366. }
  367. if (i==alltr.length-1){
  368. if (alltr.length > 1){
  369. addButton.attr('type',"hidden");
  370. }
  371. inp.attr('style',"border:none;background:transparent;box-shadow:none");
  372. inp.get(0).value = "24:00";
  373. inp.attr('readonly',true);
  374. }
  375. }
  376. }
  377. function FW_weekprofileEditAddInterval(tr)
  378. {
  379. var newtr = $(tr).clone(true);
  380. var alltr = $(tr).parent().children();
  381. for (var i = 0; i < alltr.length; ++i) {
  382. if ( $(alltr[i]).is($(tr))) {
  383. newtr.insertAfter($(alltr[i]));
  384. break;
  385. }
  386. }
  387. FW_weekprofileEditRowStyle($(tr).parent());
  388. var timSel = newtr.find('input[name="ENDTIME"]');
  389. if (alltr.length == 1)
  390. timSel = $(tr).find('input[name="ENDTIME"]');
  391. timSel.focus();
  392. timSel.select();
  393. }
  394. function FW_weekprofileEditDelInterval(tr)
  395. {
  396. var parent = $(tr).parent();
  397. $(tr).remove();
  398. FW_weekprofileEditRowStyle(parent)
  399. }
  400. function FW_weekprofileTransDay(devName,day,bnt)
  401. {
  402. var widget = $('div[informid="'+devName+'"]').get(0);
  403. var srcDay = $(widget.CONTENT).find("table[id*=\"weekprofile."+widget.DEVICE+"\"][data-day*=\""+shortDays[day]+"\"]");
  404. var dayNames = [];
  405. var dayAlias = [];
  406. for (var k=0; k < shortDays.length; k++) {
  407. if (k != day) {
  408. dayNames.push(shortDays[k]);
  409. dayAlias.push(widget.WEEKDAYS[k]);
  410. }
  411. }
  412. var selected = [];
  413. FW_weekprofileMultiSelDialog("<span>Days(s):</span>",dayNames,dayAlias,selected,0,bnt,
  414. function(selDays) {
  415. if (!selDays || selDays.length==0)
  416. return;
  417. for (var k=0; k < selDays.length; k++) {
  418. var destDay = $(widget.CONTENT).find("table[id*=\"weekprofile."+widget.DEVICE+"\"][data-day*=\""+selDays[k]+"\"]");
  419. destDay.empty();
  420. destDay.append(srcDay.clone().contents());
  421. }
  422. });
  423. }
  424. function FW_weekprofileTemp_chached(select)
  425. {
  426. var val = select.options[select.selectedIndex].value;
  427. $(select).find("option").removeAttr('selected');
  428. $(select).val(val);
  429. $(select.options[select.selectedIndex]).attr("selected","selected");
  430. }
  431. function FW_weekprofileEditDay(widget,day)
  432. {
  433. var div = $("<div>").get(0);
  434. var html= '';
  435. html += "<div style=\"padding:5px;\">";
  436. html += "<span style=\"margin-right:10px;margin-left:10px\">"+widget.WEEKDAYS[day]+"</span>";
  437. html += "<a href=\"javascript:void(0)\" onclick=\"FW_weekprofileTransDay('"+widget.DEVICE+"',"+day+",this)\" data-toggle=\"tooltip\" title=\"transfer day\">--></a>";
  438. html += "</div>";
  439. $(div).append(html);
  440. var table = $("<table>").get(0);
  441. $(table).attr('id',"weekprofile."+widget.DEVICE).attr("data-day", shortDays[day]);
  442. $(table).attr('class',"block wide weekprofile");
  443. html = '';
  444. var times = widget.PROFILE[shortDays[day]]['time'];
  445. var temps = widget.PROFILE[shortDays[day]]['temp'];
  446. for (var i = 0; i < times.length; ++i) {
  447. var startTime = (i>0) ? times[i-1] : "00:00";
  448. var endTime = (i<times.length-1) ? times[i] : "24:00";
  449. html += "<tr>";
  450. //from
  451. html += "<td><span name=\"STARTTIME\">"+startTime+"</span></td>";
  452. html += "<td>-</td>";
  453. //to
  454. html += "<td><input type=\"text\" name=\"ENDTIME\" size=\"5\" maxlength=\"5\" align=\"center\" value=\""+endTime+"\" onblur=\"FW_weekprofileEditTime_changed(this)\"/></td>";
  455. //temp
  456. var tempOn = widget.TEMP_ON;
  457. var tempOff = widget.TEMP_OFF;
  458. if (tempOn == null)
  459. tempOn = 30;
  460. if (tempOff == null)
  461. tempOff = 5;
  462. html += "<td><select name=\"TEMP\" size=\"1\" onchange=\"FW_weekprofileTemp_chached(this)\">";
  463. for (var k=tempOff; k <= tempOn; k+=.5)
  464. {
  465. var selected = (k == temps[i]) ? "selected " : "";
  466. if (k == widget.TEMP_OFF)
  467. html += "<option "+selected+"value=\"off\">off</option>";
  468. else if (k == widget.TEMP_ON)
  469. html += "<option "+selected+"value=\"on\">on</option>";
  470. else
  471. html += "<option "+selected+"value=\""+k.toFixed(1)+"\">"+k.toFixed(1)+"</option>";
  472. }
  473. html += "</select></td>";
  474. //ADD-Button
  475. html += "<td><input type=\"button\" name=\"ADD\" value=\"+\" onclick=\"FW_weekprofileEditAddInterval(this.parentNode.parentNode)\"></td>";
  476. //DEL-Button
  477. html += "<td><input type=\"button\" name=\"DEL\" value=\"-\" onclick=\"FW_weekprofileEditDelInterval(this.parentNode.parentNode)\"></td>";
  478. html += "</tr>";
  479. }
  480. $(table).append(html);
  481. $(div).append(table);
  482. FW_weekprofileEditRowStyle(table);
  483. return div;
  484. }
  485. function FW_weekprofileEditWeek(widget)
  486. {
  487. $(widget.MENU.CONTENT).empty();
  488. var table = widget.CONTENT;
  489. var daysInRow = 2;
  490. if (widget.EDIT_DAYSINROW)
  491. daysInRow = widget.EDIT_DAYSINROW;
  492. $(table).append('<tr>');
  493. var tr = $(table).find("tr:last");
  494. for (var i = 0; i < shortDays.length; ++i) {
  495. tr.append('<td>');
  496. tr.find('td:last').append(FW_weekprofileEditDay(widget,i));
  497. if ((i+1)%daysInRow == 0){
  498. $('<tr>').insertAfter(tr);
  499. tr = $(table).find("tr:last");
  500. }
  501. }
  502. tr.append("<td><table><tr>");
  503. tr = tr.find("tr:last");
  504. tr.append("<td><input type=\"button\" value=\"Speichern\" onclick=\"FW_weekprofilePrepAndSendProf('"+widget.DEVICE+"')\">");
  505. tr.append("<td><input type=\"button\" value=\"Abbrechen\" onclick=\"FW_weekprofileEditAbort('"+widget.DEVICE+"')\">");
  506. }
  507. function FW_weekprofileSendCallback(devName, data)
  508. {
  509. var widget = $('div[informid="'+devName+'"]').get(0);
  510. if(!data.match(/^[\r\n]*$/)) // ignore empty answers
  511. FW_okDialog('<pre>'+data+'</pre>',widget);
  512. }
  513. function FW_weekprofilePrepAndSendProf(devName)
  514. {
  515. var widget = $('div[informid="'+devName+'"]').get(0);
  516. var tableDay = $(widget).find("table[id*=\"weekprofile."+devName+"\"]");
  517. if (tableDay.length == 0){
  518. FW_errmsg(widget.DEVICE+" internal error ",10000);
  519. return;
  520. }
  521. var prf=new Object();
  522. for (var i = 0; i < tableDay.length; ++i) {
  523. var timeEL = $(tableDay[i]).find('input[name="ENDTIME"]');
  524. var tempEL = $(tableDay[i]).find('select[name="TEMP"]');
  525. if (timeEL.length != tempEL.length){
  526. FW_errmsg(widget.DEVICE+" internal error ",10000);
  527. return;
  528. }
  529. var day = $(tableDay[i]).attr("data-day");
  530. prf[day] = new Object();
  531. prf[day]['time'] = new Array();
  532. prf[day]['temp'] = new Array();
  533. for (var k = 0; k < timeEL.length; ++k) {
  534. prf[day]['time'].push(timeEL[k].value);
  535. prf[day]['temp'].push(tempEL[k].value);
  536. }
  537. }
  538. try {
  539. var data=JSON.stringify(prf);
  540. FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" profile_data "+widget.CURTOPIC+':'+widget.CURPRF+" "+data+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
  541. } catch(e){
  542. FW_errmsg(devName+" Parameter "+e,5000);
  543. return;
  544. }
  545. for (var i = 0; i < shortDays.length; ++i) {
  546. var day = shortDays[i];
  547. if (prf[day] != null){
  548. widget.PROFILE[day] = prf[day];
  549. }
  550. }
  551. FW_weekprofileBack(widget);
  552. }
  553. function FW_weekprofileBack(widget)
  554. {
  555. if (widget.JMPBACK){
  556. var isInIframe = (window.location != window.parent.location) ? true : false;
  557. if (isInIframe) {
  558. parent.history.back();
  559. } else
  560. window.history.back();
  561. }
  562. else {
  563. widget.MODE = "SHOW";
  564. widget.setValueFn("REUSEPRF");
  565. }
  566. }
  567. function FW_weekprofileEditAbort(devName)
  568. {
  569. var widget = $('div[informid="'+devName+'"]').get(0);
  570. FW_weekprofileBack(widget);
  571. }
  572. function FW_weekprofileGetProfileData(devName,data)
  573. {
  574. var widget = $('div[informid="'+devName+'"]').get(0);
  575. $(widget.CONTENT).empty();
  576. var reuse = (data == "REUSEPRF") ? 1 : 0;
  577. var prf={};
  578. try {
  579. (reuse) ? prf = widget.PROFILE : prf=JSON.parse(data);
  580. } catch(e){
  581. console.log(devName+" error parsing json '" +data+"'");
  582. FW_errmsg(devName+" Parameter "+e,5000);
  583. return;
  584. }
  585. widget.PROFILE = prf;
  586. widget.PRFREF = null;
  587. if (widget.MODE == 'SHOW')
  588. {
  589. if (reuse == 0 && widget.USETOPICS != 0) {
  590. //check if data is a reference
  591. FW_cmd(FW_root+'?cmd=get '+devName+' profile_references '+widget.CURTOPIC+':'+widget.CURPRF+'&XHR=1',function(data){
  592. if (data != 0) {
  593. var name = data.split(':');
  594. if (name.length == 2) {
  595. widget.PRFREF = data;
  596. } else {
  597. console.log(devName+" error get references '" +data+"'");
  598. }
  599. }
  600. FW_weekprofileShow(widget);
  601. });
  602. } else {
  603. FW_weekprofileShow(widget);
  604. }
  605. }
  606. else if (widget.MODE == 'EDIT')
  607. {
  608. FW_weekprofileEditWeek(widget);
  609. }
  610. else
  611. {
  612. FW_errmsg(devName+" unknown Mode",10000);
  613. }
  614. }
  615. function FW_weekprofileGetValues(devName,what,data)
  616. {
  617. data = data.trim();
  618. if(data.match(/^[\r\n]*$/)) {return;}
  619. var widget = $('div[informid="'+devName+'"]').get(0);
  620. if (what == "WEEKDAYS"){
  621. widget.WEEKDAYS = data.split(',');
  622. } else if (what == "PROFILENAMES") {
  623. widget.PROFILENAMES = data.split(',');
  624. if (widget.MODE != 'EDIT') {
  625. if (widget.CURPRF == null && widget.PROFILENAMES) {
  626. widget.CURPRF = widget.PROFILENAMES[0];
  627. }
  628. FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
  629. } else {
  630. widget.setValueFn("REUSEPRF");
  631. }
  632. } else if (what == "TOPICNAMES") {
  633. widget.TOPICNAMES = data.split(',');
  634. var found = 0;
  635. for (var k = 0; k < widget.TOPICNAMES.length; ++k) {
  636. widget.TOPICNAMES[k] = widget.TOPICNAMES[k].trim();
  637. if (widget.CURTOPIC == widget.TOPICNAMES[k]) {
  638. found=1;
  639. }
  640. }
  641. if (found==0) {
  642. widget.CURTOPIC = widget.TOPICNAMES[0];
  643. }
  644. FW_weekprofileChacheTo(devName,widget.CURTOPIC,null);
  645. }
  646. }
  647. function
  648. FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
  649. {
  650. // called from FW_replaceWidget fhemweb.js
  651. if( 0 ) {
  652. console.log( "elName: "+elName );
  653. console.log( "devName: "+devName ); // attr dev
  654. console.log( "vArr: "+vArr ); // attr arg split ','
  655. console.log( "currVal: "+currVal ); // attr current
  656. console.log( "set: "+set ); // attr cmd split ' ' first entry
  657. console.log( "params: "+params ); // attr cmd list split ' ' without first entry
  658. console.log( "cmd: "+cmd ); // function for ToDo
  659. }
  660. if(!vArr.length || vArr[0] != "weekprofile")
  661. return undefined;
  662. var widget = $('div[informid="'+devName+'"]').get(0);
  663. var content = $('<table class="block wide weekprofile" id="weekprofile_content">').get(0);
  664. $(widget).append(content);
  665. widget.CONTENT = content;
  666. widget.HEADER = $('div[id="weekprofile.'+devName+'.header"]').get(0);
  667. widget.MENU = new Object();
  668. widget.MENU.BASE = $(widget.HEADER).find('div[id*="menu.base"]').get(0);
  669. var menuContent = '<td style="display:inline;padding:0px;margin:0px;"><div id="weekprofile.menu.content"></td>';
  670. $(widget.MENU.BASE.parentElement.parentElement).append(menuContent);
  671. widget.MENU.CONTENT = $(widget.HEADER).find('div[id*="menu.content"]').get(0);
  672. widget.JMPBACK = null;
  673. widget.MODE = 'SHOW';
  674. widget.USETOPICS = 0;
  675. widget.TEMP_ON = null;
  676. widget.TEMP_OFF = null;
  677. for (var i = 1; i < vArr.length; ++i) {
  678. var arg = vArr[i].split(':');
  679. switch (arg[0]) {
  680. case "MODE": widget.MODE = arg[1]; break;
  681. case "JMPBACK": widget.JMPBACK = arg[1]; break;
  682. case "MASTERDEV": widget.MASTERDEV = arg[1]; break;
  683. case "USETOPICS": widget.USETOPICS = arg[1]; break;
  684. case "DAYINROW": widget.EDIT_DAYSINROW = arg[1]; break;
  685. case "TEMP_ON": widget.TEMP_ON = parseFloat(arg[1]); break;
  686. case "TEMP_OFF": widget.TEMP_OFF = parseFloat(arg[1]);break;
  687. }
  688. }
  689. widget.DEVICE = devName;
  690. widget.WEEKDAYS = shortDays.slice();
  691. var current = currVal.split(':');
  692. widget.CURTOPIC = current[0];
  693. widget.CURPRF = current[1];
  694. widget.setValueFn = function(arg){FW_weekprofileGetProfileData(devName,arg);}
  695. widget.activateFn = function(arg){
  696. FW_queryValue('get '+devName+' profile_data '+widget.CURTOPIC+':'+widget.CURPRF, widget);
  697. FW_cmd(FW_root+'?cmd={AttrVal("'+devName+'","widgetWeekdays","")}&XHR=1',function(data){FW_weekprofileGetValues(devName,"WEEKDAYS",data);});
  698. if (widget.USETOPICS == 1) {
  699. FW_cmd(FW_root+'?cmd=get '+devName+' topic_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"TOPICNAMES",data);});
  700. } else {
  701. FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
  702. }
  703. };
  704. //inform profile_count changed
  705. var prfCnt = $('<div informid="'+devName+'-profile_count" style="display:none">').get(0);
  706. prfCnt.setValueFn = function(arg){
  707. if (widget.USETOPICS == 1) {
  708. FW_cmd(FW_root+'?cmd=get '+devName+' topic_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"TOPICNAMES",data);});
  709. } else {
  710. FW_cmd(FW_root+'?cmd=get '+devName+' profile_names '+widget.CURTOPIC+'&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
  711. }
  712. }
  713. $(widget.HEADER).append(prfCnt);
  714. return widget;
  715. }
  716. FW_widgets['weekprofile'] = {
  717. createFn:FW_weekprofileCreate,
  718. };