def gen_random_device_data():
     """ Generate a random device data packet. """
     device_id = random.choice(DEVICE_TYPES)
     params = random_params(device_id)
     values = random_values(device_id, params)
     params_and_values = [(param, value)
                          for param, value in zip(params, values)]
     msg = hibike_message.make_device_data(device_id, params_and_values)
     return (ParsingTests.encode_packet(msg), )
Esempio n. 2
0
    def _process_device_read(self, msg):
        self.verbose_log("Device read received")
        device_id = hm.uid_to_device_id(self.uid)
        # Send a device data with the requested param and value tuples
        params, = struct.unpack("<H", msg.get_payload())
        read_params = hm.decode_params(device_id, params)
        read_data = []

        for param in read_params:
            if not (hm.readable(device_id, param)
                    and param in self.param_values):
                raise ValueError(
                    "Tried to read unreadable parameter {}".format(param))
            read_data.append((param, self.param_values[param]))
        hm.send(self.transport, hm.make_device_data(device_id, read_data))
Esempio n. 3
0
 async def send_subscribed_params(self):
     """Send values of subscribed parameters at a regular interval."""
     await self._ready.wait()
     device_id = hm.uid_to_device_id(self.uid)
     while not self.transport.is_closing():
         await asyncio.sleep(0.005, loop=self.event_loop)
         if self.update_time != 0 and self.delay != 0:
             if time.time() - self.update_time >= self.delay * 0.001:
                 # If the time equal to the delay has elapsed since the previous device data,
                 # send a device data with the device id
                 # and the device's subscribed params and values
                 data = []
                 for param in self.subscribed_params:
                     data.append((param, self.param_values[param]))
                 hm.send(self.transport,
                         hm.make_device_data(device_id, data))
                 self.update_time = time.time()
                 self.verbose_log("Regular data update sent from {}",
                                  hm.uid_to_device_name(self.uid))
Esempio n. 4
0
    def _process_device_write(self, msg):
        # Write to requested parameters
        # and return the values of the parameters written to using a device data
        self.verbose_log("Device write received")
        device_id = hm.uid_to_device_id(self.uid)
        write_params_and_values = hm.decode_device_write(msg, device_id)

        for (param, value) in write_params_and_values:
            if not (hm.writable(device_id, param)
                    and param in self.param_values):
                raise ValueError(
                    "Tried to write read-only parameter: {}".format(param))
            self.param_values[param] = value

        updated_params = []
        for (param, value) in write_params_and_values:
            if hm.readable(device_id, param):
                updated_params.append((param, value))
        hm.send(self.transport, hm.make_device_data(device_id, updated_params))
Esempio n. 5
0
def main():
    """
    Create virtual devices and send test data on them.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--device', required=True, help='device type')
    parser.add_argument('-p', '--port', required=True, help='serial port')
    parser.add_argument(
        '-v',
        '--verbose',
        help='print messages when sending and receiving packets',
        action="store_true")
    args = parser.parse_args()

    def verbose_log(fmt_string, *fmt_args):
        """
        Log a message using a formatting string if verbosity
        is enabled.
        """
        if args.verbose:
            print(fmt_string.format(*fmt_args))

    device = args.device
    port = args.port
    verbose_log("Device {} on port {}", device, port)
    conn = serial.Serial(port, 115200)

    for device_num in hm.DEVICES:
        if hm.DEVICES[device_num]["name"] == device:
            device_id = device_num
            break
    else:
        raise RuntimeError("Invalid Device Name!!!")

    year = 1
    randomness = random.randint(0, 0xFFFFFFFFFFFFFFFF)
    delay = 0
    update_time = 0
    uid = (device_id << 72) | (year << 64) | randomness

    # Here, the parameters and values to be sent in device datas
    # are set for each device type, the list of subscribed parameters is set to empty,
    if device == "LimitSwitch":
        subscribed_params = []
        params_and_values = [("switch0", True), ("switch1", True),
                             ("switch2", False), ("switch3", False)]
    if device == "ServoControl":
        subscribed_params = []
        params_and_values = [("servo0", 2), ("enable0", True), ("servo1", 0),
                             ("enable1", True), ("servo2", 5),
                             ("enable2", True), ("servo3", 3),
                             ("enable3", False)]
    if device == "Potentiometer":
        subscribed_params = []
        params_and_values = [("pot0", 6.7), ("pot1", 5.5), ("pot2", 34.1),
                             ("pot3", 0.15)]
    if device == "YogiBear":
        subscribed_params = []
        params_and_values = [("enable", True), ("command_state", 1),
                             ("duty_cycle", 1.0), ("pid_pos_setpoint", 2.0),
                             ("pid_pos_kp", 3.0), ("pid_pos_ki", 4.0),
                             ("pid_pos_kd", 5.0), ("pid_vel_setpoint", 6.0),
                             ("pid_vel_kp", 7.0), ("pid_vel_ki", 8.0),
                             ("pid_vel_kd", 9.0), ("current_thresh", 10.0),
                             ("enc_pos", 11.0), ("enc_vel", 12.0),
                             ("motor_current", 13.0), ("deadband", 0.5)]
    if device == "RFID":
        subscribed_params = []
        params_and_values = [("id", 0), ("tag_detect", 0)]
    if device == "BatteryBuzzer":
        subscribed_params = []
        params_and_values = [("is_unsafe", False), ("calibrated", True),
                             ("v_cell1", 11.0), ("v_cell2", 11.0),
                             ("v_cell3", 11.0), ("v_batt", 11.0),
                             ("dv_cell2", 11.0), ("dv_cell3", 11.0)]
    if device == "LineFollower":
        subscribed_params = []
        params_and_values = [("left", 1.0), ("center", 1.0), ("right", 1.0)]

    while True:
        if update_time != 0 and delay != 0:
            if time.time() - update_time >= delay * 0.001:
                # If the time equal to the delay has elapsed since the previous device data,
                # send a device data with the device id
                # and the device's subscribed params and values
                data = []
                for data_tuple in params_and_values:
                    if data_tuple[0] in subscribed_params and hm.readable(
                            device_id, data_tuple[0]):
                        data.append(data_tuple)
                hm.send(conn, hm.make_device_data(device_id, data))
                update_time = time.time()
                verbose_log("Regular data update sent from {}", device)

        msg = hm.read(conn)
        if not msg:
            time.sleep(.005)
            continue
        if msg.get_message_id() in [hm.MESSAGE_TYPES["SubscriptionRequest"]]:
            # Update the delay, subscription time,
            # and params, then send a subscription response
            verbose_log("Subscription request received")
            params, delay = struct.unpack("<HH", msg.get_payload())

            subscribed_params = hm.decode_params(device_id, params)
            hm.send(
                conn,
                hm.make_subscription_response(device_id, subscribed_params,
                                              delay, uid))
            update_time = time.time()
        if msg.get_message_id() in [hm.MESSAGE_TYPES["Ping"]]:
            # Send a subscription response
            verbose_log("Ping received")
            hm.send(
                conn,
                hm.make_subscription_response(device_id, subscribed_params,
                                              delay, uid))
        if msg.get_message_id() in [hm.MESSAGE_TYPES["DeviceRead"]]:
            # Send a device data with the requested param and value tuples
            verbose_log("Device read received")
            params = struct.unpack("<H", msg.get_payload())
            read_params = hm.decode_params(device_id, params)
            read_data = []

            for data_tuple in params_and_values:
                if data_tuple[0] in read_params:
                    if not hm.readable(device_id, data_tuple[0]):
                        # Raise a syntax error if one of the values to be read is not readable
                        raise SyntaxError(
                            "Attempted to read an unreadable value")
                    read_data.append(data_tuple)
            hm.send(conn, hm.make_device_data(device_id, read_data))

        if msg.get_message_id() in [hm.MESSAGE_TYPES["DeviceWrite"]]:
            # Write to requested parameters
            # and return the values of the parameters written to using a device data
            verbose_log("Device write received")
            write_params_and_values = hm.decode_device_write(msg, device_id)
            write_params = [
                param_val[0] for param_val in write_params_and_values
            ]
            value_types = [
                hm.PARAM_MAP[device_id][name][1] for name in write_params
            ]

            write_tuples = []
            # pylint: disable=consider-using-enumerate
            for index in range(len(write_params)):
                write_tuples.append(
                    (write_params[index], write_params_and_values[index][1]))
            for new_tuple in write_tuples:
                if not hm.writable(device_id, new_tuple[0]):
                    # Raise a syntax error if the value
                    # that the message attempted to write to is not writable
                    raise SyntaxError(
                        "Attempted to write to an unwritable value")
                params_and_values[hm.PARAM_MAP[device_id][new_tuple[0]]
                                  [0]] = new_tuple

            # Send the written data, make sure you only send data for readable parameters
            index = 0
            while index < len(write_params):
                if hm.readable(device_id, write_tuples[index][0]):
                    index += 1
                else:
                    del write_tuples[index]
            hm.send(conn, hm.make_device_data(device_id, write_tuples))
Esempio n. 6
0
    subscribed_params = []
    params_and_values = [("pot0", 6.7), ("pot1", 5.5), ("pot2", 34.1),
                         ("pot3", 0.15)]
if device == "YogiBear":
    subscribed_params = []
    params_and_values = [("duty", 20), ("forward", False)]

while (True):
    if (updateTime != 0 and delay != 0):
        if ((time.time() - updateTime) >= (delay * 0.001)):
            #If the time equal to the delay has elapsed since the previous device data, send a device data with the device id and the device's subscribed params and values
            data = [
                data_tuple for data_tuple in params_and_values
                if data_tuple[0] in subscribed_params
            ]
            hm.send(conn, hm.make_device_data(device_id, data))
            updateTime = time.time()
            print("Regular data update sent from %s" % device)

    msg = hm.read(conn)
    if not msg:
        time.sleep(.005)
        continue
    if msg.getmessageID() in [hm.messageTypes["SubscriptionRequest"]]:
        #Update the delay, subscription time, and params, then send a subscription response
        print("Subscription request recieved")
        params, delay = struct.unpack("<HH", msg.getPayload())

        subscribed_params = hm.decode_params(device_id, params)
        hm.send(
            conn,