Enclosure Api
The EnclosureApi is an abstraction over an hypothetical "body" housing OVOS
eg, The Mark 1 Device is housed in an Enclosure. The Enclosure is the shell that houses a Device that runs OVOS.
from ovos_bus_client.apis.enclosure import EnclosureApi
api = EnclosureApi(bus)
The Mark 1 Enclosure capabilities
The Mark 1 mouth and eyes can be controlled by Skills using the self.enclosure
object inherited from the OVOSSkill
base class.
This object acts as an interface to the Enclosure and allows the Skill creator to draw to the mouth display.
This is how the mouth and eyes are made to change during operations such as audio playback.
Dedicated utils for fine grained control over the mark 1 can be found at ovos-mark1-utils
Drawing to the mouth display
Drawing text to the mouth display
Text can be sent to the display using the mouth_text()
method of the enclosure
object.
self.enclosure.mouth_text('The meaning of life, the universe and everything is 42')
If the text is too long to fit on the display, the text will scroll.
@TODO how many characters will fit on the display before it will scroll?
Drawing images to the mouth display
Clearing an existing image from the mouth display
Before writing an image to the mouth display, you should clear any previous image.
self.enclosure.mouth_display(img_code="HIAAAAAAAAAAAAAA", refresh=False)
self.enclosure.mouth_display(img_code="HIAAAAAAAAAAAAAA", x=24, refresh=False)
How images are drawn on the mouth display
The mouth display is a grid, 32 pixels wide and 8 pixels high.
There are two ways to draw an image on the mouth display.
Addressing each pixel using a string encoding
You can draw an image to the mouth display by binary encoding pixel information in a string.
The binary encoding is straightforward value substitution.
Letter Value | Pixel value |
---|---|
A | 0 |
B | 1 |
C | 2 |
D | 3 |
E | 4 |
F | 5 |
G | 6 |
H | 7 |
I | 8 |
and so on.
self.enclosure.mouth_display(img_code="HIAAAAAAAAAAAAAA", refresh=False)
self.enclosure.mouth_display(img_code="HIAAAAAAAAAAAAAA", x=24, refresh=False)
The code above clears the image by sending a string consisting of HI
which stands for a Width of 7 and a height of 8 and each A stands for a segment of 4 pixels in the off state.
@TODO we really need a grid image here to show how it works - to make it easier to understand.
Sending a PNG image to the mouth display
Another way to draw an image on the mouth display is to create a PNG-formatted image with a width of 32 pixels and a height of 8 pixels, then use the mouth_display_png()
method of the enclosure
object.
The image should be black and white, with white meaning a dark pixel, and black indicating an illuminated pixel.
mouth_display_png()
expects the first argument to be the image absolute path. Optional arguments are
threshold
: The value at which a pixel should be considered 'dark' or 'illuminated'invert
: Treat white in the image as illuminated pixels, and black as dark pixelsx
: The x position (horizontal) at which the image should be displaye, in pixelsy
: The y position (vertical) at which the image should be displayed, in pixelsrefresh
: clear the display before writing to it
@TODO all the above needs to be validated - the information is educated guesswork
self.mouth_display_png('/path/to/image.png', threshold=70, invert=False, x=0, y=0, refresh=True)
Example image:
Tools for converting PNG image representations to string representations
If you don't want to convert PNG files at runtime (for example when creating simple animations) this short python script will convert PNG files to strings compatible with the img_code
of self.enclosure.mouth_display()
.
Resetting the display to the default state
When the Skill is finished, you should reset the Enclosure to the default state using
self.enclosure.reset()
This will clear the screen and blink the Mark 1's eyes once.