#!/usr/bin/env python3 from dfatool.automata import PTA from dfatool.codegen import get_simulated_accountingmethod import unittest example_json_1 = { 'parameters': ['datarate', 'txbytes', 'txpower'], 'initial_param_values': [None, None, None], 'state': { 'IDLE': { 'power': { 'static': 5, } }, 'TX': { 'power': { 'static': 100, 'function': { 'raw': 'regression_arg(0) + regression_arg(1)' ' * parameter(txpower)', 'regression_args': [100, 2] }, } }, }, 'transitions': [ { 'name': 'init', 'origin': ['UNINITIALIZED', 'IDLE'], 'destination': 'IDLE', 'duration': { 'static': 50000, }, 'set_param': { 'txpower': 10 }, }, { 'name': 'setTxPower', 'origin': 'IDLE', 'destination': 'IDLE', 'duration': {'static': 120}, 'energy ': {'static': 10000}, 'arg_to_param_map': {0: 'txpower'}, 'argument_values': [[10, 20, 30]], }, { 'name': 'send', 'origin': 'IDLE', 'destination': 'TX', 'duration': { 'static': 10, 'function': { 'raw': 'regression_arg(0) + regression_arg(1)' ' * function_arg(1)', 'regression_args': [48, 8], }, }, 'energy': { 'static': 3, 'function': { 'raw': 'regression_arg(0) + regression_arg(1)' ' * function_arg(1)', 'regression_args': [3, 5], }, }, 'arg_to_param_map': {1: 'txbytes'}, 'argument_values': [['"foo"', '"hodor"'], [3, 5]], 'argument_combination': 'zip', }, { 'name': 'txComplete', 'origin': 'TX', 'destination': 'IDLE', 'is_interrupt': 1, 'timeout': { 'static': 2000, 'function': { 'raw': 'regression_arg(0) + regression_arg(1)' ' * parameter(txbytes)', 'regression_args': [500, 16], }, }, } ], } class TestCG(unittest.TestCase): def test_statetransition_immediate(self): pta = PTA.from_json(example_json_1) pta.set_random_energy_model() pta.state['IDLE'].power.value = 9 cg = get_simulated_accountingmethod('static_statetransition_immediate')(pta, 1000000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint8_t') cg.current_state = pta.state['IDLE'] cg.sleep(7) self.assertEqual(cg.get_energy(), 9 * 7) pta.transitions[1].energy.value = 123 cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), 9 * 7 + 123) cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), (9 * 7 + 123 + 123) % 256) cg = get_simulated_accountingmethod('static_statetransition_immediate')(pta, 100000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint8_t') cg.current_state = pta.state['IDLE'] cg.sleep(7) self.assertEqual(cg.get_energy(), 0) cg.sleep(15) self.assertEqual(cg.get_energy(), 90) cg.sleep(90) self.assertEqual(cg.get_energy(), 900 % 256) cg = get_simulated_accountingmethod('static_statetransition_immediate')(pta, 100000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint16_t') cg.current_state = pta.state['IDLE'] cg.sleep(7) self.assertEqual(cg.get_energy(), 0) cg.sleep(15) self.assertEqual(cg.get_energy(), 90) cg.sleep(90) self.assertEqual(cg.get_energy(), 900) pta.state['IDLE'].power.value = 9 # -> 90 uW pta.transitions[1].energy.value = 1 # -> 100 pJ cg = get_simulated_accountingmethod('static_statetransition_immediate')(pta, 1000000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint8_t', 1e-5, 1e-5, 1e-10) cg.current_state = pta.state['IDLE'] cg.sleep(10) # 10 us self.assertEqual(cg.get_energy(), 90 * 10) cg.pass_transition(pta.transitions[1]) self.assertAlmostEqual(cg.get_energy(), 90 * 10 + 100, places=0) cg.pass_transition(pta.transitions[1]) self.assertAlmostEqual(cg.get_energy(), 90 * 10 + 100 + 100, places=0) def test_statetransition(self): pta = PTA.from_json(example_json_1) pta.set_random_energy_model() pta.state['IDLE'].power.value = 9 cg = get_simulated_accountingmethod('static_statetransition')(pta, 1000000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint8_t') cg.current_state = pta.state['IDLE'] cg.sleep(7) self.assertEqual(cg.get_energy(), 9 * 7) pta.transitions[1].energy.value = 123 cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), 9 * 7 + 123) cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), (9 * 7 + 123 + 123) % 256) def test_state_immediate(self): pta = PTA.from_json(example_json_1) pta.set_random_energy_model() pta.state['IDLE'].power.value = 9 cg = get_simulated_accountingmethod('static_state_immediate')(pta, 1000000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint8_t') cg.current_state = pta.state['IDLE'] cg.sleep(7) self.assertEqual(cg.get_energy(), 9 * 7) pta.transitions[1].energy.value = 123 cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), 9 * 7) cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), 9 * 7) def test_state(self): pta = PTA.from_json(example_json_1) pta.set_random_energy_model() pta.state['IDLE'].power.value = 9 cg = get_simulated_accountingmethod('static_state')(pta, 1000000, 'uint8_t', 'uint8_t', 'uint8_t', 'uint8_t') cg.current_state = pta.state['IDLE'] cg.sleep(7) self.assertEqual(cg.get_energy(), 9 * 7) pta.transitions[1].energy.value = 123 cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), 9 * 7) cg.pass_transition(pta.transitions[1]) self.assertEqual(cg.get_energy(), 9 * 7) cg = get_simulated_accountingmethod('static_state')(pta, 1000000, 'uint8_t', 'uint16_t', 'uint16_t', 'uint16_t') if __name__ == '__main__': unittest.main()