Giter Site home page Giter Site logo

erkexzcx / valetudopng Goto Github PK

View Code? Open in Web Editor NEW
37.0 5.0 6.0 126 KB

A Valetudo map renderer (ex Hypfer/ICantBelieveItsNotValetudo) for Home Assistant.

Home Page: https://valetudo.cloud/

License: Apache License 2.0

Go 88.83% JavaScript 10.08% Dockerfile 1.09%
go golang mqtt png valetudo roborock roborock-vacuum rockrobo vacuum vacuum-cleaner vacuum-robot

valetudopng's Introduction

ValetudoPNG

ValetudoPNG is a service designed to render map from Valetudo-enabled vacuum robot into a more accessible PNG format. This PNG map is sent to Home Assistant via MQTT, where it can be viewed as a real-time camera feed. ValetudoPNG was specifically developed to integrate with third-party frontend cards, such as the PiotrMachowski/lovelace-xiaomi-vacuum-map-card.

Alternative projects:

Broken or dead projects:

Features

  • Written in Go.
    • Single binary
    • No dependencies
    • Fast & multithreaded rendering
  • Pre-built Docker images.
  • Automatic map calibration data for PiotrMachowski/lovelace-xiaomi-vacuum-map-card.
  • Easy configuration using yaml config file.
  • Map modification:
    • Rotation
    • Scaling
    • "croping" by binding map to coordinates in robot's coordinates system
  • HTTP endpoint:
    • Access image http://ip:port/api/map/image.
    • Debug image and it's coordinates/pixels in robot's coordinates system http://ip:port/api/map/image/debug.
  • Designed to work with HomeAssistant in mind.

Supported architectures:

  • linux/amd64: x86_64, Intel 64, AMD64, 64-bit PC architecture
  • linux/arm64: aarch64, armv8, ARM 64-bit
  • linux/arm/v7: armv7l, armv7-a, ARM 32-bit version 7
  • linux/arm/v6: armv6l, armv6-a, ARM 32-bit version 6

Get started

Configure Valetudo

It is assumed that Valetudo is connected to Home Assistant via MQTT and is working.

Go to Valetudo URL -> Connectivity -> MQTT Connectivity -> Customizations. Make sure Provide map data is enabled.

Configuration file

Create config.yml file out of config.example.yml file and update according.

For starters, assuming that you don't have TLS and username/password set in your MQTT server, you can update only these for now:

    host: 192.168.0.123
    port: 1883

and these:

    # Should match "Topic prefix" in Valetudo MQTT settings
    valetudo_prefix: valetudo

    # Should match "Identifier" in Valetudo MQTT settings
    valetudo_identifier: rockrobo

Now move to installation and usage sections, where you will be able to easily "experiment" with your config.

Installation

Binaries

See Releases.

$ tar -xvzf valetudopng_v1.0.0_linux_amd64.tar.gz 
valetudopng_v1.0.0_linux_amd64
$ ./valetudopng_v1.0.0_linux_amd64 --help
Usage of ./valetudopng_v1.0.0_linux_amd64:
  -config string
        Path to configuration file (default "config.yml")
  -version
        prints version of the application

You can technically install it on robot itself:

[root@rockrobo ~]# grep -e scale config.yml
  scale: 2
[root@rockrobo ~]# ./valetudopng
2023/10/02 07:18:10 [MQTT producer] Connected
2023/10/02 07:18:10 [MQTT consumer] Connected
2023/10/02 07:18:10 [MQTT consumer] Subscribed to map data topic
2023/10/02 07:18:10 Image rendered! drawing:39ms, encoding:61ms, size:9.1kB
2023/10/02 07:18:16 Image rendered! drawing:37ms, encoding:72ms, size:9.1kB
2023/10/02 07:18:16 Image rendered! drawing:35ms, encoding:66ms, size:9.1kB
2023/10/02 07:18:17 Image rendered! drawing:44ms, encoding:50ms, size:7.4kB
2023/10/02 07:18:18 Image rendered! drawing:33ms, encoding:54ms, size:7.4kB
2023/10/02 07:18:20 Image rendered! drawing:34ms, encoding:52ms, size:7.4kB
2023/10/02 07:18:22 Image rendered! drawing:34ms, encoding:61ms, size:7.4kB
2023/10/02 07:18:24 Image rendered! drawing:32ms, encoding:56ms, size:7.7kB
2023/10/02 07:18:26 Image rendered! drawing:45ms, encoding:62ms, size:7.8kB
2023/10/02 07:18:28 Image rendered! drawing:33ms, encoding:64ms, size:7.8kB
2023/10/02 07:18:30 Image rendered! drawing:44ms, encoding:59ms, size:8.0kB
2023/10/02 07:18:32 Image rendered! drawing:38ms, encoding:62ms, size:8.2kB
2023/10/02 07:18:35 Image rendered! drawing:88ms, encoding:54ms, size:8.3kB
2023/10/02 07:18:36 Image rendered! drawing:35ms, encoding:72ms, size:8.4kB

Download binary appropriate for your robot's CPU and follow the service installation guidelines of another project: https://github.com/porech/roborock-oucher

Note that this service is still resources-intensive and drains more battery when robot is not charging. Generally it is not recommended to host it on robot.

Docker compose

  valetudopng:
    image: ghcr.io/erkexzcx/valetudopng:latest
    container_name: valetudopng
    restart: always
    volumes:
      - ./valetudopng/config.yml:/config.yml
    ports:
      - "3000:3000"

Docker CLI

docker run -d \
    --restart=always \
    --name=valetudopng \
    -v $(pwd)/valetudopng/config.yml:/config.yml \
    -p 3000:3000 \
    ghcr.io/erkexzcx/valetudopng:latest

Usage

When hosted, go to http://ip:port/api/map/image/debug and start selecting rectangles. Below the picture there will be information that you will want to copy/paste.

For example, this is how my PiotrMachowski/lovelace-xiaomi-vacuum-map-card card looks like with valetudo_prefix: valetudo and valetudo_identifier: rockrobo and RockRobo S5 vacuum:

type: custom:xiaomi-vacuum-map-card
map_source:
  camera: camera.rockrobo_rendered_map
calibration_source:
  entity: sensor.rockrobo_calibration_data
entity: vacuum.valetudo_rockrobo
vacuum_platform: Hypfer/Valetudo
internal_variables:
  topic: valetudo/rockrobo
map_modes:
  - template: vacuum_clean_zone_predefined
    selection_type: PREDEFINED_RECTANGLE
    predefined_selections:
      - zones: [[2185,2975,2310,3090]]
        label:
          text: Entrance
          x: 2247.5
          y: 3032.5
          offset_y: 28
        icon:
          name: mdi:door
          x: 2247.5
          y: 3032.5
  - template: vacuum_goto
  - template: vacuum_clean_zone
map_locked: true
two_finger_pan: false

valetudopng's People

Contributors

erkexzcx avatar mundschenk-at avatar p1-ro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

valetudopng's Issues

Calibration data unavailable after Home Assistant restarts

Describe the bug
After Home Assistant restarts (due to update, manual restart, etc.), the sensor.{{vacuum}}_calibration entity becomes unavailable. This causes xiaomi-vacuum-map-card to not render as the card's calibration_source field now points to an unavailable entity.

Current work-around is to restart the ValetudoPNG docker container which repopulates the missing entity.

To Reproduce
Steps to reproduce the behavior:

  1. Run ValetudoPNG and observe calibration and rendered map populate on the MQTT Vacuum
  2. Restart or update Home Assistant
  3. Observe _calibration sensor for vacuum is now Unavailable
  4. Observe xiaomi-vacuum-map-card fails to render due to missing calibration_source

Expected behavior
Expected calibration data to retain after home assistant restarts or ValetudoPNG to repopulate/send the calibration data again.

Screenshots/Outputs
MQTT entry for Vacuum after Home Assistant has restarted
image

Calibration entity
image

Firefox console
image

Container Logs

2023/11/02 00:00:16 Image rendered! drawing:18ms, encoding:56ms, size:36.6kB
2023/11/02 00:00:17 Skipping image render due to min_refresh_int
2023/11/02 00:01:17 Image rendered! drawing:18ms, encoding:57ms, size:36.6kB
2023/11/02 00:01:18 Skipping image render due to min_refresh_int
2023/11/02 00:02:19 Image rendered! drawing:19ms, encoding:56ms, size:36.6kB
2023/11/02 00:02:19 Skipping image render due to min_refresh_int
2023/11/02 00:03:19 Image rendered! drawing:18ms, encoding:55ms, size:36.6kB
2023/11/02 00:04:20 Image rendered! drawing:19ms, encoding:62ms, size:36.6kB
2023/11/02 00:04:21 Skipping image render due to min_refresh_int
etc...

Map is still updating correctly, but _calibration data is never sent again until the container is restarted

Home Assistant MQTT discovery topics not retained

Describe the bug
The generated discovery topics are not retained, which means when HA (or simply its MQTT integration) is restarted, they are not there for setting up the entity. HA knows that there was entity previously, so it's still listed in the device view, but it does not have current configuration, so it is unavailable. This is one of the causes for #5.

It also means that #6 never took for me, because previous retained discovery topics created for ICBINV were still around (because non-retained topics don't overwrite retained ones).

json: cannot unmarshal number

Hello, I try to start version 1.0.4 (amd64), but there is an error

Robot: Mi Robot Vacuum Mop P (Viomi V8)
Valetudo: 2023.08.0

Valetudo's exported map (part with problem):
(I can attach complete file if you need)

  "entities": [
    {
      "__class": "PointMapEntity",
      "metaData": {
        "angle": 178.51663517951965
      },
      "points": [
        1987,
        1965
      ],
      "type": "robot_position"
    },
    {
      "__class": "PointMapEntity",
      "metaData": {
        "angle": 178.51663517951965
      },
      "points": [
        1988,
        1980
      ],
      "type": "charger_location"
    },
]

Output:

2023/10/02 09:36:51 [MQTT consumer] Connected
2023/10/02 09:36:51 [MQTT producer] Connected
2023/10/02 09:36:51 [MQTT consumer] Subscribed to map data topic
2023/10/02 09:36:51 Error occurred while rendering map: json: cannot unmarshal number 178.51663517951965 into Go struct field MetaDataEntity.entities.metaData.angle of type int

Thanks!

GLIBC_2.32 not found error message

Describe the bug
Error message if i start valetudopng on a Debian GNU/Linux 11 (bullseye) amd64 based hardware

To Reproduce
Steps to reproduce the behavior:

  1. run ./valetudopng_v1.0.10_linux_amd64 --help

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots/Outputs

./valetudopng_v1.0.10_linux_amd64 --help
./valetudopng_v1.0.10_linux_amd64: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./valetudopng_v1.0.10_linux_amd64)
./valetudopng_v1.0.10_linux_amd64: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./valetudopng_v1.0.10_linux_amd64)

Congatudo support

Good afternoon,

For several months I have been using the Congatudo docker container to manage a Cecotec Conga 5090, for several days I have been trying to set up the Valetudopng container to be able to see the robot's journey in real time through HomeAssistant.

I have a problem with the Valetudopng container, when the robot starts cleaning it constantly restarts and the following message appears in the container logs:

github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).drawEntityRobot(0xc0000fc090, 0xc000480880, 0x2, 0xffffffffffffffff)
/app/pkg/renderer/drawer_entities.go:40 +0x108
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).DrawAll(0xc0000fc090)
/app/pkg/renderer/drawer.go:185 +0x908
github.com/erkexzcx/valetudopng/pkg/renderer.(*Renderer).Render(0xc19e50d9677b41b2?, {0xc00066c000?, 0xbb8740?, 0x12a05f200?}, 0xfffffffeda5d0143?)
/app/pkg/renderer/renderer.go:67 +0x47
github.com/erkexzcx/valetudopng/pkg/server.Start(0xc0000100f0)
/app/pkg/server/server.go:68 +0x74c
main.main()
/app/cmd/valetudopng/main.go:32 +0xd4
2024/07/18 08:01:38 [MQTT producer] Connected
2024/07/18 08:01:38 [MQTT consumer] Connected
2024/07/18 08:01:38 [MQTT consumer] Subscribed to map data topic
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7a2d57]
goroutine 1 [running]:
github.com/fogleman/gg.(*Context).DrawImageAnchored(0xc00012e000, {0x0, 0x0}, 0x2f6, 0xff, 0x3fe0000000000000, 0x3fe0000000000000)
/go/pkg/mod/github.com/fogleman/[email protected]/context.go:660 +0x57
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).drawEntityRobot(0xc000192090, 0xc000583100, 0x2, 0xffffffffffffffff)
/app/pkg/renderer/drawer_entities.go:40 +0x108
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).DrawAll(0xc000192090)
/app/pkg/renderer/drawer.go:185 +0x908
github.com/erkexzcx/valetudopng/pkg/renderer.(*Renderer).Render(0xc19e50d9c3ae85a8?, {0xc000666000?, 0xbb8740?, 0x12a05f200?}, 0xfffffffeda39c0bb?)
/app/pkg/renderer/renderer.go:67 +0x47
github.com/erkexzcx/valetudopng/pkg/server.Start(0xc0000100f0)
/app/pkg/server/server.go:68 +0x74c
main.main()
/app/cmd/valetudopng/main.go:32 +0xd4
2024/07/18 08:01:40 [MQTT consumer] Connected
2024/07/18 08:01:40 [MQTT producer] Connected
2024/07/18 08:01:40 [MQTT consumer] Subscribed to map data topic
2024/07/18 08:01:40 Image rendered! drawing:18ms, encoding:16ms, size:14.5kB
2024/07/18 08:01:41 Skipping image render due to min_refresh_int
2024/07/18 08:01:43 Skipping image render due to min_refresh_int
2024/07/18 08:01:46 Image rendered! drawing:18ms, encoding:17ms, size:15.0kB
2024/07/18 08:01:46 Skipping image render due to min_refresh_int
2024/07/18 08:01:48 Skipping image render due to min_refresh_int
2024/07/18 08:01:50 Skipping image render due to min_refresh_int
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7a2d57]
goroutine 1 [running]:
github.com/fogleman/gg.(*Context).DrawImageAnchored(0xc000194000, {0x0, 0x0}, 0x27e, 0xb3, 0x3fe0000000000000, 0x3fe0000000000000)
/go/pkg/mod/github.com/fogleman/[email protected]/context.go:660 +0x57
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).drawEntityRobot(0xc0001b4120, 0xc0003bb740, 0x2, 0xffffffffffffffff)
/app/pkg/renderer/drawer_entities.go:40 +0x108
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).DrawAll(0xc0001b4120)
/app/pkg/renderer/drawer.go:185 +0x908
github.com/erkexzcx/valetudopng/pkg/renderer.(*Renderer).Render(0xc19e50dd4ab55747?, {0xc000606000?, 0xbb8740?, 0x12a05f200?}, 0x29226cb85?)
/app/pkg/renderer/renderer.go:67 +0x47
github.com/erkexzcx/valetudopng/pkg/server.Start(0xc0000100f0)
/app/pkg/server/server.go:68 +0x74c
main.main()
/app/cmd/valetudopng/main.go:32 +0xd4
2024/07/18 08:01:52 [MQTT consumer] Connected
2024/07/18 08:01:52 [MQTT producer] Connected
2024/07/18 08:01:52 [MQTT consumer] Subscribed to map data topic
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7a2d57]
goroutine 1 [running]:
github.com/fogleman/gg.(*Context).DrawImageAnchored(0xc00005e000, {0x0, 0x0}, 0x27e, 0xb3, 0x3fe0000000000000, 0x3fe0000000000000)
/go/pkg/mod/github.com/fogleman/[email protected]/context.go:660 +0x57
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).drawEntityRobot(0xc0000fe120, 0xc000232080, 0x2, 0xffffffffffffffff)
/app/pkg/renderer/drawer_entities.go:40 +0x108
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).DrawAll(0xc0000fe120)
/app/pkg/renderer/drawer.go:185 +0x908
github.com/erkexzcx/valetudopng/pkg/renderer.(*Renderer).Render(0xc19e50dd78ed37b8?, {0xc000636000?, 0xbb8740?, 0x12a05f200?}, 0xfffffffeda5ab8d9?)
/app/pkg/renderer/renderer.go:67 +0x47
github.com/erkexzcx/valetudopng/pkg/server.Start(0xc0000100f0)
/app/pkg/server/server.go:68 +0x74c
main.main()
/app/cmd/valetudopng/main.go:32 +0xd4
2024/07/18 08:01:53 [MQTT producer] Connected
2024/07/18 08:01:53 [MQTT consumer] Connected
2024/07/18 08:01:53 [MQTT consumer] Subscribed to map data topic
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x7a2d57]
goroutine 1 [running]:
github.com/fogleman/gg.(*Context).DrawImageAnchored(0xc000150000, {0x0, 0x0}, 0x27e, 0xb3, 0x3fe0000000000000, 0x3fe0000000000000)
/go/pkg/mod/github.com/fogleman/[email protected]/context.go:660 +0x57
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).drawEntityRobot(0xc0001a4090, 0xc00036f7c0, 0x2, 0xffffffffffffffff)
/app/pkg/renderer/drawer_entities.go:40 +0x108
github.com/erkexzcx/valetudopng/pkg/renderer.(*valetudoImage).DrawAll(0xc0001a4090)
/app/pkg/renderer/drawer.go:185 +0x908
github.com/erkexzcx/valetudopng/pkg/renderer.(*Renderer).Render(0xc19e50ddad504387?, {0xc0006e4000?, 0xbb8740?, 0x12a05f200?}, 0xfffffffeda5e1093?)
/app/pkg/renderer/renderer.go:67 +0x47
github.com/erkexzcx/valetudopng/pkg/server.Start(0xc0000a20d8)
/app/pkg/server/server.go:68 +0x74c
main.main()
/app/cmd/valetudopng/main.go:32 +0xd4
2024/07/18 08:01:54 [MQTT consumer] Connected
2024/07/18 08:01:54 [MQTT producer] Connected
2024/07/18 08:01:54 [MQTT consumer] Subscribed to map data topic
2024/07/18 08:01:54 Image rendered! drawing:18ms, encoding:16ms, size:15.5kB
2024/07/18 08:01:56 Skipping image render due to min_refresh_int
2024/07/18 08:01:58 Skipping image render due to min_refresh_int
2024/07/18 08:01:59 Skipping image render due to min_refresh_int

Does anyone know how I can fix this problem?

Best regards,

Cannot connect using TLS

Describe the bug
When trying to connect to the MQTT broker using TLS, the connection fails [MQTT producer] Failed to connect: network Error : EOF. Retrying in 5 seconds.... Other clients connect over TLS on this port without problem, and a non-encrypted connection on port 1883 works for valetudopng.

To Reproduce
Relevant configuration:

mqtt:
  connection:
    port: 8883
  tls_ca_path: /root_ca.pem
  tls_insecure:

The CA root certificate is mounted to the relevant path and apparently can be opened by the binary (otherwise I'd expect a different error message from looking at the Go code). Changing tls_insecure to to true did not change the resulting error message.

Expected behavior
An MQTT connection can be established using a TLS listener.

-config parameter is ignored

Describe the bug
valetudopng just ignores Specified -config parameter and tries to use config.yml in the current directory.

To Reproduce

  1. Go to /mnt/data/valetudopng/
  2. Try to run ./valetudopng -config not_exist
  3. See how valetudopng starts using config file "config.yml" and not trying to use config file "not_exist" (which does not exist and should produce error)

Expected behavior
valetudopng should use -config parameter if it is specified.

Screenshots/Outputs

[root@rockrobo ~]# /mnt/data/valetudopng/valetudopng -config not_exist
2023/10/10 15:38:38 Failed to read configuration file: open config.yml: no such file or directory

[root@rockrobo ~]# cd /mnt/data/valetudopng
[root@rockrobo valetudopng]# ls
config.example.yml                     valetudopng
config.yml                             valetudopng_v1.0.8_linux_armv7.tar.gz
[root@rockrobo valetudopng]# /mnt/data/valetudopng/valetudopng -config not_exist
2023/10/10 15:38:44 [MQTT consumer] Connected
2023/10/10 15:38:44 [MQTT producer] Connected
2023/10/10 15:38:44 [MQTT consumer] Subscribed to map data topic

Create dark mode feature

Is your feature request related to a problem? Please describe.
More and more apps support dark mode, I'm using OpenHAB and Valetudo in dark mode as well, but the generated image is on a white background which stands out from every user interface.

Describe the solution you'd like
I would suggest a feature with a config option to be able to choose between light/dark mode. The simplest implementation should only change the color of the background between white/black.
Maybe the segment colors could be adjusted as well, but maybe I'm overthinking it. :)

Describe alternatives you've considered
There's no real alternative, as the image will be used in different places, which are mostly already drawn in dark mode, so a simple image color inversion or other similar techniques wouldn't solve it.

I'm happy to answer any questions that might arise.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.