Exemple #1
0
    def test_init_1(self):
        s1 = es.state("start")
        s2 = es.state("end")

        t1 = es.transition(s2, "next", condition=lambda: True)
        s1.add_transition(t1)

        sm = es.statemachine([s1, s2])

        self.assertRaises(RuntimeError,
                          sm.init)  # test if no initial state is definied

        s1.initial = True
        sm.init()
        sm.step()

        self.assertEqual(sm.state, s2)  # test if first transition works
        self.assertRaises(RuntimeError,
                          sm.step)  # test if final state works right
Exemple #2
0
def setup(temps, thresh):

    s_cold = ep_statemachine.state("cold", initial=True)  #1
    s_heatUp1 = ep_statemachine.state("heatUp1")  #2
    s_heatUp2 = ep_statemachine.state("heatUp2")  #3
    s_hot = ep_statemachine.state("hot")  #4
    s_toHot = ep_statemachine.state("toHot")  #5
    s_muchToHot = ep_statemachine.state("muchToHot")  #6

    t_12 = ep_statemachine.transition(
        s_heatUp1,
        "t_12",  # (T_Oven > T1) & T_Oven > T_TankU + dT1
        lambda: (temps("T_Oven") > thresh("T1")) &
        (temps("T_Oven") > temps("T_TankU") + thresh("T1")))

    t_23 = ep_statemachine.transition(
        s_heatUp2,
        "t_23",
        lambda: (temps("T_Oven") < temps("T_TankL") + thresh("dT1")
                 )  # T_Oven < T_TankL + dT1
    )

    t_32 = ep_statemachine.transition(
        s_heatUp1,
        "t_32",
        lambda: (temps("T_Oven") > temps("T_TankU") + thresh("dT1")
                 )  # T_Oven > T_TankU + dT1
    )

    t_cold = ep_statemachine.transition(
        s_cold,
        "t_cold",
        lambda: (temps("T_Oven") < thresh("T5"))  # T_Oven < T5
    )

    t_hot = ep_statemachine.transition(
        s_hot,
        "t_hot",
        lambda: (temps("T_TankL") > thresh("T2"))  # T_TankL > T2
    )

    t_42 = ep_statemachine.transition(
        s_heatUp1,
        "t_42",  # T_TankL < T2 - dT1 & T_Oven > T_TankU + dT1
        lambda: (temps("T_TankL") < thresh("T2") - thresh("dT1")) &
        (temps("T_Oven") > temps("T_TankU") + thresh("dT1")))

    t_toHot = ep_statemachine.transition(
        s_toHot,
        "t_toHot",
        lambda:
        (temps("T_Oven") > thresh("T3") + thresh("dT2"))  # T_Oven > T3 + dT2
    )

    t_54 = ep_statemachine.transition(
        s_hot,
        "t_54",
        lambda:
        (temps("T_Oven") < thresh("T3") - thresh("dT2"))  # T_Oven < T3 - dT2
    )

    t_56 = ep_statemachine.transition(
        s_muchToHot,
        "t_56",
        lambda:
        (temps("T_Oven") > thresh("T4") + thresh("dT2"))  # T_Oven > T4 + dT2
    )

    t_65 = ep_statemachine.transition(
        s_toHot,
        "t_65",
        lambda:
        (temps("T_Oven") < thresh("T4") - thresh("dT2"))  # T_Oven < T4 - dT2
    )

    s_cold.add_transition(t_12)
    s_cold.add_transition(t_toHot)

    s_heatUp1.add_transition(t_23)
    s_heatUp1.add_transition(t_cold)
    s_heatUp1.add_transition(t_hot)
    s_heatUp1.add_transition(t_toHot)

    s_heatUp2.add_transition(t_32)
    s_heatUp2.add_transition(t_cold)
    s_heatUp2.add_transition(t_hot)
    s_heatUp2.add_transition(t_toHot)

    s_hot.add_transition(t_cold)
    s_hot.add_transition(t_toHot)
    s_hot.add_transition(t_42)

    s_toHot.add_transition(t_54)
    s_toHot.add_transition(t_56)

    s_muchToHot.add_transition(t_65)

    return ep_statemachine.statemachine(
        [s_cold, s_heatUp1, s_heatUp2, s_hot, s_toHot, s_muchToHot])
Exemple #3
0
    def test_coffee_machine(self):
        i = 0

        def inc():
            nonlocal i
            i = i + 1

        workflow = [
            "press coffee button",
            "press coffee button",
            "press espresso button",
            "press espresso button",
            "press off button",
            "press off button",
        ]

        s_sleep = es.state("sleep", initial=True, entry_action=inc)
        s_select_input = es.state("select_input", entry_action=inc)
        s_make_coffee = es.state("make coffee")
        s_make_espresso = es.state("make espresso")
        s_done = es.state("done")
        s_off = es.state("off")

        t_wake_up = es.transition(
            s_select_input,
            identifier="wake up",
            condition=lambda: re.match("press (coffee|espresso|off) button",
                                       workflow[i]) is not None)
        s_sleep.add_transition(t_wake_up)

        t_coffee = es.transition(
            s_make_coffee,
            identifier="coffee",
            condition=lambda: workflow[i] == "press coffee button")
        s_select_input.add_transition(t_coffee)

        t_espresso = es.transition(
            s_make_espresso,
            identifier="espresso",
            condition=lambda: workflow[i] == "press espresso button")
        s_select_input.add_transition(t_espresso)

        t_finished = es.transition(s_done,
                                   identifier="finished",
                                   condition=lambda: True)
        s_make_coffee.add_transition(t_finished)
        s_make_espresso.add_transition(t_finished)

        t_back_to_sleep = es.transition(s_sleep,
                                        identifier="back to sleep",
                                        condition=lambda: True)
        s_done.add_transition(t_back_to_sleep)

        t_turn_off = es.transition(
            s_off,
            identifier="turn off",
            condition=lambda: workflow[i] == "press off button")
        s_select_input.add_transition(t_turn_off)

        sm = es.statemachine([
            s_sleep, s_select_input, s_make_coffee, s_make_espresso, s_done,
            s_off
        ])

        sm.init()
        self.assertEqual(sm.state, s_sleep)
        sm.step()  # press any button
        self.assertEqual(sm.state, s_select_input)
        sm.step()  # press coffee button
        self.assertEqual(sm.state, s_make_coffee)
        sm.step()  # wait
        self.assertEqual(sm.state, s_done)
        sm.step()  # drink coffee
        self.assertEqual(sm.state, s_sleep)
        sm.step()  # press any button
        self.assertEqual(sm.state, s_select_input)
        sm.step()  # press espresso button
        self.assertEqual(sm.state, s_make_espresso)
        sm.step()  # wait
        self.assertEqual(sm.state, s_done)
        sm.step()  # drink espresso
        self.assertEqual(sm.state, s_sleep)
        sm.step()  # press off button
        self.assertEqual(sm.state, s_select_input)
        sm.step()  # press off button
        self.assertEqual(sm.state, s_off)
        self.assertRaises(RuntimeError, sm.step)  # coffee machine is off

        sm.init()  # reinit
        i = 0
        self.assertEqual(sm.state, s_sleep)
        sm.cycle(0.01)  # run all steps at once
        self.assertEqual(sm.state, s_off)
Exemple #4
0
    def test_heater_control(self):
        i = 0

        def inc():
            nonlocal i
            i = i + 1

        s_cold = es.state("cold",
                          initial=True,
                          entry_action=inc,
                          during_action=inc)  # 1
        s_heat_up_1 = es.state("head up 1",
                               entry_action=inc,
                               during_action=inc)  # 2
        s_heat_up_2 = es.state("head up 2",
                               entry_action=inc,
                               during_action=inc)  # 3
        s_hot = es.state("hot", entry_action=inc, during_action=inc)  # 4
        s_to_hot = es.state("to hot", entry_action=inc, during_action=inc)  # 5
        s_much_to_hot = es.state("much to hot",
                                 entry_action=inc,
                                 during_action=inc)  # 6
        s_cool_down = es.state("much to hot",
                               entry_action=inc,
                               during_action=inc)  # 7

        # test array:
        # state is state before temperatures are reached
        test_array = [
            {
                "T_Oven": 40,
                "T_Tank_Upper": 30,
                "T_Tank_Lower": 25,
                "state": s_cold
            },
            {
                "T_Oven": 50,
                "T_Tank_Upper": 30,
                "T_Tank_Lower": 25,
                "state": s_cold
            },
            {
                "T_Oven": 60,
                "T_Tank_Upper": 30,
                "T_Tank_Lower": 25,
                "state": s_cold
            },
            {
                "T_Oven": 70,
                "T_Tank_Upper": 30,
                "T_Tank_Lower": 25,
                "state": s_cold
            },
            {
                "T_Oven": 70,
                "T_Tank_Upper": 40,
                "T_Tank_Lower": 25,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 70,
                "T_Tank_Upper": 50,
                "T_Tank_Lower": 30,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 70,
                "T_Tank_Upper": 50,
                "T_Tank_Lower": 40,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 60,
                "T_Tank_Upper": 60,
                "T_Tank_Lower": 50,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 55,
                "T_Tank_Upper": 60,
                "T_Tank_Lower": 50,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 55,
                "T_Tank_Upper": 60,
                "T_Tank_Lower": 55,
                "state": s_heat_up_2
            },
            {
                "T_Oven": 60,
                "T_Tank_Upper": 60,
                "T_Tank_Lower": 55,
                "state": s_heat_up_2
            },
            {
                "T_Oven": 70,
                "T_Tank_Upper": 60,
                "T_Tank_Lower": 55,
                "state": s_heat_up_2
            },
            {
                "T_Oven": 75,
                "T_Tank_Upper": 60,
                "T_Tank_Lower": 55,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 85,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 70,
                "state": s_heat_up_1
            },
            {
                "T_Oven": 85,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 70,
                "state": s_hot
            },
            {
                "T_Oven": 90,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 70,
                "state": s_hot
            },
            {
                "T_Oven": 97,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 70,
                "state": s_hot
            },
            {
                "T_Oven": 97,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 70,
                "state": s_to_hot
            },
            {
                "T_Oven": 90,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 75,
                "state": s_to_hot
            },
            {
                "T_Oven": 90,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 75,
                "state": s_hot
            },
            {
                "T_Oven": 97,
                "T_Tank_Upper": 80,
                "T_Tank_Lower": 75,
                "state": s_hot
            },
            {
                "T_Oven": 97,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_to_hot
            },
            {
                "T_Oven": 101,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_to_hot
            },
            {
                "T_Oven": 101,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_much_to_hot
            },
            {
                "T_Oven": 101,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_much_to_hot
            },
            {
                "T_Oven": 97,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_much_to_hot
            },
            {
                "T_Oven": 97,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_to_hot
            },
            {
                "T_Oven": 90,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_to_hot
            },
            {
                "T_Oven": 90,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_hot
            },
            {
                "T_Oven": 80,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_hot
            },
            {
                "T_Oven": 70,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_hot
            },
            {
                "T_Oven": 60,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_hot
            },
            {
                "T_Oven": 55,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_hot
            },
            {
                "T_Oven": 55,
                "T_Tank_Upper": 85,
                "T_Tank_Lower": 80,
                "state": s_cool_down
            },
        ]

        t_12 = es.transition(
            s_heat_up_1,
            identifier="t_12",
            condition=lambda: (test_array[i]["T_Oven"] > 65) &
            (test_array[i]["T_Oven"] > test_array[i]["T_Tank_Lower"]))
        s_cold.add_transition(t_12)

        t_23 = es.transition(
            s_heat_up_2,
            identifier="t_23",
            condition=lambda: (test_array[i]["T_Oven"] < 60) |
            (test_array[i]["T_Tank_Lower"] > test_array[i]["T_Oven"]))
        s_heat_up_1.add_transition(t_23)

        t_32 = es.transition(
            s_heat_up_1,
            identifier="t_32",
            condition=lambda:
            (test_array[i]["T_Oven"] > test_array[i]["T_Tank_Lower"] + 5))
        s_heat_up_2.add_transition(t_32)

        t_24 = t_34 = es.transition(s_hot,
                                    identifier="t_x4",
                                    condition=lambda:
                                    (test_array[i]["T_Oven"] > 80))
        s_heat_up_1.add_transition(t_24)
        s_heat_up_2.add_transition(t_34)

        t_45 = es.transition(s_to_hot,
                             identifier="t_45",
                             condition=lambda: (test_array[i]["T_Oven"] > 96))
        t_54 = es.transition(s_hot,
                             identifier="t_54",
                             condition=lambda: (test_array[i]["T_Oven"] < 94))
        s_hot.add_transition(t_45)
        s_to_hot.add_transition(t_54)

        t_56 = es.transition(s_much_to_hot,
                             identifier="t_56",
                             condition=lambda: (test_array[i]["T_Oven"] > 100))
        t_65 = es.transition(s_to_hot,
                             identifier="t_65",
                             condition=lambda: (test_array[i]["T_Oven"] < 98))
        s_to_hot.add_transition(t_56)
        s_much_to_hot.add_transition(t_65)

        t_47 = es.transition(s_cool_down,
                             identifier="t_47",
                             condition=lambda: (test_array[i]["T_Oven"] < 60))
        s_hot.add_transition(t_47)

        t_71 = es.transition(s_cold,
                             identifier="t_71",
                             condition=lambda: (test_array[i]["T_Oven"] < 50))
        s_cool_down.add_transition(t_71)

        t_72 = es.transition(
            s_heat_up_1,
            identifier="t_72",
            condition=lambda: (test_array[i]["T_Oven"] > 60) &
            (test_array[i]["T_Oven"] > test_array[i]["T_Tank_Lower"]))
        s_cool_down.add_transition(t_72)

        t_37 = es.transition(s_cool_down,
                             identifier="t_37",
                             condition=lambda: (test_array[i]["T_Oven"] < 60))
        s_cool_down.add_transition(t_37)

        sm = es.statemachine([
            s_cold, s_heat_up_1, s_heat_up_2, s_hot, s_to_hot, s_much_to_hot,
            s_cool_down
        ])
        sm.init()

        while i < len(test_array):
            self.assertEqual(sm.state, test_array[i]["state"])
            sm.step()
Exemple #5
0
    def test_coffee_machine_event(self):
        s_sleep = es.state("sleep", initial=True)
        s_select_input = es.state("select_input")
        s_make_coffee = es.state("make coffee")
        s_make_espresso = es.state("make espresso")
        s_done = es.state("done")
        s_off = es.state("off")

        e_press_coffee_button = es.event("coffee button pressed")
        e_press_espresso_button = es.event("espresso button pressed")
        e_press_off_button = es.event("off button pressed")

        t_wake_up = es.transition(s_select_input,
                                  identifier="wake up",
                                  events=[
                                      e_press_coffee_button,
                                      e_press_espresso_button,
                                      e_press_off_button
                                  ])
        s_sleep.add_transition(t_wake_up)

        t_coffee = es.transition(s_make_coffee,
                                 identifier="coffee",
                                 events=[e_press_coffee_button])
        s_select_input.add_transition(t_coffee)

        t_espresso = es.transition(s_make_espresso,
                                   identifier="espresso",
                                   events=[e_press_espresso_button])
        s_select_input.add_transition(t_espresso)

        t_finished = es.transition(s_done,
                                   identifier="finished",
                                   condition=lambda: True)
        s_make_coffee.add_transition(t_finished)
        s_make_espresso.add_transition(t_finished)

        t_back_to_sleep = es.transition(s_sleep,
                                        identifier="back to sleep",
                                        condition=lambda: True)
        s_done.add_transition(t_back_to_sleep)

        t_turn_off = es.transition(s_off,
                                   identifier="turn off",
                                   events=[e_press_off_button])
        s_select_input.add_transition(t_turn_off)

        sm = es.statemachine([
            s_sleep, s_select_input, s_make_coffee, s_make_espresso, s_done,
            s_off
        ])
        sm.init()
        self.assertEqual(sm.state, s_sleep)
        sm.action(e_press_coffee_button)
        self.assertEqual(sm.state, s_select_input)
        sm.action(e_press_coffee_button)
        self.assertEqual(sm.state, s_make_coffee)
        sm.step()
        self.assertEqual(sm.state, s_done)
        sm.step()
        self.assertEqual(sm.state, s_sleep)
        sm.action(e_press_coffee_button)
        self.assertEqual(sm.state, s_select_input)
        sm.action(e_press_espresso_button)
        self.assertEqual(sm.state, s_make_espresso)
        sm.step()
        self.assertEqual(sm.state, s_done)
        sm.step()
        self.assertEqual(sm.state, s_sleep)
        sm.action(e_press_off_button)
        self.assertEqual(sm.state, s_select_input)
        sm.action(e_press_off_button)
        self.assertEqual(sm.state, s_off)
def setup(temps, thresh):
    pump_pin = machine.Pin(14, machine.Pin.OUT)
    warn_led = machine.Pin(17, machine.Pin.OUT)

    pump_on = lambda: pump_pin.off()
    pump_off = lambda: pump_pin.on()

    warn_on = lambda: warn_led.off()
    warn_off = lambda: warn_led.on()

    def s_cold_enter():
        pump_off()
        warn_off()

    def s_heatUp1_enter():
        pump_on()
        warn_off()

    def s_heatUp2_enter():
        pump_off()
        warn_off()

    def s_hot_enter():
        pump_off()
        warn_off()

    def s_toHot_enter():
        pump_on()
        warn_on()

    def s_muchToHot_enter():
        pump_on()
        warn_on()

    s_cold = ep_statemachine.state("cold",
                                   initial=True,
                                   entry_action=s_cold_enter)  #1
    s_heatUp1 = ep_statemachine.state("heatUp1",
                                      entry_action=s_heatUp1_enter)  #2
    s_heatUp2 = ep_statemachine.state("heatUp2",
                                      entry_action=s_heatUp2_enter)  #3
    s_hot = ep_statemachine.state("hot", entry_action=s_hot_enter)  #4
    s_toHot = ep_statemachine.state("toHot", entry_action=s_toHot_enter)  #5
    s_muchToHot = ep_statemachine.state("muchToHot",
                                        entry_action=s_muchToHot_enter)  #6

    t_12 = ep_statemachine.transition(
        s_heatUp1,
        "t_12",  # (T_Oven > T1) & T_Oven > T_TankU + dT1
        lambda: (temps("T_Oven") > thresh("T1")) &
        (temps("T_Oven") > temps("T_TankU") + thresh("T1")))

    t_23 = ep_statemachine.transition(
        s_heatUp2,
        "t_23",
        lambda: (temps("T_Oven") < temps("T_TankL") + thresh("dT1")
                 )  # T_Oven < T_TankL + dT1
    )

    t_32 = ep_statemachine.transition(
        s_heatUp1,
        "t_32",
        lambda: (temps("T_Oven") > temps("T_TankU") + thresh("dT1")
                 )  # T_Oven > T_TankU + dT1
    )

    t_cold = ep_statemachine.transition(
        s_cold,
        "t_cold",
        lambda: (temps("T_Oven") < thresh("T5"))  # T_Oven < T5
    )

    t_hot = ep_statemachine.transition(
        s_hot,
        "t_hot",
        lambda: (temps("T_TankL") > thresh("T2"))  # T_TankL > T2
    )

    t_42 = ep_statemachine.transition(
        s_heatUp1,
        "t_42",  # T_TankL < T2 - dT1 & T_Oven > T_TankU + dT1
        lambda: (temps("T_TankL") < thresh("T2") - thresh("dT1")) &
        (temps("T_Oven") > temps("T_TankU") + thresh("dT1")))

    t_toHot = ep_statemachine.transition(
        s_toHot,
        "t_toHot",
        lambda:
        (temps("T_Oven") > thresh("T3") + thresh("dT2"))  # T_Oven > T3 + dT2
    )

    t_54 = ep_statemachine.transition(
        s_hot,
        "t_54",
        lambda:
        (temps("T_Oven") < thresh("T3") - thresh("dT2"))  # T_Oven < T3 - dT2
    )

    t_56 = ep_statemachine.transition(
        s_muchToHot,
        "t_56",
        lambda:
        (temps("T_Oven") > thresh("T4") + thresh("dT2"))  # T_Oven > T4 + dT2
    )

    t_65 = ep_statemachine.transition(
        s_toHot,
        "t_65",
        lambda:
        (temps("T_Oven") < thresh("T4") - thresh("dT2"))  # T_Oven < T4 - dT2
    )

    s_cold.add_transition(t_12)
    s_cold.add_transition(t_toHot)

    s_heatUp1.add_transition(t_23)
    s_heatUp1.add_transition(t_cold)
    s_heatUp1.add_transition(t_hot)
    s_heatUp1.add_transition(t_toHot)

    s_heatUp2.add_transition(t_32)
    s_heatUp2.add_transition(t_cold)
    s_heatUp2.add_transition(t_hot)
    s_heatUp2.add_transition(t_toHot)

    s_hot.add_transition(t_cold)
    s_hot.add_transition(t_toHot)
    s_hot.add_transition(t_42)

    s_toHot.add_transition(t_54)
    s_toHot.add_transition(t_56)

    s_muchToHot.add_transition(t_65)

    return ep_statemachine.statemachine(
        [s_cold, s_heatUp1, s_heatUp2, s_hot, s_toHot,
         s_muchToHot]), lambda: 1 - pump_pin.value()