Skip to content
This repository has been archived by the owner on Apr 3, 2024. It is now read-only.

Add getPosition event with x y and currentSpotAreaID #505

Open
1 task done
francescopalma86 opened this issue Jan 14, 2024 · 3 comments
Open
1 task done

Add getPosition event with x y and currentSpotAreaID #505

francescopalma86 opened this issue Jan 14, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@francescopalma86
Copy link

Is there an existing issue for this?

  • I have searched the existing issues and no issue is describing my feature request or idea

Is your feature request related to a problem?

No response

Suggested solution

My goal is to turn on the light in the room where the robot is cleaning and turn it off when it exits the room. I have studied code and examples online, and I have found that the ecovacs-deebot.js library provides the following information: along with the x and y coordinates, it also has the currentSpotAreaID property.

In vacBot.js -> let currentSpotAreaID = mapTools.isPositionInSpotArea(posX, posY, this.mapSpotAreaInfos[this.currentMapMID]);

After retrieving the polygon of each room and the current position of the robot, the process to calculate the area it is in should be as follows:

  1. Decompress the coordinates with lzma and decode the base64:
    polygon_string = _decompress_7z_base64_data(event.coordinates).decode('utf-8');

  2. Use a function like the following for each room to determine in which polygon the current bot coordinates are located:

import shapely.geometry

def is_point_inside_polygon(x, y, polygon_string):
    coordinates = [tuple(map(float, pair.split(','))) for pair in polygon_string.split(';')]
    polygon = shapely.geometry.Polygon(coordinates)
    return polygon.contains(shapely.geometry.Point(x, y))
  1. Now, you could trigger a new event or modify the value of a new sensor to inform the user that the bot has changed rooms.

Api example request

No response

Alternatives you've considered

No response

Additional information

No response

@francescopalma86 francescopalma86 added the enhancement New feature or request label Jan 14, 2024
@francescopalma86
Copy link
Author

francescopalma86 commented Jan 14, 2024

I wrote this example

import aiohttp
import asyncio
import logging
import time
import shapely.geometry

from deebot_client.api_client import ApiClient
from deebot_client.authentication import Authenticator
from deebot_client.commands.json import GetMapSubSet, GetMapSet, GetPos
from deebot_client.events import MapSubsetEvent, MapSetEvent, PositionsEvent
from deebot_client.map import _decompress_7z_base64_data
from deebot_client.models import Configuration
from deebot_client.mqtt_client import MqttClient, MqttConfiguration
from deebot_client.util import md5
from deebot_client.device import Device

device_id = md5(str(time.time()))
account_id = ""
password_hash = md5("")
country = "IT"
continent = "eu"
mapId = ""

lastDeebotArea = None


async def main():
    async with aiohttp.ClientSession() as session:
        logging.basicConfig(level=logging.DEBUG)
        config = Configuration(session, device_id=device_id, country=country, continent=continent)

        authenticator = Authenticator(config, account_id, password_hash)
        api_client = ApiClient(authenticator)

        devices_ = await api_client.get_devices()

        bot = Device(devices_[0], authenticator)

        mqtt_config = MqttConfiguration(config=config)
        mqtt = MqttClient(mqtt_config, authenticator)
        await bot.initialize(mqtt)

        subsets = []

        def get_room_dict_from(event: MapSubsetEvent):
            s_coords = _decompress_7z_base64_data(event.coordinates).decode('utf-8')
            coordinates = [tuple(map(float, pair.split(','))) for pair in s_coords.split(';')]
            polygon = shapely.geometry.Polygon(coordinates)
            return {
                "id": event.id,
                "name": event.name,
                "area": polygon
            }

        async def on_mapsubset(event: MapSubsetEvent):
            if event.type == "ar":
                subsets.append(get_room_dict_from(event))

        async def on_mapset(event: MapSetEvent):
            if event.type == "ar":
                subsets.clear()
                for room_id in event.subsets:
                    await bot.execute_command(GetMapSubSet(mid=mapId, mssid=str(room_id), type="ar", msid="0"))

        async def on_position(event: PositionsEvent):
            deebot_pos = event.positions[0]
            deebot_point = shapely.geometry.Point(deebot_pos.x, deebot_pos.y)
            print(deebot_pos.x, deebot_pos.y)
            global lastDeebotArea
            for subset in subsets:
                if subset["area"].contains(deebot_point):
                    if subset['name'] != lastDeebotArea:
                        lastDeebotArea = subset["name"]
                        print(f"Deebot has changed area: {subset['name']}")
                    break

        bot.events.subscribe(PositionsEvent, on_position)
        bot.events.subscribe(MapSetEvent, on_mapset)
        bot.events.subscribe(MapSubsetEvent, on_mapsubset)

        # Execute commands
        await bot.execute_command(GetMapSet(mid=mapId))

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.create_task(main())
    loop.run_forever()

in this example print new Area when deebot change her, now i miss homassistant dev skill

@edenhaus
Copy link
Contributor

Thanks for your improvement. Could you open a PR directly in https://github.com/DeebotUniverse/client.py? Afterwards I can add it to the component

@francescopalma86
Copy link
Author

I released implementation in currentSpotAreaID brench and opened a new pull request.
After I forked Deebot-4-Home-Assistant and homeassistant core.

Now I don't know how to proceed.

I also finished the total implementation and this is the result
Screenshot 2024-01-18 alle 20 34 50

but I did everything manually, because I don't know the process of implementing custom integrations and development on home assistants in general

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants