Advertisement
eqeqwan21

obj.js

Jun 23rd, 2025
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //v13_14 альтернатиная мнемосхема_маскировка команд
  2. //v11++фото заголовки со ссылками                                                                             
  3. "use strict";
  4. let hulla = new hullabaloo();
  5. let box = null;
  6. let circuit = null;
  7. let stlog = null;
  8. let dayly = null;
  9. let lastip = null;
  10. let lastmeter = null;
  11. //Антон: отображение команд с учетом маски
  12. let deviceObj = null;
  13.  
  14. let dt = null, mdt = null;
  15. let liveMode = true;
  16. let renewTimer = null;
  17. let dtdt = null;
  18. let commands = null;
  19. var gallery_ro = true;
  20. let cmdQueued = false;
  21. let waitingForAnswer = false;
  22. let cmdSentMark = 0;
  23. let cmdDeliveredMark = 0;
  24. let sentCmdLetter = null;
  25. let get = parseQuery(window.location.search);
  26. moment.locale(environment.language || window.navigator.userLanguage || window.navigator.language);
  27.  
  28.  
  29. $(async function () {
  30.   $("#btnLive").prop("disabled", true);
  31.   let result;
  32.   let userTown;
  33.   if (environment.login_name.indexOf("_") !== -1) {
  34.     userTown = '&town=' + environment.login_name.split('_')[0].toLowerCase()
  35.   } else {
  36.     userTown = ''
  37.   }
  38.   try {
  39.     result = await $.ajax({
  40.       url: environment.base_url + "/" + '?do=api&fn=devices&id=' + get['id'] + userTown,
  41.       type: 'GET',
  42.       dataType: "json"
  43.     });
  44. //Антон: отображение команд с учетом маски
  45.     deviceObj = result;
  46.   } catch (error) {
  47.     console.error(error);
  48.     $("#content").html("<h2>Device was not loaded</h2>");
  49.     return;
  50.   }
  51.  
  52.  
  53.   if (result.rows.length > 0)
  54.     box = result.rows.slice(0)[0];
  55.   else {
  56.     $("#content").html("<h2>Device not found</h2>");
  57.     return;
  58.   }
  59.  
  60.   if (box.DimProfile_id !== null) {
  61.     try {
  62.       dayly = await $.ajax({
  63.         url: environment.base_url + "/" + '?do=api&fn=dimdetail&now&id=' + box.DimProfile_id,
  64.         type: 'GET',
  65.         dataType: "json"
  66.       });
  67.     } catch (error) {
  68.       console.error(error);
  69.     }
  70.   }
  71.  
  72.   if (box.Type == 2)
  73.     $("#strongState").text(i18next.t("Brightness"));
  74.  
  75.   drawBoxInfo();
  76.   try {
  77.     result = await $.ajax({
  78.       url: environment.base_url + "/" + '?do=api&fn=circuit&id=' + get['id'],
  79.       type: 'GET',
  80.       dataType: "json"
  81.     });
  82.  
  83.   } catch (error) {
  84.     console.error(error);
  85.     $("#content").html("<h2>Pattern was not loaded</h2>");
  86.     return;
  87.   }
  88.  
  89.   if (result.rows.length > 0)
  90.     circuit = result.rows[0];
  91.   else
  92.     console.log("Pattern not found");
  93.  
  94.   let svg = "";
  95.   if (circuit !== null) {
  96.     let qs = circuit.qs;
  97.     if (environment.language !== "en") {
  98.       qs = qs.replace(/S/gi, "K");
  99.     }
  100.  
  101.     try {
  102.       svg = await $.ajax({
  103.         url: environment.base_url + `/images/galbox.svg?v=${config.version}&noxml&cnf=` + qs,
  104.         type: 'GET',
  105.         processData: false
  106.       });
  107.       $("#circuit").html(`${svg}`);
  108.       if (box.Name?.startsWith("TL") || box.Name?.startsWith("G")) await attachBackground();
  109.     } catch (error) {
  110.       console.error(error);
  111.     }
  112.   }
  113.  
  114.   stdatatable();
  115.   meterdatatable();
  116.  
  117.   setTimeout(renew, 1);
  118.   setTimeout(iprenew, 10);
  119.  
  120.   $("#circuit svg").addClass("col-12");
  121.   $("#circuit svg").addClass("p-0");
  122.   //Ссылки в зоголовках "статистика" и "журнал состояния" в форме Объект
  123.   $("#statlink").attr("href", `${environment.base_url}/inlog?device=${get['id']}`);
  124.   $("#stlink").attr("href", `${environment.base_url}/stlog?device=${get['id']}`);
  125.   if (box.Smart) {
  126.     try {
  127.       result = await $.ajax({
  128.         url: environment.base_url + "/" + '?do=api&fn=ServerCommand&type=1,3&DeviceType=' + box.Type,
  129.         type: 'GET',
  130.         dataType: "json"
  131.       });
  132.  
  133.     } catch (error) {
  134.       console.error(error);
  135.       return;
  136.     }
  137.     commands = result.rows;
  138.     $("#cmd").find('option').remove();
  139.  
  140.     for (let key in commands) {
  141.       if (commands[key].Letter == "F")
  142.         continue;
  143.       $("#cmd").append($("<option></option>")
  144.           .attr("value", commands[key].id)
  145.           .text(i18next.t(commands[key].Name)));
  146.     }
  147.   } else {
  148.     $("#manualDiv").hide();
  149.   }
  150. //добавление картинки светильника из галлереи с проверкой её наличия, иначе - по умолчанию
  151.   if (box.Type !== 1) {
  152.     $.ajax({
  153.       url: `${environment.base_url}/?do=api&fn=picture_list&Devices_id=${get['id']}&order=ASC&limit=1`,
  154.       type: 'GET',
  155.       dataType: "json",
  156.       success: function (result) {
  157.         if (result['list'].length > 0) {
  158.           $("#circuit").html('<img class="img-fluid" src="' + result['list'][0].src + '">');
  159.         } else {
  160.           $("#circuit").html(`<img class="img-fluid" src="${environment.base_url}/images/lamp.png">`)
  161.         }
  162.       }
  163.     });
  164.     // $("#circuit").html(`<img class="img-fluid" src="${environment.base_url}/images/lamp.png">`);
  165.   }
  166.  
  167.   $(".picture").click(() => {
  168.     galleryOpen(get['id'])
  169.   });
  170.   /*
  171.   let pl = await getPictureList(get['id'], 'desc', 100);
  172.   if(pl.length == 0) {
  173.     $(".picture").click( ()=>{galleryOpen(get['id'])});
  174.   } else {
  175.     let html="";
  176.     let i=0;
  177.     pl.forEach(el => {
  178.       let title = "";
  179.       let opt = {month: "long", day:"numeric", year:"numeric"};
  180.       let separ=", ";
  181.       let opt2= {hour:"numeric", minute:"numeric"};
  182.       let disp="";
  183.  
  184.       if(el.Exiftime!==null) {
  185.         let dda = el.Exiftime.split(" ");
  186.         if(dda.length==2) {
  187.           let dds = dda[0].replaceAll(":","-") + " " + dda[1]+"Z";
  188.           let dd = new Date(dds);
  189.  
  190.           if(!(dd===NaN) && !dd!="Invalid Date") {
  191.             disp = "<i class='fa fa-camera'></i>&nbsp;" + dd.toLocaleDateString(environment.language, opt) + separ +
  192.             dd.toLocaleTimeString(environment.language, opt2);
  193.           }
  194.         }
  195.       }
  196.  
  197.       let dd = new Date(el.Loaded+"Z");
  198.       if(!(dd===NaN) && !dd!="Invalid Date") {
  199.         if(disp!="")
  200.           disp+="<br>";
  201.         disp += "<i class='fa fa-upload'></i>&nbsp;" + dd.toLocaleDateString(environment.language, opt) + separ +
  202.         dd.toLocaleTimeString(environment.language, opt2);
  203.       }
  204.  
  205.       title = `data-container="body" data-html="true" data-placement="top" data-toggle="tooltip" title="${disp}"`;
  206.  
  207.       html += `<div ${title}><img onclick="galleryOpen(${get['id']}, ${i})" class="border border-primary rounded imgpic" width="60px" height="60px" src="${el.src}&thumb"></div>`;
  208.       i++;
  209.     });
  210.     $("#pg").html(html);
  211.     $('[data-toggle="tooltip"]').tooltip({
  212.       boundary:"viewport",
  213.       html: true
  214.     });
  215.   }
  216.   */
  217.  
  218. });
  219.  
  220. async function runCmd() {
  221.   $("#btnCmd").prop("disabled", true);
  222.   setTimeout(() => $("#btnCmd").prop("disabled", false), 1500);
  223.   let srvcmd = {};
  224.   cmdQueued = false;
  225.   sentCmdLetter = null;
  226.   srvcmd.cmd = parseInt($("#cmd").val());
  227.   let selcmd = commands.find(x => x.id == srvcmd.cmd);
  228.   let cmdtext = i18next.t(selcmd.Name);
  229.  
  230.   srvcmd.devs = [box.id];
  231.  
  232.   let result = null;
  233.   try {
  234.     result = await $.ajax({
  235.       url: environment.base_url + "/" + '?do=api&fn=makecalls',
  236.       data: JSON.stringify(srvcmd),
  237.       type: 'PUT',
  238.       contentType: "application/json; charset=utf-8",
  239.       dataType: "json"
  240.     });
  241.  
  242.   } catch (error) {
  243.     console.error(error);
  244.     hulla.send(i18next.t("Device control error"));
  245.     return false;
  246.   }
  247.  
  248.   if (result.success) {
  249.     switch (result.queued) {
  250.       case 0:
  251.         hulla.send(i18next.t("Command not queued"));
  252.         break;
  253.       case 1:
  254.         hulla.send(`${i18next.t("Command")} "${cmdtext}" ${i18next.t("queued")}`, "success");
  255.         cmdQueued = true;
  256.         cmdSentMark = Date.now();
  257.         sentCmdLetter = selcmd.Letter;
  258.         break;
  259.       default:
  260.         hulla.send(`${cmdtext} - ${i18next.t("Command queued for multiple devices")} (${result.queued})`, "success");
  261.         break;
  262.     }
  263.   } else {
  264.     hulla.send(i18next.t("An error occurred while adding commands to the queue"));
  265.     console.log(result);
  266.   }
  267.  
  268.   return false;
  269. }
  270.  
  271. let pbox = null, plines = null;
  272.  
  273. async function drawBoxInfo() {
  274.   $("#Phone").html(number10html(box.Phone));
  275. //Добавление строки "Серийный номер"  
  276.   for (let fld of ["CustomNum", "Name", "sn", "DimProfile_Name", "Station", "ControlTime"]) {
  277.     let val = box[fld];
  278.     if (val !== null) {
  279.       if (fld == "ControlTime")
  280.         $("#" + fld).text(val.substr(0, 5));
  281.       else
  282.         $("#" + fld).text(val);
  283.     }
  284.   }
  285.   if (box.Station == null && box.Lines_id) {
  286.     //let pbox =null, plines = null;
  287.     try {
  288.       pbox = await $.ajax({
  289.         url: environment.base_url + "/" + '?do=api&fn=devices&id=' + box.Box_id,
  290.         type: 'GET',
  291.         dataType: "json"
  292.       });
  293.  
  294.     } catch (error) {
  295.       console.error(error);
  296.       return;
  297.     }
  298.     try {
  299.       plines = await $.ajax({
  300.         url: environment.base_url + "/" + '?do=api&fn=lines&id=' + box.Box_id,
  301.         type: 'GET',
  302.         dataType: "json"
  303.       });
  304.  
  305.     } catch (error) {
  306.       console.error(error);
  307.       return;
  308.     }
  309.  
  310.     if (pbox && plines) {
  311.       let ln = plines.rows.find(x => x.id == box.Lines_id)
  312.       let txt = ln.Num.toString().padStart(2, "0") + ". " + i18next.t(appdata.LinesType.find(x => x.id == ln.Type).Name);
  313.  
  314.       if (ln.Switch > 0)
  315.         txt += " " + i18next.t(appdata.Switches.find(x => x.id == ln.Switch).Name);
  316.       if (ln.Phase > 0)
  317.         txt += ", " + i18next.t("Phase") + " " + appdata.Phases.find(x => x.id == ln.Phase).Name;
  318.  
  319.       $("#Station").html(`<a target="obj${box.Box_id}" href="${environment.base_url}/obj?id=${box.Box_id}" id="aStation"></a>, ${txt}`);
  320.       $("#aStation").text(`${i18next.t("Box")} № ${pbox.rows[0].CustomNum}`);
  321.     }
  322.   }
  323.   $("#Mode").text(i18next.t(appdata.AutoModes.find(x => x.id == box.Mode).Name));
  324.   $("#Location").text(makeAddress(box));
  325.  
  326.   $("#shiftdiv").hide();
  327.  
  328.   daylyTable();
  329. }
  330.  
  331.  
  332. function daylyTable() {
  333.   if (dayly == null)
  334.     return;
  335.  
  336.   let drw = dayly.rows;
  337.   let aShift = null;
  338.   if (box.PardShift)
  339.     aShift = box.PardShift.split(",");
  340.  
  341.   let str1 = "<tr>", str2 = "<tr>", str3 = "<tr>";
  342.   for (let i = 0; i < config.pard_maxvalue; i++) {
  343.     let time = '', val = '';
  344.     if (!(drw[i] === undefined)) {
  345.  
  346.       time = drw[i].Time.substr(0, 5);
  347.       if (box.Type == 2) //lamp
  348.         val = "" + drw[i].DimValue + "%";
  349.       else
  350.         val = SwitchStateForMask(drw[i].DimValue);//Антон: отображение команд с учетом маски
  351.     }
  352.     if (aShift) {
  353.       let tt = '';
  354.       if (aShift[i]) {
  355.         let tti = parseInt(aShift[i]);
  356.         let sign = "";
  357.         if (tti < 0)
  358.           sign = "-";
  359.         if (tti > 0)
  360.           sign = "+";
  361.         tti = Math.abs(tti);
  362.         let min = tti % 60;
  363.         let hr = (tti - min) / 60;
  364.  
  365.         tt = `${sign}${new Intl.NumberFormat(environment.language, {minimumIntegerDigits: 2}).format(hr)}:${new Intl.NumberFormat(environment.language, {minimumIntegerDigits: 2}).format(min)}`;
  366.       }
  367.       str3 += `<td class="text-center">${tt}</td>`;
  368.     }
  369.  
  370.  
  371.     str1 += `<td class="text-center">${time}</td>`;
  372.     str2 += `<td class="text-center">${val}</td>`;
  373.   }
  374.   str1 += "</tr>";
  375.   str2 += "</tr>";
  376.   $("#dimDetail").append(str1);
  377.  
  378.   if (aShift) {
  379.     str3 += "</tr>";
  380.     $("#dimDetail").append(str3);
  381.   }
  382.   $("#dimDetail").append(str2);
  383. }
  384.  
  385. let loadfail = 0;
  386.  
  387. async function dataload() {
  388.   let url = environment.base_url + "/" + "?do=api&fn=stlog&limit=64&device=" + get['id'];
  389.   let result, ret = false;
  390.   try {
  391.     result = await $.ajax({
  392.       url: url,
  393.       type: 'GET',
  394.       dataType: "json",
  395.       cache: false
  396.     });
  397.   } catch (error) {
  398.     console.log("Error: ", error);
  399.  
  400.     if (error.status == 401) //unautorized
  401.       window.location = environment.base_url + "/" + "?do=login&b=" + encodeURIComponent(window.location);
  402.  
  403.     loadfail++;
  404.     if (stlog === null)
  405.       $("#content").html("<h2>Log was not loaded</h2>");
  406.     else if (loadfail > 1) {
  407.       hulla.send(i18next.t(`No connection to the server (${error.statusText})`));
  408.       loadfail = 0;
  409.     }
  410.     return ret;
  411.   }
  412.   loadfail = 0;
  413.   if (stlog == null || stlog.timestamp != result.timestamp) {
  414.     stlog = result;
  415.     ret = true;
  416.   }
  417.  
  418.   return ret;
  419. }
  420.  
  421.  
  422. async function ipload() {
  423.   let url = environment.base_url + "/" + "?do=api&fn=lastip&device=" + get['id'];
  424.   let result, ret = false;
  425.   try {
  426.     result = await $.ajax({
  427.       url: url,
  428.       type: 'GET',
  429.       dataType: "json",
  430.     });
  431.   } catch (error) {
  432.     console.log("Error: ", error);
  433.     return ret;
  434.   }
  435.   if (lastip == null || lastip.timestamp != result.timestamp) {
  436.     lastip = result;
  437.     ret = true;
  438.   }
  439.  
  440.   return ret;
  441. }
  442.  
  443. async function meterload() {
  444.   let url = environment.base_url + "/" + "?do=api&fn=lastmeter&device=" + get['id'];
  445.   let result, ret = false;
  446.   try {
  447.     result = await $.ajax({
  448.       url: url,
  449.       type: 'GET',
  450.       dataType: "json",
  451.     });
  452.   } catch (error) {
  453.     console.log("Error: ", error);
  454.     return ret;
  455.   }
  456.   if (lastmeter == null || result.timestamp != lastmeter.timestamp) {
  457.     lastmeter = result;
  458.     ret = true;
  459.   }
  460.  
  461.   return ret;
  462. }
  463.  
  464.  
  465. async function renew() {
  466.   // let nextt = 1000;
  467.   // let isnew = await dataload();
  468.   // if (isnew) {
  469.   //   onlogchane();
  470.   //   nextt = 2000;
  471.   // }
  472.   // setTimeout(renew, nextt);
  473.   if (!liveMode) return;
  474.   let nextt = 1000;
  475.   const isnew = await dataload();
  476.   if (isnew) {
  477.     onlogchane();
  478.     nextt = 2000;
  479.   }
  480.   renewTimer = setTimeout(renew, nextt);
  481. }
  482.  
  483. async function iprenew() {
  484.  
  485.   let nextt = 1000;
  486.   let isnew = await ipload();
  487.  
  488.   if (isnew) {
  489.     if (lastip !== null && lastip.rowCount > 0) {
  490.       let li = lastip.rows[0];
  491.       let m = moment(li.unixtime * 1000);
  492.       $("#iptime").text(m.format("L LT"));
  493.       $("#ipdata").text(li.Msg);
  494.       $("#divstat").show();
  495.     } else
  496.       $("#divstat").hide();
  497.  
  498.     let isnewmeter = await meterload();
  499.     if (isnewmeter) {
  500.       if (lastmeter !== null && lastmeter.rowCount > 0) {
  501.         let lm = lastmeter.rows[0];
  502.  
  503.         let dd = new Date(lm.Timestamp + "Z");
  504.         let disp = dd.toLocaleDateString(environment.language) + " " +
  505.             dd.toLocaleTimeString(environment.language, {hour: "numeric", minute: "numeric"});
  506.         $("#metertime").text(disp);
  507.         $("#meterlink").attr("href", `${environment.base_url}/meterlog?device=${get['id']}`);
  508. //Открытие новой вкладки для "Показания учета"
  509.         //$("#meterlink").attr("target", `meterlog${get['id']}`);
  510.         mdt.ajax.reload();
  511.         $("#meterstat").show();
  512.       } else
  513.         $("#meterstat").hide();
  514.     }
  515.  
  516.     nextt = 5000;
  517.   }
  518.   setTimeout(iprenew, nextt);
  519. }
  520.  
  521.  
  522. async function onlogchane() {
  523.   if (dt != null) {
  524.     dt.ajax.reload();
  525.     $('[data-toggle="tooltip"]').tooltip('dispose');
  526.     $(".tooltip").remove();
  527.     $('[data-toggle="tooltip"]').tooltip();
  528.   }
  529.   let result = null;
  530.  
  531.   try {
  532.     result = await $.ajax({
  533.       url: environment.base_url + "/" + "?do=api&fn=states&Devices_id=" + get['id'],
  534.       type: 'GET',
  535.       dataType: "json"
  536.     });
  537.   } catch (error) {
  538.     console.error(error);
  539.   }
  540.  
  541.   if (result !== null && result.rows.length > 0) {
  542.     let state = result.rows[0];
  543.     setSvgstate(state);
  544.     setTextstate(state);
  545.     if (cmdQueued) {
  546.       const ev = stlog?.rows?.find(r =>
  547.           r.OutgoingLog_id &&
  548.           r.unixtime * 1000 >= cmdSentMark - 3000
  549.       );
  550.       if (ev) {
  551.         cmdDeliveredMark = ev.unixtime * 1000;
  552.         waitingForAnswer = true;
  553.         cmdQueued = false;
  554.         $("#circuit").addClass("waiting");
  555.       }
  556.     }
  557.     if (waitingForAnswer) {
  558.       const lastAnswerTime = Math.max(
  559.           stlog?.rows?.[0]?.IncomingLog_id ? stlog.rows[0].unixtime * 1000 : 0,
  560.           state.unixtime * 1000
  561.       );
  562.  
  563.       if (lastAnswerTime > cmdDeliveredMark) {
  564.         $("#circuit").removeClass("waiting");
  565.         waitingForAnswer = false;
  566.         sentCmdLetter = null;
  567.       }
  568.     }
  569.   }
  570. }
  571.  
  572. function setTextstate(state) {
  573.   let m = moment(state.unixtime * 1000);
  574.   $("#StateTime").text(m.format("LT, L"));
  575.   if (box.Type == 2)
  576.     $("#SwState").text("" + state.State + "%");
  577.   else
  578.     $("#SwState").text(SwitchStateForMask(state.State));//Антон: отображение команд с учетом маски
  579.   let mode = state.Mode == 4 ? "Manual" : "Auto";
  580.   mode = i18next.t(mode);
  581.   if (state.Mode == 1)
  582.     mode += ", " + box.DimProfile_Name;
  583.   $("#CurrentMode").text(mode);
  584.  
  585.   let door = i18next.t("Closed");
  586.   if (!state.Door)
  587.     door = '<span class="text-danger">' + i18next.t("Open") + "</span>";
  588.   $("#DoorStatus").html(door);
  589.  
  590.  
  591.   let sync = i18next.t("Synced");
  592.   if (state.Ous)
  593.     sync = '<span class="text-danger">' + i18next.t("Out of sync") + "</span>";
  594.   $("#SyncStatus").html(sync);
  595.  
  596. }
  597.  
  598. function setSvgstate(state) {
  599.  
  600.   let onoff = SwitchState(state.State);
  601.  
  602.   const ruge = "#ecabab";
  603.   const salat = "#abecab";
  604.  
  605.   const errorColor = state.Trouble == STATE_ERROR_UNKNOWN ? ruge : "red";
  606.   const greenColor = state.Trouble == STATE_ERROR_UNKNOWN ? salat : "green";
  607.  
  608.   //const phasecolor = state.Power?"green":ruge;
  609.   let aphst = [];
  610.   for (let i = 0; i < 3; i++) {
  611.     let plet = String.fromCharCode("A".charCodeAt() + i);
  612.     let phst = state.Power & (1 << i);
  613.     aphst[i] = phst;
  614.     let phasecolor = phst ? greenColor : errorColor;
  615.     $(`#phase_${plet}`).css("stroke", phasecolor);
  616. //V11
  617.     $("#Volt" + i).text(plet);
  618.     if (state.PhaseV) {
  619.       let aVolt = JSON.parse(state.PhaseV);
  620.       if (aVolt[i] !== null && aVolt[i] > 1)
  621.         $("#Volt" + i).text(aVolt[i]);
  622.     }
  623.   }
  624.   //$(".phase").css("stroke",phasecolor);
  625.  
  626.  
  627. // КОНТАКТОРЫ
  628.   for (let i = 1; i <= 4; i++) {
  629.     let swtrouble = state.Trouble & (1 << (i - 1));     //аварийность контактора
  630.     let altsw = state.Trouble & (1 << (i + 27));        //альтернативное включение контактора
  631.     let on = (onoff[i - 1] !== '0');                    // значение управления on/off && aphst[0]; 20.07.21 - remove Phase A falsification
  632.     // Команда на включение ON
  633.     if (on) {
  634.       $(`.S${i}_on`).attr("visibility", "visible");     //видимость состояния on
  635.       $(`.S${i}_off`).attr("visibility", "hidden");     //скрыть состояние off
  636.       $(`.S${i}_onoff`).attr("visibility", "hidden");   //скрыть состояние onoff
  637.       $(`.S${i}_offon`).attr("visibility", "hidden");   //скрыть состояние offon
  638.       let swc = "green";
  639.       $(`#S${i}_rect1`).css("fill", "#AFEEEE");         // левый прямоугольник (голубой)
  640.       $(`#S${i}_rect2`).css("fill", swc);               // правый прямоугольник "зеленый"
  641.       $(`#S${i}_tilda`).css("stroke", swc);             //цвет контура синусоиды "зеленый"
  642.       $(`#S${i}_tilda`).css("fill", swc);               //цвет заполнения синусоиды "зеленый"
  643.       $(`.fuse_S${i}`).css("fill", swc);                    //предохранители под напряжением "зеленые"
  644.       //Отсутствие фазы «А»
  645.       if (!aphst[0]) {
  646.         $(`.S${i}_off`).attr("visibility", "hidden");       // не видимость контактора, как Off
  647.         $(`.S${i}_on`).attr("visibility", "hidden");        //не видимость контактора, как ON
  648.         $(`.S${i}_onoff`).attr("visibility", "visible");    //видимость состояния onoff
  649.         $(`.S${i}_offon`).attr("visibility", "hidden"); //скрыть состояние offon
  650.         swc = salat;
  651.         $(`#S${i}_rect1`).css("fill", "#AFEEEE");           // левый прямоугольник "голубой"
  652.         $(`#S${i}_rect2`).css("fill", swc);             // правый прямоугольник "салатный"
  653.         $(`#S${i}_tilda`).css("stroke", "white");           //белый синус
  654.         $(`#S${i}_tilda`).css("fill", "white");         //белый синус
  655.         $(`.fuse_S${i}`).css("fill", "white");              //предохранители "белые"
  656.         if (altsw) {                                            //если альтернативно-включенный контактор
  657.           $(`.S${i}_onoff`).attr("visibility", "hidden");   //не видимость состояния onoff
  658.           $(`.S${i}_offon`).attr("visibility", "visible");  //видимость состояния offon
  659.           $(`#S${i}_rect2`).css("fill", "red");             // правый прямоугольник
  660.           $(`.fuse_S${i}`).css("fill", "green");                //предохранители под напряжением "зеленые"_07_09
  661.         }
  662.       }
  663.       //аварийность контактора
  664.       if (swtrouble) {
  665.         $(`.S${i}_onoff`).attr("visibility", "visible");    // видимость контактора, как onoff
  666.         $(`.S${i}_offon`).attr("visibility", "hidden"); //скрыть состояние offon
  667.         $(`.S${i}_off`).attr("visibility", "hidden");       // не видимость контактора, как Off
  668.         $(`.S${i}_on`).attr("visibility", "hidden");        //не видимость включенного контактора
  669.         $(`#S${i}_rect1`).css("fill", errorColor);          // левый прямоугольник "красный"
  670.         $(`#S${i}_rect2`).css("fill", salat);               // правый прямоугольник "салатный"
  671.         $(`#S${i}_tilda`).css("stroke", "white");           //белый синус
  672.         $(`#S${i}_tilda`).css("fill", "white");         //белый синус
  673.         $(`.fuse_S${i}`).css("fill", "white");              //предохранители "белые"
  674.       }
  675.     }
  676.     // Команда на выключение OFF
  677.     else {
  678.       $(`.S${i}_on`).attr("visibility", "hidden");      //скрыть состояние ON
  679.       $(`.S${i}_onoff`).attr("visibility", "hidden");   //скрыть состояние onoff
  680.       $(`.S${i}_offon`).attr("visibility", "hidden");   //скрыть состояние offon
  681.       $(`.S${i}_off`).attr("visibility", "visible");        //показать состояние OFF
  682.       $(`#S${i}_rect2`).css("fill", "white");           // правый прямоугольник "белый"
  683.       $(`#S${i}_rect1`).css("fill", "#AFEEEE");         // левый прямоугольник голубой
  684.       $(`#S${i}_tilda`).css("stroke", "green");         //цвет контура синусоиды
  685.       $(`#S${i}_tilda`).css("fill", "green");           //цвет заполнения синусоиды
  686.       $(`.fuse_S${i}`).css("fill", "white");                //предохранители
  687.       // Отсутствие фазы А
  688.       if (!aphst[0]) {
  689.         $(`#S${i}_tilda`).css("stroke", "white");   //белый синус
  690.         $(`#S${i}_tilda`).css("fill", "white");
  691.       } //белый синус
  692.       // Авария контактора
  693.       if (swtrouble) {
  694.         $(`#S${i}_rect1`).css("fill", errorColor);      // левый прямоугольник красный
  695.         $(`#S${i}_tilda`).css("stroke", "white");       //белый синус
  696.         $(`#S${i}_tilda`).css("fill", "white");
  697.       }     //белый синус
  698.       // Альтернативное включение
  699.       if (altsw) {                                      //если есть альтернативно-включенный контактор
  700.         $(`.S${i}_off`).attr("visibility", "hidden");
  701.         $(`.S${i}_offon`).attr("visibility", "visible");
  702.         $(`#S${i}_rect2`).css("fill", "red");           // правый прямоугольник красный
  703.         $(`.fuse_S${i}`).css("green");              //предохранители под напряжением "зеленые"_07_09
  704.       }
  705.     }
  706.   }
  707.  
  708. //ПРЕДОХРАНИТЕЛИ 
  709.   for (let i = 0; i < 3; i++)
  710.     if (!aphst[i])
  711.       $(`.fuse_P${i}`).css("fill", "none");
  712.  
  713. //V10__Отображение значений напряжения на линиях/предохранителях   
  714.   let volt = null;
  715.   try {
  716.     volt = JSON.parse(state.Voltage);
  717.   } catch (e) {
  718.  
  719.   }
  720. //V11  
  721.   $('[id^="fuse_"]').find("title").remove();
  722.   for (let i = 1; i <= 24; i++) {
  723.     let ftrouble = state.Trouble & (1 << (i + 3));
  724.     $(`.fuse_${i}_rect`).attr("visibility", "hidden");  //V14   Не видимость знака стрелок
  725.     if (volt) {
  726.       let fVolt = volt[i - 1];
  727.       if (fVolt) {
  728.         $(`#fuse_${i}_rect`).css("fill", "green");
  729.         let titlestr = fVolt > 1 ? fVolt + "V" : "⚡";
  730.         let title = document.createElementNS("http://www.w3.org/2000/svg", "title");
  731.         title.textContent = titlestr;
  732. //V11              
  733.         $(`#fuse_${i}`).append(title);
  734.       } else
  735.         $(`#fuse_${i}_rect`).css("fill", "white");
  736.  
  737. //V14 окраска встречки градиентом "зеленого" и символ "стрелки"
  738.       if (ftrouble && fVolt) {
  739.         $(`#fuse_${i}_rect`).css("fill", "url(#MyGradient)");
  740.         $(`.fuse_${i}_rect`).attr("visibility", "visible");     // видимость знака стрелок
  741.       }
  742.  
  743. //V14  окраска пониженного напряжения градиентом2 "зеленого"
  744.       if (fVolt < 180 && fVolt > 30) {
  745.         $(`#fuse_${i}_rect`).css("fill", "url(#MyGradient2)");
  746.         $(`.fuse_${i}_rect`).attr("visibility", "hidden");  // не видимость знака стрелок
  747.       }
  748.  
  749.       if (ftrouble && !fVolt)
  750.         $(`#fuse_${i}_rect`).css("fill", errorColor);
  751.  
  752.     }
  753.  
  754.     //else {
  755.     //if(ftrouble)
  756.     //$(`#fuse_${ i }_rect`).css("fill",errorColor);}
  757.  
  758.   }
  759. }
  760.  
  761. function SwitchState(num) {
  762.   if (num === null)
  763.     return "-";
  764.  
  765.   num = Math.min(num, 0b1111);
  766.  
  767.   return num.toString(2).padStart("4", "0"); //For robot
  768. }
  769.  
  770. //Антон: отображение команд с учетом маски
  771. function SwitchStateForMask(num) {
  772.   if (num === null)
  773.     return "-";
  774.   let maskCommand = box ? box.Mask_Command : ''
  775.   if (!maskCommand) {
  776.     num = Math.min(num, 0b1111);
  777.  
  778.     return num.toString(2).padStart("4", "0");
  779.   }
  780.   let len = maskCommand ? maskCommand.length : 4;
  781.  
  782.   let binStr = num.toString(2).padStart(len, "0");
  783.  
  784.   let result = "";
  785.   for (let i = 0; i < len; i++) {
  786.     if (maskCommand[i] === "1") {
  787.       result += binStr[i];
  788.     }
  789.   }
  790.   return result;
  791. }
  792.  
  793. function meterdatatable() {
  794.   mdt = $('#meterlog').DataTable({
  795.     "ajax": function (data, callback, settings) {
  796.       let dt = [];
  797.       if (lastmeter !== null)
  798.         dt = lastmeter.rows;
  799.       callback({data: dt});
  800.     },
  801.     "info": false,
  802.     "rowId": "id",
  803.     "language": datatables_locale,
  804.     "paging": false,
  805.     "ordering": false,
  806.     "searching": false,
  807.     "scrollX": true,
  808.     "columns": [
  809.       {
  810.         "data": "Tag",
  811.         render: function (data, type, row) {
  812.           return i18next.t("msg_meter_" + data);
  813.         }
  814.       },
  815.       {
  816.         "data": "Value", className: 'text-right',
  817.         render: function (data, type, row) {
  818.           let tag = appdata.Meter[row.Tag];
  819.           if (tag.type == "decimal") {
  820.             let num = parseFloat(data);
  821.             if (type == "export")
  822.               return num;
  823.             return Intl.NumberFormat(environment.language, {minimumFractionDigits: 3}).format(num);
  824.           }
  825.           return data;
  826.         }
  827.       },
  828.     ],
  829.   });
  830.  
  831.   mdt.on("draw", function () {
  832.     $('[data-toggle="tooltip"]').tooltip();
  833.   });
  834.  
  835.   mdt.on("init", function () {
  836.     $('[data-toggle="tooltip"]').tooltip();
  837.   });
  838. }
  839.  
  840. function stdatatable() {
  841.  
  842.   dt = $('#stlog').DataTable({
  843.     "ajax": function (data, callback, settings) {
  844.       if (stlog !== null)
  845.         callback({data: stlog.rows});
  846.     },
  847.     "info": false,
  848.     "rowId": "id",
  849.     "language": datatables_locale,
  850.     "paging": false,
  851.     "ordering": false,
  852.     "searching": false,
  853.     "scrollX": true,
  854.     "scrollY": "27rem",
  855.     "scrollCollapse": true,
  856.     "deferRender": true,
  857.  
  858.     "columns": [
  859.       {"data": "id", visible: false},
  860.       {
  861.         "data": "Timestamp",
  862.         render: function (data, type, row) {
  863.           if (type == "display") {
  864.             let m = moment(row.unixtime * 1000);
  865.             let td = moment();
  866.             let fs = "L LT";
  867.             if (td.isSame(m, 'd'))
  868.               fs = "LT";
  869.             let tz = row.tz.charAt(0) == "-" ? "" : "+" + row.tz;
  870.             let stime = data + " " + tz;
  871.             return `<span data-toggle="tooltip" title="${stime}">${m.format(fs)}</span>`;
  872.           }
  873.           return data;
  874.         }
  875.       },
  876.  
  877.       {
  878.         "data": "Mode",
  879.         render: function (data, type, row) {
  880.           let strm = i18next.t("Unmanaged");
  881.           if (row.Smart)
  882.             strm = i18next.t(appdata.AutoModes.find(x => x.id == data).Name);
  883.  
  884.           return strm;
  885.         }
  886.       },
  887.  
  888.       {
  889.         "data": "State",
  890.         "className": "text-center",  //Антон: центровка отображения команд с учетом маски
  891.         render: function (data, type, row) {
  892.           let str = data + "%";
  893.           if (row.Type == 1) {//Box
  894.             str = SwitchStateForMask(data);//Антон: отображение команд с учетом маски
  895.           }
  896.           return str;
  897.         }
  898.  
  899.       },
  900.       {
  901.         "data": "Sip",
  902.         "className": "text-center text-nowrap",
  903.         render: function (data, type, row) {
  904.           if (type == "display") {
  905.             let ret = "";
  906.             if (row.Power >= 7 || (row.Power && box.Type == 2))
  907.               ret = `<span class="fa fa-plug text-success" data-toggle="tooltip" title="${i18next.t('Power Ok')}"></span>&nbsp;`;
  908.             else {
  909.               let title = i18next.t('Power Fail');
  910.               title += " (" + reverseString(row.Power.toString(2).padStart(3, "0")) + ")";
  911.  
  912.               ret = `<span class="fa fa-plug text-danger" data-toggle="tooltip" title="${title}"></span>&nbsp;`;
  913.             }
  914.  
  915.             if (!row.Trouble)
  916.               ret += `<span class="fa fa-check-circle text-success" data-toggle="tooltip" title="${i18next.t('Facility is Ok')}"></span>&nbsp;`;
  917.             else
  918.               ret += `<span class="fa fa-exclamation-triangle text-danger" data-html="true" data-toggle="tooltip" title="${errDecode(row.Trouble, box.Type)}"></span>&nbsp;`;
  919.  
  920.  
  921.             if (data)
  922.               ret += `<span class="fa fa-phone-square text-success" data-toggle="tooltip" title="${i18next.t('SIP is Ok')}"></span>&nbsp;`;
  923.             else
  924.               ret += `<span class="fa fa-phone-square text-danger" data-toggle="tooltip" title="${i18next.t('SIP fault')}"></span>&nbsp;`;
  925.  
  926.             if (row.Ip)
  927.               ret += `<span class="fa fa-wifi text-success" data-toggle="tooltip" title="${i18next.t('IP is Ok')}"></span>&nbsp;`;
  928.             else
  929.               ret += `<span class="fa fa-wifi text-danger" data-toggle="tooltip" title="${i18next.t('IP fault')}"></span>&nbsp;`;
  930.  
  931.             if (!row.Timeallert)
  932.               ret += `<span class="fa fa-clock-o text-success" data-toggle="tooltip" title="${i18next.t('Clock is Ok')}"></span>&nbsp;`;
  933.             else
  934.               ret += `<span class="fa fa-clock-o text-danger" data-toggle="tooltip" title="${i18next.t('Clock error')}"></span>&nbsp`;
  935.  
  936.             if (row.Controller)
  937.               ret += `<span class="fa fa-microchip text-success" data-toggle="tooltip" title="${i18next.t('Controller is OK')}"></span>&nbsp`;
  938.             else
  939.               ret += `<span class="fa fa-microchip text-danger" data-toggle="tooltip" title="${i18next.t('Controller error')}"></span>&nbsp`;
  940.  
  941.             if (row.Door)
  942.               ret += `<span class="fa fa-lock text-success" data-toggle="tooltip" title="${i18next.t('Case closed')}"></span>&nbsp`;
  943.             else
  944.               ret += `<span class="fa fa-unlock text-danger" data-toggle="tooltip" title="${i18next.t('Case open')}"></span>&nbsp`;
  945.  
  946.             if (row.Ous)
  947.               ret += `<span class="fa fa-refresh text-danger" data-toggle="tooltip" title="${i18next.t('Out of sync')}"></span>`;
  948.             else
  949.               ret += `<span class="fa fa-refresh text-success" data-toggle="tooltip" title="${i18next.t('Synced')}"></span>`;
  950.  
  951.             return ret;
  952.  
  953.           }
  954.           return data;
  955.         }
  956.       },
  957.  
  958.  
  959.       {
  960.         "data": "DimProfileName",
  961.         "className": "text-nowrap",
  962.         render: function (data, type, row) {
  963.           let strd = "";
  964.           let title = ""
  965.           if (row.Smart) {
  966.  
  967.             if (!(row.IncomingLog_id === null)) {
  968.               title = i18next.t("Notification");
  969.               if (!(row.Status_name === null))
  970.                 strd = escapeQuote(i18next.t(row.Status_Name)) + " ";
  971.               if (!(row.RemoteIP === null)) {
  972.                 strd = i18next.t("Statistics") + " ";
  973.                 title = "IP: " + row.RemoteIP;
  974.               }
  975.               strd += "(&lArr;)";
  976.  
  977.               if (type == "display")
  978.                 strd = `<span data-toggle="tooltip" title="${title}">${strd}</span>`;
  979.             }
  980.             if (!(row.OutgoingLog_id === null)) {
  981.               strd = "&rArr;";
  982.               strd = escapeQuote(i18next.t(row.Command_Name)) + " (" + strd + ")";
  983.               if (row.IP_Name)
  984.                 strd = escapeQuote(i18next.t(row.IP_Name)) + ", " + strd;
  985.               title = i18next.t("Command");
  986.               if (type == "display")
  987.                 strd = `<span data-toggle="tooltip" title="${title}" class="text-${row.Hangupcause == 17 ? 'success' : 'danger'}">${strd}</span>`;
  988.  
  989.             }
  990.             if (!(row.DimProfile_id === null)) {
  991.               strd = data;
  992.               title = i18next.t("Shedule");
  993.               if (type == "display")
  994.                 strd = `<span data-toggle="tooltip" title="${title}"}">${strd}</span>`;
  995.            }
  996.          }
  997.          return strd;
  998.        }
  999.      }
  1000.  
  1001.    ]
  1002.  
  1003.  });
  1004.  
  1005.  dt.on("draw", function () {
  1006.    $('[data-toggle="tooltip"]').tooltip();
  1007.  
  1008.  });
  1009.  
  1010.  dt.on("init", function () {
  1011.    $('[data-toggle="tooltip"]').tooltip();
  1012.  });
  1013.  $('#stlog tbody').on('click', 'tr', function () {
  1014.  
  1015.    const rowData = dt.row(this).data();
  1016.    if (!rowData) return;
  1017.    liveMode = false;
  1018.    clearTimeout(renewTimer);
  1019.    $("#btnLive").prop("disabled", false);
  1020.    setSvgstate(rowData);
  1021.    setTextstate(rowData);
  1022.  
  1023.    $(this).addClass('table-primary').siblings().removeClass('table-primary');
  1024.  });
  1025.  $('#btnLive').on('click', () => {
  1026.    if (stlog?.rows?.length) {
  1027.      if (liveMode) return;
  1028.      liveMode = true;
  1029.      $("#btnLive").prop("disabled", true);
  1030.      $('#stlog tbody tr').removeClass('table-primary');
  1031.  
  1032.      onlogchane();
  1033.      renew();
  1034.    }
  1035.  });
  1036.  
  1037. }
  1038.  
  1039. async function attachBackground() {
  1040.  const $svg = $("#circuit").children("svg");
  1041.  if (!$svg.length || $("#schemaWrapper").length) return;
  1042.  
  1043.  let typeCode = null;
  1044.  if (box.Name?.startsWith("TL")) typeCode = "TL";
  1045.  else if (box.Name?.startsWith("G")) typeCode = "G";
  1046.  
  1047.  let bgSrc = `${environment.base_url}/images/types/${typeCode || "default"}.png`;
  1048.  
  1049.  // картинка "заказного" фона мнемосхемы объекта
  1050.  $svg.wrap(
  1051.      '<div id="schemaWrapper" ' +
  1052.      '     style="position:relative; display: flex;\n' +
  1053.      '    align-items: flex-end;\n' +
  1054.      '    justify-content: center;\n' +
  1055.      '    padding-bottom: 75px;margin-top: 5px;">' +
  1056.      "</div>"
  1057.  );
  1058.  $("#schemaWrapper").prepend(
  1059.      `<img id="schemaBg" ` +
  1060.      `     src="${bgSrc}" ` +
  1061.      `     style="position:absolute;top:-10px; bottom: 0;left:-3px;width:100%;` +
  1062.       `            height:100%; object-fit: contain;object-position: left;z-index:1;pointer-events:none;" />`
  1063.  );
  1064.  $svg.css({position: "relative", zIndex: 2, maxWidth: '60%', marginRight: '30%', marginBottom: '-70px'});
  1065. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement