Changes between Version 43 and Version 44 of Proposal


Ignore:
Timestamp:
Jul 8, 2013, 2:27:02 PM (11 years ago)
Author:
Frédéric
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Proposal

    v43 v44  
    154154== Simple rule ==
    155155
    156 My first idea was to provide a special API to create rules, in a simple way, like this:
    157 
    158 {{{
    159 #!python
    160 from pknyx.api import trigger, group
    161 
    162 @trigger.schedule.every(minute=5)
    163 def heatingBathroomManagement(event):
    164 
    165     tempObj = group.findById("bathroom_temp")
    166     tempSetupObj = group.findById("bathroom_temp_setup")
    167     heaterObj = group.findById("bathroom_heater")
    168 
    169     if tempObj.value < tempSetupObj.value - 0.25:
    170         heaterObj.value = 1
    171     elif tempObj.value > tempSetupObj.value + 0.25:
    172         heaterObj.value = 0
    173 }}}
    174 
    175 but it implies to define the group objects mapping, which is exactly what we did in the [[#VirtualDevice|Virtual Device]] example! So, let's see rules as virtual devices... All we have to do is to define the needed Datapoints:
    176 
    177 {{{
    178 #!python
    179 from pknyx.api import Rule, Stack, ETS
    180 
    181 stack = Stack()
     156My first idea was to provide a special API to create rules, but in fact, they can be implemented as Functional Block. This way, we use the same paradigm, wich is always better ;o)
     157
     158{{{
     159#!python
     160from pknyx.api import FunctionalBlock, Stack, ETS, Scheduler
     161
     162
     163stack = Stack(individualAddress="1.2.3")
    182164ets = ETS(stack)
    183 
    184 class BathroomHeater(Rule):
    185 
    186     DP_01 = dict(name="bathroom_temp", dptId="9.001", flags="CWTU", priority="low")
    187     DP_02 = dict(name="bathroom_temp_setup", dptId="9.001", flags="CWTU", priority="low")
    188     DP_03 = dict(name="bathroom_heater", dptId="1.001", flags="CWTU", priority="low")
    189 
    190     @Rule.schedule.every(minute=5)
    191     def checkTemperature(self):
    192 
    193         if self.dp["bathroom_temp"].value < self.dp["bathroom_temp_setup"].value - 0.25:
    194             self.dp["bathroom_heater"].value = "On"
    195         elif self.dp["bathroom_temp"].value > self.dp["bathroom_temp_setup"].value + 0.25:
    196             self.dp["bathroom_heater"].value = "Off"
    197 
    198 heater = BathroomHeater(name="bathroom_heater", desc="Bathroom heating management", address="1.2.3")
    199 ets.register(heaterRule)
    200 ets.link(rule=heater, dp="bathroom_temp", gad="1/1/1")
    201 ets.link(rule=heater, dp="bathroom_temp_setup", gad="1/1/2")
    202 ets.link(rule=heater, dp="bathroom_heater", gad="1/1/3")
    203 }}}
    204 
    205 This way, we use the same paradigm, which is always better ;)
    206 
     165schedule = Scheduler()
     166
     167
     168class HeatingManagerBlock(FunctionalBlock):
     169
     170    DP_01 = dict(name="temperature", access="input", dptId="9.001", default=19.)
     171    DP_02 = dict(name="setup", access="input", dptId="9.001", default=19.)
     172    DP_03 = dict(name="heater", access="output", dptId="1.001", default="Off")
     173
     174    GO_01 = dict(dp="temperature", flags="CWU", priority="low")
     175    GO_02 = dict(dp="setup", flags="CWU", priority="low")
     176    GO_03 = dict(dp="heater", flags="CRT", priority="low")
     177
     178    @schedule.every(minute=5)
     179    def manageHeater(self):
     180
     181        # Read inputs
     182        temperature = self.dp["bathroom"].value
     183        setup = self.dp["setup"].value
     184
     185        # Manage heater
     186        if temperature < setup - 0.25:
     187            heater = "On"
     188        elif temperature > setup + 0.25:
     189            heater = "Off"
     190
     191        # Set outputs
     192        self.dp["bathroom_heater"].value = heater
     193
     194
     195heatingManagerBlock = HeatingManagerBlock(name="heating_manager", desc="A simple heating manager block example")
     196
     197ets.register(heatingManagerBlock)
     198
     199ets.weave(fb=heatingManagerBlock, dp="temperature", gad="1/1/1")
     200ets.weave(fb=heatingManagerBlock, dp="setup", gad="1/1/2")
     201ets.weave(fb=heatingManagerBlock, dp="heater", gad="1/1/3")
     202
     203stack.serve()
     204}}}
     205
     206All you have to do is to use the Group Addresses you use in your real installation, through ETS application. The first one will update the temperature the Functional Block needs; the second one is used to give the setpoint, and the last one is used to switch on/off a real heater, through a KNX actuator.
     207
     208Note that it is possible to instanciate several heating managers, and weave them to different heaters.
     209
     210A more complex heating manager could compute a PID and output the power to use to heat.
    207211== '''linknx''' compatibility mode ==
    208212