Baza wiedzy Sinum

Dodanie konfiguracji termostatów

  1. Konfiguracja termostatów będzie odbywać się prawdopodobnie bardzo rzadko, dlatego ustawianie takiej listy na głównym widoku urządzenia nie jest pożądane. Konfigurację ustawimy w widoku rozszerzonym urządzenia niestandardowego.

  2. W tym celu otwieramy edycję urządzenia i przechodzimy na zakładkę Widok rozszerzony.

  3. Dodajemy nową kolumnę w istniejącym wierszu.

  4. W kolumnie po lewej dodajemy element typu Tekst. W edycji elementu w polu Wartość wpisujemy:
    Wybrane termostaty

  5. W kolumnie po prawej dodajemy element typu Konfiguracja urządzeń.

  6. W edycji elementu uzupełniamy:

    • Nazwa elementu: thermostats_selector

    • Wybór wielu urządzeń: Tak

    • Dozwolone typy urządzeń: Termostat

  1. Następnie należy zmodyfikować fragmenty kodu, które sprawdzają wszystkie urządzenia wirtualne, i zastąpić je urządzeniami wybranymi w konfiguratorze.

  2. Na początek dodajemy funkcję pomocniczą, która pobierze wybrane termostaty. Funkcję należy dodać na początek kodu:

    -- pobranie listy termostatów wybranej w konfiguratorze urządzeń
    function CustomDevice:getThermostats()
       return self:getElement("thermostats_selector"):getValue("associations.selected")
    end
    
  3. Wszystkie miejsca w kodzie, gdzie używaliśmy:

       -- iterujemy wszystkie urządzenia wirtualne
       for _, dev in pairs(virtual) do

    możemy teraz zastąpić:

    -- iterujemy skonfigurowane termostaty
       for _, dev in pairs(self:getThermostats()) do
    
  4. Następnie należy usunąć warunek, który sprawdza typ urządzenia:

           -- sprawdzamy czy urządzenie jest termostatem
           if dev:getValue("type") == "thermostat" then
  5. Należy pamiętać, aby usunąć również kończące słowo kluczowe end, które w języku Lua zamyka blok warunkowy.

  6. Czyli z kodu:

     -- sprawdzamy czy urządzenie jest termostatem
           if dev:getValue("type") == "thermostat" then
    
    
               -- urządzenie jest termostatem, ustawiamy żądany tryb
               dev:call("set_mode", mode)
    
    
           end
    

    powinno zostać tylko:

    dev:call("set_mode", mode)
  7. Postępujemy analogicznie we wszystkich miejscach kodu, w których występują powyższe elementy.

  8. Zapisujemy konfigurację.

  9. Po zapisaniu konfiguracji kliknięcie w przycisk lub zmiana wartości na suwaku nie będzie miała wpływu na termostaty w Sinum, dopóki nie zostaną skonfigurowane.

  10. Aby wskazać, dla których termostatów urządzenie ma działać, otwieramy widok rozszerzony urządzenia, klikając w ikonę strzałek obok trzech kropek w prawym górnym rogu.

  11. Zostanie wyświetlone okno z dodanymi wcześniej elementami.

  12. Klikając na Wybierz urządzenia, możemy dodawać termostaty do naszego urządzenia wirtualnego. Aby dodać kolejne termostaty, klikamy w strzałkę po prawej stronie elementu.

  13. Po wybraniu termostatów, przyciski trybów oraz suwak zmiany temperatury będą obowiązywać tylko dla wybranych termostatów, nie wpływając na pozostałe.


Kod utworzonego urządzenia wirtualnego do sterowania termostatami:

-- pobranie listy termostatów wybranej w konfiguratorze urządzeń
function CustomDevice:getThermostats()
   return self:getElement("thermostats_selector"):getValue("associations.selected")
end

-- funkcja ustawia tryb podany w argumencie 'mode' dla każdego termostatu
function CustomDevice:setMode(mode)

   -- iterujemy skonfigurowane termostaty
   for _, dev in pairs(self:getThermostats()) do

           dev:call("set_mode", mode)

   end
end

-- callback dla przycisku Grzanie
function CustomDevice:onHeating (element)
   self:setMode("heating")
end

-- callback dla przycisku Chłodzenie
function CustomDevice:onCooling (element)
   self:setMode("cooling")
end

-- callback dla przycisku Wyłączenie
function CustomDevice:onThermostatsOff (element)
   self:setMode("off")
end

-- callback dla suwaka zadanej temperatury
-- w argumencie newValue znajduje się nowa wartość suwaka
function CustomDevice:onTargetChange (newValue, element)
   -- pobranie elementu tekstowego z wyświetlaną wartością nad suwakiem i przypisanie do zmiennej
   -- do pobrania używamy funkcji getElement do której podajemy nazwę elementu
   local textElement = self:getElement("target_temperature_text")

   -- ustawienie wartości w elemencie tekstowym, wykorzystana jest funkcja formatująca tekst na podstawie podanych argumentów
   -- w tym przypadku wartości liczbowej suwaka
   textElement:setValue("value", string.format("%.1f℃", newValue))

   -- iterujemy skonfigurowane termostaty
   for _, dev in pairs(self:getThermostats()) do

           -- temperatura zadana trzymana w termostacie to wartość w stopniach celsjusza x10
           -- dlatego wartość pobraną z suwaka musimy pomnożyć przez 10
           dev:setValue("target_temperature", newValue * 10)

   end
end

-- kod wykonywany przy każdej zmianie w Sinum
function CustomDevice:onEvent(event)
   -- sprawdzenie czy zmieniła się minuta, aktualizacja temperatur co minutę
   if dateTime:changed() or
   -- sprawdzenie czy zmienił się parametr urządzenia o nazwie temperature
       (event.type == "device_state_changed" and event.details == "temperature") then

       -- zadeklarujemy zmienne, w których zapiszemy sumę temperatur i liczbę termostatów
       local temperatureSum = 0
       local thermostatsCount = 0

       -- iterujemy wszystkie urządzenia wirtualne i sprawdzamy czy typ to termostat
       for _, dev in pairs(self:getThermostats()) do

               -- zwiększenie liczby termostatów w zmiennej
               thermostatsCount = thermostatsCount + 1

               -- pobranie temperatury z termostatu i dodanie do sumy w zmiennej
               temperatureSum = temperatureSum + dev:getValue("temperature")
       end
       -- jeśli jest co najmniej jeden termostat, aktualizujemy tekst obliczoną średnią
       if thermostatsCount > 0 then
           -- obliczamy średnią
           local average = temperatureSum / thermostatsCount
           -- wartości zapisane są w stopniach celsjusza x10, żeby poprawnie wyświetlić, dzielimy przez 10
           average = average / 10


           -- pobieramy element tekstu i aktualizujemy wartość tekstową
            self:getElement("average_temperature_text"):setValue("value", string.format("%.1f℃", average))
       end
   end
end