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)