fhemweb_weekprofile.js 28 KB

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