Sendspin Image
The sendspin image platform displays album and artist artwork streamed from a
Sendspin group. The Sendspin hub must be configured on the
same device.
The Sendspin server delivers the artwork already scaled to the requested size; it is decoded at runtime and exposed as a regular image that you can draw on a display or use with LVGL widgets.
Configure one entry per artwork you want to show, up to a maximum of four. This platform only works on ESP32-based chips.
# Example configuration entrysendspin:
image: - platform: sendspin id: album_slot format: JPEG type: RGB565 resize: 240x240 current_image: id: album_artThe entry’s own id refers to the slot, which is what the action targets. The id inside
current_image is the image itself, and is what you reference from a display lambda or an LVGL widget.
Configuration variables
Section titled “Configuration variables”-
id (Optional, ID): The ID of the artwork slot. Use this to target the action below.
-
format (Required): The format the artwork is encoded with. One of
JPEG,PNGorBMP. -
resize (Required, string): The size the artwork is requested and rendered at, as
WIDTHxHEIGHT. The Sendspin server scales the artwork to these dimensions before sending it. -
type (Required): Specifies how to encode the image internally.
BINARY: Two colors, suitable for 1 color displays or a 2 color image on color displays. Uses 1 bit per pixel, 8 pixels per byte. Onlychroma_keytransparency is available.GRAYSCALE: Full scale grey. Uses 8 bits per pixel, 1 pixel per byte.RGB565: Lossy RGB color. Uses 2 bytes per pixel, 3 with an alpha channel.RGB: Full RGB color. Uses 3 bytes per pixel, 4 with an alpha channel.
-
current_image (Required): The image showing the artwork that is currently playing.
- id (Required, ID): The ID to reference the image in your display or LVGL code.
-
transition_image (Optional): A second image holding the outgoing artwork while a transition runs, for transitions that must keep it on screen after
on_image_displayreturns. It holds the current artwork at any other time, and is black until the first artwork has been shown. When set, the server is not told the device is ready for more artwork untilsendspin.image.transition_finishedruns. See Cross-fading between tracks.- id (Required, ID): The ID to reference the outgoing artwork.
-
source (Optional): Which artwork to display. One of
album(default) orartist. -
display_offset (Optional, Time): Request a shift when
on_image_displayfires relative to the moment the server asked for the artwork to appear. A positive value fires it early, a negative value delays it. Must be a whole number of milliseconds between-60sand60s. Defaults to0ms. -
transparency (Optional): If set, the alpha channel of the artwork will be taken into account. The possible values are
opaque(default),chroma_keyandalpha_channel. See the discussion on transparency in the image component. -
byte_order (Optional, string): For RGB565 images, the pixels are converted to 16 bit values. By default these are stored in little endian byte order (LSB first), but you can override this by setting
byte_ordertobig_endian. Options arelittle_endian(default) andbig_endian. Not applicable to other image formats. -
placeholder (Optional, ID): ID of another image to display until the first artwork has been received. This placeholder image will not be resized. It only applies when the image is drawn from a display lambda; LVGL widgets show nothing instead.
-
sendspin_id (Optional, ID): The ID of the Sendspin hub to attach to. Only needed if you have more than one hub configured.
NOTE
Each entry permanently reserves memory for two pictures at the configured resize size. 240x240 artwork of
type RGB565 costs 230 kB.
Automations
Section titled “Automations”-
on_image_display (Optional, Automation): An automation to perform when new artwork is ready to be shown. A common use is to refresh the display so the new artwork is drawn.
The variable
lateness_msis available in lambdas. It reports how many milliseconds past the intended moment the artwork actually arrived, so a transition can be shortened by that much and still finish on schedule. -
on_image_clear (Optional, Automation): An automation to perform when the artwork is cleared, such as at the end of a stream. The image is blank from this point until new artwork arrives. An LVGL widget keeps drawing the artwork it was pointed at.
-
on_image_error (Optional, Automation): An automation to perform when the artwork could not be decoded, or when it decoded to dimensions other than the ones requested with
resize. The artwork already on screen is left in place.
Actions
Section titled “Actions”sendspin.image.transition_finished Action
Section titled “sendspin.image.transition_finished Action”Report that the transition for the artwork just displayed has finished, telling the server the device is ready
for more. Only needed when a transition_image is configured.
IMPORTANT
Every displayed artwork must be acknowledged with this action exactly once if transition_image is
configured, either from on_image_display or from whatever finishes the transition it starts. If it is not
run, no further artwork appears until the artwork is cleared, and a warning naming the slot is logged ten
seconds after the artwork was displayed.
Configuration variables
Section titled “Configuration variables”- id (Required, ID): The artwork slot the transition belongs to.
on_...: - sendspin.image.transition_finished: album_slotExamples
Section titled “Examples”Display album artwork and refresh the display whenever it changes:
sendspin:
image: - platform: sendspin id: album_slot format: JPEG type: RGB565 resize: 240x240 current_image: id: album_art on_image_display: - component.update: my_displaydisplay: - platform: ... id: my_display # ... lambda: |- // Draw the album artwork at position [x=0,y=0] it.image(0, 0, id(album_art));Album and artist artwork can be requested at the same time by configuring one entry per source:
image: - platform: sendspin id: album_slot format: JPEG type: RGB565 resize: 240x240 source: album current_image: id: album_art - platform: sendspin id: artist_slot format: PNG type: RGB565 resize: 96x96 source: artist current_image: id: artist_artCross-fading between tracks
Section titled “Cross-fading between tracks”To dissolve the old artwork into the new one, both have to be on screen at once, so this needs a
transition_image and two stacked LVGL widgets. Later-declared widgets render on top, so declare the incoming
one first and let the outgoing one fade out above it.
A widget keeps drawing whichever artwork it was last pointed at, so both widgets are pointed at their image
again on every display. display_offset starts the fade early so it is centered on the change of track.
image: - platform: sendspin id: album_slot format: JPEG type: RGB565 resize: 240x240 display_offset: 1s current_image: id: album_art transition_image: id: album_art_transition on_image_display: - lvgl.image.update: id: outgoing_art src: album_art_transition - lvgl.image.update: id: incoming_art src: album_art - lvgl.animation.start: album_art_crossfade
lvgl: animations: - id: album_art_crossfade duration: 2s widgets: - id: outgoing_art opa: from: 100% to: 0% on_stop: - sendspin.image.transition_finished: album_slot widgets: - image: id: incoming_art src: album_art - image: id: outgoing_art src: album_artThe fade outlives the automation that starts it, so the transition is reported as finished from the animation’s
on_stop rather than at the end of on_image_display. The fade always runs for the same length here; to have
it end on schedule even when artwork arrives late, pass a duration to
lvgl.animation.start shortened by lateness_ms.