Пример #1
0
def main_interface():
    """
    Render the main interface page.
    """
    HIBIKE_INSTANCE.subscribe_all()
    from collections import namedtuple
    import time
    # Wait for Hibike to read from devices
    time.sleep(0.5)
    devices = []
    for uid in HIBIKE_INSTANCE.uids:
        dev_id = hibike_message.uid_to_device_id(uid)
        dev_name = hibike_message.uid_to_device_name(uid)
        all_params = hibike_message.all_params_for_device_id(dev_id)
        params_list = []
        for param_name in all_params:
            param = namedtuple(
                "Parameter",
                ("name", "type", "readable", "writeable", "init_value"))
            param.name = param_name
            param.type = hibike_message.param_type(dev_id, param_name)
            param.writeable = hibike_message.writable(dev_id, param_name)
            param.readable = hibike_message.readable(dev_id, param_name)
            param.init_value = HIBIKE_INSTANCE.get_last_cached(uid, param_name)
            params_list.append(param)
        params_list.sort(key=lambda p: p.name)
        device = namedtuple("Device", ("uid", "params", "name"))
        device.uid = uid
        device.params = params_list
        device.name = dev_name
        devices.append(device)
    return render_template("index.html", devices=devices)
Пример #2
0
 def subscribe_all(self):
     """
     Subscribe to all devices with all parameters.
     """
     for uid in self.uids:
         dev_id = hibike_message.uid_to_device_id(uid)
         all_params = hibike_message.all_params_for_device_id(dev_id)
         readable_params = []
         for param in all_params:
             if hibike_message.readable(dev_id, param):
                 readable_params.append(param)
         self.pipe_to_child.send(["subscribe_device", [uid, self.DEFAULT_DELAY,
                                                       readable_params]])
Пример #3
0
def read_all_params(uid):
    """
    Read all parameters from a device.
    """
    if uid not in HIBIKE_INSTANCE.uids:
        abort(404)
    dev_id = hibike_message.uid_to_device_id(uid)
    all_params = hibike_message.all_params_for_device_id(dev_id)
    readable_params = [p for p in all_params if hibike_message.readable(dev_id, p)]
    param_values = {}
    for param in readable_params:
        param_values[param] = HIBIKE_INSTANCE.get_last_cached(uid, param)
    return json.dumps(param_values)
Пример #4
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))
Пример #5
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))
Пример #6
0
def get_device_info(uid):
    """
    Get a dictionary representing information about a device.
    """
    if uid not in HIBIKE_INSTANCE.uids:
        raise DeviceNotFoundError()
    device_id = hibike_message.uid_to_device_id(uid)
    device_name = hibike_message.device_id_to_name(device_id)
    params = hibike_message.all_params_for_device_id(device_id)
    json_map = {"device_name": device_name, "params": []}
    for param in params:
        readable = hibike_message.readable(device_id, param)
        writeable = hibike_message.writable(device_id, param)
        param_type = hibike_message.param_type(device_id, param)
        json_map["params"].append({"name": param,
                                   "readable": readable,
                                   "writeable": writeable,
                                   "type": param_type})
    return json_map
Пример #7
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))