def linked_tile(rpc_agent, tmpdir): """Create a connected HardwareManager instance with a proxy pointed at an RPCDispatcher.""" visor, _client1, _client2 = rpc_agent # Create a config file that we can use to initialize a virtual device that will point at our # BasicRPCDispatch via a running IOTileSupervisor. Currently, HardwareManager can only # load configurations for virtual devices from actual files, so we need to save this to a # temp file. config = { "device": { "iotile_id": 1, "tiles": [{ "name": "service_delegate", "address": 11, "args": { "url": "ws://127.0.0.1:%d/services" % visor. port, # This has to match the port of the supervisor instance that we want to connect to "service": "service_1", # This has to match the service name that the RPCDispatcher is registered as an agent for "name": "bsctst" # This is the 6 character string that must match the ModuleName() of the proxy and is used to find the right proxy } }] } } # This is a special py.path.local object from pytest # https://docs.pytest.org/en/latest/tmpdir.html config_path_obj = tmpdir.join('config.json') config_path_obj.write(json.dumps(config)) config_path = str(config_path_obj) reg = ComponentRegistry() reg.register_extension('iotile.proxy', 'test_proxy', BasicRPCDispatcherProxy) # This will create a HardwareManager pointed at a virtual tile based device # where the tiles that are added to the virtual device are found using the config # file specified after the @ symbol. hw = HardwareManager(port="virtual:tile_based@%s" % config_path) # pylint:disable=invalid-name; We use hw throughout CoreTools to denote a HardwareManager instance # We specified that the virtual device should be at uuid 1 (using iotile_id above) # so we know how to connect to it. We also know that we specified a single tile # at address 11 inside that virtual device so we will be able to get its proxy # object by calling hw.get(11) once we are connected. hw.connect(1) yield hw hw.disconnect() reg.clear_extensions('iotile.proxy')
class SemihostedRPCExecutor(RPCExecutor): """An RPC executor that runs RPCs on an IOTile device. This is used for "semihosting" a sensor graph where the SG engine runs on your computer but all RPCs are executed on a separete IOTile device. Semihosting is not 100% the same as running the SensorGraph on the device itself because: 1. system inputs and inputs are currently not forwarded from the device to the computer so you cannot respond to events from tiles. (This will be addressed in the future) 2. config variables set in the sensor graph are currently not set in the device, which means tiles that have required configurations need to be manually configured before semihosting a sensor graph. (This will be addressed in the future) Args: port (str): The port we should use to create a HardwareManager instance conected to our device. device_id (int): The device id we should connect to. """ def __init__(self, port, device_id): self.hw = HardwareManager(port=port) self.hw.connect(device_id) super(SemihostedRPCExecutor, self).__init__() def _call_rpc(self, address, rpc_id, payload): """Call an RPC with the given information and return its response. Must raise a hardware error of the appropriate kind if the RPC can not be executed correctly. Otherwise it should return the binary response payload received from the RPC. Args: address (int): The address of the tile we want to call the RPC on rpc_id (int): The id of the RPC that we want to call payload (bytes, bytearray): The data that we want to send as the payload """ # FIXME: Set a timeout of 1.1 seconds to make sure we fail if the device hangs but # this should be long enough to accommodate any actual RPCs we need to send. status, response = self.hw.stream.send_rpc(address, rpc_id, payload, timeout=1.1) return response
class TestBLED112Loopback(unittest.TestCase): def setUp(self): self.vdev = subprocess.Popen( ['virtual_device', 'bled112', 'report_test']) bleds = BLED112Adapter.find_bled112_devices() print(bleds) self.hw = HardwareManager(port='bled112:{}'.format(bleds[1])) def tearDown(self): self.hw.close() self.vdev.terminate() def test_loopback(self): time.sleep(2) print(self.hw.scan()) self.hw.connect(1) con = self.hw.controller() assert con.ModuleName() == 'Simple' self.hw.enable_streaming() assert self.hw.count_reports() == 11
def inline_config_report_hw(tmpdir): config = { "device": { "iotile_id": "1", "reading_start": 0, "num_readings": 0, "stream_id": "5001", "format": "signed_list", "report_length": 0, "signing_method": 0 } } config_obj = tmpdir.join("config.json") config_obj.write(json.dumps(config)) config_path = str(config_obj) hw = HardwareManager(port="virtual:report_test@%s" % config_path) hw.connect(1) yield hw hw.disconnect()