Skip to content

gickowtf/pixoo-homeassistant

Repository files navigation

Divoom Pixoo 64 Home Assistant Integration

hacs_badge Donate python badge last commit

Custom component for easy use of a Pixoo64 within Home Assistant. With this integration you have the possibility to display different designs and personalize them with information from the Home Assistant. For example, you can use this integration to display several texts {{ templates }} and images on one page. You can also use this integration to determine how long you want to see a page, e.g. you can set the page to change every 15 seconds. In addition, you also have a light entity for switching the display on and off or changing the brightness. Last but not least, you can create automations with which you can use certain triggers to display the pages that are available to you as a push.

Installation

  1. Install this integration with HACS (adding repository required), or copy the contents of this repository's custom_components/divoom_pixoo directory into your custom_components/divoom_pixoo directory.

    Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

  2. Restart Home Assistant.

  3. Go to Settings / Integrations and add integration "Divoom Pixoo 64".

    Add Integration to your Home Assistant instance.

  4. Please select a discovered Pixoo 64 device from the list or select 'Manual IP' to manually enter the device's IP yourself.

Configuration

Base

Settings > Devices > Divoom Pixoo > Configure

IP address of the device: discovered or manually entered IP

Scan interval (in seconds): The amount of time a page is displayed

List of pages in YAML: See below (Optional)

Page Types & Configurations

Each page type will have configuration options unique to it. All configs should be written using YAML If you're new to this integration, we recommend starting with the components page type.

In the YAML config, all pages are nested under - page_type: XXX When setting the default configuration. Multiple pages can be set. These will be rotated through using the "duration" tag, or by default the time set in "scan interval".

YAML Layout example

- page_type: channel
  id: 0
- page_type: clock
  id: 182

In addition, all page types can be dynamically set to Enable/Disable based on HA entities.

Config Options required Default Values
enabled No true bool or {{ template }} #expects state = 'true', 'yes', 'on' or '1'
- page_type: PAGE_TYPE
  enabled: "{{ states.input_boolean.YOURS.state }}"

You can also set the duration of a page in seconds. This will override the scan interval set in the device settings.

Config Options required Default Values
duration No (The Scan Interval) integer/float in seconds
- page_type: PAGE_TYPE
  duration: 10

Note

The enabled tag and duration tag only apply when used in the configuration. Therefore, they won't word in the service.

Page: Components

A components page turns your Pixoo into your canvas! You can tie multiple text/image configs to a single page.

- page_type: components
  components:
    - type: text
      #[text config]
    - type: text
      #[text config]
    - type: image
      #[image config]
    - type: rectangle
      #[rectangle config]
    - type: templatable
      #[templatable config]

Note

Position X,Y coordinates will need to be manually configured for each component type

XY Positioning

Component Configurations

-type: [ text | image | rectangle ]

Component: Text

Config Options required Default Values
position Yes The text position on a XY axis at 64x64 pixel
content Yes Your message! {{ templates }} and Newline Support in text
font No pico_8 Fonts
color No white [R, G, B] or Colors

Example

    - type: text
      position: [0,0]
      content: Welcome Home!

Component: Image

Config Options required Default Values
position Yes The text position on a XY axis at 64x64 pixel
image_path Yes(pick one) image path like /config/img/haus.png
image_url Yes(pick one) image url like template {{ entity image }} or https://raw.githubusercontent.com/gickowtf/pixoo-homeassistant/main/images/fuel.png
image_data Yes(pick one) image data in base64. Convert images here.
height No If none is selected, the image will be at it's original size. If one is selected, it will become the longest side. Proportional
width No If none is selected, the image will be at it's original size. If one is selected, it will become the longest side. Proportional
resample_mode No box box, nearest, bilinear, hamming, bicubic, lanczos

Example

    - type: image
      position: [5,5]
      image_path: /config/image/haus.png
      resample_mode: box
      height: 64

Component: Rectangle

Config Options required Default Values
position Yes The text position on a XY axis at 64x64 pixel
size Yes final size of the rectangle. looks like [width, height]
color No [R, G, B] or Colors
filled No boolean

Example

    - type: rectangle
      position: [20,  20]
      size: [10,  10]
      color: yellow
      filled: "{{ states.input_boolean.YOURS.state }}"  #optional

Component: Templatable

Config Options required Default Values
template Yes jinja2 template

Example

    - type: templatable
      template: >-
        {% set entities = [["input_boolean.sw1", "input_boolean.sw2"],
        ["input_boolean.sw2"]] %} {% set origin = [1, 62] %}

        {% set output = namespace(list=[], position_x = origin[0], position_y =
        origin[1]) %} {% for entity_group in entities -%} {# {%- if loop.first
        %}The {% elif loop.last %} and the {% else %}, the {% endif -%} #}

        {% for entity in entity_group -%} {# {%- if loop.first %}The {% elif
        loop.last %} and the {% else %}, the {% endif -%} #} {% set entity_state
        = states(entity) %}

        {## Select the color ##} {% if entity_state=="off" or
        entity_state=="not_home" or entity_state == "standby" %} {% set
        color="red" %} {% elif entity_state=="on" or entity_state=="home" %} {%
        set color="green" %} {% elif entity_state=="playing" or
        entity_state=="idle" or entity_state=="paused" %} {% set color="blue" %}
        {% else %} {% set color="white" %} {% endif %}

        {% set component = {"type": "rectangle", "size": [1,1], "color": color,
        "position": [output.position_x, output.position_y]}%}

        {## Make next pixel 2px higher ##} {% set output.position_y =
        output.position_y - 2 %} {## Add to the output list##} {% set
        output.list = output.list + [component] %}

        {%- endfor %} {## Make next pixel 2px to the right ##} {% set
        output.position_x = output.position_x + 2 %} {## reset y ##} {% set
        output.position_y = origin[1] %} {%- endfor %} {{output.list}}

Variables (Optional) (Only for the components page)

If you wish for easier sharing of your custom component pages, you can define variables in the variables tag. These can then be used in any template.

Note

The variables tag is not supported in the service call. For those, you have to use Home Assistant's variables feature (with automations/scripts)

Example usage:

- page_type: components
  variables:
    power: "{{ states('input_number.power') }}"
    storage: "{{ states('input_number.storage') }}"
  components:
    - type: image
      image_path: /config/custom_components/divoom_pixoo/img/sunpower.png
      position: [2,1]
    - type: text
      content: "{{ power }}"
      color: "{{ [255,175,0] if power|int >= 1 else [131,131,131] }}"
      font: gicko
      position: [17,8]
    - type: image
      image_path: "{{ '/config/custom_components/divoom_pixoo/img/akku80-100.png' if storage|int >= 80 else '/config/custom_components/divoom_pixoo/img/akku60-80.png' if storage|int >= 60 else '/config/custom_components/divoom_pixoo/img/akku40-60.png' if storage|int >= 40 else '/config/custom_components/divoom_pixoo/img/akku20-40.png' if storage|int >= 20 else '/config/custom_components/divoom_pixoo/img/akku00-20.png'}}"
      position: [2, 17]
    - type: text
      content: "{{ storage }}"
      color: "{{ [255,0,68] if storage|int <= 0 else [4,204,2] }}"
      font: gicko
      position: [17, 18]

Page: gif

Animated GIFs

  1. Download the gif on your computer.
  2. Resize your gif to 16x16, 32x32 or 64x64. I know some websites say it's 64x64, but it has to actually be 64x64. You can resize gifs on multiple websites. Here's an example. (You only have to select manually the width and height of the size down the page).
  3. Re-download the gif.
  4. Re-upload the gif. You can use many image services like this one. (Make sure you use the gif file's link, and not the "gif viewing page". You can get that by right-clicking the gif on the website, and then clicking "Copy Image Link". The link in your clipboard probably now ends in .gif, like your file. (Although this might not be 100% the case.))
Config Options required Default Values
gif_url Yes URL

Example:

- page_type: gif
  gif_url: https://i.ibb.co/tKnvLs2/ezgif-5-30ff95e9ca.gif

Page: Channel

In Divoom app you can set three different custom channels which you can select here.

Note

The Divoom custom channel pic cycle rate must be set in the app itself.

  • Channel 1 = id: 0
  • Channel 2 = id: 1
  • Channel 3 = id: 2
Config Options required Default Values
id Yes Integer

Example:

- page_type: channel
  id: 0

Page: Clock

In Divoom app, there's a big list of clocks that you can set to your device.

- page_type: clock

Config Options required Default Values
id Yes Clock ID list of clock ID's

Example:

- page_type: clock
  id: 182

Alternative Method to find ClockFace ID's

  1. Navigate to settings > integrations > Divoom Pixoo 64
  2. Activate debug logging
  3. Open the Divoom app on your smartphone and select your preferred ClockFace.
  4. As soon as this is displayed on your Pixoo64, you will find "Device Data" in the log and then "CurClockId".
  5. The CurClockId is the number you were looking for.

Page: Visualizer

This adds the visualizer page to the integration.

Config Options required Default Values
id Yes Clock (visualizer) ID

The id starts at zero and it represents the clocks from top left to bottom right as can be seen in the app.

Example:

- page_type: visualizer
  id: 2

Page: PV

Photovoltaic - PV is a pre-designed page. The icon changes depending on the battery capacity and the font color changes from red to green Helper entities may have to be used here

- page_type: PV
  enabled: "{{ states.input_boolean.YOURS.state }}"  #is only displayed if the state = 'true', 'yes', 'on' or '1'
  power: "{{ states.sensor.YOUR_SENSOR.state }}"
  storage: "{{ states.sensor.YOUR_SENSOR.state }}"
  discharge: "{{ states.sensor.YOUR_SENSOR.state }}"
  powerhousetotal: "{{ states.sensor.YOUR_SENSOR.state }}"
  vomNetz: "{{ states.sensor.YOUR_SENSOR.state }}"
  time: "{{ now().strftime('%H:%M') }}"

Page: Progress Bar

Pre-designed page with a progress bar, for example, for the status of the dishwasher or for the charging status of the car

- page_type: progress_bar

Config Options required Default Values
header Yes string or use {{ template }} e.g. Dishwasher
progress Yes integer or use {{ template }}
footer Yes string or use {{ template }} e.g. Date
bg_color No blue use "[R, G, B]" or Colors
header_offset No 2 integer
header_font_color No white use "[R, G, B]" or Colors
progress_bar_color No red use "[R, G, B]" or Colors
progress_text_color No white use "[R, G, B]" or Colors
time_color No grey use "[R, G, B]" or Colors
footer_offset No 2 integer
footer_font_color No white use "[R, G, B]" or Colors

Example:

- page_type: progress_bar
  enabled: >-
  {% if is_state('sensor.DISHWASCHER_STATE', 'Run') %} true {% else %} false {% endif %}
  header: DISHWASHER
  progress: "{{ states.sensor.DISHWASHER_PROGRESS.state }}"
  footer: ANY FOOTER
  header_font_color: "[255, 255, 255]"

Page: Fuel

Special Page for Gas Station Pricing. Helper entities may have to be used here

- page_type: fuel


Config Options required Default Values
title Yes string - can use {{ template }} e.g. Gas Station Name
name1 Yes string - can use {{ template }} e.g. fuel type
price1 Yes use {{ template }} e.g. fuel price
name2 Yes string - can use {{ template }}
price2 Yes use {{ template }}
name3 Yes string - can use {{ template }}
price3 Yes use {{ template }} eg. fuel price
status Yes string - can use {{ template }} Any extra field in my case an opening status
font_color No white "[R, G, B]" or Colors
bg_color No yellow (255, 230, 0) "[R, G, B]" or Colors
price_color No white "[R, G, B]" or Colors
title_color No black "[R, G, B]" or Colors
stripe_color No font_color "[R, G, B]" or Colors
title_offset No 2 integer used to center the text

Example of the image:

- page_type: Fuel
  enabled: "{{ states.input_boolean.YOURS.state }}"
  title: Classic
  name1: Diesel
  price1: "{{ states.sensor.diesel.state }}"
  name2: Super
  price2: "{{ states.sensor.super.state }}"
  name3: E10
  price3: "{{ states.sensor.e10.state }}"
  status: >-
  {% if is_state('binary_sensor.status', 'on') %} Offen {%
  else %} Geschlossen {% endif %}
  title_offset: "10"
  font_color: "[255, 255, 255]"

Newline

Newline Support in content: example:

content: |-
text 1
{{ states.*.state }}

There is no limit to the maximum newlines except for 64 pixels ;)


Services

Service: Send a page to Divoom Pixoo (show_message) Push Notification

You can use it for Push Notifications. Trigger with anything! Call it with the Service "Divoom Pixoo 64: Send a page to Divoom Pixoo".

You can input in the Page Data field the data of one page in the normal YAML format. It can be anything!

Note

This is intended to be a temporary override of your default configuration. Any Enable/disable lines will not be respected here.

Some examples of Page Data:

page_type: clock
id: 182

or

page_type: components
components:
  - type: text
    position: [10,  0]
    content: 2 github/gickowtf
    font: gicko
    color: [255,  0,  0]
  - type: image
    image_path: /config/img/haus.png
    position: [30,  30]

Service: Play a Buzzer

Play the buzzer on the Divoom Pixoo. Beware that this maybe could damage the device. Use at your own risk.

Buzzing Time per cycle. in milliseconds default: 500 milliseconds

The working time of the buzzer per cycle. The buzzer will not buzz continuously; it will go on and off in cycles (duration in-between not controllable).

Idle Time per cycle in milliseconds default: 500 milliseconds

Idle time of the buzzer per cycle.

Total Time in milliseconds default: 3000 milliseconds

The total time the buzzer will be working.


Service: Restart the Divoom Pixoo

Restart the Divoom Pixoo device. (It has a little bit of delay. Be patient.)



Templates

As mentioned above, templates allow you to bring Entity states and attributes directly to your Pixoo! (eg. Temperature, brightness, presence, entity on/off). They can be used in most settings in the integration. For a deep dive see https://www.home-assistant.io/docs/configuration/templating/ or even https://jinja.palletsprojects.com/en/latest/templates/ (The language behind templates)

You can find the entity ID in HA under Developer > States (Although you shouldn't need this.)

Example usages of templates

Report Raw Sensor Readings

Binary sensors are the easiest to start with, as they simply live in one of two states, On or Off.

- page_type: components
  components:
    - type: text
      position: [0,0]
      color: white
      content: "Motion-FL1: {{ states('binary_sensor.MotionDetector') }}"

In the above example, the Pixoo would display

Motion-FL1: [on/off]

Conditionally replacing text based on sensor readings

What if you want to change on -> detected and off -> clear?

One way is to use a combination of If/then/else (short form below) and a state comparator (is_state)

content: >-
Motion-FL1: {{ 'Detected' if
is_state('binary_sensor.MotionDetector', ['on']) else
'clear' }}

You might say "well that's pretty nifty, but I also want to dynamically change the color because a e s t h e t i c s.

Well I've got great news for you!

Using templates to dynamically change text color

We can take the exact same concept used for the text, and apply it to color. All we need to do is swap text for color codes.

If Motion Detected, color = red (255,0,0); else color = green (0,255,0)

color: >-
{{ [255,0,0] if is_state('binary_sensor.motionDetector',
['on']) else [0,255,0] }}

Animations through automations

Note

In this example we're using a count helper to act as a countdown. This also uses an automation and not the config.

alias: pixoo64 - auto-ani
description: ""
trigger: []
condition: []
action:
  - service: counter.reset
    metadata: {}
    data: {}
    target:
      entity_id: counter.pixoo_5s_count_down
  - repeat:
      count: 20
      sequence:
        - service: divoom_pixoo.show_message
          target:
            entity_id: sensor.divoom_pixoo_64_current_page
          data:
            page_data:
              page_type: components
              components:
                - type: text
                  position:
                    - 0
                    - 30
                  content: "Auth Check in: {{ states('counter.pixoo_5s_count_down') }}"
                  font: pico_8
                  color: white
                - type: image
                  image_url: https://pub.inflowbogie.dev/lock_closed.png
                  position:
                    - 0
                    - 40
                  resample_mode: box
                  height: 20
                - type: image
                  image_url: https://pub.inflowbogie.dev/key.png
                  position:
                    - "{{ 2 * states('counter.pixoo_5s_count_down') }}"
                    - 50
                  resample_mode: box
                  height: 7
        - service: counter.decrement
          metadata: {}
          data: {}
          target:
            entity_id: counter.pixoo_5s_count_down
        - delay:
            hours: 0
            minutes: 0
            seconds: 1
            milliseconds: 0
        - if:
            - condition: state
              entity_id: counter.pixoo_5s_count_down
              state: "0"
          then:
            - service: counter.reset
              metadata: {}
              data: {}
              target:
                entity_id: counter.pixoo_5s_count_down
mode: single

animated

References

Fonts

Font Image
gicko FONT_GICKO.png
five_pix five_pix.png
pico_8 PICO_8.png
eleven_pix eleven_pix.png
clock CLOCK.png


Color Presets

The colors in this chart can be used as presets to replace the [R,G,B] color coding.



Issues

Sometimes the display crashes, especially with animated images. I have often read on the Internet that this is due to the power supply being too weak or the brightness being too high. I now have the display permanently set to 90% and it no longer crashes.



Discussions

I would be happy if you present your own configuration/usages of the integration or ask questions in the discussions!

https://github.com/gickowtf/pixoo-homeassistant/discussions



Disclaimer

This is not official software from Divoom.

It is a custom integration created by me (gickowtf) and therefore Divoom is not responsible for any damages/problems caused by this integration, nor does Divoom provide any end-user support for the integration.

Use this integration at your own risk.



❤️ Many thanks to

@Mrredstone5230 - Thanks for the conversion to config flow and many many more