Leo0777

Untitled

Nov 26th, 2025
87
0
23 hours
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 38.66 KB | None | 0 0
  1. <?php
  2. // Zpracování požadavku na přepnutí relé
  3. if (isset($_GET['rele']) && isset($_GET['kanal']) && isset($_GET['stav'])) {
  4.     $rele = $_GET['rele'];
  5.     $kanal = $_GET['kanal'];
  6.     $stav = strtoupper($_GET['stav']);
  7.    
  8.     // Speciální případ pro zásuvku (nemá kanál, jen stav)
  9.     if ($rele === 'zasuvka_sekacka') {
  10.         exec("sudo /home/leo/skripty/muj_web/zasuvka_kurnik_sekacka.sh $stav");
  11.     } else {
  12.         // Běžné relé s kanálem
  13.         exec("sudo /home/leo/skripty/muj_web/rele_{$rele}.sh $kanal $stav");
  14.     }
  15.    
  16.     // Vrátit JSON odpověď
  17.     header('Content-Type: application/json');
  18.     echo json_encode(['success' => true, 'rele' => $rele, 'kanal' => $kanal, 'stav' => $stav]);
  19.     exit;
  20. }
  21. ?>
  22.  
  23.  
  24.  
  25.  
  26. <!DOCTYPE html>
  27. <html lang="cs">
  28. <head>
  29.   <meta charset="UTF-8">
  30.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  31.   <title>MQTT Dashboard</title>
  32.   <style>
  33.     body {
  34.       margin: 0;
  35.       padding: 20px;
  36.       background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  37.       min-height: 100vh;
  38.       font-family: Arial, sans-serif;
  39.     }
  40.    
  41.     .dashboard {
  42.       max-width: 1200px;
  43.       margin: 0 auto;
  44.     }
  45.    
  46.     .dashboard-title {
  47.       text-align: center;
  48.       color: white;
  49.       font-size: 32px;
  50.       margin-bottom: 30px;
  51.       text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
  52.     }
  53.    
  54.     .teplomery-container {
  55.       display: flex;
  56.       flex-wrap: wrap;
  57.       gap: 20px;
  58.       justify-content: center;
  59.       margin-bottom: 30px;
  60.       min-height: 200px;
  61.       width: 100%;
  62.       max-width: 800px;
  63.       margin: 0 auto 30px auto;
  64.       background: rgba(255,255,255,0.1);
  65.       border-radius: 10px;
  66.       padding: 20px;
  67.     }
  68.  
  69.     .rele-container {
  70.       display: flex;
  71.       flex-wrap: wrap;
  72.       gap: 20px;
  73.       justify-content: center;
  74.       min-height: 150px;
  75.       width: 100%;
  76.       max-width: 800px;
  77.       margin: 0 auto 30px auto;
  78.       background: rgba(255,255,255,0.1);
  79.       border-radius: 10px;
  80.       padding: 20px;
  81.     }
  82.    
  83.     .power-container {
  84.       display: flex;
  85.       flex-wrap: wrap;
  86.       gap: 20px;
  87.       justify-content: center;
  88.       min-height: 150px;
  89.       width: 100%;
  90.       max-width: 800px;
  91.       margin: 0 auto;
  92.       background: rgba(255,255,255,0.1);
  93.       border-radius: 10px;
  94.       padding: 20px;
  95.     }
  96.    
  97.     .widget {
  98.       background: #1e293b;
  99.       color: #e2e8f0;
  100.       padding: 20px;
  101.       border-radius: 10px;
  102.       box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  103.       width: 170px;
  104.       height: auto;
  105.       flex-shrink: 0;
  106.     }
  107.    
  108.     .widget-rele {
  109.       background: #1e293b;
  110.       color: #e2e8f0;
  111.       padding: 15px;
  112.       border-radius: 10px;
  113.       box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  114.       width: 220px;
  115.       height: auto;
  116.       flex-shrink: 0;
  117.     }
  118.    
  119.     .widget-power {
  120.       background: #1e293b;
  121.       color: #e2e8f0;
  122.       padding: 0;
  123.       border-radius: 10px;
  124.       box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  125.       width: 250px;
  126.       height: auto;
  127.       flex-shrink: 0;
  128.       overflow: hidden;
  129.     }
  130.    
  131.     .widget h2 {
  132.       text-align: center;
  133.       margin: 0 0 10px 0;
  134.       font-size: 16px;
  135.       color: white;
  136.       padding: 5px 0;
  137.     }
  138.    
  139.     .widget-rele h2 {
  140.       text-align: center;
  141.       margin: 0 0 10px 0;
  142.       font-size: 16px;
  143.       color: white;
  144.       padding: 5px 0;
  145.     }
  146.    
  147.     .widget-row {
  148.       display: flex;
  149.       justify-content: space-between;
  150.       padding: 8px 0;
  151.       border-bottom: 1px solid #444;
  152.     }
  153.    
  154.     .widget-row:last-child {
  155.       border-bottom: none;
  156.     }
  157.    
  158.     .widget-row span:first-child {
  159.       font-weight: bold;
  160.     }
  161.    
  162.    .status {
  163.      text-align: center;
  164.      color: white;
  165.      font-size: 14px;
  166.      margin-bottom: 20px;
  167.      padding: 10px;
  168.      background: transparent;
  169.      border-radius: 5px;
  170.      max-width: 200px;
  171.      margin-left: auto;
  172.      margin-right: auto;
  173.     }
  174.    
  175.     .status.connected {
  176.        background: transparent;
  177.        color: white;
  178.     }
  179.    
  180.     .status.error {
  181.       background: transparent;
  182.       color: white;
  183.      }
  184.    
  185.     .rele-row {
  186.       display: flex;
  187.       justify-content: space-between;
  188.       align-items: center;
  189.       padding: 6px 0;
  190.       border-bottom: 1px solid #374151;
  191.     }
  192.    
  193.     .rele-row:last-child {
  194.       border-bottom: none;
  195.     }
  196.    
  197.     .rele-row span {
  198.       display: flex;
  199.       align-items: center;
  200.       font-size: 13px;
  201.     }
  202.    
  203.     .image-switch {
  204.       cursor: pointer;
  205.       width: 50px;
  206.       height: auto;
  207.       vertical-align: middle;
  208.       transition: transform 0.1s;
  209.     }
  210.    
  211.     .image-switch:active {
  212.       transform: scale(0.95);
  213.     }
  214.    
  215.     .image-switch.disabled {
  216.       opacity: 0.5;
  217.       cursor: wait;
  218.     }
  219.    
  220.     .power-header {
  221.       display: flex;
  222.       align-items: center;
  223.       justify-content: space-between;
  224.       padding: 15px;
  225.       background: #1e293b;
  226.       border-bottom: none;
  227.     }
  228.    
  229.     .power-device-info {
  230.       display: flex;
  231.       align-items: center;
  232.       gap: 8px;
  233.       flex: 1;
  234.       min-width: 0;
  235.     }
  236.    
  237.     .power-device-icon {
  238.       width: 28px;
  239.       height: 28px;
  240.       background: #e8e8e8;
  241.       border-radius: 6px;
  242.       display: flex;
  243.       align-items: center;
  244.       justify-content: center;
  245.       font-size: 16px;
  246.       flex-shrink: 0;
  247.     }
  248.    
  249.     .power-device-name {
  250.       color: #ffffff;
  251.       font-size: 16px;
  252.       font-weight: bold;
  253.       overflow: hidden;
  254.       text-overflow: ellipsis;
  255.       white-space: nowrap;
  256.       text-align: center;
  257.       width: 100%;
  258.     }
  259.    
  260.     .power-metrics {
  261.       padding: 0;
  262.       background: #1e293b;
  263.     }
  264.    
  265.     .power-metric-row {
  266.       display: flex;
  267.       align-items: center;
  268.       justify-content: space-between;
  269.       padding: 5px 15px;
  270.       border-bottom: none;
  271.       transition: background 0.15s ease;
  272.     }
  273.    
  274.     .power-metric-row:hover {
  275.       background: #2d3e52;
  276.     }
  277.    
  278.     .power-metric-label {
  279.       display: flex;
  280.       align-items: center;
  281.       gap: 8px;
  282.       color: #e2e8f0;
  283.       font-size: 13px;
  284.       font-weight: 400;
  285.     }
  286.    
  287.     .power-metric-label span {
  288.       color: #e2e8f0;
  289.     }
  290.    
  291.     .power-metric-icon {
  292.       font-size: 16px;
  293.       width: 20px;
  294.       text-align: center;
  295.     }
  296.    
  297.     .power-metric-value {
  298.       display: flex;
  299.       align-items: baseline;
  300.       gap: 3px;
  301.       color: #ffffff;
  302.       font-size: 15px;
  303.       font-weight: 500;
  304.     }
  305.    
  306.     .power-metric-unit {
  307.       color: #e2e8f0;
  308.       font-size: 12px;
  309.       font-weight: 400;
  310.     }
  311.    
  312.     .icon-state { color: #f4d03f; }
  313.     .icon-power { color: #5fb878; }
  314.     .icon-current { color: #ff9f43; }
  315.     .icon-voltage { color: #5eb3f6; }
  316.     .icon-energy { color: #26c6da; }
  317.    
  318.     @media (max-width: 768px) {
  319.       .teplomery-container,
  320.       .rele-container,
  321.       .power-container {
  322.         flex-direction: column;
  323.         align-items: center;
  324.       }
  325.      
  326.       .widget, .widget-rele, .widget-power {
  327.         width: 100%;
  328.         max-width: 300px;
  329.       }
  330.     }
  331.   </style>
  332. </head>
  333. <body>
  334.  
  335.  
  336.   <div class="dashboard">
  337.     <h1 class="dashboard-title">🏠 Domácí Dashboard</h1>
  338.    
  339.     <div id="status" class="status">Načítám data...</div>
  340.    
  341.     <!-- TEPLOMĚRY -->
  342.     <div class="teplomery-container">
  343.  
  344. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  345. <!------------- teploměry sklep --------------------------------------------------------------------------------------------------------------------->
  346. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  347.      
  348.       <div class="widget">
  349.         <h2>Teploměry sklep</h2>
  350.         <div class="widget-row">
  351.           <span>🔥 Kotel:</span>
  352.           <span id="temp_kotel">-- °C</span>
  353.         </div>
  354.         <div class="widget-row">
  355.           <span>💧 Voda:</span>
  356.           <span id="temp_voda">-- °C</span>
  357.         </div>
  358.       </div>
  359.  <!-------------------------------------------------------------------------------------------------------------------------------------------------->
  360. <!------------- teploměr venku ---------------------------------------------------------------------------------------------------------------------->
  361. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  362.      
  363.       <div class="widget">
  364.         <h2>Teploměr venku</h2>
  365.         <div class="widget-row">
  366.           <span>🌡️ Teplota:</span>
  367.           <span id="temp_venku">-- °C</span>
  368.         </div>
  369.         <div class="widget-row">
  370.           <span>💧 Vlhkost:</span>
  371.           <span id="hum_venku">-- %</span>
  372.         </div>
  373.       </div>
  374. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  375. <!------------- teploměry zahrada ------------------------------------------------------------------------------------------------------------------->
  376. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  377.      
  378.       <div class="widget">
  379.         <h2>Teploměr zahrada</h2>
  380.         <div class="widget-row">
  381.           <span>🌡️ Teplota:</span>
  382.           <span id="temp_zahrada">-- °C</span>
  383.         </div>
  384.         <div class="widget-row">
  385.           <span>💧 Vlhkost:</span>
  386.           <span id="hum_zahrada">-- %</span>
  387.         </div>
  388.       </div>
  389.  <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  390. <!------------- teploměry koupelna ------------------------------------------------------------------------------------------------------------------->
  391. <!---------------------------------------------------------------------------------------------------------------------------------------------------->
  392.      
  393.       <div class="widget">
  394.         <h2>Teploměr koupelna</h2>
  395.         <div class="widget-row">
  396.           <span>🌡️ Teplota:</span>
  397.           <span id="temp_koupelna">-- °C</span>
  398.         </div>
  399.         <div class="widget-row">
  400.           <span>💧 Vlhkost:</span>
  401.           <span id="hum_koupelna">-- %</span>
  402.         </div>
  403.       </div>
  404. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  405. <!------------- teploměry loznice ------------------------------------------------------------------------------------------------------------------->
  406. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  407.    
  408.       <div class="widget">
  409.         <h2>Teploměr ložnice</h2>
  410.         <div class="widget-row">
  411.           <span>🌡️ Teplota:</span>
  412.           <span id="temp1">-- °C</span>
  413.         </div>
  414.         <div class="widget-row">
  415.           <span>💧 Vlhkost:</span>
  416.           <span id="hum1">-- %</span>
  417.         </div>
  418.       </div>
  419. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  420. <!------------- teploměry pokoj --------------------------------------------------------------------------------------------------------------------->
  421. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  422.      
  423.       <div class="widget">
  424.         <h2>Teploměr pokoj</h2>
  425.         <div class="widget-row">
  426.           <span>🌡️ Teplota:</span>
  427.           <span id="temp2">-- °C</span>
  428.         </div>
  429.         <div class="widget-row">
  430.           <span>💧 Vlhkost:</span>
  431.           <span id="hum2">-- %</span>
  432.         </div>
  433.       </div>
  434.  <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  435. <!------------- teploměry obyvak --------------------------------------------------------------------------------------------------------------------->
  436. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  437.      
  438.       <div class="widget">
  439.         <h2>Teploměr obývák</h2>
  440.         <div class="widget-row">
  441.           <span>🌡️ Teplota:</span>
  442.           <span id="temp3">-- °C</span>
  443.         </div>
  444.         <div class="widget-row">
  445.           <span>💧 Vlhkost:</span>
  446.           <span id="hum3">-- %</span>
  447.         </div>
  448.       </div>
  449.      
  450.     </div>
  451. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  452. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  453. <!------------- rele -------------------------------------------------------------------------------------------------------------------------------->
  454. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  455. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  456.  
  457.     <!-- RELÉ -->
  458.     <div class="rele-container">
  459. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  460. <!------------- rele světla ------------------------------------------------------------------------------------------------------------------------->
  461. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  462.      
  463.       <!-- Světla -->
  464.       <div class="widget-rele">
  465.         <h2>Relé světla</h2>
  466.        
  467.         <div class="rele-row">
  468.           <span>⭐ Kanál L1</span>
  469.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_l1" data-state="OFF" data-rele="svetla" data-kanal="l1">
  470.         </div>
  471.        
  472.         <div class="rele-row">
  473.           <span>⭐ Kanál L2</span>
  474.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_l2" data-state="OFF" data-rele="svetla" data-kanal="l2">
  475.         </div>
  476.        
  477.         <div class="rele-row">
  478.           <span>⭐ Kanál L3</span>
  479.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_l3" data-state="OFF" data-rele="svetla" data-kanal="l3">
  480.         </div>
  481.        
  482.         <div class="rele-row">
  483.           <span>⭐ Kanál L4</span>
  484.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_l4" data-state="OFF" data-rele="svetla" data-kanal="l4">
  485.         </div>
  486.       </div>
  487. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  488. <!------------- rele půda --------------------------------------------------------------------------------------------------------------------------->
  489. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  490.  
  491.       <!-- Půda -->
  492.       <div class="widget-rele">
  493.         <h2>Relé půda</h2>
  494.        
  495.         <div class="rele-row">
  496.           <span>⭐ Kanál L1</span>
  497.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_puda_l1" data-state="OFF" data-rele="puda" data-kanal="l1">
  498.         </div>
  499.        
  500.         <div class="rele-row">
  501.           <span>⭐ Kanál L2</span>
  502.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_puda_l2" data-state="OFF" data-rele="puda" data-kanal="l2">
  503.         </div>
  504.        
  505.         <div class="rele-row">
  506.           <span>⭐ Kanál L3</span>
  507.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_puda_l3" data-state="OFF" data-rele="puda" data-kanal="l3">
  508.         </div>
  509.        
  510.         <div class="rele-row">
  511.           <span>⭐ Kanál L4</span>
  512.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_puda_l4" data-state="OFF" data-rele="puda" data-kanal="l4">
  513.         </div>
  514.       </div>
  515. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  516. <!------------- rele garáž -------------------------------------------------------------------------------------------------------------------------->
  517. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  518.  
  519.       <!-- Garáž -->
  520.       <div class="widget-rele">
  521.         <h2>Relé garáž</h2>
  522.        
  523.         <div class="rele-row">
  524.           <span>⭐ Kanál L1</span>
  525.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_garaz_l1" data-state="OFF" data-rele="garaz" data-kanal="l1">
  526.         </div>
  527.        
  528.         <div class="rele-row">
  529.           <span>⭐ Kanál L2</span>
  530.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_garaz_l2" data-state="OFF" data-rele="garaz" data-kanal="l2">
  531.         </div>
  532.        
  533.         <div class="rele-row">
  534.           <span>⭐ Kanál L3</span>
  535.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_garaz_l3" data-state="OFF" data-rele="garaz" data-kanal="l3">
  536.         </div>
  537.        
  538.         <div class="rele-row">
  539.           <span>⭐ Kanál L4</span>
  540.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_garaz_l4" data-state="OFF" data-rele="garaz" data-kanal="l4">
  541.         </div>
  542.       </div>
  543. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  544. <!------------- rele dveře pravé -------------------------------------------------------------------------------------------------------------------->
  545. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  546.  
  547.       <!-- Dveře pravé -->
  548.       <div class="widget-rele">
  549.         <h2>Relé dveře P</h2>
  550.        
  551.         <div class="rele-row">
  552.           <span>⭐ Kanál L1</span>
  553.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_p_l1" data-state="OFF" data-rele="dvere_p" data-kanal="l1">
  554.         </div>
  555.        
  556.         <div class="rele-row">
  557.           <span>⭐ Kanál L2</span>
  558.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_p_l2" data-state="OFF" data-rele="dvere_p" data-kanal="l2">
  559.         </div>
  560.        
  561.         <div class="rele-row">
  562.           <span>⭐ Kanál L3</span>
  563.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_p_l3" data-state="OFF" data-rele="dvere_p" data-kanal="l3">
  564.         </div>
  565.        
  566.         <div class="rele-row">
  567.           <span>⭐ Kanál L4</span>
  568.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_p_l4" data-state="OFF" data-rele="dvere_p" data-kanal="l4">
  569.         </div>
  570.       </div>
  571. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  572. <!------------- rele dveře levé --------------------------------------------------------------------------------------------------------------------->
  573. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  574.  
  575.       <!-- Dveře levé -->
  576.       <div class="widget-rele">
  577.         <h2>Relé dveře L</h2>
  578.        
  579.         <div class="rele-row">
  580.           <span>⭐ Kanál L1</span>
  581.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_l_l1" data-state="OFF" data-rele="dvere_l" data-kanal="l1">
  582.         </div>
  583.        
  584.         <div class="rele-row">
  585.           <span>⭐ Kanál L2</span>
  586.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_l_l2" data-state="OFF" data-rele="dvere_l" data-kanal="l2">
  587.         </div>
  588.        
  589.         <div class="rele-row">
  590.           <span>⭐ Reprak AirAux</span>
  591.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_l_l3" data-state="OFF" data-rele="dvere_l" data-kanal="l3">
  592.         </div>
  593.        
  594.         <div class="rele-row">
  595.           <span>⭐ Kanál L4</span>
  596.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_dvere_l_l4" data-state="OFF" data-rele="dvere_l" data-kanal="l4">
  597.         </div>
  598.       </div>
  599. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  600. <!------------- rele venku před dveřmi -------------------------------------------------------------------------------------------------------------->
  601. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  602.  
  603.       <!-- Venku před dveřmi -->
  604.       <div class="widget-rele">
  605.         <h2>Relé venku</h2>
  606.        
  607.         <div class="rele-row">
  608.           <span>⭐ Kamera Hiseeu</span>
  609.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_venku_l1" data-state="OFF" data-rele="venku" data-kanal="l1">
  610.         </div>
  611.        
  612.         <div class="rele-row">
  613.           <span>⭐ Kanál L2</span>
  614.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_venku_l2" data-state="OFF" data-rele="venku" data-kanal="l2">
  615.         </div>
  616.        
  617.         <div class="rele-row">
  618.           <span>⭐ TP-Link router</span>
  619.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_venku_l3" data-state="OFF" data-rele="venku" data-kanal="l3">
  620.         </div>
  621.        
  622.         <div class="rele-row">
  623.           <span>⭐ Kanál L4</span>
  624.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="state_venku_l4" data-state="OFF" data-rele="venku" data-kanal="l4">
  625.         </div>
  626.       </div>
  627. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  628. <!------------- rele Slepice ------------------------------------------------------------------------------------------------------------------------>
  629. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  630.  
  631.       <!-- Slepice -->
  632.       <div class="widget-rele">
  633.         <h2>Relé slepice</h2>
  634.        
  635.         <div class="rele-row">
  636.           <span>⭐ Kamera</span>
  637.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="rele_slepice_l1" data-state="OFF" data-rele="slepice" data-kanal="l1">
  638.         </div>
  639.        
  640.         <div class="rele-row">
  641.           <span>⭐ Kanál L2</span>
  642.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="rele_slepice_l2" data-state="OFF" data-rele="slepice" data-kanal="l2">
  643.         </div>
  644.        
  645.         <div class="rele-row">
  646.           <span>⭐ Kanál L3</span>
  647.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="rele_slepice_l3" data-state="OFF" data-rele="slepice" data-kanal="l3">
  648.         </div>
  649.        
  650.         <div class="rele-row">
  651.           <span>⭐ Kanál L4</span>
  652.           <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="rele_slepice_l4" data-state="OFF" data-rele="slepice" data-kanal="l4">
  653.         </div>
  654.       </div>
  655. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  656. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  657. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  658.    
  659.     </div>
  660.  
  661. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  662. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  663. <!------------- Power Monitoring -------------------------------------------------------------------------------------------------------------------->
  664. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  665. <!--------------------------------------------------------------------------------------------------------------------------------------------------->
  666.    
  667.     <!-- POWER MONITORING -->
  668.     <div class="power-container">
  669.      
  670.       <!-- Zásuvka sekačka -->
  671.       <div class="widget-power">
  672.         <div class="power-header">
  673.           <div class="power-device-info">
  674.             <div class="power-device-name">Zásuvka sekačka</div>
  675.           </div>
  676.         </div>
  677.        
  678.         <div class="power-metrics">
  679.           <div class="power-metric-row">
  680.             <div class="power-metric-label">
  681.               <span class="power-metric-icon icon-state"></span>
  682.               <span>Stav</span>
  683.             </div>
  684.             <img src="Switch_off.png" alt="Switch OFF" class="image-switch" id="zasuvka_sekacka_switch" data-state="OFF" data-rele="zasuvka_sekacka" data-kanal="dummy">
  685.           </div>
  686.          
  687.           <div class="power-metric-row">
  688.             <div class="power-metric-label">
  689.               <span class="power-metric-icon icon-power">🔋</span>
  690.               <span>Napájení</span>
  691.             </div>
  692.             <div class="power-metric-value">
  693.               <span id="power_napajeni">0</span>
  694.               <span class="power-metric-unit">W</span>
  695.             </div>
  696.           </div>
  697.          
  698.           <div class="power-metric-row">
  699.             <div class="power-metric-label">
  700.               <span class="power-metric-icon icon-current">🟡</span>
  701.               <span>Aktuální</span>
  702.             </div>
  703.             <div class="power-metric-value">
  704.               <span id="power_aktualni">0.00</span>
  705.               <span class="power-metric-unit">A</span>
  706.             </div>
  707.           </div>
  708.          
  709.           <div class="power-metric-row">
  710.             <div class="power-metric-label">
  711.               <span class="power-metric-icon icon-voltage"></span>
  712.               <span>Napětí</span>
  713.             </div>
  714.             <div class="power-metric-value">
  715.               <span id="power_napeti">0</span>
  716.               <span class="power-metric-unit">V</span>
  717.             </div>
  718.           </div>
  719.          
  720.           <div class="power-metric-row">
  721.             <div class="power-metric-label">
  722.               <span class="power-metric-icon icon-energy">🔌</span>
  723.               <span>Energie</span>
  724.             </div>
  725.             <div class="power-metric-value">
  726.               <span id="power_energie">0.00</span>
  727.               <span class="power-metric-unit">kWh</span>
  728.             </div>
  729.           </div>
  730.         </div>
  731.       </div>
  732.      
  733.     </div>
  734.   </div>
  735.  
  736.  
  737. <script>
  738. // KONFIGURAČNÍ PROMĚNNÉ
  739. // =====================
  740. const API_URL = "http://192.168.1.5:1880/api/teplomery";
  741. const REFRESH_INTERVAL = 1000;
  742. const SWITCH_OFF_IMG = "Switch_off.png";
  743. const SWITCH_ON_IMG = "Switch_on.png";
  744.  
  745. let lastClickTime = 0;
  746.  
  747. /**
  748.  * HLAVNÍ FUNKCE PRO NAČÍTÁNÍ DAT
  749.  */
  750. async function nacistData() {
  751.   try {
  752.     const now = Date.now();
  753.     if (now - lastClickTime < 500) {
  754.       return;
  755.     }
  756.    
  757.     const response = await fetch(API_URL);
  758.    
  759.     if (!response.ok) {
  760.       throw new Error("Chyba při načítání dat");
  761.     }
  762.    
  763.     const data = await response.json();
  764.  
  765. //------------------------------------------------------------------------------------------------------      
  766. //----- AKTUALIZACE TEPLOMĚRŮ --------------------------------------------------------------------------
  767. //------------------------------------------------------------------------------------------------------
  768.  
  769.     // Teploměry ve sklepě
  770.     if (data.sklep) {
  771.       if (data.sklep.kotel !== null) {
  772.         document.getElementById("temp_kotel").innerText = data.sklep.kotel.toFixed(1) + " °C";
  773.       } else {
  774.         document.getElementById("temp_kotel").innerText = "-- °C";
  775.       }
  776.      
  777.       if (data.sklep.voda !== null) {
  778.         document.getElementById("temp_voda").innerText = data.sklep.voda.toFixed(1) + " °C";
  779.       } else {
  780.         document.getElementById("temp_voda").innerText = "-- °C";
  781.       }
  782.     } else {
  783.       document.getElementById("temp_kotel").innerText = "-- °C";
  784.       document.getElementById("temp_voda").innerText = "-- °C";
  785.     }
  786.    
  787.     // Venkovní teploměr
  788.     if (data.venku && data.venku.temperature !== null) {
  789.       document.getElementById("temp_venku").innerText = data.venku.temperature.toFixed(1) + " °C";
  790.       document.getElementById("hum_venku").innerText = data.venku.humidity.toFixed(1) + " %";
  791.     } else {
  792.       document.getElementById("temp_venku").innerText = "-- °C";
  793.       document.getElementById("hum_venku").innerText = "-- %";
  794.     }
  795.    
  796.     // Teploměr zahrada
  797.     if (data.teplomer_zahrada && data.teplomer_zahrada.temperature !== null) {
  798.       document.getElementById("temp_zahrada").innerText = data.teplomer_zahrada.temperature.toFixed(1) + " °C";
  799.       document.getElementById("hum_zahrada").innerText = data.teplomer_zahrada.humidity.toFixed(1) + " %";
  800.     } else {
  801.       document.getElementById("temp_zahrada").innerText = "-- °C";
  802.       document.getElementById("hum_zahrada").innerText = "-- %";
  803.     }
  804.    
  805.     // Teploměr koupelna
  806.     if (data.koupelna && data.koupelna.temperature !== null) {
  807.       document.getElementById("temp_koupelna").innerText = data.koupelna.temperature.toFixed(1) + " °C";
  808.       document.getElementById("hum_koupelna").innerText = data.koupelna.humidity.toFixed(1) + " %";
  809.     } else {
  810.       document.getElementById("temp_koupelna").innerText = "-- °C";
  811.       document.getElementById("hum_koupelna").innerText = "-- %";
  812.     }
  813.    
  814.     // Teploměr ložnice
  815.     if (data.loznice && data.loznice.temperature !== null) {
  816.       document.getElementById("temp1").innerText = data.loznice.temperature.toFixed(1) + " °C";
  817.       document.getElementById("hum1").innerText = data.loznice.humidity.toFixed(1) + " %";
  818.     } else {
  819.       document.getElementById("temp1").innerText = "-- °C";
  820.       document.getElementById("hum1").innerText = "-- %";
  821.     }
  822.    
  823.     // Teploměr pokoj
  824.     if (data.pokoj && data.pokoj.temperature !== null) {
  825.       document.getElementById("temp2").innerText = data.pokoj.temperature.toFixed(1) + " °C";
  826.       document.getElementById("hum2").innerText = data.pokoj.humidity.toFixed(1) + " %";
  827.     } else {
  828.       document.getElementById("temp2").innerText = "-- °C";
  829.       document.getElementById("hum2").innerText = "-- %";
  830.     }
  831.    
  832.     // Teploměr obývák
  833.     if (data.obyvak && data.obyvak.temperature !== null) {
  834.       document.getElementById("temp3").innerText = data.obyvak.temperature.toFixed(1) + " °C";
  835.       document.getElementById("hum3").innerText = data.obyvak.humidity.toFixed(1) + " %";
  836.     } else {
  837.       document.getElementById("temp3").innerText = "-- °C";
  838.       document.getElementById("hum3").innerText = "-- %";
  839.     }
  840.  
  841. //------------------------------------------------------------------------------------------------------      
  842. //----- AKTUALIZACE STAVU RELÉ -------------------------------------------------------------------------
  843. //------------------------------------------------------------------------------------------------------
  844.  
  845.     if (data.rele) {
  846.       const updateSwitchImage = (elementId, newState) => {
  847.         const imgElement = document.getElementById(elementId);
  848.         if (imgElement) {
  849.           const isON = newState === "ON";
  850.           imgElement.src = isON ? SWITCH_ON_IMG : SWITCH_OFF_IMG;
  851.           imgElement.alt = isON ? "Switch ON" : "Switch OFF";
  852.           imgElement.dataset.state = newState;
  853.         }
  854.       };
  855.      
  856.       // Světla
  857.       updateSwitchImage("state_l1", data.rele.state_l1);
  858.       updateSwitchImage("state_l2", data.rele.state_l2);
  859.       updateSwitchImage("state_l3", data.rele.state_l3);
  860.       updateSwitchImage("state_l4", data.rele.state_l4);
  861.      
  862.       // Půda
  863.       updateSwitchImage("state_puda_l1", data.rele.state_puda_l1);
  864.       updateSwitchImage("state_puda_l2", data.rele.state_puda_l2);
  865.       updateSwitchImage("state_puda_l3", data.rele.state_puda_l3);
  866.       updateSwitchImage("state_puda_l4", data.rele.state_puda_l4);
  867.      
  868.       // Garáž
  869.       updateSwitchImage("state_garaz_l1", data.rele.state_garaz_l1);
  870.       updateSwitchImage("state_garaz_l2", data.rele.state_garaz_l2);
  871.       updateSwitchImage("state_garaz_l3", data.rele.state_garaz_l3);
  872.       updateSwitchImage("state_garaz_l4", data.rele.state_garaz_l4);
  873.      
  874.       // Dveře pravé
  875.       updateSwitchImage("state_dvere_p_l1", data.rele.state_dvere_p_l1);
  876.       updateSwitchImage("state_dvere_p_l2", data.rele.state_dvere_p_l2);
  877.       updateSwitchImage("state_dvere_p_l3", data.rele.state_dvere_p_l3);
  878.       updateSwitchImage("state_dvere_p_l4", data.rele.state_dvere_p_l4);
  879.      
  880.       // Dveře levé
  881.       updateSwitchImage("state_dvere_l_l1", data.rele.state_dvere_l_l1);
  882.       updateSwitchImage("state_dvere_l_l2", data.rele.state_dvere_l_l2);
  883.       updateSwitchImage("state_dvere_l_l3", data.rele.state_dvere_l_l3);
  884.       updateSwitchImage("state_dvere_l_l4", data.rele.state_dvere_l_l4);
  885.      
  886.       // Venku
  887.       updateSwitchImage("state_venku_l1", data.rele.state_venku_l1);
  888.       updateSwitchImage("state_venku_l2", data.rele.state_venku_l2);
  889.       updateSwitchImage("state_venku_l3", data.rele.state_venku_l3);
  890.       updateSwitchImage("state_venku_l4", data.rele.state_venku_l4);
  891.      
  892.       // Slepice
  893.       updateSwitchImage("rele_slepice_l1", data.rele.rele_slepice_l1);
  894.       updateSwitchImage("rele_slepice_l2", data.rele.rele_slepice_l2);
  895.       updateSwitchImage("rele_slepice_l3", data.rele.rele_slepice_l3);
  896.       updateSwitchImage("rele_slepice_l4", data.rele.rele_slepice_l4);
  897.     }
  898.  
  899. //------------------------------------------------------------------------------------------------------
  900. //----- AKTUALIZACE ZÁSUVKY SEKAČKY -------------------------------------------------------------------
  901. //------------------------------------------------------------------------------------------------------
  902.  
  903.     if (data.zasuvka_sekacka) {
  904.       // Aktualizace přepínače
  905.       const imgElement = document.getElementById("zasuvka_sekacka_switch");
  906.       if (imgElement) {
  907.         const isON = data.zasuvka_sekacka.state === "ON";
  908.         imgElement.src = isON ? SWITCH_ON_IMG : SWITCH_OFF_IMG;
  909.         imgElement.alt = isON ? "Switch ON" : "Switch OFF";
  910.         imgElement.dataset.state = data.zasuvka_sekacka.state;
  911.       }
  912.      
  913.       // Aktualizace hodnot
  914.       document.getElementById("power_napajeni").innerText = data.zasuvka_sekacka.power || 0;
  915.       document.getElementById("power_aktualni").innerText = (data.zasuvka_sekacka.current || 0).toFixed(2);
  916.       document.getElementById("power_napeti").innerText = data.zasuvka_sekacka.voltage || 0;
  917.       document.getElementById("power_energie").innerText = (data.zasuvka_sekacka.energy || 0).toFixed(2);
  918.     }
  919.    
  920.     // Aktualizace stavového řádku
  921.     const statusElement = document.getElementById("status");
  922.     statusElement.innerText = "✓ Připojeno - " + new Date().toLocaleTimeString();
  923.     statusElement.className = "status connected";
  924.    
  925.   } catch (error) {
  926.     console.error("Chyba:", error);
  927.     const statusElement = document.getElementById("status");
  928.     statusElement.innerText = "✗ Chyba připojení";
  929.     statusElement.className = "status error";
  930.   }
  931. }
  932.  
  933. /**
  934.  * FUNKCE PRO OVLÁDÁNÍ RELÉ
  935.  */
  936. async function ovladatRele(imgElement) {
  937.   const rele = imgElement.dataset.rele;
  938.   const kanal = imgElement.dataset.kanal;
  939.   const currentState = imgElement.dataset.state;
  940.   const newState = currentState === "ON" ? "OFF" : "ON";
  941.  
  942.   imgElement.classList.add('disabled');
  943.  
  944.   try {
  945.     lastClickTime = Date.now();
  946.    
  947.     const statusElement = document.getElementById("status");
  948.     statusElement.innerText = `Přepínám ${rele}...`;
  949.     statusElement.className = "status";
  950.    
  951.     const response = await fetch(`?rele=${rele}&kanal=${kanal}&stav=${newState.toLowerCase()}`);
  952.    
  953.     if (!response.ok) {
  954.       throw new Error("Chyba při ovládání");
  955.     }
  956.    
  957.     const result = await response.json();
  958.    
  959.     if (result.success) {
  960.       imgElement.src = newState === "ON" ? SWITCH_ON_IMG : SWITCH_OFF_IMG;
  961.       imgElement.alt = newState === "ON" ? "Switch ON" : "Switch OFF";
  962.       imgElement.dataset.state = newState;
  963.      
  964.       statusElement.innerText = `✓ ${rele} přepnuto na ${newState}`;
  965.       statusElement.className = "status connected";
  966.     } else {
  967.       throw new Error("Přepnutí selhalo");
  968.     }
  969.    
  970.     setTimeout(() => {
  971.       lastClickTime = 0;
  972.       nacistData();
  973.     }, 200);
  974.    
  975.   } catch (error) {
  976.     console.error("Chyba:", error);
  977.     const statusElement = document.getElementById("status");
  978.     statusElement.innerText = "✗ Chyba při přepínání";
  979.     statusElement.className = "status error";
  980.    
  981.     imgElement.src = currentState === "ON" ? SWITCH_ON_IMG : SWITCH_OFF_IMG;
  982.     imgElement.dataset.state = currentState;
  983.     lastClickTime = 0;
  984.   } finally {
  985.     imgElement.classList.remove('disabled');
  986.   }
  987. }
  988.  
  989. // INICIALIZACE DASHBOARDU
  990.   document.querySelectorAll('.image-switch').forEach(img => {
  991.    img.addEventListener('click', function() {
  992.     ovladatRele(this);
  993.   });
  994. });
  995.  
  996.   nacistData();
  997.   setInterval(nacistData, REFRESH_INTERVAL);
  998.  
  999.   console.log("Dashboard s 7 relé, 7 teploměrů a 1 zásuvkou spuštěn");
  1000. </script>
  1001.  
  1002. </body>
  1003. </html>
  1004.  
Advertisement
Add Comment
Please, Sign In to add comment