HA-meural: custom integration for Netgear Meural Canvas digital art frames

Tags: #<Tag:0x00007f73b4d9ef48>

UPDATE: HA-meural is now available through HACS. It’s no longer necessary to manually copy the code or add it as a custom repository first. You can find it listed under integrations in HACS as: HA-meural.

Original post:
I’ve recently purchased a Netgear Meural Canvas II, a digital art frame that can display both your own images and a collection of classic and modern art via Meural’s subscription system. After finding the following topic here I was inspired to work on an integration to control the Canvas from Home Assistant:

The integration is available here:

The Canvas offers both a local interface and a cloud API. This integration leverages both to control the Canvas as a media player in Home Assistant. This way all regular media player services work as you’d expect - you can turn the Canvas on or off, pause and play, go to previous/next image, change playlists and set shuffle. It will retrieve artwork thumbnail, artwork title and artist name to display in the Media Control card. Looks like this in Lovelace:

And if you click through to the entity details you have some more controls:

There are also some service calls registered under the meural.xxx domain that will let you set brightness, reset the brightness based on current ambient light, set device options on the Meural server, or toggle display of the information card on your device.

Additionally, because it’s set up as a media player, it can be exposed to Google Assistant (as opposed to the Alexa-only support that Meural offers) via Nabu Casa or your manually configured setup. As a proof of concept I posted this video to Twitter:

I’m not a dev and the last time I coded in Python was when I was at university, over a decade ago, so this is very much a learning-by-doing experiment. Feel free to give me feedback on what can be improved!


Bringing in a reply from another topic to centralize here.

Can you check if any media_player is being created? It’s created using the canvas name of the device you have set up on Meural’s servers. E.g. this is what it looks like on Meural’s website for me:

I’ve renamed mine to be named ‘Mural’ (because of testing with Google Home, so it knows what I’m talking about when I say ‘Meural’). My entity is called: media_player.mural
If you haven’t renamed it, the default Meural names are a painter’s name with a dash and 3 numbers, like picasso-491. Then your entity would be called: media_player.picasso-491

aha, that makes sense but I didn’t think of it using a different name!

Because of this log line:
2020-05-29 20:15:25 INFO (MainThread) [homeassistant.components.media_player] Setting up media_player.meural

I assumed it was trying to create an entity called that. Maybe it would help to add the word “domain” there to avoid confusion.

I guess i also expected a log line saying that the entity media_player.X was created.

In my case, I have media_player.mondrian-490 so I’m going to rename my Canvas now and hopefully things will still work.

Great news! And if you rename the Canvas, just restart Home Assistant and it will create a new entity with the new corresponding name instead!

I just updated the master branch on github again, worth updating to that while you’re at it. It speeds up switching playlists a LOT (like, in the order of 10x) by moving to local calls instead of always going through an upload via the Meural API.

And I’ll look into better logging messages, I haven’t looked into that part at all to be honest. It’s basically doing whatever the default scaffolding @balloob built me says.

Cool, I’ll see if I can have a go and add some logging then.

Thank you very much, I was hoping to avoid for the last year starting to write this myself :wink:

One of the things I’d like to do is to send an image to the device, so that I can temporarily show who’s ringing the doorbell.

I can do this with any of the chromecasts I have:

Any idea whether it would be hard to have the code send that image to the meural locally to be displayed?

So far I’ve only worked on the passive side of playing art/playlists already in the system, so I haven’t really looked into it, but according to the REST API docs we could definitely upload new images. The current play_media code will only accept an item ID for images uploaded to Meural’s servers, not file paths, so I suppose you could upload the image from the doorbell to Meural and display the new item immediately afterwards.

Turns out there IS a local option, there’s a /remote/postcard/ call that the web remote uses to temporarily override the currently displayed item (it won’t show in your media control card). If you to go to the remote it’s the camera icon in the top-right:

Works fine on my frame from the web remote, I just don’t know how to send the data to upload an image for a call like this. Never did something like that before.

Yeah, I tried that last week and was able to do it with a POST request of a jpeg.

curl -F “[email protected]/home/thomasvs/Downloads/eye.png” http://meural/remote/postcard

Gave it a shot tonight but I’m afraid dealing with retrieving the image from a given URL, then POSTing that image to the remote/postcard call is a few bridges too far for me right now. No experience at all with doing that in python.

I’ll have to learn how to write components in HA at some point.

If you can point me to where in the code you’d add it, I can take a look at adding it?

Sure! If you go to the dev branch:

I created the service preview_image in media_player.py, which calls the function self.local_meural.send_postcard with the image URL.

That function is defined at the bottom in pymeural.py:

Which should take that image URL and turn that into image data we can then POST request to /remote/postcard/…

Would be awesome if you’re able to add this :slight_smile:

Give this pull request a go: https://github.com/GuySie/ha-meural/pull/15

I spent way too long diving into the depths of aiohttp chasing down a bug, when in the end it looks like there may just be a bug in the Meural web server. Both through this and with the remote web control, uploading an image sometimes makes the meural display a previously uploaded image. When it hits that state, I can’t recover. A reboot helps.

Do you have a v2 Meural or an original one?

1 Like

Thanks, that’s awesome! I’m running your code now, this seems to work perfectly. Haven’t managed to crash it out to a previously uploaded image yet, either. I’m just torn if this should be a part of play_media because it’s not actually playing (changing the current item being displayed) but previewing.

I’ve got the v2. Don’t really know if there are really any differences between the two, aside from the frame and the smaller 21" size they added to the v2 line-up.

I did it that way because that’s how it works for chromecast (see Display image on chromecast)

I’m not sure about the distinction of playing vs previewing - is previewing something specific supported by media_player entities?

Given that sending the image this way is permanent until you take a user action, it feels more like playing than previewing to me.

What web server version does your meural report? Mine says Server: Apache/2.4.7 (Ubuntu)

What OS version does your meural report? My app says it’s 2.0.8 (updated it yesterday, it was 2.0.7 before)

Previewing is a term Meural uses for sending an image to the Canvas to be displayed that is not officially on that device yet; it’s normally used to preview art you might want to buy from their art collection on the large screen.

Ah, this seems to be different for us. It is not permanent for me - it displays exactly as long as the preview duration you can set through the Meural web interface - that’s why I’m pretty sure postcard is the same as Meural’s preview system. I had that set to 60 seconds so after a minute it went back to my original playlist.

Server says: Apache/2.4.18 (Ubuntu)
Meural app says: 2.1.9
Device JSON says: V2.1.9_2.0.10

Which version Canvas do you have?

I have the v1. Can you capture a full POST as made by the webapp? Where does it specify duration?

The duration is specified in the settings in Meural’s web interface:

Do you have those settings or is that different for the v1?

Yes, quite different.

BTW, notice the inspect console on the right. This is right after uploading an image.
Can you do the same thing? Ctrl-Shift-I for inspect, open the Network tab, upload the image, then click on the postcard/ URL on the left, and click on “Source” bottom right for the form data.

Oh sorry, I was unclear. What you’re posting is what I call the web remote, which looks identical on my end.

There appears to be no setting here for any of the durations, nor of several other settings (eg Shuffle) that can only be set via the Meural app or Meural website. It’s one of the things that I don’t know how to deal with yet - if I could get and set these locally, we wouldn’t have to deal with the Meural servers at all.

The image I posted was from the interface on Meural’s website, but the same settings can be set through the Meural app.

The Preview duration is the one that I was referring to. I can’t set it locally from the web remote, but that settings does influence how long the postcard image remains visible on my device.