This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

scripting knx
#1
Good morning,

I'm having a problem with the functions and I don't know how to solve it.

Here's the problem:

I currently have three logic machines taking KNX data from temperature, humidity, and CO2 sensors. I need them to calculate the average temperature, CO2, and humidity. But I only want to calculate this for the sensors located in rented properties.

I have the following variables.


Rented or non-rented status of 27 dwellings in group addresses from 2/0/176 to 2/0/202:

- Rented = 1

- Non-rented = 0
Temperature values delivered by each dwelling sensor:

'0/0/11','0/0/27','0/0/43','0/0/59','0/0/75','0/0/91','0/0/107',

'0/0/123','0/0/139','0/0/155','0/0/171','0/0/187','0/0/203',

'0/0/219','0/0/235','0/0/251',

'0/1/11','0/1/27','0/1/43','0/1/59','0/1/75','0/1/91','0/1/107',

'0/1/123','0/1/139','0/1/155','0/1/171'

Variable where the average building temperature will be stored:

2/0/164

And now I'll show you the code I wrote:

Code:
-- Direcciones de estado de las 27 viviendas (0=libre, 1=alquilada, 2=mantenimiento, 3=ocupada)
local estados = {}
for i = 1, 27 do
    estados[i] = '2/0/' .. (175 + i)  -- 176 → 202
end

-- Direcciones de temperatura individuales
local direcciones_temp = {
    '0/0/11','0/0/27','0/0/43','0/0/59','0/0/75','0/0/91','0/0/107',
    '0/0/123','0/0/139','0/0/155','0/0/171','0/0/187','0/0/203',
    '0/0/219','0/0/235','0/0/251',
    '0/1/11','0/1/27','0/1/43','0/1/59','0/1/75','0/1/91','0/1/107',
    '0/1/123','0/1/139','0/1/155','0/1/171'
}

-- Dirección donde guardar la temperatura media
local destino1 = '2/0/164'

-- Rango válido de temperaturas
local min_temp = -20
local max_temp = 60

-- Intervalo de espera: 5 minutos (300 segundos)
local INTERVALO = 300


-- ============================================================
-- BUCLE PRINCIPAL (TU MISMO CÓDIGO, REPITIÉNDOSE PARA SIEMPRE)
-- ============================================================

while true do

    local suma = 0
    local contador = 0

    -- Recorrer las 27 viviendas
    for i = 1, 27 do
        local estado = grp.getvalue(estados[i])
        local valor = grp.getvalue(direcciones_temp[i])

        -- Solo usar temperatura si la vivienda está alquilada
        if estado == 1 then
            if valor ~= nil and type(valor) == "number" then
                if valor >= min_temp and valor <= max_temp then
                    suma = suma + valor
                    contador = contador + 1
                else
                    log("Temperatura fuera de rango en " .. direcciones_temp[i] .. ": " .. tostring(valor))
                end
            else
                log("Valor de temperatura inválido o nulo en " .. direcciones_temp[i])
            end
        end
    end

    -- Guardar la media si hay datos válidos
    if contador > 0 then
        local media = suma / contador
        grp.write(destino1, media)
        log("Temperatura media (solo alquilados) actualizada en " .. destino1 .. ": " .. media)
    else
        log("No hay viviendas alquiladas con temperatura válida para calcular la media")
    end

    -- Esperar 5 minutos antes de repetir
    os.sleep(INTERVALO)

end

Lo he intentado por todos los medios posibles y no me  calcula la temperatura media y cuando lo hace satura la memoria de la logic machine.
Reply
#2
What script type are you using? The correct approach is to use a scheduled script that runs every 5 minutes and remove the while loop and os.sleep at the end.

What is the data type of rented status object. Is it boolean or 1 byte?
Reply
#3
Buenas tardes,

Estaba ocupado con la construcción. Adjunto fotos del tipo de datos utilizado para los estados de las propiedades; es la versión 7.2.

En cuanto al script, se trata de un script basado en eventos.

Attached Files Thumbnail(s)
       
Reply
#4
It can't be an event script. Make a scheduled script as suggested earlier.
Reply
#5
I haven't tried yet to create scripts scheduled at specific times and dates; I'm worried that the code won't understand that it needs to update the average temperature every 5 or 10 minutes.
Reply
#6
(08.04.2026, 14:59)ALEJANDRO Wrote: I haven't tried yet to create scripts scheduled at specific times and dates; I'm worried that the code won't understand that it needs to update the average temperature every 5 or 10 minutes.

If you need to start script every 5 minutes then you can set '*/5' in minutes parameter
Reply
#7
Are you sure this is 5 minutes?

Attached Files Thumbnail(s)
   
Reply
#8
Yes, it is. But you need to remove the while loop from the code for it to works correctly. Check the Logs tabs, you will see 5 minutes between logs from this script.
Code:
local estados = {}
for i = 1, 27 do
    estados[i] = '2/0/' .. (175 + i)  -- 176 → 202
end

-- Direcciones de temperatura individuales
local direcciones_temp = {
    '0/0/11','0/0/27','0/0/43','0/0/59','0/0/75','0/0/91','0/0/107',
    '0/0/123','0/0/139','0/0/155','0/0/171','0/0/187','0/0/203',
    '0/0/219','0/0/235','0/0/251',
    '0/1/11','0/1/27','0/1/43','0/1/59','0/1/75','0/1/91','0/1/107',
    '0/1/123','0/1/139','0/1/155','0/1/171'
}

-- Dirección donde guardar la temperatura media
local destino1 = '2/0/164'

-- Rango válido de temperaturas
local min_temp = -20
local max_temp = 60

-- ============================================================
-- BUCLE PRINCIPAL (TU MISMO CÓDIGO, REPITIÉNDOSE PARA SIEMPRE)
-- ============================================================
local suma = 0
local contador = 0

-- Recorrer las 27 viviendas
for i = 1, 27 do
    local estado = grp.getvalue(estados[i])
    local valor = grp.getvalue(direcciones_temp[i])

    -- Solo usar temperatura si la vivienda está alquilada
    if estado == 1 then
        if valor ~= nil and type(valor) == "number" then
            if valor >= min_temp and valor <= max_temp then
                suma = suma + valor
                contador = contador + 1
            else
                log("Temperatura fuera de rango en " .. direcciones_temp[i] .. ": " .. tostring(valor))
            end
        else
            log("Valor de temperatura inválido o nulo en " .. direcciones_temp[i])
        end
    end
end

-- Guardar la media si hay datos válidos
if contador > 0 then
    local media = suma / contador
    grp.write(destino1, media)
    log("Temperatura media (solo alquilados) actualizada en " .. destino1 .. ": " .. media)
else
    log("No hay viviendas alquiladas con temperatura válida para calcular la media")
end
Reply
#9
Yes, of course

I realized about that, thanks
Reply
#10
Is it possible to create a resident script whose execution frequency is the value in hours of a group address called frequency_Test_Comms?
Reply
#11
Can you explain what task are you trying to solve? Most likely there is simpler solution.
------------------------------
Ctrl+F5
Reply
#12
Let me explain. I have a series of IP addresses that I need to check:
- Portal 1 IP: 192.168.0.11 on 32/3/14

- Portal 2 IP: 192.168.0.12 on 32/3/15

- Portal 3 IP: 192.168.0.13 on 32/3/16

- Garage IP: 192.168.0.16 on 32/3/17

If a ping is successful and there is communication, the idea is to set IP addresses 32/3/14, 15, 16, and 17 to 1.

If there is no communication after the ping, the idea is to trigger alarms stored on the following addresses by setting these addresses to 1:
- Portal 1_Alarm IP on 32/3/27

- Portal 2_Alarm IP on 32/3/28
-ip portal 3_Alarma on 32/3/29

-ip Garaje_Alarma on 32/3/30

This IP monitoring process depends on two variables:

frec_test_comms 32/3/40 = 1
Enable_Test_IP 32/3/41 = 1
Reply
#13
Well you can make os.delay(3600) 3600=1h but why do you want to make it configurable?
------------------------------
Ctrl+F5
Reply
#14
I'm being asked to do this in the project, I'll try to explain. The project tells me that the LMs (4 in total) and the gateways connected to each logic machine should have their IPs monitored based on whether an enabler variable, enable_test_ip = 1 and frec_test_comms = 1. enable_test_ip is boolean, frec_test_comms can be in a range from 1 hour to 23 hours.
Reply
#15
Create a scheduled script that runs once every hour.

Use the following settings:
Minute: 0
Hour: *
Day of the month: *
Month of the year: Every month of the year
Day of the week: Every day of the week

Add your test sequence to the end of this script:
Code:
test_enabled = grp.getvalue('32/3/41')
test_freq = grp.getvalue('32/3/40')

if not test_enabled then
  return
end

key = 'prev_test_time'

curr_time = os.time()
prev_time = storage.get(key, 0)
elapsed_hours = math.round((curr_time - prev_time) / 3600)

if elapsed_hours < test_freq then
  return
end

storage.set(key, curr_time)

-- perform test sequence
Reply


Forum Jump: