Example #1
0
def lookup():
    """Render JSON formatted device MODBUS map.

    Render a JSON listing of filtered MODBUS map records for use in external
    applications or by the simple register lookup tool itself.

    @return: JSON encoded MODBUS map records.
    @rtype: str
    """

    # Parse user query parameters
    device_name = request.args.get("device_name", ALL_DEVICES_NAME)
    tags = prepareFilterArg(request.args.get("tags", ALL_TAGS_NAME))
    not_tags = prepareFilterArg(request.args.get("not-tags", "null"))
    add_reg_names = prepareFilterArg(request.args.get("add-reg-names", "null"))
    add_regs_str = prepareFilterArg(request.args.get("add-regs", "null"))
    expand = request.args.get("expand-addresses", "true")
    dataset_cols = prepareFilterArg(request.args.get("fields", "null"))

    dataset_cols = map(
        lambda x: "access" if x == "rw" else x,
        dataset_cols
    )

    # If the desired attributes were not provided, use defaults.
    if not dataset_cols:
        dataset_cols = serialize.DEVICE_MODBUS_MAP_COLS

    # Check if a device was specified and, if it wasn"t, default to all devices.
    if device_name in INVALID_FILTER_ARGUMENTS:
        device_name = ALL_DEVICES_NAME

    # If not specified, do not expand LMMM fields.
    if expand in INVALID_FILTER_ARGUMENTS:
        expand = "false"

    # Choose between either the MODBUS maps with raw LJMMM entries or the maps
    # with LJMMM fields interpreted and expanded.
    if expand == "true" or add_regs_str:
        regs_to_use = reg_data_expanded
    else:
        regs_to_use = reg_data_compressed

    # Filter out which entries to use based on device.
    if device_name != ALL_DEVICES_NAME:
        regs_to_use = [x for x in regs_to_use if match_device(x, device_name)]

    # If the selected device / modbus map is not available, default to not
    # found.
    if len(regs_to_use) == 0:
        flask.abort(404)

    # Pre filter
    unfiltered_registers = []
    if add_reg_names:
        for entry in regs_to_use:
            for reg_num in add_reg_names:
                if unicode(reg_num) in unicode(entry["name"]):
                    unfiltered_registers.append(entry)

    if add_regs_str:
        add_regs = map(lambda x: int(x), add_regs_str)
        regs_to_use = filter(lambda x: x["address"] in add_regs, regs_to_use)

    # Filter by tag
    if tags and unicode(ALL_TAGS_NAME) not in tags:
        tags_set = set(tags)
        regs_to_use = filter(
            lambda x: set(x["tags"]).issuperset(tags_set),
            regs_to_use
        )

    # Filter by not-tag
    if not_tags: # and unicode(NO_TAGS_NAME) not in not_tags:
        entries_to_remove = []
        for entry in regs_to_use:
            for map_tag in entry["tags"]:
                for not_tag in not_tags:
                    if map_tag.find(unicode(not_tag)) != -1:
                        entries_to_remove.append(entry)

        for entry in entries_to_remove:
            regs_to_use.remove(entry)

    # Add the pre-filter contents
    for unfiltered_reg in unfiltered_registers:
        duplicate = False
        for reg in regs_to_use:
            if unicode(unfiltered_reg["name"]) == unicode(reg["name"]):
                duplicate = True

        if not duplicate:
            regs_to_use.append(unfiltered_reg)

    # Serialize the results and return.
    modbus_map_serialized = serialize.serialize_device_modbus_map(regs_to_use,
        dataset_cols)
    response = flask.make_response(json.dumps(modbus_map_serialized))
    response.headers["X-XSS-Protection"] = "0"
    response.headers["Access-Control-Allow-Origin"] = ALLOWED_REDISPLAY_DOMAIN
    return response
def lookup():
    """Render JSON formatted device MODBUS map.

    Render a JSON listing of filtered MODBUS map records for use in external
    applications or by the simple register lookup tool itself.

    @return: JSON encoded MODBUS map records.
    @rtype: str
    """

    # Parse user query parameters
    device_name = request.args.get("device_name", ALL_DEVICES_NAME)
    tags = prepareFilterArg(request.args.get("tags", ALL_TAGS_NAME))
    not_tags = prepareFilterArg(request.args.get("not-tags", "null"))
    add_reg_names = prepareFilterArg(request.args.get("add-reg-names", "null"))
    add_regs_str = prepareFilterArg(request.args.get("add-regs", "null"))
    expand = request.args.get("expand-addresses", "true")
    dataset_cols = prepareFilterArg(request.args.get("fields", "null"))

    dataset_cols = map(lambda x: "access" if x == "rw" else x, dataset_cols)

    # If the desired attributes were not provided, use defaults.
    if not dataset_cols:
        dataset_cols = serialize.DEVICE_MODBUS_MAP_COLS

    # Check if a device was specified and, if it wasn"t, default to all devices.
    if device_name in INVALID_FILTER_ARGUMENTS:
        device_name = ALL_DEVICES_NAME

    # If not specified, do not expand LMMM fields.
    if expand in INVALID_FILTER_ARGUMENTS:
        expand = "false"

    # Choose between either the MODBUS maps with raw LJMMM entries or the maps
    # with LJMMM fields interpreted and expanded.
    if expand == "true" or add_regs_str:
        regs_to_use = reg_data_expanded
    else:
        regs_to_use = reg_data_compressed

    # Filter out which entries to use based on device.
    if device_name != ALL_DEVICES_NAME:
        regs_to_use = [x for x in regs_to_use if match_device(x, device_name)]

    # If the selected device / modbus map is not available, default to not
    # found.
    if len(regs_to_use) == 0:
        flask.abort(404)

    # Pre filter
    unfiltered_registers = []
    if add_reg_names:
        for entry in regs_to_use:
            for reg_num in add_reg_names:
                if unicode(reg_num) in unicode(entry["name"]):
                    unfiltered_registers.append(entry)

    if add_regs_str:
        add_regs = map(lambda x: int(x), add_regs_str)
        regs_to_use = filter(lambda x: x["address"] in add_regs, regs_to_use)

    # Filter by tag
    if tags and unicode(ALL_TAGS_NAME) not in tags:
        tags_set = set(tags)
        regs_to_use = filter(lambda x: set(x["tags"]).issuperset(tags_set), regs_to_use)

    # Filter by not-tag
    if not_tags:  # and unicode(NO_TAGS_NAME) not in not_tags:
        entries_to_remove = []
        for entry in regs_to_use:
            for map_tag in entry["tags"]:
                for not_tag in not_tags:
                    if map_tag.find(unicode(not_tag)) != -1:
                        entries_to_remove.append(entry)

        for entry in entries_to_remove:
            regs_to_use.remove(entry)

    # Add the pre-filter contents
    for unfiltered_reg in unfiltered_registers:
        duplicate = False
        for reg in regs_to_use:
            if unicode(unfiltered_reg["name"]) == unicode(reg["name"]):
                duplicate = True

        if not duplicate:
            regs_to_use.append(unfiltered_reg)

    # Serailize the results and return.
    modbus_map_serialized = serialize.serialize_device_modbus_map(regs_to_use, dataset_cols)
    response = flask.make_response(json.dumps(modbus_map_serialized))
    response.headers["X-XSS-Protection"] = "0"
    response.headers["Access-Control-Allow-Origin"] = ALLOWED_REDISPLAY_DOMAIN
    return response
    def test_serialize_device_modbus_map(self):
        """Test serializing a modbus map for a single device."""
        test_modbus_map = [{
            "name": "test_1",
            "address": 1,
            "type": "UINT16",
            "numregs": 1,
            "fwmin": 0,
            "readwrite": {
                "read": True,
                "write": False
            },
            "tags": ["tag1", "tag2"],
            "description": "test1"
        }, {
            "name": "test_2",
            "address": 2,
            "type": "UINT16",
            "numregs": 1,
            "fwmin": 0,
            "readwrite": {
                "read": False,
                "write": True
            },
            "tags": ["tag3", "tag4"],
            "description": "test2",
            "altnames": ["alternate_name"],
            "usesRAM": True,
        }]
        expected = [[
            "name",
            "address",
            "type",
            "access",
            "tags",
            "description",
            "default",
            "streamable",
            "isBuffer",
            "devices",
            "constants",
            "altnames",
            "usesRAM",
        ],
                    [
                        "test_1",
                        1,
                        "UINT16",
                        "R",
                        "tag1, tag2",
                        "test1",
                        "",
                        None,
                        None,
                        None,
                        None,
                        [],
                        None,
                    ],
                    [
                        "test_2 (also known as: alternate_name)",
                        2,
                        "UINT16",
                        "W",
                        "tag3, tag4",
                        "test2",
                        "",
                        None,
                        None,
                        None,
                        None,
                        ['alternate_name'],
                        True,
                    ]]

        serialized = serialize.serialize_device_modbus_map(test_modbus_map)
        self.assertListEqual(serialized, expected)