Page 1 of 1

Smartest way to shutdown my pellets stove from any state

Posted: Tuesday 25 December 2018 15:31
by tezzlicious
Hi there,

Just bought a pellets stove and have done some coding with dzVents, but can use a little help in optimizing the code to shutdown from every possible state the stove is in.

Stove has the following characteristics.
- The infrared remote has 2 buttons. One to step through the ventilation levels and one through the warming levels. I have recorded these commands and can send them through shell scripts with push on buttons. It works great.
- You can't press both buttons simultaneously.
- There has to be some delay (let's take 1 second) between every button press, to ensure that the infrared commands are send correctly.
- You can only step through both levels incrementally. So you can't switch from 1 to i.e. level 5 in one press.
- It has 6 (1 t/m 6, no off state) levels of ventilation which work independent of the level of warming
- It has 5 levels of warming which work independent of the ventilation level.
- It goes into shutdown mode (off state) when you press one more time on the warming button after level 5 and wait for more than 5 seconds. If you press again within 5 seconds it goes back to level 1. Let's call this warming level 0 (=Off).
- You can turn the stove on from the off state to any level of warming. But have to do this incrementally of course.

I track the state of both levels with global variables. I don't touch the buttons on the stove. I use a custom button and control the stove through domoticz. I have defined 1 on/off switch and 2 push on buttons (1 for stepping through ventilation level and one through warming). I have a selector switch from which I can put the stove in several combinations of ventilation and warming with one click. It all works pretty good.

Now the question :P. What is the smartest code to shutdown the stove with a on/off switch, not matter what combination of vent/warming levels the stove is in?

Hope I didn't forget something, feel free to ask and thanks for any help!

Re: Smartest way to shutdown my pellets stove from any state

Posted: Tuesday 25 December 2018 17:27
by waaren
tezzlicious wrote: Tuesday 25 December 2018 15:31 Hope I didn't forget something, feel free to ask and thanks for any help!
It would help if you attach the scripts you already have or the names / id's of your switch / pushbuttons and names/types of your vars and the possible states of your pushbuttons.

Re: Smartest way to shutdown my pellets stove from any state

Posted: Tuesday 25 December 2018 22:27
by tezzlicious
Push Buttons
- Pellet Ventilation

Code: Select all

return {
	active = true,
	on = {
		devices = {
			'Pellet Ventilation'
		}
	},
   execute = function(domoticz, switch)
        if (switch.state == 'On') then
         
            if (domoticz.globalData.PelletVentilation < 7) then
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVentilation = domoticz.globalData.PelletVentilation + 1
                print('Pellet Ventilation: ' .. domoticz.globalData.PelletVentilation)
                domoticz.variables('PelletVentilation').set(domoticz.globalData.PelletVentilation)
                    if (domoticz.globalData.PelletVentilation == 7) then
                        domoticz.globalData.initialize('PelletVentilation')
                        domoticz.globalData.PelletVentilation = domoticz.globalData.PelletVentilation + 1
                        domoticz.variables('PelletVentilation').set(domoticz.globalData.PelletVentilation)
                    end     
            end
        end
   end
}
- Pellet Heat

Code: Select all

return {
	active = true,
	on = {
		devices = {
			'Pellet Heat'
		}
	},
	execute = function(domoticz, switch)
        if (switch.state == 'On') then
                               
            if (domoticz.globalData.PelletHeat < 6) then
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                domoticz.variables('PelletHeat').set(domoticz.globalData.PelletHeat)
                print('Pellet Heat: ' .. domoticz.globalData.PelletHeat)
            end
            
             if (domoticz.globalData.PelletHeat == 6) then
                --skip off state
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.initialize('PelletHeat')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                domoticz.variables('PelletHeat').set(domoticz.globalData.PelletHeat)
            end  

        end
        
	end
}
global_data.lua

Code: Select all

    
return {
       helpers = {},
       data = {
            PelletHeat = { initial = 0 },
            PelletVent = { initial = 0 },

       }
    }
The selector switch 'Stove Mode' has 3 levels: Low, Mid, High heating.

Snippet from that one:

Code: Select all

        if (switch.state == 'Low') then
            if (domoticz.globalData.PelletHeat == 0) then
                domoticz.devices('Pellet Stove').switchOn()
            elseif (domoticz.globalData.PelletHeat == 1) then
                print('Heating stays level 1')
            elseif (domoticz.globalData.PelletHeat == 2) then
                print('Heating goes to level 1 from level 2')
                domoticz.devices('Pellet Heat').switchOn().afterSec(2)
                --3
                domoticz.devices('Pellet Heat').switchOn().afterSec(4)
                --4
                domoticz.devices('Pellet Heat').switchOn().afterSec(6)
                --5
                domoticz.devices('Pellet Heat').switchOn().afterSec(8)
                --1

etc. Same trick for Ventilation but with different timings (later than Heat actions).

On part of the script:

Code: Select all

if (domoticz.devices('Pellet Stove').state == 'On') then
            if (domoticz.globalData.PelletHeat == 0) then
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                print('Pellet Stove switched On')
                domoticz.variables('PelletHeat').set(domoticz.globalData.PelletHeat)
            end
        end

The off part contains now every possible combination the stove state can be in to reach the off state (=ventilation 1, heating 0) by sending the necessary commands. So it's huge and I think I'm just thinking too difficult/stupid. :P

Re: Smartest way to shutdown my pellets stove from any state

Posted: Thursday 27 December 2018 10:36
by waaren
tezzlicious wrote: Tuesday 25 December 2018 22:27 etc. Same trick for Ventilation but with different timings (later than Heat actions).
The off part contains now every possible combination the stove state can be in to reach the off state (=ventilation 1, heating 0) by sending the necessary commands. So it's huge and I think I'm just thinking too difficult/stupid. :P
some observations:
you call an OS script from dzVents. If you don't use this script elsewhere it will probably be more efficient to execute the commands used in this script directly from the dzVents script using io.popen.
to get the sequence of commands you could use a (for) loop. It would make your code shorter but not necessarily easier to read/understand.
If you want I can help but then please send the complete (os) scripts via PM.

Re: Smartest way to shutdown my pellets stove from any state

Posted: Thursday 27 December 2018 11:22
by tezzlicious
Thanks for your observations waaren!

The shell scripts are wrappers which call a python script to execute infrared commands to an IR blaster.

i.e.

Code: Select all

bash -c 'python /home/pi/Pellet/stove.py /home/pi/Pellet/PelletVentUp.txt' &
I don't mind a bit complexer code, I can learn from it and I would want this to flow in the most efficient way.

Again a snippet from the on/off switch code, but now with 2 combinations of off states. Doing it sequentially like this works without building in delays for the IR executions:

Code: Select all

return {
	active = true,
	on = {
		devices = {
            'Pellet Stove'
		}
	},
	execute = function(domoticz, switch)

        if (domoticz.devices('Pellet Stove').state == 'On') then
            if (domoticz.globalData.PelletHeat == 0) then
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                print('Pellet Stove switched On')
                domoticz.variables('PelleHeat').set(domoticz.globalData.PelletHeat)
            end
        end
        
        if (domoticz.devices('Pellet Stove').state == 'Off' ) then
            if (domoticz.globalData.PelletHeat == 1 and domoticz.globalData.PelletVent == 1) then
                print('Pellet Stove will be switched off from state 1-1')
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.initialize('PelletHeat')    
                domoticz.variables('PelleHeat').set(domoticz.globalData.PelletHeat)
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.initialize('PelletVent')    
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                domoticz.variables('PelletVent').set(domoticz.globalData.PelletVent)
            end
            
            if (domoticz.globalData.PelletHeat == 1 and domoticz.globalData.PelletVent == 2) then
                print('Pellet Stove will be switched off from state 1-2')
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.PelletHeat = domoticz.globalData.PelletHeat + 1
                os.execute('sudo /home/pi/Pellet/PelletHeat.sh')
                domoticz.globalData.initialize('PelletHeat')    
                domoticz.variables('PelleHeat').set(domoticz.globalData.PelletHeat)
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                os.execute('sudo /home/pi/Pellet/PelletVent.sh')
                domoticz.globalData.initialize('PelletVent')    
                domoticz.globalData.PelletVent = domoticz.globalData.PelletVent + 1
                domoticz.variables('PelletVent').set(domoticz.globalData.PelletVent)
            end
            
    ...
    
    

Re: Smartest way to shutdown my pellets stove from any state

Posted: Thursday 27 December 2018 12:47
by waaren
tezzlicious wrote: Thursday 27 December 2018 11:22 The shell scripts are wrappers which call a python script to execute infrared commands to an IR blaster.

Code: Select all

bash -c 'python /home/pi/Pellet/stove.py /home/pi/Pellet/PelletVentUp.txt' &
Again a snippet from the on/off switch code, but now with 2 combinations of off states. Doing it sequentially like this works without building in delays for the IR executions:
Understand. Is this the kind of approach you are looking for ?

Code: Select all

-- stoveManager.lua
return {
        on = {  devices =   { 'Pellet Stove' }},
                
                logging =   { level  =  domoticz.LOG_DEBUG,   
                              marker =  "stove manager" 
                    },
    
    execute = function(dz, item)
        local heatStates         = 5
        local ventStates         = 6
        local pelletScriptDir    = '/home/pi/Pellet/'
        local heat               = 'PelletHeat'
        local vent               = 'PelletVent'
        local heatOff            = 0
        local ventOff            = 1
    
        local function logWrite(str,level)
            dz.log(tostring(str),level or dz.LOG_DEBUG)
        end
        
        local function setvars(name,value)
            dz.globalData[name] = value
            dz.variables(name).set(value)
        end

        local function triggerOSScript(name)
            os.execute('sudo ' .. pelletScriptDir .. name .. '.sh')
            logWrite("os.execute('sudo " .. pelletScriptDir .. name .. ".sh')")
        end

        if item.state == 'On' then
            if dz.globalData.PelletHeat == heatOff then
                triggerOSScript(heat)
                setvars(heat,1)
                logWrite(item.name  .. 'switched On')
            end
        else 
            logWrite('Pellet Stove will be switched off from state ' ..  dz.globalData.PelletHeat .. '-' .. dz.globalData.PelletVent)
            for i=heatOff, heatStates - dz.globalData.PelletHeat do
                triggerOSScript(heat)
            end
            setvars(heat,heatOff)

            for i=ventOff, ventStates - dz.globalData.PelletVent do
                triggerOSScript(vent)
            end
            setvars(vent,ventOff)
        end 
    end 
}

Re: Smartest way to shutdown my pellets stove from any state

Posted: Thursday 27 December 2018 13:15
by tezzlicious
waaren wrote: Thursday 27 December 2018 12:47
tezzlicious wrote: Thursday 27 December 2018 11:22 The shell scripts are wrappers which call a python script to execute infrared commands to an IR blaster.

Code: Select all

bash -c 'python /home/pi/Pellet/stove.py /home/pi/Pellet/PelletVentUp.txt' &
Again a snippet from the on/off switch code, but now with 2 combinations of off states. Doing it sequentially like this works without building in delays for the IR executions:
Understand. Is this the kind of approach you are looking for ?
This looks so slick! I'll try it in a bit and report back. Thanks so much.

Re: Smartest way to shutdown my pellets stove from any state

Posted: Saturday 29 December 2018 23:36
by tezzlicious
waaren wrote: Thursday 27 December 2018 12:47 Understand. Is this the kind of approach you are looking for ?
Just tested it.

The heating is spot on. No matter what level the heating is on, it always goes back to off (0).

But the ventilation behaves strange. Just to be clear, the ventilation has no off state. It's just level 1 till 6. After 6 the next level is 1 again. The stove switches itself off after it cools down (20 minutes or so after heating is switched off), but the ventilation state stays 1 although the stove is off...

Another possibility that the venting levels don't reach level 1 from whatever level it's coming from is that the IR code is a bit off. Sending with a minimum delay (milliseconds) is always spot on. I don't know what happens within the for loop when it loops those os.execute commands.

Re: Smartest way to shutdown my pellets stove from any state

Posted: Saturday 29 December 2018 23:55
by tezzlicious
tezzlicious wrote: Saturday 29 December 2018 23:36
waaren wrote: Thursday 27 December 2018 12:47 Understand. Is this the kind of approach you are looking for ?
Another possibility that the venting levels don't reach level 1 from whatever level it's coming from is that the IR code is a bit off. Sending with a minimum delay (milliseconds) is always spot on. I don't know what happens within the for loop when it loops those os.execute commands.
It's for sure the IR command. I've put a 'sleep 1' into the sh script and now it behaves steady. The only part that is missing is that with 'ventStates = 6' it misses one extra loop. So as a workaround I've put it on 7. And also when the the ventilation is on level 1, it doesn't need to loop around back to 1 again. It doesn't need to do anything for the ventilation at that point.

Re: Smartest way to shutdown my pellets stove from any state

Posted: Sunday 30 December 2018 0:44
by waaren
tezzlicious wrote: Saturday 29 December 2018 23:36
waaren wrote: Thursday 27 December 2018 12:47 Understand. Is this the kind of approach you are looking for ?
Just tested it.

The heating is spot on. No matter what level the heating is on, it always goes back to off (0).

But the ventilation behaves strange. Just to be clear, the ventilation has no off state. It's just level 1 till 6. After 6 the next level is 1 again. The stove switches itself off after it cools down (20 minutes or so after heating is switched off), but the ventilation state stays 1 although the stove is off...

Another possibility that the venting levels don't reach level 1 from whatever level it's coming from is that the IR code is a bit off. Sending with a minimum delay (milliseconds) is always spot on. I don't know what happens within the for loop when it loops those os.execute commands.
Could be something with the delay or a misalignment between real vent-state and the state in dz.globalData.

I added extra logWrites and a small delay between the sequential triggering of the IR script.

Code: Select all

-- stoveManager.lua
return {
        on = {  devices =   { 'Pellet Stove' }},
                
                logging =   { level  =  domoticz.LOG_DEBUG,   
                              marker =  "stove manager" 
                    },
    
    execute = function(dz, item)
        local heatStates         = 5
        local ventStates         = 6
        local pelletScriptDir    = '/home/pi/Pellet/'
        local heat               = 'PelletHeat'
        local vent               = 'PelletVent'
        local heatOff            = 0
        local ventOff            = 1
    
        local function logWrite(str,level)
            dz.log(tostring(str),level or dz.LOG_DEBUG)
        end
        
        local function setvars(name,value)
            dz.globalData[name] = value
            dz.variables(name).set(value)
        end

        local function delay(ms)
            os.execute("sleep " .. ms/1000) 
            logWrite("Awake after sleep")
        end

        local function triggerOSScript(name)
            os.execute('sudo ' .. pelletScriptDir .. name .. '.sh')
            logWrite("os.execute('sudo " .. pelletScriptDir .. name .. ".sh')")
            delay(100)
        end
        
        if item.state == 'On' then
            if dz.globalData.PelletHeat == heatOff then
                triggerOSScript(heat)
                setvars(heat,1)
                logWrite(item.name  .. 'switched On')
            end
        else 
            logWrite('Pellet Stove will be switched off from state ' ..  dz.globalData.PelletHeat .. '-' .. dz.globalData.PelletVent)
            for i=heatOff, heatStates - dz.globalData.PelletHeat do
                triggerOSScript(heat)
            end
            setvars(heat,heatOff)

            for i=ventOff, ventStates - dz.globalData.PelletVent do
                triggerOSScript(vent)
                logWrite("Ventstate should be level ".. tostring( dz.globalData.PelletVent + i )  .. " now")  
            end
            setvars(vent,ventOff)
        end 
    end 
}

Re: Smartest way to shutdown my pellets stove from any state

Posted: Sunday 30 December 2018 11:28
by tezzlicious
waaren wrote: Sunday 30 December 2018 0:44 Could be something with the delay or a misalignment between real vent-state and the state in dz.globalData.

I added extra logWrites and a small delay between the sequential triggering of the IR script.
Yes, the ventilation stepping is now much more accurate. Didn't see it firing more than once per sequence.

Only thing left is that the ventilation has no off state but goes back to level 1 after 6. Workaround now is 'local ventStates = 7'.

Re: Smartest way to shutdown my pellets stove from any state

Posted: Sunday 30 December 2018 13:05
by waaren
tezzlicious wrote: Sunday 30 December 2018 11:28 Yes, the ventilation stepping is now much more accurate. Didn't see it firing more than once per sequence.
Only thing left is that the ventilation has no off state but goes back to level 1 after 6. Workaround now is 'local ventStates = 7'.
Not sure I understand; does is work as required now with your workaround or is there still something to work on ?

Re: Smartest way to shutdown my pellets stove from any state

Posted: Sunday 30 December 2018 21:36
by tezzlicious
waaren wrote: Sunday 30 December 2018 13:05 Not sure I understand; does is work as required now with your workaround or is there still something to work on ?
It's working. Thanks very much for your time and knowledge waaren. Much appreciated. :D