eqeqwan21

obj.js

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