Advertisement
eqeqwan21

mgtt.js

Jun 20th, 2025
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //исправлено Антоном для привязки пользователя к городу,v13
  2. "use strict";
  3. let hulla = new hullabaloo();
  4. let wb = new wbdialog();
  5.  
  6. let scrollX=true;
  7. let pagesize=15;
  8. let get = parseQuery(window.location.search);
  9.  
  10. let address = null;
  11. let commands = null;
  12. let parProfiles = null;
  13. let deviceNames = null;
  14. let parents = {};
  15.  
  16. let editmode = false;
  17.  
  18. const filterstoragekey = "filter"+window.location.pathname;
  19.  
  20. moment.locale(environment.language || window.navigator.userLanguage || window.navigator.language);
  21.  
  22. function capitalizeFirstLetter(string) {
  23.     return string.charAt(0).toUpperCase() + string.slice(1);
  24. }
  25. $(async function() {
  26.   $('#notificationBell').hide();
  27.   $('#loader').show();
  28.   let town;
  29.   if (environment.login_name.indexOf("_") !== -1) {
  30.     town = '&town='+capitalizeFirstLetter(environment.login_name.split('_')[0])
  31.   }
  32.   else{
  33.     town = ''
  34.   }
  35.   let previousTotal = localStorage.getItem('previousTotal') ? parseInt(localStorage.getItem('previousTotal') - 1) : 0;
  36.   let soundEnabled = false;
  37.  
  38.   function updateEventData() {
  39.     $.ajax({
  40.       url: environment.base_url+"/"+'?do=api&fn=last_statistic'+town,
  41.       type: 'GET',
  42.       dataType: "json",
  43.       success: function(data) {
  44.         let eventData = data.rows[0]
  45.         var eventList = $('#eventList');
  46.         const now = new Date();
  47.         const formattedDateTime = now.toLocaleString();
  48.         const total = eventData.PowerFailureCount + eventData.EquipmentFailureCount + eventData.SipFailureCount + eventData.IpFailureCount + eventData.TimeAlertFailureCount + eventData.ControllerFailureCount + eventData.DoorOpenCount + eventData.SyncFailureCount;
  49.         if (total !== previousTotal) {
  50.           eventList.empty();
  51.           eventList.append('<li class="datetime">Time: ' + formattedDateTime + '</li>');
  52.           eventList.append('<li>' + i18next.t("Power Failure") + ': ' + eventData.PowerFailureCount + '</li>');
  53.           eventList.append('<li>' + i18next.t("Object Failure") + ': ' + eventData.EquipmentFailureCount + '</li>');
  54.           eventList.append('<li>' + i18next.t("SIP failure") + ':  ' + eventData.SipFailureCount + '</li>');
  55.           eventList.append('<li>' + i18next.t("IP failure") + ': ' + eventData.IpFailureCount + '</li>');
  56.           eventList.append('<li>' + i18next.t("Clock error") + ': ' + eventData.TimeAlertFailureCount + '</li>');
  57.           eventList.append('<li>' + i18next.t("Controller error") + ': ' + eventData.ControllerFailureCount + '</li>');
  58.           eventList.append('<li>' + i18next.t("Door open") + ': ' + eventData.DoorOpenCount + '</li>');
  59.           eventList.append('<li>' + i18next.t("Out of sync") + ': ' + eventData.SyncFailureCount + '</li>');
  60.           $('#eventCount').text(total)
  61.         } else {
  62.           eventList.find('li.datetime').text('Time: ' + formattedDateTime + '')
  63.         }
  64.         $('#loader').hide();
  65.         $('#notificationBell').show();
  66.         if(total > 100){
  67.           $('.notification-container').addClass('large')
  68.         }
  69.         if (total > previousTotal && soundEnabled) {
  70.           $('#notificationSound')[0].play();
  71.         }
  72.  
  73.         previousTotal = total;
  74.         localStorage.setItem('previousTotal', previousTotal);
  75.       }
  76.     });
  77.   }
  78.  
  79.   setInterval(updateEventData, 1000);
  80.  
  81.   $('#eventCount').click(function() {
  82.     $('#eventDropdown').toggle();
  83.   });
  84.  
  85.   $('#notificationBell').click(function() {
  86.     soundEnabled = true;
  87.     $('#notificationBell').removeClass('disabled').addClass('active');
  88.   });
  89.  
  90.   $(document).click(function(event) {
  91.     if (!$(event.target).closest('#eventCount, #eventDropdown').length) {
  92.       if ($('#eventDropdown').is(":visible")) {
  93.         $('#eventDropdown').hide();
  94.       }
  95.     }
  96.   });
  97. });
  98.  
  99.  
  100. $(function() {
  101.   $('[data-toggle="tooltip"]').tooltip();
  102.    
  103.  scrollX  = !($('#descktop-visible').is(':visible'));
  104.  if(scrollX)
  105.      pagesize=10;
  106.  
  107.  onload();
  108. });
  109.  
  110. async function onload() {
  111.     let result;
  112.  
  113.     try {
  114.         result = await $.ajax({
  115.             url: environment.base_url+"/"+'?do=api&fn=address',
  116.             type: 'GET',
  117.             dataType: "json"
  118.         });
  119.  
  120.     } catch (error) {
  121.         console.error(error);
  122.         $("#content").html("<h2>Address info's was not loaded</h2>");
  123.         return;
  124.     }
  125.    
  126.     address = result;
  127. // привязка к городу
  128.     //$('#Town_id').find('option').remove();
  129.    
  130.     let towns = address.towns.rows;
  131. //Привязка пользователей к городу
  132. //  if (environment.login_name.indexOf("_") !== -1) {
  133.     if (environment.login_name.indexOf("_") !== -1 || environment.login_name === 'автодор') {
  134.         for (let key in towns) {
  135. //          if (environment.login_name.split('_')[0].toLowerCase() === towns[key].Name.toLowerCase()) {
  136.             if ((environment.login_name.split('_')[0].toLowerCase() === towns[key].Name.toLowerCase()) || (environment.login_name === 'автодор' && towns[key].Name.toLowerCase().includes('орстрой'))) {  
  137.                     $("#Town_id").append($("<option></option>")
  138.                     .attr("value", towns[key].id)
  139.                     .prop("selected", true)
  140.                     .text(towns[key].Name));
  141.             }
  142.         }
  143.     } else {
  144.         $("#Town_id").append($("<option></option>")
  145.             .attr("value", "")
  146.             .prop("selected", true)
  147.             .text(i18next.t("Any city")));
  148.  
  149.         for (let key in towns) {
  150.             $("#Town_id").append($("<option></option>")
  151.                 .attr("value", towns[key].id)
  152.                 .text(towns[key].Name));
  153.         }
  154.     }
  155.    
  156.     try {
  157.         result = await $.ajax({
  158.             url: environment.base_url+"/"+'?do=api&fn=ServerCommand&type=1,3',
  159.             type: 'GET',
  160.             dataType: "json"
  161.         });
  162.  
  163.     } catch (error) {
  164.         console.error(error);
  165.         $("#content").html("<h2>Commands was not loaded</h2>");
  166.         return;
  167.     }
  168.     commands = result.rows;
  169.     try {
  170.         result = await $.ajax({
  171.             url: environment.base_url+"/"+'?do=api&fn=dimprofiles&filter=true',
  172.             type: 'GET',
  173.             dataType: "json"
  174.         });
  175.  
  176.     } catch (error) {
  177.         console.error(error);
  178.         $("#content").html("<h2>Profiles was not loaded</h2>");
  179.         return;
  180.     }
  181.     parProfiles = result.rows; 
  182.     try {
  183.         result = await $.ajax({
  184.             url: environment.base_url+"/"+'?do=api&fn=devicenames&filter=true',
  185.             type: 'GET',
  186.             dataType: "json"
  187.         });
  188.  
  189.     } catch (error) {
  190.         console.error(error);
  191.         $("#content").html("<h2>Names was not loaded</h2>");
  192.         return;
  193.     }
  194.     deviceNames = result.rows; 
  195.  
  196.     try {
  197.         result = await $.ajax({
  198.             url: environment.base_url+"/"+'?do=api&fn=parents',
  199.             type: 'GET',
  200.             dataType: "json"
  201.         });
  202.  
  203.     } catch (error) {
  204.         console.error(error);
  205.         $("#content").html("<h2>Parents was not loaded</h2>");
  206.         return;
  207.     }
  208.     parents.stations = result.stations.rows;
  209.     parents.boxes = result.boxes.rows;
  210.  
  211.    
  212.    
  213.     addNames();
  214.     addProfiles();
  215.     selTypeMenu("#seltype",0,"obj");
  216.    
  217.     add2Address();
  218.    
  219.     modeMenu("#mode",0);
  220.     powerMenu("#power");
  221.     condMenu("#cond");
  222.     comMenu("#com");
  223.     onoffMenu("#onoff");
  224. //привязка к городу
  225. if($('#map').length > 0) {
  226.   goTown();  
  227. }
  228.     //addParents();
  229.     setTimeout(function () {
  230.     if($('#Town_id').val().length > 0) {
  231.         add2Address()      
  232.     }  
  233. },500);
  234.     if( get['device']==undefined ) {
  235.         loadflt();
  236.     }
  237.  
  238.     let initflt = {show:false};
  239.     Object.assign(initflt, JSON.parse(localStorage.getItem(filterstoragekey)) || {} );
  240.    
  241.     if( get['device']!==undefined ) {
  242.         initflt = {show:initflt.show};
  243.     }
  244.  
  245.     if(initflt.show)
  246.         tougleOpt();
  247.    
  248.     setTimeout(renew,100);
  249.    
  250. }
  251. function add2Address() {
  252.     addAddress("District", address.districts.rows, i18next.t("Any district"));
  253.     addAddress("Location", address.locations.rows, i18next.t("Any street"));
  254.     addParents();
  255.     $("#Location").selectpicker('refresh');
  256. }
  257.  
  258. function addAddress(sel, obj, anystr="Any") {
  259.     let town = $('#Town_id').val();
  260.    
  261.     $("#"+sel).find('option').remove();
  262.  
  263.     $("#"+sel).append($("<option></option>")
  264.         .attr("value","")
  265.         .prop("selected",true)
  266.         .text(i18next.t(anystr)));  
  267.        
  268.     let names = new Set( obj.filter((x)=> town == "" || x.Town_id == town).map((x) => x.Name) );
  269.    
  270.     for (let name of names) {
  271.         $("#"+sel).append($("<option></option>")
  272.             .attr("value",name)
  273.             .text(name));
  274.     }
  275. }
  276.  
  277. function addProfiles() {
  278.     $("#DimProfile_id").find('option').remove();
  279.  
  280.     $("#DimProfile_id").append($("<option></option>")
  281.         .attr("value","")
  282.         .prop("selected",true)
  283.         .text(i18next.t("Any shedule")));  
  284.  
  285.     for (let pard of parProfiles) {
  286.         $("#DimProfile_id").append($("<option></option>")
  287.             .attr("value",`{"DimProfile_id":${pard.id}}`)
  288.             .text(pard.Name));
  289.     }
  290.  
  291. }
  292.  
  293. function addNames() {
  294.     $("#Name").find('option').remove();
  295.  
  296.     $("#Name").append($("<option></option>")
  297.         .attr("value","")
  298.         .prop("selected",true)
  299.         .text(i18next.t("Any name")));  
  300.  
  301.     for (let name of deviceNames) {
  302.         $("#Name").append($("<option></option>")
  303.             .attr("value",name.Name)
  304.             .text(name.Name));
  305.     }
  306.  
  307. }
  308.  
  309. function addParents() {
  310.    
  311.     let town = $("#Town_id").val();
  312.    
  313.     let typeval = $("#seltype").val(), type = 0;
  314.     if(typeval)
  315.         type = JSON.parse(typeval).Type;
  316.    
  317.     $("#Station").find('option').remove();
  318.  
  319.     $("#Station").append($("<option></option>")
  320.         .attr("value","")
  321.         .prop("selected",true)
  322.         .text(i18next.t("Any connection")));    
  323.  
  324.     if(type==0 || type==2) {
  325.         let boxes = parents.boxes.filter(x => town == "" || x.Town_id == town);
  326.         for (let box of boxes) {
  327.             $("#Station").append($("<option></option>")
  328.                 .attr("value",`{"box":${box.id}}`)
  329.                 .text(`№${box.CustomNum} ${box.Name}`));
  330.         }
  331.     }
  332.    
  333.     let stations;
  334.     if(type==0 || type==1)
  335.         stations = new Set( parents.stations.filter((x)=> x.Station && (town == "" || x.Town_id == town)).map((x) => x.Station) );
  336.     console.log(stations);
  337.     if(type==0 && stations.size)
  338.         $("#Station").append($("<option></option>")
  339.             .prop("disabled",true)
  340.             .text("  "+i18next.t("Station")+":"));   
  341.    
  342.     if(type==0 || type==1) {
  343.         for (let station of stations) {
  344.             $("#Station").append($("<option></option>")
  345.                 .attr("value",station)
  346.                 .text(station));
  347.         }
  348.     }
  349.     $("#Name").find('option').remove();
  350.  
  351.     $("#Name").append($("<option></option>")
  352.         .attr("value","")
  353.         .prop("selected",true)
  354.         .text(i18next.t("Any name")));
  355.  
  356.     let names = deviceNames.filter(x => town == "" || x.Town_id == town);
  357.     for (let name of names) {
  358.         $("#Name").append($("<option></option>")
  359.             .attr("value",name.Name)
  360.             .text(name.Name));
  361.     }
  362.  
  363.     $("#DimProfile_id").find('option').remove();
  364.  
  365.     $("#DimProfile_id").append($("<option></option>")
  366.         .attr("value","")
  367.         .prop("selected",true)
  368.         .text(i18next.t("Any shedule")));
  369.  
  370.     let pars = parProfiles.filter(x => town == "" || x.Town_id == town);
  371.     for (let pard of pars) {
  372.         $("#DimProfile_id").append($("<option></option>")
  373.             .attr("value",`{"DimProfile_id":${pard.id}}`)
  374.             .text(pard.Name));
  375.     }
  376.  
  377. }
  378.  
  379.  
  380.  
  381. function addcmd(devtype) {
  382.     $("#cmd").find('option').remove();
  383.  
  384.     for (let key in commands) {
  385.         if(commands[key].DeviceType == devtype && commands[key].Letter!="F") {
  386.             $("#cmd").append($("<option></option>")
  387.                 .attr("value",commands[key].id)
  388.                 .text(i18next.t(commands[key].Name)));
  389.         }
  390.     }      
  391. }
  392.  
  393. async function runCmd() {
  394.     let ids = seldev.slice(0);
  395.     //cmdclear();
  396.     let srvcmd = {};
  397.    
  398.     srvcmd.cmd = parseInt($("#cmd").val());
  399.     let selcmd = commands.find(x => x.id == srvcmd.cmd);
  400.     let cmdtext=i18next.t(selcmd.Name);
  401.    
  402.     for(let i=0; i<ids.length;i++) ids[i] = parseInt(ids[i]);
  403.     srvcmd.devs = ids;
  404.    
  405.     let result = null;
  406.     try {
  407.         result = await $.ajax({
  408.             url: environment.base_url+"/"+'?do=api&fn=makecalls',
  409.             data: JSON.stringify(srvcmd),
  410.             type: 'PUT',
  411.             contentType: "application/json; charset=utf-8",
  412.             dataType: "json"
  413.         });
  414.    
  415.     } catch (error) {
  416.         console.error(error);
  417.         hulla.send(i18next.t("Device control error"));
  418.         return false;
  419.     }
  420.    
  421.     if(result.success) {
  422.         switch (result.queued) {
  423.             case 0:
  424.               hulla.send(i18next.t("Command not queued"));
  425.               break;
  426.             case 1:
  427.               hulla.send(`${i18next.t("Command")} "${cmdtext}" ${i18next.t("queued")}`,"success");
  428.               break;
  429.             default:
  430.               hulla.send(`${cmdtext} - ${i18next.t("Command queued for multiple devices")} (${result.queued})`,"success");
  431.               break;
  432.         }
  433.     } else {
  434.         hulla.send(i18next.t("An error occurred while adding commands to the queue"));
  435.         console.log(result);
  436.     }
  437.    
  438.     return false;
  439. }
  440.  
  441. function tougleOpt() {
  442.     let flt = JSON.parse(localStorage.getItem(filterstoragekey)) || {};
  443.     if($("#opt-form").hasClass("d-none")) {
  444.         $("#opt-form").removeClass("d-none");
  445.         $("#hdcap").removeClass("fa-angle-double-down");
  446.         $("#hdcap").addClass("fa-angle-double-up");
  447.         $(".address").removeClass("d-none");
  448.         flt.show = true;
  449.     }
  450.     else {
  451.         $("#hdcap").removeClass("fa-angle-double-up");
  452.         $("#hdcap").addClass("fa-angle-double-down");
  453.         $("#opt-form").addClass("d-none");
  454.         $(".address").addClass("d-none");
  455.         flt.show = false;
  456.     }
  457.     localStorage.setItem(filterstoragekey,JSON.stringify(flt));
  458. }
  459.  
  460. const simplefld = ['Town_id','District','Location','seltype','power','mode','cond','com','onoff', 'DimProfile_id', 'Name', 'Station'];
  461. function changeflt() {
  462.    
  463.     let saveflt = JSON.parse(localStorage.getItem(filterstoragekey)) || {} ;
  464.     for(let sel of simplefld) {
  465.         let val = $("#"+sel).val();
  466.         if(val==0 || val==null || val=="") {
  467.             if(saveflt.hasOwnProperty(sel))
  468.                 delete saveflt[sel];
  469.             continue;
  470.         }
  471.        
  472.         saveflt[sel]=val;
  473.     }
  474.     if( get['device']==undefined )
  475.         localStorage.setItem( filterstoragekey, JSON.stringify(saveflt) );
  476. }
  477.  
  478. function loadflt() {
  479.     let saveflt = JSON.parse(localStorage.getItem(filterstoragekey)) || {} ;
  480.     for(let sel of simplefld) {
  481.         if(saveflt.hasOwnProperty(sel) && saveflt[sel]!==null && saveflt[sel]!=="" && saveflt[sel]!==0) {
  482.             $("#"+sel).val(saveflt[sel]);
  483.             if(sel=="Location")
  484.                 $("#Location").selectpicker('refresh');
  485.         }
  486.     }      
  487. }
  488.  
  489. function makeflt() {
  490.     let flt = {};
  491.     for(let sel of simplefld) {
  492.        
  493.         let val = $("#"+sel).val();
  494.         if(val==0 || val==null || val=="")
  495.             continue;
  496.        
  497.         if( val[0]=="{" || val[0]=="[" )
  498.             val=JSON.parse(val);
  499.         if( val !== "") {
  500.             if(Array.isArray(val))
  501.                 flt[sel] = val.join(",");
  502.             else if(typeof val === "object") {
  503.                 for(let key in val) {
  504.                     let prop = val[key];
  505.                     if(Array.isArray(prop))
  506.                         flt[key]=prop.join(",");
  507.                     else
  508.                         flt[key]=prop;
  509.                 }
  510.             }
  511.             else {
  512.                 flt[sel]=val;
  513.             }
  514.            
  515.         }
  516.     }
  517.     return flt;
  518. }
  519.  
  520. let saveprocessing = false;
  521. async function seteditmode(mode=false, save=false) {
  522.     if(save) {
  523.         if(saveprocessing)
  524.             return;
  525.         saveprocessing=true;
  526.        
  527.         if(movedObj.size == 0)
  528.             hulla.send(i18next.t("Objects have not been moved"), "info");
  529.         else {
  530.            
  531.             let url=environment.base_url+"/"+'?do=api&fn=devicebulkupdate';
  532.        
  533.             try {
  534.                 await $.ajax({
  535.                     url: url,
  536.                     type: 'POST',
  537.                     contentType: "application/json; charset=utf-8",
  538.                     data: JSON.stringify( Object.fromEntries(movedObj) ),
  539.                     dataType: "json"
  540.                 });
  541.             } catch (error) {
  542.                 console.log(error);
  543.                 hulla.send(`${i18next.t("Failed to save data")} - ${i18next.t("Error occurred")}`);
  544.                 saveprocessing=false;
  545.                 return;
  546.             }      
  547.             hulla.send(i18next.t("Objects moved") + ": " + movedObj.size, "success");
  548.         }
  549.         saveprocessing=false;
  550.     }
  551.     editmode = mode;
  552.     if(editmode) {
  553.         $("#dbtnEdit, #dbtnTougleFilter").addClass("d-none");
  554.         $("#dbtnSave, #dbtnCancel").removeClass("d-none");
  555.     } else {
  556.         $("#dbtnEdit, #dbtnTougleFilter").removeClass("d-none");
  557.         $("#dbtnSave, #dbtnCancel").addClass("d-none");
  558.     }
  559.    
  560.     setTimeout(markers, 500);
  561.     cmdpanel();
  562.     movedObj.clear();
  563. }
  564.  
  565.  
  566. function devicon(dev) {
  567.     let rnd=[];
  568.  
  569.     let iconName = 'lamp.svg';
  570.    
  571.     if(dev.Type==1)
  572.         iconName = 'box.svg';
  573.  
  574.     iconName +="?ver=" + config.version;
  575.    
  576.     if(dev.Smart == 0)
  577.         rnd.push('unmanaged');
  578.    
  579.     if(dev.Sip==0 || dev.Ip==0)
  580.         rnd.push('nocon');
  581.     if((dev.Power < 7 && dev.Type==1) || dev.Power==0)
  582.         rnd.push('nopower');
  583.     if(dev.Mode == 4)
  584.         rnd.push('manual');
  585.     else
  586.         rnd.push('auto');
  587.     if(dev.Trouble > 0)
  588.         rnd.push('trouble');
  589.    
  590.     if(dev.State)
  591.         rnd.push('on');
  592.     else
  593.         rnd.push('off');   
  594.     if(dev.Timeallert)
  595.         rnd.push('timeallert');
  596.     if(!dev.Controller)
  597.         rnd.push('controlallert');
  598.    
  599.     if(!dev.Door)
  600.         rnd.push('open');
  601.    
  602.     if(config.ous_pulse && dev.Ous)
  603.         rnd.push('ous');
  604.     if (dev.num_contactors >= 2 && dev.State > 0) {
  605.         rnd.push('multiple=true');
  606.     }
  607.     if (dev.Door === 0) rnd.push("open=1");
  608.     if (dev.Type == 1)
  609.         rnd.push('state=' + (dev.State ?? 0));
  610.     iconName += "&"+rnd.join("&");
  611.    
  612.     return environment.base_url+"/images/"+iconName;
  613. }
  614.  
  615. function selection_fire(clear=false) {
  616.     let atxt=[];
  617.     let acls=[];
  618.     let aspn=[];
  619.     if(seldev.length == 0) {
  620.         if(clear)
  621.             cmdclear();
  622.         return;
  623.     }
  624.    
  625.     let id1 = seldev.slice(0, 1)[0];
  626.     let ind1 = ddata.map[id1];
  627.     let dt1 = ddata.rows[ind1].Type;
  628.     let mix = false;
  629.    
  630.     for(let id of seldev) {
  631.         let ind = ddata.map[id];
  632.         let dev = ddata.rows[ind];
  633.         if(dt1 !== dev.Type) {
  634.             mix = true;
  635.             break;
  636.         }
  637.         acls.push("."+"cli"+dev.id);
  638.         aspn.push(`<div data-toggle="tooltip" data-placement="right" data-html="true" id="ctrl_${dev.id}" class="devctrl" onclick="goDevice(${dev.id},false,true)">${dev.CustomNum}</div>`)
  639.     }
  640.    
  641.     if(mix) {
  642.         hulla.send(i18next.t("Mixed types selection are not allowed"));
  643.         cmdclear();
  644.         return;
  645.     }
  646.    
  647.     $("#devlist").html(aspn.join(" "));
  648.  
  649.     $(".cli").removeClass("border border-primary");
  650.     $(acls.join(",")).addClass("border border-primary");
  651.     addcmd(dt1);
  652.     cmdpanel();
  653. }
  654.  
  655. function removeFilter() {
  656.     $("#District, #Location, #power, #mode, #cond, #com, #onoff, #DimProfile_id, #Name, #Station").prop('selectedIndex', 0).trigger("change");
  657.     $("#seltype").prop('selectedIndex', 2).trigger("change");
  658. }
  659.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement