| Ligne 44 : |
Ligne 44 : |
| | | | |
| | {{underline|Remarks:}} forced state can also be used during a normal heating process to stop it. In such case, the forced state will get disabled when the lower temperature is reached. | | {{underline|Remarks:}} forced state can also be used during a normal heating process to stop it. In such case, the forced state will get disabled when the lower temperature is reached. |
| | + | |
| | + | |
| | + | == The code == |
| | + | |
| | + | Here is the code of [https://github.com/mchobby/micropython-mydin/blob/main/examples/backplanes/TwoRelay3Mod/async-thermostat2.py thermostat2.py] available in the repository. |
| | + | |
| | + | <syntaxhighlight lang="python" line> |
| | + | from mydin import configure |
| | + | from mydin.pico import Pico3Mod |
| | + | from mydin.backplane.relays import TwoRelay3Mod |
| | + | from hyst import HeaterTh |
| | + | import time, sys, asyncio |
| | + | |
| | + | # Which Controler + Backplane to use |
| | + | din = configure( Pico3Mod, TwoRelay3Mod ) |
| | + | thermostat = HeaterTh( 25, 2 ) # Thermostat |
| | + | forced = None # Forced state (High=True,Low=False,None=None) |
| | + | last_print = 1 |
| | + | |
| | + | # === OneWire bus & DS18B20 =================== |
| | + | # When running DinControler asynchronously, a task |
| | + | # is created to capture the DS18B20 temperature! |
| | + | # The AsyncIO task is scheduled every 60 seconds |
| | + | # (see pico.py; DS18B20_UPDATE_TIME) |
| | + | |
| | + | async def loop( din ): |
| | + | """ called again and again (like Arduino) """ |
| | + | global thermostat, forced, last_print |
| | + | if din.temp_ds18b20==None: |
| | + | await asyncio.sleep( 2 ) |
| | + | return |
| | + | |
| | + | # User Force state change ? |
| | + | if din.was_pressed( 0 ): |
| | + | forced = not(din.rel1.value()) |
| | + | |
| | + | |
| | + | # Ask to reset forced state ? |
| | + | if din.was_pressed( 1 ): |
| | + | forced = None |
| | + | |
| | + | # Increate / decrease setpoint |
| | + | if din.was_pressed( 2 ): |
| | + | thermostat.setpoint -= 1 |
| | + | print( 'setpoint @ %i °C' % thermostat.setpoint ) |
| | + | din.led2.on() |
| | + | await asyncio.sleep_ms( 300 ) |
| | + | din.led2.off() |
| | + | if din.was_pressed( 3 ): |
| | + | thermostat.setpoint += 1 |
| | + | print( 'setpoint @ %i °C' % thermostat.setpoint ) |
| | + | din.led3.on() |
| | + | await asyncio.sleep_ms( 300 ) |
| | + | din.led3.off() |
| | + | |
| | + | # IF forced THEN apply forced state |
| | + | if forced != None: |
| | + | heat = forced |
| | + | # Should we auto-reset the forced state |
| | + | if (forced == thermostat.update( din.temp_ds18b20) ): |
| | + | forced=None # Reset forced state |
| | + | |
| | + | # IF not forced THEN follow thermostat |
| | + | if forced==None: |
| | + | heat = thermostat.update( din.temp_ds18b20 ) |
| | + | |
| | + | din.led1.value( forced!=None ) |
| | + | din.led0.value( heat ) |
| | + | din.rel1.value( heat ) |
| | + | |
| | + | # print status once every 2 seconds |
| | + | if time.ticks_diff( time.ticks_ms(), last_print )>2000: |
| | + | print( "[%s] %s °C - %s - %s" % (thermostat.setpoint, din.temp_ds18b20, "Heat" if heat else "...", "(forced)" if forced!=None else "") ) |
| | + | last_print = time.ticks_ms() |
| | + | |
| | + | await asyncio.sleep_ms( 100 ) |
| | + | |
| | + | |
| | + | din.setup( setup=None, loop=loop ) |
| | + | din.run() |
| | + | </syntaxhighlight> |
| | + | |
| | + | == Improve it == |
| | + | |
| | + | In house, thermostat are associated with a scheduler used to define one or more day-time hours range for heating (the remaining being the night-time). |
| | + | |
| | + | Some advanced thermostat can defines a day temperature and night temperature. |
| | + | |
| | + | In such case, the forced mode could be used to switch between day-time and night-time (with the corresponding temperature). |
| | + | |
| | + | |
| | + | {{traduction}} |