def test_crc_checking(self): """ Test the crc checking in the MasterCommunciator. """ action = master_api.sensor_humidity_list() out_fields = {} for i in range(0, 32): out_fields['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, i) out_fields['crc'] = [ord('C'), 1, 240] out_fields2 = {} for i in range(0, 32): out_fields2['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, 2 * i) out_fields2['crc'] = [ord('C'), 0, 0] serial_mock = SerialMock([sin(action.create_input(1)), sout(action.create_output(1, out_fields)), sin(action.create_input(2)), sout(action.create_output(2, out_fields2))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() output = comm.do_command(action) self.assertEquals('\x00', output['hum0'].get_byte()) self.assertEquals('\x01', output['hum1'].get_byte()) self.assertRaises(CrcCheckFailedException, lambda: comm.do_command(action))
def test_background_consumer(self): """ Test the background consumer mechanism. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([ sout("OL\x00\x01\x03\x0c\r\n"), sin(action.create_input(1, in_fields)), sout("junkOL\x00\x02\x03\x0c\x05\x06\r\n here"), sout(action.create_output(1, out_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() got_output = {"phase": 1} def callback(output): """ Callback that check if the correct result was returned for OL. """ if got_output["phase"] == 1: self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"]) got_output["phase"] = 2 elif got_output["phase"] == 2: self.assertEquals([(3, int(12 * 10.0 / 6.0)), (5, int(6 * 10.0 / 6.0))], output["outputs"]) got_output["phase"] = 3 comm.register_consumer(BackgroundConsumer(master_api.output_list(), 0, callback)) comm.start() self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals(3, got_output["phase"]) self.assertEquals("junk here", comm.get_passthrough_data())
def test_watchdog(self): """ Test the watchdog. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} serial_mock = SerialMock([ sin(action.create_input(1, in_fields)), sin(action.create_input(2, in_fields)), sin(action.create_input(3, in_fields)) ]) timeout = False watchdog = {} def callback(): """ Callback for the watchdog """ watchdog['done'] = True comm = MasterCommunicator(serial_mock, init_master=False, watchdog_period=0.5, watchdog_callback=callback) comm.start() try: comm.do_command(action, in_fields, timeout=0.1) except CommunicationTimedOutException: timeout = True time.sleep(1) self.assertTrue(timeout) self.assertFalse('done' in watchdog) timeout = False try: comm.do_command(action, in_fields, timeout=0.1) except CommunicationTimedOutException: timeout = True self.assertTrue(timeout) timeout = False try: comm.do_command(action, in_fields, timeout=0.1) except CommunicationTimedOutException: timeout = True time.sleep(1.5) self.assertTrue(timeout) self.assertTrue('done' in watchdog)
def test_do_command(self): """ Test for standard behavior MasterCommunicator.do_command. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock( [sin(action.create_input(1, in_fields)), sout(action.create_output(1, out_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() output = comm.do_command(action, in_fields) self.assertEquals("OK", output["resp"])
def test_do_command_timeout(self): """ Test for timeout in MasterCommunicator.do_command. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} serial_mock = SerialMock([sin(action.create_input(1, in_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() try: comm.do_command(action, in_fields, timeout=0.1) self.assertTrue(False) except CommunicationTimedOutException: pass
def test_send_passthrough_data(self): """ Test the passthrough if no other communications are going on. """ pt_input = "data from passthrough" pt_output = "got it !" serial_mock = SerialMock([sin(pt_input), sout(pt_output)]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() comm.send_passthrough_data(pt_input) self.assertEquals(pt_output, comm.get_passthrough_data())
def test_do_command(self): """ Test for standard behavior MasterCommunicator.do_command. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([ sin(action.create_input(1, in_fields)), sout(action.create_output(1, out_fields)) ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() output = comm.do_command(action, in_fields) self.assertEquals("OK", output["resp"])
def test_passthrough(self): """ Test the passthrough. """ master_mock = SerialMock([ sout("data for the passthrough"), sin("response"), sout("more data"), sin("more response")]) passthrough_mock = SerialMock([ sin("data for the passthrough"), sout("response"), sin("more data"), sout("more response")]) master_communicator = MasterCommunicator(master_mock, init_master=False) master_communicator.enable_passthrough() master_communicator.start() passthrough = PassthroughService(master_communicator, passthrough_mock) passthrough.start() time.sleep(1) self.assertEquals(33, master_communicator.get_bytes_read()) self.assertEquals(21, master_communicator.get_bytes_written()) self.assertEquals(33, master_mock.bytes_read) self.assertEquals(21, master_mock.bytes_written) self.assertEquals(21, passthrough_mock.bytes_read) self.assertEquals(33, passthrough_mock.bytes_written) passthrough.stop()
def test_send_passthrough_data(self): """ Test the passthrough if no other communications are going on. """ pt_input = "data from passthrough" pt_output = "got it !" serial_mock = SerialMock([sin(pt_input), sout(pt_output)]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() comm.send_passthrough_data(pt_input) self.assertEquals(pt_output, comm.get_passthrough_data())
def test_do_command_split_data(self): """ Test MasterCommunicator.do_command when the data is split over multiple reads. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} sequence = [] for i in range(1, 18): sequence.append(sin(action.create_input(i, in_fields))) output_bytes = action.create_output(i, out_fields) sequence.append(sout(output_bytes[:i])) sequence.append(sout(output_bytes[i:])) serial_mock = SerialMock(sequence) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() for i in range(1, 18): self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
def test_do_command_split_data(self): """ Test MasterCommunicator.do_command when the data is split over multiple reads. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} sequence = [] for i in range(1, 18): sequence.append(sin(action.create_input(i, in_fields))) output_bytes = action.create_output(i, out_fields) sequence.append(sout(output_bytes[:i])) sequence.append(sout(output_bytes[i:])) serial_mock = SerialMock(sequence) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() for i in range(1, 18): self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
def test_passthrough_output(self): """ Test the passthrough output if no other communications are going on. """ serial_mock = SerialMock( [sout("passthrough"), sout(" my "), sout("data")]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() self.assertEquals("passthrough", comm.get_passthrough_data()) self.assertEquals(" my ", comm.get_passthrough_data()) self.assertEquals("data", comm.get_passthrough_data())
def test_bytes_counter(self): """ Test the number of bytes written and read from the serial port. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([ sin(action.create_input(1, in_fields)), sout("hello"), sout(action.create_output(1, out_fields)) ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello", comm.get_passthrough_data()) self.assertEquals(21, comm.get_bytes_written()) self.assertEquals(5 + 18, comm.get_bytes_read())
def test_passthrough(self): """ Test the passthrough. """ master_mock = SerialMock([ sout("data for the passthrough"), sin("response"), sout("more data"), sin("more response") ]) passthrough_mock = SerialMock([ sin("data for the passthrough"), sout("response"), sin("more data"), sout("more response") ]) master_communicator = MasterCommunicator(master_mock, init_master=False) master_communicator.start() passthrough = PassthroughService(master_communicator, passthrough_mock) passthrough.start() time.sleep(1) self.assertEquals(33, master_communicator.get_bytes_read()) self.assertEquals(21, master_communicator.get_bytes_written()) self.assertEquals(33, master_mock.bytes_read) self.assertEquals(21, master_mock.bytes_written) self.assertEquals(21, passthrough_mock.bytes_read) self.assertEquals(33, passthrough_mock.bytes_written) passthrough.stop()
def test_crc_checking(self): """ Test the crc checking in the MasterCommunciator. """ action = master_api.sensor_humidity_list() out_fields = {} for i in range(0, 32): out_fields['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, i) out_fields['crc'] = [ord('C'), 1, 240] out_fields2 = {} for i in range(0, 32): out_fields2['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, 2 * i) out_fields2['crc'] = [ord('C'), 0, 0] serial_mock = SerialMock([ sin(action.create_input(1)), sout(action.create_output(1, out_fields)), sin(action.create_input(2)), sout(action.create_output(2, out_fields2)) ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() output = comm.do_command(action) self.assertEquals('\x00', output['hum0'].get_byte()) self.assertEquals('\x01', output['hum1'].get_byte()) self.assertRaises(CrcCheckFailedException, lambda: comm.do_command(action))
def test_passthrough_output(self): """ Test the passthrough output if no other communications are going on. """ serial_mock = SerialMock([sout("passthrough"), sout(" my "), sout("data")]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() self.assertEquals("passthrough", comm.get_passthrough_data()) self.assertEquals(" my ", comm.get_passthrough_data()) self.assertEquals("data", comm.get_passthrough_data())
def test_background_consumer(self): """ Test the background consumer mechanism. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([ sout("OL\x00\x01\x03\x0c\r\n"), sin(action.create_input(1, in_fields)), sout("junkOL\x00\x02\x03\x0c\x05\x06\r\n here"), sout(action.create_output(1, out_fields)) ]) SetUpTestInjections(controller_serial=serial_mock) comm = MasterCommunicator(init_master=False) comm.enable_passthrough() got_output = {"phase": 1} def callback(output): """ Callback that check if the correct result was returned for OL. """ if got_output["phase"] == 1: self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"]) got_output["phase"] = 2 elif got_output["phase"] == 2: self.assertEquals([(3, int(12 * 10.0 / 6.0)), (5, int(6 * 10.0 / 6.0))], output["outputs"]) got_output["phase"] = 3 comm.register_consumer( BackgroundConsumer(master_api.output_list(), 0, callback)) comm.start() self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals(3, got_output["phase"]) self.assertEquals("junk here", comm.get_passthrough_data())
def test_bytes_counter(self): """ Test the number of bytes written and read from the serial port. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock( [sin(action.create_input(1, in_fields)), sout("hello"), sout(action.create_output(1, out_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello", comm.get_passthrough_data()) self.assertEquals(21, comm.get_bytes_written()) self.assertEquals(5 + 18, comm.get_bytes_read())
def test_background_consumer_passthrough(self): """ Test the background consumer with passing the data to the passthrough. """ serial_mock = SerialMock([sout("OL\x00\x01"), sout("\x03\x0c\r\n")]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() got_output = {"passed": False} def callback(output): """ Callback that check if the correct result was returned for OL. """ self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"]) got_output["passed"] = True comm.register_consumer( BackgroundConsumer(master_api.output_list(), 0, callback, True)) comm.start() self.assertEquals(True, got_output["passed"]) self.assertEquals("OL\x00\x01\x03\x0c\r\n", comm.get_passthrough_data())
def bootload_modules(type, filename, verbose, logger): """ Bootload all modules of the given type with the firmware in the given filename. :param type: Type of the modules (o, d, i, t, c) :type type: chr :param filename: The filename for the hex file to load :type filename: string :param verbose: If true the serial communication is printed. :param verbose: boolean """ config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') master_serial = Serial(port, 115200) master_communicator = MasterCommunicator(master_serial, verbose=verbose) master_communicator.start() addresses = get_module_addresses(master_communicator, type) blocks = 922 if type == 'c' else 410 ihex = intelhex.IntelHex(filename) crc = calc_crc(ihex, blocks) success = True for address in addresses: logger("Bootloading module %s" % pretty_address(address)) try: bootload(master_communicator, address, ihex, crc, blocks, logger) except Exception as exception: success = False logger("Bootloading failed") traceback.print_exc() return success
def test_pulse_counter_status(self): action = master_api.pulse_list() in_fields = {} out_fields = {'pv0': 0, 'pv1': 1, 'pv2': 2, 'pv3': 3, 'pv4': 4, 'pv5': 5, 'pv6': 6, 'pv7': 7, 'pv8': 8, 'pv9': 9, 'pv10': 10, 'pv11': 11, 'pv12': 12, 'pv13': 13, 'pv14': 14, 'pv15': 15, 'pv16': 16, 'pv17': 17, 'pv18': 18, 'pv19': 19, 'pv20': 20, 'pv21': 21, 'pv22': 22, 'pv23': 23, 'crc': [67, 1, 20]} serial_mock = SerialMock([sin(action.create_input(1, in_fields)), sout(action.create_output(1, out_fields))]) master_communicator = MasterCommunicator(serial_mock, init_master=False) master_communicator.start() controller = self._get_controller(master_communicator) controller.set_pulse_counter_amount(26) controller.set_pulse_counter_status(24, 123) controller.set_pulse_counter_status(25, 456) status = controller.get_pulse_counter_status() self.assertEquals(range(0, 24) + [123, 456], status) # Set pulse counter for unexisting pulse counter try: controller.set_pulse_counter_status(26, 789) self.fail('Exception should have been thrown') except ValueError as e: self.assertEquals('Could not find pulse counter 26', str(e)) # Set pulse counter for physical pulse counter try: controller.set_pulse_counter_status(23, 789) self.fail('Exception should have been thrown') except ValueError as e: self.assertEquals('Cannot set pulse counter status for 23 (should be > 23)', str(e))
def test_background_consumer_passthrough(self): """ Test the background consumer with passing the data to the passthrough. """ serial_mock = SerialMock([sout("OL\x00\x01"), sout("\x03\x0c\r\n")]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() got_output = {"passed": False} def callback(output): """ Callback that check if the correct result was returned for OL. """ self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"]) got_output["passed"] = True comm.register_consumer(BackgroundConsumer(master_api.output_list(), 0, callback, True)) comm.start() MasterCommunicatorTest._wait_for_callback(True, got_output, 3) self.assertEquals(True, got_output["passed"]) self.assertEquals("OL\x00\x01\x03\x0c\r\n", comm.get_passthrough_data())
def test_passthrough(self): """ Test the passthrough. """ master_mock = SerialMock([ sout("data for the passthrough"), sin("response"), sout("more data"), sin("more response") ]) passthrough_mock = SerialMock([ sin("data for the passthrough"), sout("response"), sin("more data"), sout("more response") ]) SetUpTestInjections(controller_serial=master_mock, passthrough_serial=passthrough_mock) master_communicator = MasterCommunicator(init_master=False) master_communicator.enable_passthrough() master_communicator.start() SetUpTestInjections(master_communicator=master_communicator) passthrough = PassthroughService() passthrough.start() time.sleep(1) self.assertEquals( 33, master_communicator.get_communication_statistics()['bytes_read']) self.assertEquals( 21, master_communicator.get_communication_statistics() ['bytes_written']) self.assertEquals(33, master_mock.bytes_read) self.assertEquals(21, master_mock.bytes_written) self.assertEquals(21, passthrough_mock.bytes_read) self.assertEquals(33, passthrough_mock.bytes_written) passthrough.stop()
def test_do_command_timeout(self): """ Test for timeout in MasterCommunicator.do_command. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} serial_mock = SerialMock([sin(action.create_input(1, in_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() try: comm.do_command(action, in_fields, timeout=0.1) self.assertTrue(False) except CommunicationTimedOutException: pass
def test_do_command_timeout_test_ongoing(self): """ Test if communication resumes after timeout. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([ sin(action.create_input(1, in_fields)), sin(action.create_input(2, in_fields)), sout(action.create_output(2, out_fields)) ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() try: comm.do_command(action, in_fields, timeout=0.1) self.assertTrue(False) except CommunicationTimedOutException: pass output = comm.do_command(action, in_fields) self.assertEquals("OK", output["resp"])
def test_do_command_timeout_test_ongoing(self): """ Test if communication resumes after timeout. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([sin(action.create_input(1, in_fields)), sin(action.create_input(2, in_fields)), sout(action.create_output(2, out_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() try: comm.do_command(action, in_fields, timeout=0.1) self.assertTrue(False) except CommunicationTimedOutException: pass output = comm.do_command(action, in_fields) self.assertEquals("OK", output["resp"])
def main(): """ Main function. """ config = ConfigParser() config.read(constants.get_config_file()) defaults = { 'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass') } user_controller = UserController(constants.get_user_database_file(), defaults, 3600) led_service = LedService() controller_serial_port = config.get('OpenMotics', 'controller_serial') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') power_serial_port = config.get('OpenMotics', 'power_serial') controller_serial = Serial(controller_serial_port, 115200) passthrough_serial = Serial(passthrough_serial_port, 115200) power_serial = RS485(Serial(power_serial_port, 115200, timeout=None)) master_communicator = MasterCommunicator(controller_serial) master_communicator.start() power_controller = PowerController(constants.get_power_database_file()) power_communicator = PowerCommunicator(power_serial, power_controller) power_communicator.start() gateway_api = GatewayApi(master_communicator, power_communicator, power_controller) maintenance_service = MaintenanceService( gateway_api, constants.get_ssl_private_key_file(), constants.get_ssl_certificate_file()) passthrough_service = PassthroughService(master_communicator, passthrough_serial) passthrough_service.start() web_interface = WebInterface(user_controller, gateway_api, constants.get_scheduling_database_file(), maintenance_service, led_service.in_authorized_mode) plugin_controller = PluginController(web_interface) plugin_controller.start_plugins() web_interface.set_plugin_controller(plugin_controller) gateway_api.set_plugin_controller(plugin_controller) web_service = WebService(web_interface) web_service.start() led_service.set_led('stat2', True) led_thread = threading.Thread(target=led_driver, args=(led_service, master_communicator, power_communicator)) led_thread.setName("Serial led driver thread") led_thread.daemon = True led_thread.start() def stop(signum, frame): """ This function is called on SIGTERM. """ sys.stderr.write("Shutting down") led_service.set_led('stat2', False) web_service.stop() signal(SIGTERM, stop)
def main(): """ The main function. """ parser = argparse.ArgumentParser(description='Tool to control the master.') parser.add_argument('--port', dest='port', action='store_true', help='get the serial port device') parser.add_argument('--sync', dest='sync', action='store_true', help='sync the serial port') parser.add_argument('--reset', dest='reset', action='store_true', help='reset the master') parser.add_argument('--hard-reset', dest='hardreset', action='store_true', help='perform a hardware reset on the master') parser.add_argument('--version', dest='version', action='store_true', help='get the version of the master') parser.add_argument('--wipe', dest='wipe', action='store_true', help='wip the master eeprom') args = parser.parse_args() config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') if args.port: print port elif args.hardreset: print 'Performing hard reset...' gpio_dir = open('/sys/class/gpio/gpio44/direction', 'w') gpio_dir.write('out') gpio_dir.close() def power(master_on): """ Set the power on the master. """ gpio_file = open('/sys/class/gpio/gpio44/value', 'w') gpio_file.write('1' if master_on else '0') gpio_file.close() power(False) time.sleep(5) power(True) print 'Done performing hard reset' elif args.sync or args.version or args.reset or args.wipe: master_serial = Serial(port, 115200) master_communicator = MasterCommunicator(master_serial) master_communicator.start() if args.sync: print 'Sync...' try: master_communicator.do_command(master_api.status()) print 'Done sync' sys.exit(0) except CommunicationTimedOutException: print 'Failed sync' sys.exit(1) elif args.version: status = master_communicator.do_command(master_api.status()) print '{0}.{1}.{2} H{3}'.format(status['f1'], status['f2'], status['f3'], status['h']) elif args.reset: print 'Resetting...' try: master_communicator.do_command(master_api.reset()) print 'Done resetting' sys.exit(0) except CommunicationTimedOutException: print 'Failed resetting' sys.exit(1) elif args.wipe: (num_banks, bank_size, write_size) = (256, 256, 10) print 'Wiping the master...' for bank in range(0, num_banks): print '- Wiping bank {0}'.format(bank) for addr in range(0, bank_size, write_size): master_communicator.do_command( master_api.write_eeprom(), {'bank': bank, 'address': addr, 'data': '\xff' * write_size} ) master_communicator.do_command(master_api.activate_eeprom(), {'eep': 0}) print 'Done wiping the master' else: parser.print_help()
def test_pulse_counter_status(self): action = master_api.pulse_list() in_fields = {} out_fields = { 'pv0': 0, 'pv1': 1, 'pv2': 2, 'pv3': 3, 'pv4': 4, 'pv5': 5, 'pv6': 6, 'pv7': 7, 'pv8': 8, 'pv9': 9, 'pv10': 10, 'pv11': 11, 'pv12': 12, 'pv13': 13, 'pv14': 14, 'pv15': 15, 'pv16': 16, 'pv17': 17, 'pv18': 18, 'pv19': 19, 'pv20': 20, 'pv21': 21, 'pv22': 22, 'pv23': 23, 'crc': [67, 1, 20] } serial_mock = SerialMock([ sin(action.create_input(1, in_fields)), sout(action.create_output(1, out_fields)) ]) SetUpTestInjections(controller_serial=serial_mock) master_communicator = MasterCommunicator(init_master=False) master_communicator.start() controller = self._get_controller(master_communicator) controller.set_pulse_counter_amount(26) controller.set_pulse_counter_status(24, 123) controller.set_pulse_counter_status(25, 456) status = controller.get_pulse_counter_status() self.assertEquals(range(0, 24) + [123, 456], status) # Set pulse counter for unexisting pulse counter try: controller.set_pulse_counter_status(26, 789) self.fail('Exception should have been thrown') except ValueError as e: self.assertEquals('Could not find pulse counter 26', str(e)) # Set pulse counter for physical pulse counter try: controller.set_pulse_counter_status(23, 789) self.fail('Exception should have been thrown') except ValueError as e: self.assertEquals( 'Cannot set pulse counter status for 23 (should be > 23)', str(e))
def main(): """ Main function. """ config = ConfigParser() config.read(constants.get_config_file()) defaults = { 'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass') } controller_serial_port = config.get('OpenMotics', 'controller_serial') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') power_serial_port = config.get('OpenMotics', 'power_serial') gateway_uuid = config.get('OpenMotics', 'uuid') config_lock = threading.Lock() user_controller = UserController(constants.get_config_database_file(), config_lock, defaults, 3600) config_controller = ConfigurationController( constants.get_config_database_file(), config_lock) led_service = LedService() controller_serial = Serial(controller_serial_port, 115200) power_serial = RS485(Serial(power_serial_port, 115200, timeout=None)) master_communicator = MasterCommunicator(controller_serial) if passthrough_serial_port: passthrough_serial = Serial(passthrough_serial_port, 115200) passthrough_service = PassthroughService(master_communicator, passthrough_serial) passthrough_service.start() master_communicator.start( ) # A running master_communicator is required for the startup of services below power_controller = PowerController(constants.get_power_database_file()) power_communicator = PowerCommunicator(power_serial, power_controller) gateway_api = GatewayApi(master_communicator, power_communicator, power_controller) scheduling_controller = SchedulingController( constants.get_scheduling_database_file(), config_lock, gateway_api) maintenance_service = MaintenanceService( gateway_api, constants.get_ssl_private_key_file(), constants.get_ssl_certificate_file()) web_interface = WebInterface(user_controller, gateway_api, maintenance_service, led_service.in_authorized_mode, config_controller, scheduling_controller) scheduling_controller.set_webinterface(web_interface) plugin_controller = PluginController(web_interface, config_controller) web_interface.set_plugin_controller(plugin_controller) gateway_api.set_plugin_controller(plugin_controller) # Metrics metrics_cache_controller = MetricsCacheController( constants.get_metrics_database_file(), threading.Lock()) metrics_collector = MetricsCollector(gateway_api) metrics_controller = MetricsController(plugin_controller, metrics_collector, metrics_cache_controller, config_controller, gateway_uuid) metrics_collector.set_controllers(metrics_controller, plugin_controller) metrics_collector.set_plugin_intervals(plugin_controller.metric_intervals) metrics_controller.add_receiver(metrics_controller.receiver) metrics_controller.add_receiver(web_interface.distribute_metric) plugin_controller.set_metrics_controller(metrics_controller) web_interface.set_metrics_collector(metrics_collector) web_interface.set_metrics_controller(metrics_controller) web_service = WebService(web_interface, config_controller) def _on_output(*args, **kwargs): metrics_collector.on_output(*args, **kwargs) gateway_api.on_outputs(*args, **kwargs) def _on_input(*args, **kwargs): metrics_collector.on_input(*args, **kwargs) gateway_api.on_inputs(*args, **kwargs) master_communicator.register_consumer( BackgroundConsumer(master_api.output_list(), 0, _on_output, True)) master_communicator.register_consumer( BackgroundConsumer(master_api.input_list(), 0, _on_input)) power_communicator.start() plugin_controller.start_plugins() metrics_controller.start() scheduling_controller.start() metrics_collector.start() web_service.start() led_thread = threading.Thread(target=led_driver, args=(led_service, master_communicator, power_communicator)) led_thread.setName("Serial led driver thread") led_thread.daemon = True led_thread.start() def stop(signum, frame): """ This function is called on SIGTERM. """ _ = signum, frame sys.stderr.write("Shutting down") web_service.stop() metrics_collector.stop() metrics_controller.stop() plugin_controller.stop() signal(SIGTERM, stop)
def test_maintenance_passthrough(self): """ Test the behavior of passthrough in maintenance mode. """ serial_mock = SerialMock([ sout("For passthrough"), sin(master_api.to_cli_mode().create_input(0)), sout("OK"), sin("error list\r\n"), sout("the list\n"), sin("exit\r\n"), sout("Passthrough again")]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() def passthrough_thread(): """ Background thread that reads the passthrough data. """ self.assertEquals("For passthrough", comm.get_passthrough_data()) self.assertEquals("Passthrough again", comm.get_passthrough_data()) thread = threading.Thread(target=passthrough_thread) thread.start() comm.start_maintenance_mode() self.assertEquals("OK", comm.get_maintenance_data()) comm.send_maintenance_data("error list\r\n") self.assertEquals("the list\n", comm.get_maintenance_data()) comm.stop_maintenance_mode() thread.join()
def test_maintenance_mode(self): """ Test the maintenance mode. """ serial_mock = SerialMock([sin(master_api.to_cli_mode().create_input(0)), sout("OK"), sin("error list\r\n"), sout("the list\n"), sin("exit\r\n")]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() comm.start_maintenance_mode() try: comm.send_passthrough_data("test") self.assertTrue(False) except InMaintenanceModeException: pass try: comm.do_command(None, None) self.assertTrue(False) except InMaintenanceModeException: pass self.assertEquals("OK", comm.get_maintenance_data()) comm.send_maintenance_data("error list\r\n") self.assertEquals("the list\n", comm.get_maintenance_data()) comm.stop_maintenance_mode()
def test_maintenance_passthrough(self): """ Test the behavior of passthrough in maintenance mode. """ serial_mock = SerialMock([ sout("For passthrough"), sin(master_api.to_cli_mode().create_input(0)), sout("OK"), sin("error list\r\n"), sout("the list\n"), sin("exit\r\n"), sout("Passthrough again") ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() def passthrough_thread(): """ Background thread that reads the passthrough data. """ self.assertEquals("For passthrough", comm.get_passthrough_data()) self.assertEquals("Passthrough again", comm.get_passthrough_data()) thread = threading.Thread(target=passthrough_thread) thread.start() comm.start_maintenance_mode() self.assertEquals("OK", comm.get_maintenance_data()) comm.send_maintenance_data("error list\r\n") self.assertEquals("the list\n", comm.get_maintenance_data()) comm.stop_maintenance_mode() thread.join()
def main(): """ The main function. """ parser = argparse.ArgumentParser(description='Tool to control the master.') parser.add_argument('--port', dest='port', action='store_true', help='get the serial port device') parser.add_argument('--sync', dest='sync', action='store_true', help='sync the serial port') parser.add_argument('--reset', dest='reset', action='store_true', help='reset the master') parser.add_argument('--hard-reset', dest='hardreset', action='store_true', help='perform a hardware reset on the master') parser.add_argument('--version', dest='version', action='store_true', help='get the version of the master') parser.add_argument('--wipe', dest='wipe', action='store_true', help='wip the master eeprom') args = parser.parse_args() config = ConfigParser() config.read(constants.get_config_file()) port = config.get('OpenMotics', 'controller_serial') if args.port: print port elif args.hardreset: print "Performing hard reset" gpio_dir = open('/sys/class/gpio/gpio44/direction', 'w') gpio_dir.write('out') gpio_dir.close() def power(master_on): """ Set the power on the master. """ gpio_file = open('/sys/class/gpio/gpio44/value', 'w') gpio_file.write('1' if master_on else '0') gpio_file.close() power(False) time.sleep(5) power(True) print "Done" elif args.sync or args.version or args.reset or args.wipe: master_serial = Serial(port, 115200) master_communicator = MasterCommunicator(master_serial) master_communicator.start() if args.sync: try: master_communicator.do_command(master_api.status()) except CommunicationTimedOutException: print "Failed" sys.exit(1) else: print "Done" sys.exit(0) elif args.version: status = master_communicator.do_command(master_api.status()) print "%d.%d.%d H%d" % (status['f1'], status['f2'], status['f3'], status['h']) elif args.reset: master_communicator.do_command(master_api.reset()) print "Reset !" elif args.wipe: (num_banks, bank_size, write_size) = (256, 256, 10) print "Wiping the master" for bank in range(0, num_banks): print " Wiping bank %d" % bank for addr in range(0, bank_size, write_size): master_communicator.do_command(master_api.write_eeprom(), { 'bank': bank, 'address': addr, 'data': '\xff' * write_size }) master_communicator.do_command(master_api.activate_eeprom(), {'eep': 0}) print "Done wiping the master" else: parser.print_help()
def test_do_command_passthrough(self): """ Test for the do_command with passthrough data. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock([ sin(action.create_input(1, in_fields)), sout("hello" + action.create_output(1, out_fields)), sin(action.create_input(2, in_fields)), sout(action.create_output(2, out_fields) + "world"), sin(action.create_input(3, in_fields)), sout("hello" + action.create_output(3, out_fields) + " world"), sin(action.create_input(4, in_fields)), sout("hello"), sout(action.create_output(4, out_fields)) ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello", comm.get_passthrough_data()) self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("world", comm.get_passthrough_data()) self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello world", comm.get_passthrough_data()) self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello", comm.get_passthrough_data())
def test_do_command_passthrough(self): """ Test for the do_command with passthrough data. """ action = master_api.basic_action() in_fields = {"action_type": 1, "action_number": 2} out_fields = {"resp": "OK"} serial_mock = SerialMock( [sin(action.create_input(1, in_fields)), sout("hello" + action.create_output(1, out_fields)), sin(action.create_input(2, in_fields)), sout(action.create_output(2, out_fields) + "world"), sin(action.create_input(3, in_fields)), sout("hello" + action.create_output(3, out_fields) + " world"), sin(action.create_input(4, in_fields)), sout("hello"), sout(action.create_output(4, out_fields))]) comm = MasterCommunicator(serial_mock, init_master=False) comm.enable_passthrough() comm.start() self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello", comm.get_passthrough_data()) self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("world", comm.get_passthrough_data()) self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello world", comm.get_passthrough_data()) self.assertEquals("OK", comm.do_command(action, in_fields)["resp"]) self.assertEquals("hello", comm.get_passthrough_data())
def test_maintenance_mode(self): """ Test the maintenance mode. """ serial_mock = SerialMock([ sin(master_api.to_cli_mode().create_input(0)), sout("OK"), sin("error list\r\n"), sout("the list\n"), sin("exit\r\n") ]) comm = MasterCommunicator(serial_mock, init_master=False) comm.start() comm.start_maintenance_mode() try: comm.send_passthrough_data("test") self.assertTrue(False) except InMaintenanceModeException: pass try: comm.do_command(None, None) self.assertTrue(False) except InMaintenanceModeException: pass self.assertEquals("OK", comm.get_maintenance_data()) comm.send_maintenance_data("error list\r\n") self.assertEquals("the list\n", comm.get_maintenance_data()) comm.stop_maintenance_mode()
def main(): """ Main function. """ log('Starting service...') config = ConfigParser() config.read(constants.get_config_file()) defaults = {'username': config.get('OpenMotics', 'cloud_user'), 'password': config.get('OpenMotics', 'cloud_pass')} controller_serial_port = config.get('OpenMotics', 'controller_serial') passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial') power_serial_port = config.get('OpenMotics', 'power_serial') gateway_uuid = config.get('OpenMotics', 'uuid') config_lock = threading.Lock() user_controller = UserController(constants.get_config_database_file(), config_lock, defaults, 3600) config_controller = ConfigurationController(constants.get_config_database_file(), config_lock) dbus_service = DBusService('openmotics_service') controller_serial = Serial(controller_serial_port, 115200) power_serial = RS485(Serial(power_serial_port, 115200, timeout=None)) master_communicator = MasterCommunicator(controller_serial) eeprom_controller = EepromController( EepromFile(master_communicator), EepromExtension(constants.get_eeprom_extension_database_file()) ) if passthrough_serial_port: passthrough_serial = Serial(passthrough_serial_port, 115200) passthrough_service = PassthroughService(master_communicator, passthrough_serial) passthrough_service.start() power_controller = PowerController(constants.get_power_database_file()) power_communicator = PowerCommunicator(power_serial, power_controller) pulse_controller = PulseCounterController( constants.get_pulse_counter_database_file(), master_communicator, eeprom_controller ) observer = Observer(master_communicator, dbus_service) gateway_api = GatewayApi(master_communicator, power_communicator, power_controller, eeprom_controller, pulse_controller, dbus_service, observer, config_controller) observer.set_gateway_api(gateway_api) scheduling_controller = SchedulingController(constants.get_scheduling_database_file(), config_lock, gateway_api) maintenance_service = MaintenanceService(gateway_api, constants.get_ssl_private_key_file(), constants.get_ssl_certificate_file()) web_interface = WebInterface(user_controller, gateway_api, maintenance_service, dbus_service, config_controller, scheduling_controller) scheduling_controller.set_webinterface(web_interface) # Plugins plugin_controller = PluginController(web_interface, config_controller) web_interface.set_plugin_controller(plugin_controller) gateway_api.set_plugin_controller(plugin_controller) # Metrics metrics_cache_controller = MetricsCacheController(constants.get_metrics_database_file(), threading.Lock()) metrics_collector = MetricsCollector(gateway_api, pulse_controller) metrics_controller = MetricsController(plugin_controller, metrics_collector, metrics_cache_controller, config_controller, gateway_uuid) metrics_collector.set_controllers(metrics_controller, plugin_controller) metrics_controller.add_receiver(metrics_controller.receiver) metrics_controller.add_receiver(web_interface.distribute_metric) plugin_controller.set_metrics_controller(metrics_controller) plugin_controller.set_metrics_collector(metrics_collector) web_interface.set_metrics_collector(metrics_collector) web_interface.set_metrics_controller(metrics_controller) web_service = WebService(web_interface, config_controller) plugin_controller.set_webservice(web_service) observer.subscribe_master(Observer.MasterEvents.INPUT_TRIGGER, metrics_collector.on_input) observer.subscribe_master(Observer.MasterEvents.INPUT_TRIGGER, plugin_controller.process_input_status) observer.subscribe_master(Observer.MasterEvents.ON_OUTPUTS, metrics_collector.on_output) observer.subscribe_master(Observer.MasterEvents.ON_OUTPUTS, plugin_controller.process_output_status) observer.subscribe_master(Observer.MasterEvents.ON_SHUTTER_UPDATE, plugin_controller.process_shutter_status) observer.subscribe_events(web_interface.process_observer_event) led_thread = threading.Thread(target=led_driver, args=(dbus_service, master_communicator, power_communicator)) led_thread.setName("Serial led driver thread") led_thread.daemon = True led_thread.start() master_communicator.start() observer.start() power_communicator.start() metrics_controller.start() scheduling_controller.start() metrics_collector.start() web_service.start() gateway_api.start() plugin_controller.start() signal_request = {'stop': False} def stop(signum, frame): """ This function is called on SIGTERM. """ _ = signum, frame log('Stopping service...') web_service.stop() metrics_collector.stop() metrics_controller.stop() plugin_controller.stop() log('Stopping service... Done') signal_request['stop'] = True signal(SIGTERM, stop) log('Starting service... Done') while not signal_request['stop']: time.sleep(1)