Help getting idotmatrix working in HA

idotmatrix is an Android/iOS app using to configure LED displays (e.g. 16x16, 32x32) with images and GIFs as well as a number of other things. Work has been done to create a Python shell client as well as a library to directly interact with the device via Bluetooth (see GitHub - derkalle4/python3-idotmatrix-client: reverse engineered python3 client to control all your 16x16 or 32x32 pixel displays (experimental)). I’ve been able to install the client successfully in Home Assistant and also execute the commands via terminal. Based on this, I created shell_commands to trigger the client but have hit a roadblock where the action fails with the following error:

stdout: ""
stderr: |-
  Traceback (most recent call last):
    File "/config/./app.py", line 7, in <module>
      from core.cmd import CMD
    File "/config/core/cmd.py", line 9, in <module>
      from idotmatrix import ConnectionManager
  ModuleNotFoundError: No module named 'idotmatrix'
returncode: 1

My configuration.yaml snippet:

shell_command:

  set_pixel_display_time: 'python3 ./app.py --address 72:A8:19:ED:04:DE --sync-time'
  set_pixel_display_clock_with_date: 'python3 ./app.py --address 72:A8:19:ED:04:DE --clock 0 --clock-with-date'
  set_pixel_display_image: 'python3 ./app.py --address 72:A8:19:ED:04:DE --image true --set-image {{ image }} --process-image 16'
  set_pixel_display_gif: 'python3 ./app.py --address 72:A8:19:ED:04:DE --set-gif {{ image }} --process-gif 16'
  set_pixel_display_text: 'python3 ./app.py --address 72:A8:19:ED:04:DE --set-text "{{ text }}" --text-size {{ size }} --text-mode {{ mode }} --text-speed {{ speed }} --text-color-mode {{ colormode }}'
  set_pixel_display_pixels: 'python3 ./app.py --address 72:A8:19:ED:04:DE --pixel-color {{ xyrgb }}'
  set_pixel_display_colour: 'python3 ./app.py --address 72:A8:19:ED:04:DE --fullscreen-color {{ rgb }}'
  set_pixel_display_off: 'python3 ./app.py --address 72:A8:19:ED:04:DE --screen off'
  set_pixel_display_on: 'python3 ./app.py --address 72:A8:19:ED:04:DE --screen on'
  

Any help or pointers on how to fix this appreciated!

You have to install necessary runtime libraries (such asi idotmatrix) into home assistant environment to do so.

Instead of doing so, i suggest you to use pyscript or appdaemon.

It is not possible to use Python imports with this integration. 
If you want to do more advanced scripts, you can take a look at AppDaemon or pyscript

Thanks for the suggestion. I’ve installed Pyscript but I’m getting ‘Module not found’ errors for idotmatrix. I’ve installed idotmatrix via Terminal. Any ideas how I get it to point to the right location?

Okay. So I appear to have this working in HA with my display.
What I did was install pyscript and create a requirements.txt file in the pyscript folder that simply has"

idotmatrix

Then I have a test.py file (still in testing), that looks like this:

import asyncio
import time
from idotmatrix import ConnectionManager
from idotmatrix import Chronograph
from idotmatrix import Clock
from idotmatrix import Gif
from idotmatrix import Image
from idotmatrix import Scoreboard
from idotmatrix import Text

@service
async def clock(address=None, style=5, r=255, g=255, b=255):
    # connect F7:37:34:43:02:93
    conn = ConnectionManager()
    await conn.connectByAddress(address)
    # Chronograph().setMode(mode = 1)
    Clock().setMode(style=style, visibleDate=False, hour24=True, r=r, g=g, b=b)
@service
async def chrono(address=None, mode=[0,1,2,3]):
    # connect F7:37:34:43:02:93
    conn = ConnectionManager()
    await conn.connectByAddress(address)
    Chronograph().setMode(mode = mode)

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        quit()

This then allows my to fire pyscript services (clock and chrono) to a given MAC address with the various parameters.
e.g. this one shows a simple 24hr clock with white text:

action: pyscript.clock
data: 
  address: "insert your device address here"
  style: 6

I have countdown, full screen colour and scoreboard working too. For some reason I can’t get text working. But I’m muddling through without much knowledge, so I’m sure it’s something simple I’m missing.

I believe we have solved the initial problem of missing dependency issue.

you mentioned that text functionality is not working, but you should share the respective function over here so we can comment on it

You are correct. I should have. I was just excited to get something working :slight_smile:
This is the snippet that I’ve tried that’s not sending anything:

import asyncio
import time
from idotmatrix import ConnectionManager
from idotmatrix import Chronograph
from idotmatrix import Clock
from idotmatrix import Common
from idotmatrix import Countdown
from idotmatrix import Effect

# from idotmatrix import Eco
from idotmatrix import FullscreenColor
from idotmatrix import Gif
from idotmatrix import Graffiti
from idotmatrix import Image

# from idotmatrix import MusicSync
from idotmatrix import Scoreboard

# from idotmatrix import System
from idotmatrix import Text

[Other working services]

@service
async def text():
    conn = ConnectionManager()
    await conn.connectByAddress("[device MAC]")
    Text().setMode("HELLO WORLD")

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        quit()

I’m not sure if there are other arguments that are required to be sent as part of the Text module?
The test.py example only appears to send a text string and a font_path, but my reading of the text.py is that that bit is optional.

you might need to install the default font over here, but finding the right path would be hard now.

Hmm… I don’t think that’s it. I managed to get the demo gif to load by downloading it at putting it in /config/pyscript/images/ and referencing that, but the same filepath doesn’t work with the text module.

I’m wondering if it’s this part of the text.py which is causing issues because I’m using a 16x16 device, not 32x32?

    logging = logging.getLogger(__name__)
    # must be 16x32 or 8x16
    image_width = 16
    image_height = 32
    # must be x05 for 16x32 or x02 for 8x16
    separator = b"\x05\xff\xff\xff"

But I don’t know how to change that to 8x16 and x02 in the function…
I assume it’s something like

Text(image_width=8,  image_height=16, separator=b"\x02\xff\xff\xff").setMode("HELLO WORLD")

But that does nothing too…