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 whether you accept or reject these cookies being set.

Resident script pump circulation
#41
Hi Admin,
I have not valveStates variable but I have valveStatesInverno and valveStatesEstate. Because I have 2 condition. But as per the loggin below valveStatesInverno change is value without changing group address 2/0/2.

Tesy_pompa_circolazione_mansarda 24.10.2018 14:49:48
* table:
[1]
* table:
[export]
* number: 0
[disablelog]
* number: 1
[tagcache]
* string: clima, pompa_circolazione_mansarda_inverno, pompa_circolazione_mansarda_estate
[datahex]
* string: 01
[units]
* string:
[value]
* bool: true
[comment]
* string:
[updatetime]
* number: 1540385348
[datatype]
* number: 1009
[address]
* string: 2/0/107
[id]
* number: 4203
[data]
* bool: true
[highpriolog]
* number: 0
[pollinterval]
* string:
[readoninit]
* number: 0
[name]
* string: T7 FB Elettrovalvola pavimento mansarda
[decoded]
* bool: true
Tesy_pompa_circolazione_mansarda 24.10.2018 14:49:48
* arg: 1
* bool: true
* arg: 2
* bool: true
* arg: 3
* number: 1540385388
* arg: 4
* number: 1540385348
Reply
#42
Try adding log to all checkwrite calls, like this:
Code:
if opened then
    fullyOpened = (os.microtime() - firstTimestamp) >= openingValveTime
    if fullyOpened then
        log(grp.checkwrite(pumpGA, true))
        nextCalculationAfter = minInterval
    else
        log(grp.checkwrite(pumpGA, false))
        nextCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
    end
else
    log(grp.checkwrite(pumpGA, false))
    nextCalculationAfter = openingValveTime + 1
end
Reply
#43
(24.10.2018, 13:42)admin Wrote: Try adding log to all checkwrite calls, like this:
Code:
if opened then
   fullyOpened = (os.microtime() - firstTimestamp) >= openingValveTime
   if fullyOpened then
       log(grp.checkwrite(pumpGA, true))
       nextCalculationAfter = minInterval
   else
       log(grp.checkwrite(pumpGA, false))
       nextCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
   end
else
   log(grp.checkwrite(pumpGA, false))
   nextCalculationAfter = openingValveTime + 1
end

Ok, here below. The log of checkwrite is done only the first time. Everything change but not the 2/0/2.

Thanks.



Tesy_pompa_circolazione_mansarda 24.10.2018 16:01:48
* arg: 1
 * nil
* arg: 2
 * string: same boolean value


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:01:48
* table:
[1]
 * table:
  [export]
   * number: 0
  [disablelog]
   * number: 1
  [tagcache]
   * string: clima, pompa_circolazione_mansarda_inverno, pompa_circolazione_mansarda_estate
  [datahex]
   * string: 00
  [units]
   * string:
  [value]
   * bool: false
  [comment]
   * string:
  [updatetime]
   * number: 1540389692
  [datatype]
   * number: 1009
  [address]
   * string: 2/0/107
  [id]
   * number: 4203
  [data]
   * bool: false
  [highpriolog]
   * number: 0
  [pollinterval]
   * string:
  [readoninit]
   * number: 0
  [name]
   * string: T7 FB Elettrovalvola pavimento mansarda
  [decoded]
   * bool: true
[/size]


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:01:48
* arg: 1
 * bool: true
* arg: 2
 * bool: false
* arg: 3
 * number: 1540389708
* arg: 4
 * number: 0
[/size]


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:03:29
* table:
[1]
 * table:
  [export]
   * number: 0
  [disablelog]
   * number: 1
  [tagcache]
   * string: clima, pompa_circolazione_mansarda_inverno, pompa_circolazione_mansarda_estate
  [datahex]
   * string: 01
  [units]
   * string:
  [value]
   * bool: true
  [comment]
   * string:
  [updatetime]
   * number: 1540389805
  [datatype]
   * number: 1009
  [address]
   * string: 2/0/107
  [id]
   * number: 4203
  [data]
   * bool: true
  [highpriolog]
   * number: 0
  [pollinterval]
   * string:
  [readoninit]
   * number: 0
  [name]
   * string: T7 FB Elettrovalvola pavimento mansarda
  [decoded]
   * bool: true
[/size]


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:03:29
* arg: 1
 * bool: true
* arg: 2
 * bool: true
* arg: 3
 * number: 1540389809
* arg: 4
 * number: 1540389805
[/size]
Reply
#44
(24.10.2018, 14:05)Domoticatorino Wrote:
(24.10.2018, 13:42)admin Wrote: Try adding log to all checkwrite calls, like this:
Code:
if opened then
   fullyOpened = (os.microtime() - firstTimestamp) >= openingValveTime
   if fullyOpened then
       log(grp.checkwrite(pumpGA, true))
       nextCalculationAfter = minInterval
   else
       log(grp.checkwrite(pumpGA, false))
       nextCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
   end
else
   log(grp.checkwrite(pumpGA, false))
   nextCalculationAfter = openingValveTime + 1
end

Ok, here below. The log of checkwrite is done only the first time. Everything change but not the 2/0/2.

Thanks.



Tesy_pompa_circolazione_mansarda 24.10.2018 16:01:48
* arg: 1
 * nil
* arg: 2
 * string: same boolean value


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:01:48
* table:
[1]
 * table:
  [export]
   * number: 0
  [disablelog]
   * number: 1
  [tagcache]
   * string: clima, pompa_circolazione_mansarda_inverno, pompa_circolazione_mansarda_estate
  [datahex]
   * string: 00
  [units]
   * string:
  [value]
   * bool: false
  [comment]
   * string:
  [updatetime]
   * number: 1540389692
  [datatype]
   * number: 1009
  [address]
   * string: 2/0/107
  [id]
   * number: 4203
  [data]
   * bool: false
  [highpriolog]
   * number: 0
  [pollinterval]
   * string:
  [readoninit]
   * number: 0
  [name]
   * string: T7 FB Elettrovalvola pavimento mansarda
  [decoded]
   * bool: true
[/size]


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:01:48
* arg: 1
 * bool: true
* arg: 2
 * bool: false
* arg: 3
 * number: 1540389708
* arg: 4
 * number: 0
[/size]


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:03:29
* table:
[1]
 * table:
  [export]
   * number: 0
  [disablelog]
   * number: 1
  [tagcache]
   * string: clima, pompa_circolazione_mansarda_inverno, pompa_circolazione_mansarda_estate
  [datahex]
   * string: 01
  [units]
   * string:
  [value]
   * bool: true
  [comment]
   * string:
  [updatetime]
   * number: 1540389805
  [datatype]
   * number: 1009
  [address]
   * string: 2/0/107
  [id]
   * number: 4203
  [data]
   * bool: true
  [highpriolog]
   * number: 0
  [pollinterval]
   * string:
  [readoninit]
   * number: 0
  [name]
   * string: T7 FB Elettrovalvola pavimento mansarda
  [decoded]
   * bool: true
[/size]


[size=undefined]
Tesy_pompa_circolazione_mansarda 24.10.2018 16:03:29
* arg: 1
 * bool: true
* arg: 2
 * bool: true
* arg: 3
 * number: 1540389809
* arg: 4
 * number: 1540389805
[/size]

Hi admin,
have you any idea to find out what happens?
Thanks.
Reply
#45
Hi,

I have noticed twice now that scripts triggered by tag group didn’t work as expected in latest FW.

From 12 tagged objects 11 worked (triggered script) and from 1 not..

After reboot the tagged script worked perfect on all tagged objects. 

I still need to double check this.

Did you try rebooting the controller?

BR,

Erwin
Reply
#46
(24.10.2018, 16:19)Erwin van der Zwart Wrote: Hi,

I have noticed twice now that scripts triggered by tag group didn’t work as expected in latest FW.

From 12 tagged objects 11 worked (triggered script) and from 1 not..

After reboot the tagged script worked perfect on all tagged objects. 

I still need to double check this.

Did you try rebooting the controller?

BR,

Erwin
Hi Erwin,
I reboot the device but nothin happened. Firmware of my Schneider Homelynk is 2.0.1. Do you suggest to update fimrware to the last? Thanks.
Reply
#47
Hi,

No i don’t think that the issue you are facing is FW related. Just because i’m not 100% sure that 2.3.0 might have a issue with tagged scripts i pointed it out to try a reboot.

As that did not helped i’m pretty sure it’s somewhere in your script.

BR,


Erwin
Reply
#48
Domoticarino, please translate to english your variables. Please describe once more what is the current goal for this script. Because now it has checking season and you try to support multiple zones so maybe better would be reorganize the code to have all in one more intuitive scriptWink
Done is better than perfect
Reply
#49
You can try something like this for all zones. Firstly you could only switch off older scripts and check if this would work same as older but for all zones and in only one script. Maybe when you define your zones in same place you found something.

Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
    end
    
    return opened, firstTimestamp
end

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.checkwrite(pumpGA, true)
            nextZoneCalculationAfter = minInterval
        else
            grp.checkwrite(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
        end
    else
        grp.checkwrite(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
    end
end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    os.sleep(nextCalculationAfter)
else
    os.sleep(30)
end
Done is better than perfect
Reply
#50
(24.10.2018, 20:08)buuuudzik Wrote: You can try something like this for all zones. Firstly you could only switch off older scripts and check if this would work same as older but for all zones and in only one script. Maybe when you define your zones in same place you found something.

Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
    end
    
    return opened, firstTimestamp
end

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.checkwrite(pumpGA, true)
            nextZoneCalculationAfter = minInterval
        else
            grp.checkwrite(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
        end
    else
        grp.checkwrite(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
    end
end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    os.sleep(nextCalculationAfter)
else
    os.sleep(30)
end
First of all let me thank you for your support.

Unfortunately this script does not work as well. Log is this one:

Pompa_circolazione_mansarda 24.10.2018 22:22:13
* nil



[size=undefined]
Pompa_circolazione_mansarda 24.10.2018 22:23:23
* nil
[/size]


I am getting crazy. It is very strange because I use the same code for in other 2 scripts and they are working without any problem. System is working with these scripts for about 1 year without any problem. Since 16th of September script related to circulation pump with address 2/0/2 does not work anymore.

The function is very easy. I have this following variable:

- heating and cooling valve state 
- dehumidifier valve state.

In winter when heating valve state (2/0/107) is ON, circulation pump must start after 60 seconds or the time I fix. When heating state valve is OFF, circulation pump must stop immediately.

In summer when cooling valve state (2/0/107) or dehumidifier valve state are ON, circulation pump must start after 60 seconds or the time I fix. When cooling valve state or dehumidifier valve state are OFF, circulation pump must stop immediately.

I cannot understand the reason why it does not anymore.
Reply
#51
What did you logged?
Done is better than perfect
Reply
#52
(24.10.2018, 20:51)buuuudzik Wrote: What did you logged?

Nothing, I simply copy your code and I verify if there was some log in that script. I saw it but if now I check again there is not anything.

Probably it was simply a misprint of previous code.

In any case it does not work.

It could be how I wrote the tag descrption? pompa_circolazione_mansarda_inverno probably too long? too _ underscore?
Reply
#53
If I can give you some tips:
- tags shouldn't be very, very long because if they are very long you can accidently assign new tag which is misspelled and probably you don't see whole tag/tags in Objects view. In your case you has e.g. "pompa_circolazione_giorno_estate" which means "circulation pump summer day" so you can think how to short this name, maybe you can remove "day" from it, use shortcut name and let e.g. pump_ce1

- please use english in your code, you will do better programs, all people in forums can help
 you faster.

- when you debug code don't be afraid to use a lot of log() function (also like log('Label 1', your_variable)) and also try to check step by step where is the start of the problem because when you have complex script then when something is bad calculated at start then end could be very mess and unpredictable so you should check full path from. You can also log only certain data e.g. when you are logging knx object then you can log full object but more readable would be to log only specific properties like log(obj.name, obj.value).

- use functions for splitting your code into a few simple and easy to test parts which would be also much more readable

- use tables, objects, for loops, tags for multiple zones, don't create another script for it

- for checking simple Lua based thing in code you can check also such tool like https://www.lua.org/demo.html

This are only some tips from me, because I see that you are trying to do better(more advanced) programs.



If it about your code please check step by step every line. I'm strongly recommend you use this last version because it is more readable and more ready for future changes which you will probably do.

1. Please stop all other pump circulation scripts.
2. Please use another script with a name e.g. 'Test' (it must be fresh script)and copy there such script which parallelly creates logs object and at the end ot prints it:
Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'
logging = true

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

if logging then logs = {season = season} end -- #TO DELETE

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInWinter = {} end -- #TO DELETE
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
        
        if logging then logs.zones[#logs.zones].valvesInWinter[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInSummer = {} end -- #TO DELETE
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
      
      if logging then logs.zones[#logs.zones].valvesInSummer[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

if logging then
    logs.season = season
    logs.zones = {}
end -- #TO DELETE

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    if logging then
        logs.zones[z] = {
            settings = {
                summerTag = summerTag,
                winterTag = winterTag,
                pumpGA = pumpGA,
                pumpBeforeCmd = grp.getvalue(pumpGA),
                openingValveTime = openingValveTime,
                minInterval = minInterval
            }
        }
    end -- #TO DELETE
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    if logging then
        logs.zones[z].opened = opened
        logs.zones[z].firstTimestamp = firstTimestamp
    end -- # TO DELETE
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.checkwrite(pumpGA, true)
            nextZoneCalculationAfter = minInterval
            if logging then logs.zones[z].info = 'Turn on pump because valve is fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's' end -- # TO DELETE
        else
            grp.checkwrite(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
            if logging then logs.zones[z].info = 'Turn off pump because valve isn't yet fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's' end -- # TO DELETE
        end
    else
        grp.checkwrite(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
        if logging then logs.zones[z].info = 'Turn on pump because valve is closed. Next calculation after ' .. nextZoneCalculationAfter .. 's. ' end -- # TO DELETE
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
        if logging then logs.zones[z].info = logs.zones[z].info .. 'Variable nextCalculationAfter was changed to ' .. nextZoneCalculationAfter .. '.' end -- # TO DELETE
    end

end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    if logging then
        logs.sleepDescription = 'Calculated ' .. nextCalculationAfter .. 's'
        log(logs)
    end -- # TO DELETE
    os.sleep(nextCalculationAfter)
else
    if logging then
        logs.sleepDescription = 'Default ' .. nextCalculationAfter .. 's (calculated value is 0 or other equal to false)'
        log(logs)
    end -- # TO DELETE
    os.sleep(30)
end
3. Print here the log result.

Please add here also the list of valves in each zones, and I will check if all are calculated.

And if it is about a day when script stopped working correctly, maybe you've done some changes in tags(maybe you've changed multiple tags and accidentally deleted the necessary tag)?
Done is better than perfect
Reply
#54
(25.10.2018, 06:04)buuuudzik Wrote: If I can give you some tips:
- tags shouldn't be very, very long because if they are very long you can accidently assign new tag which is misspelled and probably you don't see whole tag/tags in Objects view. In your case you has e.g. "pompa_circolazione_giorno_estate" which means "circulation pump summer day" so you can think how to short this name, maybe you can remove "day" from it, use shortcut name and let e.g. pump_ce1

- please use english in your code, you will do better programs, all people in forums can help
 you faster.

- when you debug code don't be afraid to use a lot of log() function (also like log('Label 1', your_variable)) and also try to check step by step where is the start of the problem because when you have complex script then when something is bad calculated at start then end could be very mess and unpredictable so you should check full path from. You can also log only certain data e.g. when you are logging knx object then you can log full object but more readable would be to log only specific properties like log(obj.name, obj.value).

- use functions for splitting your code into a few simple and easy to test parts which would be also much more readable

- use tables, objects, for loops, tags for multiple zones, don't create another script for it

- for checking simple Lua based thing in code you can check also such tool like https://www.lua.org/demo.html

This are only some tips from me, because I see that you are trying to do better(more advanced) programs.



If it about your code please check step by step every line. I'm strongly recommend you use this last version because it is more readable and more ready for future changes which you will probably do.

1. Please stop all other pump circulation scripts.
2. Please use another script with a name e.g. 'Test' (it must be fresh script)and copy there such script which parallelly creates logs object and at the end ot prints it:
Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'
logging = true

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

if logging then logs = {season = season} end -- #TO DELETE

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInWinter = {} end -- #TO DELETE
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
        
        if logging then logs.zones[#logs.zones].valvesInWinter[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInSummer = {} end -- #TO DELETE
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
      
      if logging then logs.zones[#logs.zones].valvesInSummer[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

if logging then
    logs.season = season
    logs.zones = {}
end -- #TO DELETE

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    if logging then
        logs.zones[z] = {
            settings = {
                summerTag = summerTag,
                winterTag = winterTag,
                pumpGA = pumpGA,
                pumpBeforeCmd = grp.getvalue(pumpGA),
                openingValveTime = openingValveTime,
                minInterval = minInterval
            }
        }
    end -- #TO DELETE
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    if logging then
        logs.zones[z].opened = opened
        logs.zones[z].firstTimestamp = firstTimestamp
    end -- # TO DELETE
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.checkwrite(pumpGA, true)
            nextZoneCalculationAfter = minInterval
            if logging then logs.zones[z].info = 'Turn on pump because valve is fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's' end -- # TO DELETE
        else
            grp.checkwrite(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
            if logging then logs.zones[z].info = 'Turn off pump because valve isn't yet fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's' end -- # TO DELETE
        end
    else
        grp.checkwrite(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
        if logging then logs.zones[z].info = 'Turn on pump because valve is closed. Next calculation after ' .. nextZoneCalculationAfter .. 's. ' end -- # TO DELETE
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
        if logging then logs.zones[z].info = logs.zones[z].info .. 'Variable nextCalculationAfter was changed to ' .. nextZoneCalculationAfter .. '.' end -- # TO DELETE
    end

end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    if logging then
        logs.sleepDescription = 'Calculated ' .. nextCalculationAfter .. 's'
        log(logs)
    end -- # TO DELETE
    os.sleep(nextCalculationAfter)
else
    if logging then
        logs.sleepDescription = 'Default ' .. nextCalculationAfter .. 's (calculated value is 0 or other equal to false)'
        log(logs)
    end -- # TO DELETE
    os.sleep(30)
end
3. Print here the log result.

Please add here also the list of valves in each zones, and I will check if all are calculated.

And if it is about a day when script stopped working correctly, maybe you've done some changes in tags(maybe you've changed multiple tags and accidentally deleted the necessary tag)?

Hi Buuuudzik,
thank you for your effort and suggestion. Please find below log list you required. It is very strange because everything seems working fine but group address 2/0/2 does not change. Always in off.

Thanks.

Circolazione mansarda 26.10.2018 16:37:22
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn on pump because valve is closed. Next calculation after 61s. Variable nextCalculationAfter was changed to 61.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [firstTimestamp]
     * number: 0
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: false
        [firstTimestamp]
         * number: 0
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: false
    [opened]
     * bool: false
[sleepDescription]
 * string: Calculated 61s
[season]
 * bool: true



[size=undefined]
Circolazione mansarda 26.10.2018 16:38:23
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn off pump because valve is not yet fully opened. Next calculation after 46sVariable nextCalculationAfter was changed to 46.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [firstTimestamp]
     * number: 1540564688
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540564688
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true
    [opened]
     * bool: true
[sleepDescription]
 * string: Calculated 46s
[season]
 * bool: true[/size]
Reply
#55
Hi
I think the only way out from it is to send your backup. You can drop to PM.
BR
Reply
#56
Code:
   [valvesInSummer]
    * table:
     [1]
      * table:
       [value]
        * bool: false
       [firstTimestamp]
        * number: 0
       [name]
        * string: T7 FB Heating floor attic valve
       [opened]
        * bool: false
   [opened]
    * bool: false
All looks good except above firstTimestamp = 0 which should have some value, not 0. But except this all looks good.

26.10.2018 16:37:22
Valve 'T7 FB Heating floor attic valve' is closed
Pump is turned off. Scripts waits 61s because minimum fully open time is 60s.

26.10.2018 16:38:23
Valve 'T7 FB Heating floor attic valve' is not fully opened
Pump is turned off. Script waits another 46s when valve will be fully opened.

What you can do further:
1. Replace grp.checkwrite() with grp.write()
2. Log grp.find() of pump after writing value to it.

Below updated script.
Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES ------------------
------------------------------------------------------
seasonGA = '2/0/100'
logging = true

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW --------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

if logging then logs = {season = season} end -- #TO DELETE

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones]valvesInWinter = {} end -- #TO DELETE
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
        
        if logging then logs.zones[#logs.zones]valvesInWinter[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones]valvesInSummer = {} end -- #TO DELETE
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
      
      if logging then logs.zones[#logs.zones]valvesInSummer[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

if logging then
    logs.season = season
    logs.zones = {}
end -- #TO DELETE

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    if logging then
        logs.zones[z] = {
            settings = {
                summerTag = summerTag,
                winterTag = winterTag,
                pumpGA = pumpGA,
                pumpBeforeCmd = grp.getvalue(pumpGA),
                openingValveTime = openingValveTime,
                minInterval = minInterval
            }
        }
    end -- #TO DELETE
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    if logging then
        logs.zones[z].opened = opened
        logs.zones[z].firstTimestamp = firstTimestamp
    end -- # TO DELETE
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if logging then
        local pump = grp.find(pumpGA)
        local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
        logs.zones[z].pumpState = {before = pumpState}
    end
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.write(pumpGA, true)
            nextZoneCalculationAfter = minInterval
            if logging then logs.zones[z].info = 'Turn on pump because valve is fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
        else
            grp.write(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
            if logging then logs.zones[z].info = "Turn off pump because valve isn't yet fully opened. Next calculation after " .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
        end
    else
        grp.write(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
        if logging then logs.zones[z].info = 'Turn off pump because valve is closed. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
    end
    
    if logging then
        local pump = grp.find(pumpGA)
        local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
        logs.zones[z].pumpState.after = pumpState
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
        if logging then logs.zones[z].info = logs.zones[z].info .. ' Variable nextCalculationAfter was changed to ' .. nextZoneCalculationAfter .. '.' end -- # TO DELETE
    end

end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    if logging then
        logs.sleepDescription = 'Calculated ' .. nextCalculationAfter .. 's'
        log(logs)
    end -- # TO DELETE
    os.sleep(nextCalculationAfter)
else
    if logging then
        logs.sleepDescription = 'Default ' .. nextCalculationAfter .. 's (calculated value is 0 or other equal to false)'
        log(logs)
    end -- # TO DELETE
    os.sleep(30)
end
Done is better than perfect
Reply
#57
Hi buuuudzik,
there is a mistake in the code. Enclosed the error.

Thanks.

Attached Files Image(s)
   
Reply
#58
Here updated version (there was a lack of "." after tablename):

Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'
logging = true

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

if logging then logs = {season = season} end -- #TO DELETE

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInWinter = {} end -- #TO DELETE
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
        
        if logging then logs.zones[#logs.zones].valvesInWinter[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInSummer = {} end -- #TO DELETE
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
      
      if logging then logs.zones[#logs.zones].valvesInSummer[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

if logging then
    logs.season = season
    logs.zones = {}
end -- #TO DELETE

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    if logging then
        logs.zones[z] = {
            settings = {
                summerTag = summerTag,
                winterTag = winterTag,
                pumpGA = pumpGA,
                pumpBeforeCmd = grp.getvalue(pumpGA),
                openingValveTime = openingValveTime,
                minInterval = minInterval
            }
        }
    end -- #TO DELETE
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    if logging then
        logs.zones[z].opened = opened
        logs.zones[z].firstTimestamp = firstTimestamp
    end -- # TO DELETE
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if logging then
        local pump = grp.find(pumpGA)
        local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
        logs.zones[z].pumpState = {before = pumpState}
    end
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.write(pumpGA, true)
            nextZoneCalculationAfter = minInterval
            if logging then logs.zones[z].info = 'Turn on pump because valve is fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
        else
            grp.write(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
            if logging then logs.zones[z].info = "Turn off pump because valve isn't yet fully opened. Next calculation after " .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
        end
    else
        grp.write(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
        if logging then logs.zones[z].info = 'Turn off pump because valve is closed. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
    end
    
    if logging then
        local pump = grp.find(pumpGA)
        local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
        logs.zones[z].pumpState.after = pumpState
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
        if logging then logs.zones[z].info = logs.zones[z].info .. ' Variable nextCalculationAfter was changed to ' .. nextZoneCalculationAfter .. '.' end -- # TO DELETE
    end

end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    if logging then
        logs.sleepDescription = 'Calculated ' .. nextCalculationAfter .. 's'
        log(logs)
    end -- # TO DELETE
    os.sleep(nextCalculationAfter)
else
    if logging then
        logs.sleepDescription = 'Default ' .. nextCalculationAfter .. 's (calculated value is 0 or other equal to false)'
        log(logs)
    end -- # TO DELETE
    os.sleep(30)
end
Done is better than perfect
Reply
#59
(27.10.2018, 14:44)buuuudzik Wrote: Here updated version (there was a lack of "." after tablename):

Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'
logging = true

zones = {
    {
        summer = 'pompa_circolazione_giorno_estate',
        winter = 'pompa_circolazione_giorno_inverno',
        pump = '2/0/1',
        offset = 60,
        minimum = 30
    }
}


------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone

if logging then logs = {season = season} end -- #TO DELETE

function calcOutOfTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInWinter = {} end -- #TO DELETE
    
    for v = 1, #valves, 1 do
        local valve = valves[v]
        
        if valve.value then
            opened = true
            if firstTimestamp > 0 then
                if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
            else
                firstTimestamp = valve.updatetime
            end
        end
        
        if logging then logs.zones[#logs.zones].valvesInWinter[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

function calcDuringTheSeason(tag)
    local opened = false
    local firstTimestamp = 0
    local valves = grp.tag(tag)
    
    if logging then logs.zones[#logs.zones].valvesInSummer = {} end -- #TO DELETE
    
    valves = grp.tag(tag)
    for v = 1, #valves, 1 do
      valve = valves[v]
      
      if valve.value then
        opened = true
        if firstTimestamp > 0 then
          if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
        else
          firstTimestamp = valve.updatetime
        end
      end
      
      if logging then logs.zones[#logs.zones].valvesInSummer[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
    end
    
    return opened, firstTimestamp
end

if logging then
    logs.season = season
    logs.zones = {}
end -- #TO DELETE

for z, zone in ipairs(zones) do
    local summerTag = zone.summer
    local winterTag = zone.winter
    local pumpGA = zone.pump
    local openingValveTime = zone.offset
    local minInterval = zone.minimum
    
    if logging then
        logs.zones[z] = {
            settings = {
                summerTag = summerTag,
                winterTag = winterTag,
                pumpGA = pumpGA,
                pumpBeforeCmd = grp.getvalue(pumpGA),
                openingValveTime = openingValveTime,
                minInterval = minInterval
            }
        }
    end -- #TO DELETE
    
    -- CALCULATE SINGLE
    
    local opened, firstTimestamp = false, 0
    
    -- Calc valve state and firsttimestamp for update
    if season then
        opened, firstTimestamp = calcDuringTheSeason(winterTag)
    else
        opened, firstTimestamp = calcOutOfTheSeason(summerTag)
    end
    
    if logging then
        logs.zones[z].opened = opened
        logs.zones[z].firstTimestamp = firstTimestamp
    end -- # TO DELETE
    
    -- Find nextZoneCalculationAfter for current zone
    local nextZoneCalculationAfter = 0
    
    if logging then
        local pump = grp.find(pumpGA)
        local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
        logs.zones[z].pumpState = {before = pumpState}
    end
    
    if opened then
        local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
        
        if fullyOpened then
            grp.write(pumpGA, true)
            nextZoneCalculationAfter = minInterval
            if logging then logs.zones[z].info = 'Turn on pump because valve is fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
        else
            grp.write(pumpGA, false)
            nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
            if logging then logs.zones[z].info = "Turn off pump because valve isn't yet fully opened. Next calculation after " .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
        end
    else
        grp.write(pumpGA, false)
        nextZoneCalculationAfter = openingValveTime + 1
        if logging then logs.zones[z].info = 'Turn off pump because valve is closed. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
    end
    
    if logging then
        local pump = grp.find(pumpGA)
        local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
        logs.zones[z].pumpState.after = pumpState
    end
    
    -- Update nextCalculationAfter (global)
    if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
        nextCalculationAfter = nextZoneCalculationAfter
        if logging then logs.zones[z].info = logs.zones[z].info .. ' Variable nextCalculationAfter was changed to ' .. nextZoneCalculationAfter .. '.' end -- # TO DELETE
    end

end

-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
    if logging then
        logs.sleepDescription = 'Calculated ' .. nextCalculationAfter .. 's'
        log(logs)
    end -- # TO DELETE
    os.sleep(nextCalculationAfter)
else
    if logging then
        logs.sleepDescription = 'Default ' .. nextCalculationAfter .. 's (calculated value is 0 or other equal to false)'
        log(logs)
    end -- # TO DELETE
    os.sleep(30)
end

Unfortunately not working.

Here below log:

Circolazione mansarda 29.10.2018 17:10:50
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn off pump because valve is closed. Next calculation after 61s. Variable nextCalculationAfter was changed to 61.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [pumpState]
     * table:
      [after]
       * table:
        [lastupdate]
         * number: 0
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
      [before]
       * table:
        [lastupdate]
         * number: 60
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
    [firstTimestamp]
     * number: 0
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: false
        [firstTimestamp]
         * number: 0
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: false
    [opened]
     * bool: false
[sleepDescription]
 * string: Calculated 61s
[season]
 * bool: true



[size=undefined]
Circolazione mansarda 29.10.2018 17:11:51
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn off pump because valve isn't yet fully opened. Next calculation after 43s. Variable nextCalculationAfter was changed to 43.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [pumpState]
     * table:
      [after]
       * table:
        [lastupdate]
         * number: 0
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
      [before]
       * table:
        [lastupdate]
         * number: 61
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
    [firstTimestamp]
     * number: 1540829493
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829493
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true
    [opened]
     * bool: true
[sleepDescription]
 * string: Calculated 43s
[season]
 * bool: true
[/size]


[size=undefined]
Circolazione mansarda 29.10.2018 17:12:34
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn off pump because valve isn't yet fully opened. Next calculation after 59s. Variable nextCalculationAfter was changed to 59.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [pumpState]
     * table:
      [after]
       * table:
        [lastupdate]
         * number: 0
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
      [before]
       * table:
        [lastupdate]
         * number: 43
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
    [firstTimestamp]
     * number: 1540829552
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829552
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true
    [opened]
     * bool: true
[sleepDescription]
 * string: Calculated 59s
[season]
 * bool: true
[/size]


[size=undefined]
Circolazione mansarda 29.10.2018 17:13:33
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn off pump because valve isn't yet fully opened. Next calculation after 60s. Variable nextCalculationAfter was changed to 60.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [pumpState]
     * table:
      [after]
       * table:
        [lastupdate]
         * number: 0
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
      [before]
       * table:
        [lastupdate]
         * number: 59
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
    [firstTimestamp]
     * number: 1540829612
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829612
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true
    [opened]
     * bool: true
[sleepDescription]
 * string: Calculated 60s
[season]
 * bool: true
[/size]


[size=undefined]
Circolazione mansarda 29.10.2018 17:14:33
* table:
[zones]
 * table:
  [1]
   * table:
    [info]
     * string: Turn off pump because valve isn't yet fully opened. Next calculation after 60s. Variable nextCalculationAfter was changed to 60.
    [settings]
     * table:
      [pumpGA]
       * string: 2/0/2
      [summerTag]
       * string: summer_pump
      [pumpBeforeCmd]
       * bool: false
      [winterTag]
       * string: winter_pump
      [minInterval]
       * number: 30
      [openingValveTime]
       * number: 60
    [pumpState]
     * table:
      [after]
       * table:
        [lastupdate]
         * number: 0
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
      [before]
       * table:
        [lastupdate]
         * number: 60
        [name]
         * string: Pompa Circolazione Mansarda
        [value]
         * bool: false
    [firstTimestamp]
     * number: 1540829672
    [valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829672
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true
    [opened]
     * bool: true
[sleepDescription]
 * string: Calculated 60s
[season]
 * bool: true[/size]
Reply
#60
Could you define what means "not working"? What is current state of your system?

But probably I've found the source of problemWink Please log in "Object logs" valve status because for 99% you are updating your valve every minute(not only on change) so the timestamp is updated and is still too fresh and is recognized as not fully open.

Looks in logs:
[valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829552
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true

[valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829612
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true

[valvesInSummer]
     * table:
      [1]
       * table:
        [value]
         * bool: true
        [firstTimestamp]
         * number: 1540829672
        [name]
         * string: T7 FB Heating floor attic valve
        [opened]
         * bool: true

Everytime script runs there is different firstTimestamp which is equal to updatetime of valve with alias 'T7 FB Heating floor attic valve'. So the status of this valve is updated every minute. But this is not by this script because this script only controls the pump based on valve statuses.


I think you are upodating state of valve every minute. Please log
Done is better than perfect
Reply


Forum Jump: