예제 #1
0
 def parse(raw: bytes, colors, drawables, texts, sizes, image_config, *args, **kwargs) -> MapData:
     scale = float(image_config[CONF_SCALE])
     map_image_size = raw.find(bytes([127, 123]))
     map_image = raw[16:map_image_size + 1]
     map_info_raw = raw[map_image_size + 1:]
     map_info = json.loads(map_info_raw)
     width = map_info["width"]
     height = map_info["height"]
     x_min = map_info["x_min"]
     y_min = map_info["y_min"]
     resolution = map_info["resolution"]
     x_min_calc = x_min / resolution
     y_min_calc = y_min / resolution
     map_data = MapData(0, 1000)
     map_data.rooms = MapDataParserRoidmi.parse_rooms(map_info)
     image = MapDataParserRoidmi.parse_image(map_image, width, height, x_min_calc, y_min_calc, resolution,
                                             colors, image_config, map_data.rooms)
     map_data.image = image
     map_data.path = MapDataParserRoidmi.parse_path(map_info)
     map_data.vacuum_position = MapDataParserRoidmi.parse_vacuum_position(map_info)
     map_data.charger = MapDataParserRoidmi.parse_charger_position(map_info)
     map_data.no_go_areas, map_data.no_mopping_areas, map_data.walls = MapDataParserRoidmi.parse_areas(map_info)
     if not map_data.image.is_empty:
         MapDataParserRoidmi.draw_elements(colors, drawables, sizes, map_data, image_config)
         if len(map_data.rooms) > 0 and map_data.vacuum_position is not None:
             map_data.vacuum_room = MapDataParserRoidmi.get_current_vacuum_room(map_image, map_data, width)
             if map_data.vacuum_room is not None:
                 map_data.vacuum_room_name = map_data.rooms[map_data.vacuum_room].name
         ImageHandlerRoidmi.rotate(map_data.image)
         ImageHandlerRoidmi.draw_texts(map_data.image, texts)
     return map_data
예제 #2
0
 def extract_attributes(map_data: MapData, attributes_to_return: List[str],
                        country) -> Dict[str, Any]:
     attributes = {}
     rooms = []
     if map_data.rooms is not None:
         rooms = dict(
             filter(lambda x: x[0] is not None,
                    ((x[0], x[1].name) for x in map_data.rooms.items())))
         if len(rooms) == 0:
             rooms = list(map_data.rooms.keys())
     for name, value in {
             ATTRIBUTE_CALIBRATION: map_data.calibration(),
             ATTRIBUTE_CHARGER: map_data.charger,
             ATTRIBUTE_CLEANED_ROOMS: map_data.cleaned_rooms,
             ATTRIBUTE_COUNTRY: country,
             ATTRIBUTE_GOTO: map_data.goto,
             ATTRIBUTE_GOTO_PATH: map_data.goto_path,
             ATTRIBUTE_GOTO_PREDICTED_PATH: map_data.predicted_path,
             ATTRIBUTE_IGNORED_OBSTACLES: map_data.ignored_obstacles,
             ATTRIBUTE_IGNORED_OBSTACLES_WITH_PHOTO:
             map_data.ignored_obstacles_with_photo,
             ATTRIBUTE_IMAGE: map_data.image,
             ATTRIBUTE_IS_EMPTY: map_data.image.is_empty,
             ATTRIBUTE_MAP_NAME: map_data.map_name,
             ATTRIBUTE_NO_GO_AREAS: map_data.no_go_areas,
             ATTRIBUTE_NO_MOPPING_AREAS: map_data.no_mopping_areas,
             ATTRIBUTE_OBSTACLES: map_data.obstacles,
             ATTRIBUTE_OBSTACLES_WITH_PHOTO: map_data.obstacles_with_photo,
             ATTRIBUTE_PATH: map_data.path,
             ATTRIBUTE_ROOM_NUMBERS: rooms,
             ATTRIBUTE_ROOMS: map_data.rooms,
             ATTRIBUTE_VACUUM_POSITION: map_data.vacuum_position,
             ATTRIBUTE_VACUUM_ROOM: map_data.vacuum_room,
             ATTRIBUTE_VACUUM_ROOM_NAME: map_data.vacuum_room_name,
             ATTRIBUTE_WALLS: map_data.walls,
             ATTRIBUTE_ZONES: map_data.zones
     }.items():
         if name in attributes_to_return:
             attributes[name] = value
     return attributes
예제 #3
0
    def parse(raw: bytes, colors, drawables, texts, sizes,
              image_config) -> MapData:
        map_data = MapData(0, 1)
        buf = ParsingBuffer('header', raw, 0, len(raw))
        feature_flags = buf.get_uint32('feature_flags')
        map_id = buf.peek_uint32('map_id')
        _LOGGER.debug('feature_flags: 0x%x, map_id: %d', feature_flags, map_id)

        if feature_flags & MapDataParserViomi.FEATURE_ROBOT_STATUS != 0:
            MapDataParserViomi.parse_section(buf, 'robot_status', map_id)
            buf.skip('unknown1', 0x28)

        if feature_flags & MapDataParserViomi.FEATURE_IMAGE != 0:
            MapDataParserViomi.parse_section(buf, 'image', map_id)
            map_data.image, map_data.rooms, map_data.cleaned_rooms = \
                MapDataParserViomi.parse_image(buf, colors, image_config, DRAWABLE_CLEANED_AREA in drawables)

        if feature_flags & MapDataParserViomi.FEATURE_HISTORY != 0:
            MapDataParserViomi.parse_section(buf, 'history', map_id)
            map_data.path = MapDataParserViomi.parse_history(buf)

        if feature_flags & MapDataParserViomi.FEATURE_CHARGE_STATION != 0:
            MapDataParserViomi.parse_section(buf, 'charge_station', map_id)
            map_data.charger = MapDataParserViomi.parse_position(buf, 'pos')
            foo = buf.get_float32('foo')
            _LOGGER.debug('pos: %s, foo: %f', map_data.charger, foo)

        if feature_flags & MapDataParserViomi.FEATURE_RESTRICTED_AREAS != 0:
            MapDataParserViomi.parse_section(buf, 'restricted_areas', map_id)
            map_data.walls, map_data.no_go_areas = MapDataParserViomi.parse_restricted_areas(
                buf)

        if feature_flags & MapDataParserViomi.FEATURE_CLEANING_AREAS != 0:
            MapDataParserViomi.parse_section(buf, 'cleaning_areas', map_id)
            map_data.zones = MapDataParserViomi.parse_cleaning_areas(buf)

        if feature_flags & MapDataParserViomi.FEATURE_NAVIGATE != 0:
            MapDataParserViomi.parse_section(buf, 'navigate', map_id)
            buf.skip('unknown1', 4)
            map_data.goto = MapDataParserViomi.parse_position(buf, 'pos')
            foo = buf.get_float32('foo')
            _LOGGER.debug('pos: %s, foo: %f', map_data.goto, foo)

        if feature_flags & MapDataParserViomi.FEATURE_REALTIME != 0:
            MapDataParserViomi.parse_section(buf, 'realtime', map_id)
            buf.skip('unknown1', 5)
            map_data.vacuum_position = MapDataParserViomi.parse_position(
                buf, 'pos')
            foo = buf.get_float32('foo')
            _LOGGER.debug('pos: %s, foo: %f', map_data.vacuum_position, foo)

        if feature_flags & 0x00000800 != 0:
            MapDataParserViomi.parse_section(buf, 'unknown1', map_id)
            MapDataParserViomi.parse_unknown_section(buf)

        if feature_flags & MapDataParserViomi.FEATURE_ROOMS != 0:
            MapDataParserViomi.parse_section(buf, 'rooms', map_id)
            MapDataParserViomi.parse_rooms(buf, map_data.rooms)

        if feature_flags & 0x00002000 != 0:
            MapDataParserViomi.parse_section(buf, 'unknown2', map_id)
            MapDataParserViomi.parse_unknown_section(buf)

        if feature_flags & 0x00004000 != 0:
            MapDataParserViomi.parse_section(buf, 'room_outlines', map_id)
            MapDataParserViomi.parse_room_outlines(buf)

        buf.check_empty()

        _LOGGER.debug('rooms: %s',
                      [str(room) for number, room in map_data.rooms.items()])
        if not map_data.image.is_empty:
            MapDataParserViomi.draw_elements(colors, drawables, sizes,
                                             map_data, image_config)
            if len(map_data.rooms
                   ) > 0 and map_data.vacuum_position is not None:
                map_data.vacuum_room = MapDataParserViomi.get_current_vacuum_room(
                    buf, map_data.vacuum_position)
                if map_data.vacuum_room is not None:
                    map_data.vacuum_room_name = map_data.rooms[
                        map_data.vacuum_room].name
                _LOGGER.debug('current vacuum room: %s', map_data.vacuum_room)
            ImageHandlerViomi.rotate(map_data.image)
            ImageHandlerViomi.draw_texts(map_data.image, texts)
        return map_data
예제 #4
0
 def create_empty(colors) -> MapData:
     map_data = MapData()
     empty_map = ImageHandler.create_empty_map_image(
         colors, "Vacuum not supported")
     map_data.image = ImageData.create_empty(empty_map)
     return map_data
    def parse(raw: bytes,
              colors,
              drawables,
              texts,
              sizes,
              image_config,
              map_data_type: MapDataTypes = MapDataTypes.REGULAR,
              *args,
              **kwargs) -> Optional[MapData]:
        map_data = MapData(0, 1000)

        header = MapDataParserDreame.parse_header(raw)

        if header.frame_type != MapDataParserDreame.FrameTypes.I_FRAME:
            _LOGGER.error("unsupported map frame type")
            return

        if len(
                raw
        ) >= MapDataParserDreame.HEADER_SIZE + header.image_width * header.image_height:
            image_raw = raw[MapDataParserDreame.
                            HEADER_SIZE:MapDataParserDreame.HEADER_SIZE +
                            header.image_width * header.image_height]
            additional_data_raw = raw[MapDataParserDreame.HEADER_SIZE +
                                      header.image_width *
                                      header.image_height:]
            additional_data_json = json.loads(
                additional_data_raw.decode("utf8"))
            _LOGGER.debug(f'map additional_data: {additional_data_json}')

            map_data.charger = header.charger_position
            map_data.vacuum_position = header.vacuum_position

            map_data.image, map_data.rooms = MapDataParserDreame.parse_image(
                image_raw, header, colors, image_config, additional_data_json,
                map_data_type)

            if additional_data_json.get("rism") and \
                    additional_data_json.get("ris") and additional_data_json["ris"] == 2:
                rism_map_data = MapDataParserDreame.decode_map(
                    additional_data_json["rism"], colors, drawables, texts,
                    sizes, image_config, MapDataParserDreame.MapDataTypes.RISM)
                map_data.no_go_areas = rism_map_data.no_go_areas
                map_data.no_mopping_areas = rism_map_data.no_mopping_areas
                map_data.walls = rism_map_data.walls
                map_data.rooms = rism_map_data.rooms
                _LOGGER.debug(f"rooms: {map_data.rooms}")

                if not rism_map_data.image.is_empty:
                    map_data.image = rism_map_data.image

            if additional_data_json.get("tr"):
                map_data.path = MapDataParserDreame.parse_path(
                    additional_data_json["tr"])

            if additional_data_json.get("vw"):
                if additional_data_json["vw"].get("rect"):
                    map_data.no_go_areas = MapDataParserDreame.parse_areas(
                        additional_data_json["vw"]["rect"])
                if additional_data_json["vw"].get("mop"):
                    map_data.no_mopping_areas = MapDataParserDreame.parse_areas(
                        additional_data_json["vw"]["mop"])
                if additional_data_json["vw"].get("line"):
                    map_data.walls = MapDataParserDreame.parse_virtual_walls(
                        additional_data_json["vw"]["line"])

            if additional_data_json.get("sa") and isinstance(
                    additional_data_json["sa"], list):
                active_segment_ids = [
                    sa[0] for sa in additional_data_json["sa"]
                ]

            if not map_data.image.is_empty:
                if map_data_type == MapDataParserDreame.MapDataTypes.REGULAR:
                    MapDataParserDreame.draw_elements(colors, drawables, sizes,
                                                      map_data, image_config)
                    ImageHandlerDreame.rotate(map_data.image)

        return map_data
 def create_empty(colors, text) -> MapData:
     map_data = MapData()
     empty_map = ImageHandler.create_empty_map_image(colors, text)
     map_data.image = ImageData.create_empty(empty_map)
     return map_data