PiotrMachowski / Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor

This custom integration provides a way to present a live view of a map for Xiaomi (Roborock/Viomi/Roidmi/Dreame) vacuums without a need for rooting.
MIT License
1.14k stars 121 forks source link

Add support for local valuetdo vacuums #408

Closed tobi1449 closed 11 months ago

tobi1449 commented 1 year ago

This PR adds the ability to use valetudo robots as source for map data instead of the Xiaomi cloud. It accepts a valetudo camera entity and extracts the map data from the camera's image.

Implemented and working:

Open TODOs:

sca075 commented 1 year ago

I found a method to generate the image without using Nunpy.. I use the PIL Draw instance and it works fine. Layer one (empty new pill image max_x, max_y), save, draw the flour (layer 1), daw the walls (layer 2) and then path, robot and changer (layer 3) total run time 0:00:04.475454 per json that is similar to Numpy (that I try too and.. it is a pain to keep it at centre :) how can I upload the code I made for your evaluation?

def from_json_to_image(draw, data, pixel_size, color): for x, y, z in data: for i in range(z): col = (x + i) pixel_size row = y pixel_size draw.rounded_rectangle([(col, row), (col + pixel_size - 1, row + pixel_size - 1)], fill=color)

Create PIL image

img = Image.new('RGBA', (size_x, size_x)) img.save("output.png") edit_img = ImageDraw.Draw(img) from_json_to_image(edit_img, flour_pixel, pixel_size, color_home_background) from_json_to_image(edit_img, wall_pixel, pixel_size, color_wall)

Draw the charger, path and robot position on the stored image.

edit_img.rounded_rectangle((charger_pos[0]-15, charger_pos[1]-15, charger_pos[0]+15, charger_pos[1]+15), radius=150, fill=charger_color) edit_img.line(path_pixels, fill=color_move, width=5, joint=1) edit_img.rounded_rectangle((robot_position[0]-15, robot_position[1]-15, robot_position[0]+15, robot_position[1]+15), radius=150, fill=color_white)

PiotrMachowski commented 1 year ago

I found a method to generate the image without using Nunpy.. I use the PIL Draw instance and it works fine.

This is the same as current implementation of Map Extractor. I have to check if numpy approach is faster

sca075 commented 1 year ago

I do have some code also with Numpy, just please confirm, is the json coming from MQTT or from the query to the Valetudo api.. something like.. 'http://valetudo-myvacuum.local/api/v2/robot/state/map ? Will check my code with Numpy and share it to you.. and Ps. it work fast same as drawing (but we drawing we need to crop the image causing an offset between vacuum position and image centre / vacuum position).

sca075 commented 1 year ago


``` def from_json_to_image(data, pixel_size, color):
             image_array = np.zeros((5120, 5120, 3), dtype=np.uint8)
             for x, y, z in data:
                for i in range(z):
                     col = (x + i) * pixel_size
                     row = y * pixel_size
                    image_array[row:row+pixel_size, col:col+pixel_size] = color
      return image_array
sca075 commented 1 year ago

The function above is the one that create the a Numpy array. You can then use that to create the Layer_flour, Layer_Walls, and ... tested this right now the process time is 0:00:00.565693 for both layers added to an image. Not made yet the path..

layers = from_json_to_image(floor_pixels, pixel_size, floor_color) layers = layers + from_json_to_image(walls_pixels, pixel_size, walls_color) image = Image.fromarray(layers)

The list _pixel is a list of list [[520, 254, 7], [x, y, n] ...]

Hope this helps

tobi1449 commented 1 year ago

I found a method to generate the image without using Nunpy.. I use the PIL Draw instance and it works fine.

This is the same as current implementation of Map Extractor. I have to check if numpy approach is faster

It's much faster. As far as I could see that's also why it is generally recommended now over manually setting the pixels.

I do have some code also with Numpy, just please confirm, is the json coming from MQTT or from the query to the Valetudo api.. something like.. 'http://valetudo-myvacuum.local/api/v2/robot/state/map ? Will check my code with Numpy and share it to you.. and Ps. it work fast same as drawing (but we drawing we need to crop the image causing an offset between vacuum position and image centre / vacuum position).

The json is coming from the Valetudo vacuum encoded in the image published via MQTT.

sca075 commented 1 year ago

I found a method to generate the image without using Nunpy.. I use the PIL Draw instance and it works fine.

This is the same as current implementation of Map Extractor. I have to check if numpy approach is faster

It's much faster. As far as I could see that's also why it is generally recommended now over manually setting the pixels.

I do have some code also with Numpy, just please confirm, is the json coming from MQTT or from the query to the Valetudo api.. something like.. 'http://valetudo-myvacuum.local/api/v2/robot/state/map ? Will check my code with Numpy and share it to you.. and Ps. it work fast same as drawing (but we drawing we need to crop the image causing an offset between vacuum position and image centre / vacuum position).

The json is coming from the Valetudo vacuum encoded in the image published via MQTT.

Thanks a lot for your replay, and yep, it Numpy is much faster than edit the image with PIL, and I saw also that CPU and Memory usage went down too.. I changed the array to 4 dimensions to get the full RGB value (RRR.GGG.BBB.STS) just playing now with the Path draw.. I guess via MQTT is better too.. but I´m currently not at home.. so.. no test done till now. Would anyhow contribute if needed.. thanks for the great job Guys.

tobi1449 commented 1 year ago

I found a method to generate the image without using Nunpy.. I use the PIL Draw instance and it works fine.

This is the same as current implementation of Map Extractor. I have to check if numpy approach is faster

It's much faster. As far as I could see that's also why it is generally recommended now over manually setting the pixels.

I do have some code also with Numpy, just please confirm, is the json coming from MQTT or from the query to the Valetudo api.. something like.. 'http://valetudo-myvacuum.local/api/v2/robot/state/map ? Will check my code with Numpy and share it to you.. and Ps. it work fast same as drawing (but we drawing we need to crop the image causing an offset between vacuum position and image centre / vacuum position).

The json is coming from the Valetudo vacuum encoded in the image published via MQTT.

Thanks a lot for your replay, and yep, it Numpy is much faster than edit the image with PIL, and I saw also that CPU and Memory usage went down too.. I changed the array to 4 dimensions to get the full RGB value (RRR.GGG.BBB.STS) just playing now with the Path draw.. I guess via MQTT is better too.. but I´m currently not at home.. so.. no test done till now. Would anyhow contribute if needed.. thanks for the great job Guys.

Well there's (probably) not much left to do anyway. As I wrote in the PR description, what still needs some work are scaling and trimming, the calculation for the map objects' positions don't take that into account. The rest should be implemented.

deam0n commented 1 year ago

may i pay someone a beer to carry on this pr?

PiotrMachowski commented 1 year ago

@deam0n You can buy a beer to @tobi1449 for creating this PR. I plan to work on this integration soon (I was working on the lovelace vacuum map card lately)

sca075 commented 1 year ago

@deam0n You can buy a beer to @tobi1449 for creating this PR. I plan to work on this integration soon (I was working on the lovelace vacuum map card lately)

We will do it for sure :) I just completed some experiment too on this matter.. and @PiotrMachowski the new card was interfaced successfully from my side thanks to the super documentation you did on this well done component. If you don't mind I linked your project here https://github.com/sca075/valetudo_vacuum_mapper/tree/main

phrozen77 commented 1 year ago

Quick question: if i understand the discussion so far correctly, this PR needs to be merged to be able to show the map of a "local-only" Valetudo Roborock S5 in "Lovelace Vacuum Map card", right?

PiotrMachowski commented 1 year ago

@phrozen77 you can check out this project https://github.com/sca075/valetudo_vacuum_camera

phrozen77 commented 1 year ago

@phrozen77 you can check out this project https://github.com/sca075/valetudo_vacuum_camera

Found and tried it in the meanwhile - doesn't support external MQTT servers, sadly - thanks for the heads up!

sca075 commented 1 year ago

@phrozen77 We will work on it.. keep an an eye open soon I hope we can support MQTT external servers ;) @PiotrMachowski Thanks once again for your super work ;)

PiotrMachowski commented 1 year ago

@sca075 now that I have found out about your component I don't know what to do with this PR... I wanted to merge it, but recently I have also extracted map parsing to separate pypi packages, so I would have to do it for Valetudo as well

sca075 commented 1 year ago

If there is anything I can do to help you out you can reach me also via discord. [sandro0538] I can speak Polish too ;)

sca075 commented 1 year ago

@PiotrMachowski In the end it was possible to fix the configuration issue reported by @phrozen77 I would say quite easily. So it is really up to you, I think it is clear that your main aim is to support unrooted vacuums, the card is supporting already the Valetudo vacuums beautifully and it is a master peace also your extractor that I used for several years too. Point is that this isn't a competition.. not for me for instance. When I did start the development of the camera integration for the Valetudo vacuums it was just because understanding yours and @tobi1449 busy times I couldn't use most of the functionalities your card offers. With this, I guess just that there is a common understanding.. I don't do this for fame or incomes, but just.. once again, because I really appreciate the work you have done and you are continuously doing. Therefore no hard feeling whatever you will decide to do guys ;) as per the goal in the end is a common one.

PiotrMachowski commented 1 year ago

@sca075 I've sent you a message on Discord

sca075 commented 1 year ago

@PiotrMachowski revived ;)

tobi1449 commented 11 months ago

As something very similar has been implemented by @sca075 with valetudo_vacuum_camera, I will close this PR.

Thanks @sca075 for your work 👍