Advertisement
eqeqwan21

Untitled

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