Witam,
Potrzebuję pomocy w skrypcie, który będzie pobierał dane co 5 minut z licznika wody (m3) i będzie wysyłał dane do wirtulanego licznika przepływu wody (l/min).
Poniżej co zdołałem zrobić, ale nie chce mi to poprawnie działać:
return
{
on =
{
timer = {'every 5 minutes'}
},
data =
{
poprzedniaWoda = { initial = {} }
},
execute = function(domoticz, sensor)
local obecnaWoda = domoticz.devices('Licznik wody') -- obecny stan licznika
local przeplyw = domoticz.devices('Przepływ wody')
przeplyw = (obecnaWoda - poprzedniaWoda)*200
domoticz.devices(182).updateWaterflow(przeplyw)
-- zapamietywanie ostatniego wskazania
domoticz.data.poprzedniaWoda = obecnaWoda
end
}
Wydaje mi się, że problem jest z prawidłowym pobraniem liczby z wirtualnego czujnika licznika wody, bo do licznika przepływu zwracana jest ciągle liczba 0.
Proszę o pomoc
@superprzemo ten skrypt się nie zacznie , ale po kolei
Polecam do każdego skryptu dodać sobie logi , to bardzo ułatwia pracę ze skryptem czyli początek skryptu
return
{
on =
{
timer = {'every 5 minutes'}
},
logging =
{
level = domoticz.LOG_DEBUG,
marker = 'Licznik wody',
},
Definicja funkcji u Ciebie wymusza wyzwalanie skryptu na podstawie urządzeń sensor, a oprócz timera nie zdeklarowałeś żadnego czujnika
więc albo
execute = function(domoticz, timer)
albo
execute = function(domoticz, item)
W dalszej matematyce nie pomogę bo nie znam typów i podtypów urządzeń na których ma to się wykonywać
Jak dodałem logowanie i zmieniłem sensor na item, to zwraca mi takie coś:
2021-01-06 12:30:00.167 Error: dzVents: Error: (3.0.2) Licznik wody: An error occurred when calling event handler Przepływ wody
2021-01-06 12:30:00.167 Error: dzVents: Error: (3.0.2) Licznik wody: ...icz/scripts/dzVents/generated_scripts/Przepływ wody.lua:23: attempt to perform arithmetic on a table value (local 'obecnaWoda'
Czy ja nie muszę zamienić zmiennej pobranej z licznika na zmienną, na której można przeprowadzać działania matematyczne?
Samo wysyłanie do wirtualnego czujnika chyba działa, bo jak zamiast zmiennej przeplyw w funkcji:
domoticz.devices('Przepływ wody').updateWaterflow(przeplyw)
wpiszę np '20', to wartość 20 zostaje wysłana do tego czujnika.
@superprzemo jak patrzę na twoje działanie matematyczne to nie rozumiem co chcesz obliczyć , inicjujesz stałą "data = nic czyli zawsze 0 i potem chcesz od wartości licznika odjąć to zero i pomnożyć przez 200 , w jakim celu ?
Najpierw chyba wypada zaktualizować data do wartości licznika a potem dopiero aktualizować czyli po aktualizacji data, gdy data = czujnik m3
nowy czujnik.updateWaterflow(matematyka * 200 )
Zacznijmy od początku.
Obecnie mam odczyt stanu licznika wody (ten sran jest odzczytywany z różną częstotliowścią.
Głównym założeniem jest odczytywanie przeływu wody (żeby móc zobaczyć w którym momencie jest najwięszke zużycie wody).
Teoretycznie sprawa jest prosta. Co 5 minut trzeba pobierać wartość ze stanu licznika (przechować tą wartość w pamięci) i odjąć ją od obecnej wartości licznika. Ponieważ odczyt jest co 5 minut, więc otrzymany wynik dzielę przez 5 i mnożę przez 1000 (bo licznik jest w m3), a przepływ przepływ jest w l/min.
Po odjęciu obecnego stanu od poprzedniego (w m3) i pomnożeniu przez 200 wychodzi obecny przepływ (w l/min).
Jak to naprościej zrobić?
@superprzemo trochę inaczej to widzę , ale pewnie efekt podobny
Masz dwie wersje , pierwsza aktywuje skrypt co minutę i zapisuje aktualny stan dziennego wskazania licznika m3 do "data" pomnożony przez factor, w Twoim wypadku pewnie 1000 , w skrypcie do testu ustawiony na 1 .
Potem te dane są porównywane z aktualnym stanem licznika dziennego i ponieważ ma to być w l/min obliczany jest przepływ .
Obliczenia są co minutę bo wskazania mają być litry / min
Dołożyłem opcję która kasuje licznik litrów gdy czujnik m3 nie wyśle nic przez 10 min
Druga wersja liczy na podstawie odczytów z czujnika , wyzwalaczem jest licznik m3
Test robiłem na wirtualnych czujnikach aktualizowanych przez json , bo nie mam u siebie liczników wody, więc nie daję gwarancji że wszystko będzie ok.
@isom dzięki za pomoc, wkleiłem skrypt w pierwszej wersji i teraz wyrzuca mi taki błąd:
2021-01-07 21:05:00.516 Error: dzVents: Error: (3.0.2) Licznik wody: An error occurred when calling event handler Przepływ wody
2021-01-07 21:05:00.517 Error: dzVents: Error: (3.0.2) Licznik wody: ...icz/scripts/dzVents/generated_scripts/Przepływ wody.lua:22: attempt to perform arithmetic on a nil value (field 'counterToday')
Odczyt danych z licznika wody jest nieregularny, dostosowany jest do godzin pracy inkasentów, w dzień stan wody (ramki z danymi) wysyłany jest co kilkanaście sekund, w nocy i weekendy co kilka-kilkanaście minut.
Założyłem przesył danych co 5 minut, ponieważ domoticz chyba zapisuje dane w takim odstępie czasu. Dla przykładu jeżeli odczyt byłby co 5 min a różnica miedzy wskazaniem wodomierza byłaby 323.324 m3 oraz 323.327 m3 czyli różnica to 0.003m3 przez 5 minut. Mnożąc 0.003 przez 200, otrzymuje się przepływ 0.6 l/min, co mnożąc przez 5 minut daje nam w sumie 3 litry.
@superprzemo nie wiem co ty masz za licznik w m3 , który nie zlicza dziennego zużycia , bo taki błąd jest u Ciebie
Moje urządzenia oczywiście tylko do testów
@isom właśnie zauważyłem że starsznie dużo zmiennych jest tych skryptach 😊
Ja mam licznik jako Custom Sensor odczytujący drogą radiową aktualny stan licznika wody nadawany przez nakładkę APATOR'a , zamieściłem opis jak to zrobić: https://www.smartnydom.pl/forum/domoticz/wmbus-odczyt-danych-z-wodomierza/
Czyli nie mam licznika inkrementalnego impulsowego, tylko odczytywana jest wartość z wodomierza.
Wiem jak wysłać stan (jakąś wartość) do licznika przepływu, tylko mam problem z pobraniem wartości z licznika wody w takim stanie żebym mógł na niej przeprowadzić proste zadanie arytmetyczne.
Czy jest jakaś funkcja zmieniająca ciąg znaków z czujnika na liczby?
@superprzemo spróbuj zdeklarować ten czujnik tak
local licznik=tonumber(dz.devices('Licznik wody').state)
wtedy operacje matematyczne będą możliwe na samych liczbach
@isom dzięki, właśnie o to chodziło, poniżej działający skrypt:
return
{
on =
{
timer = { 'every 5 minutes'}
},
data =
{
poprzedniaWoda = { initial = {}, },
},
logging = {
level = domoticz.LOG_DEBUG, -- zmien na domoticz.LOG_DEBUG, gdy skrypt bedzie Ok
-- marker = "Licznik wody"
},
execute = function(dz, item)
local przeplyw = dz.devices('Przepływ wody') -- nazwa wirtualnego licznika przepływu litry / min
local licznik=tonumber(dz.devices('Licznik wody').state) -- nazwa licznika wody m3
if dz.data.poprzedniaWoda ~= nil then -- pierwszy odczyt nie jest brany pod uwagę do obliczeń
przeplyw = (licznik - dz.data.poprzedniaWoda) *200 -- obliczanie aktualnego przepływu
dz.devices('Przepływ wody').updateWaterflow(przeplyw) -- wysłanie obliczonego przepływu do wirtualnego przepływomierza
end
dz.data.poprzedniaWoda = licznik -- zapammiętanie odczytu z licznika wody
end
}
Poniżej wykres dobowy licznika przepływu:
Mogłeś od razu napisać, że to custom sensor :)) i proponuję zmianę logów z DEBUG na ERROR , to moje wina bo zle napisałem komentarz w pierwszym skrypcie , zmień na
level = domoticz.LOG_ERROR,
@superprzemo Probuje odpalic ten skrypt i bez rezultatu
Ciagle mam blad w logach