Info display for home
After completing the home electricity meter hack I looked for options to have small display hanging on the wall, which would show useful information. I had previously bought Samsung SPF-87H photo frame which can be used as an external monitor. The frame connects to computer with usb and the picture is updated by simply sending it in jpeg format. Few caveats are that display needs to be first initialized to “mini monitor”-mode and the picture size must match exactly to the display resolution (800×480 in case of SPF-87H). I chose Beagleboard as the embedded computer to keep the power usage low. BB has one usb and one usb-otg port. I’m planning to change the Beagleboard to Raspberry Pi, when they became available since this doesn’t use all the resources provided by the Beagleboard.
Even that the Beagleboard has only one true usb-port, I did not need to add the usb-hub to setup, since the usb-otg port can also be used as host. The display connects to otg-port, since it has it’s own power supply (otg-port can’t supply power) and the regular usb port is used for wlan adapter.
Setup
The photo frame has desk stand but no hole to hang it on the wall. This was fixed by using hot glue to attach a piece of wire to the backside to act as hanger. I learned later that I should have made a loop to the both ends of the wire to increase gluing surface. The frame dropped to floor after couple of days, resulting small crack to bezel and a dent to floor. Fortunately the display continued working.
The finished display looks quite nice. The Beagleboard and the power supply are hidden on top of cupboard and the display cables are hidden inside cable duct.
Software
The software “WallDisplay” running on the Beagleboard is written in C++ and uses Qt. The software simply reads Sqlite database, which contains a list of urls and time, how long the url is displayed on the screen. The web pages are loaded to QWebPage and its contents are exported as jpeg file, which in turn is pushed to the display. Qt’s webkit implementation has too many ties to the user interface for it to be used as command line QtCore-application. Since the program does not have to actually show anything on a real monitor nor accept user input, I’m using xvfb to simulate X-server. In future I’m planning to add web interface to make it easier to manage the displayed pages.
Currently the display is rotating following pages:
- Electricity usage
- Weather forecast
- Calendar, exported from iCal
- Irc log from the channel we used with my friends
- Last picture from the security camera
The sources are available at: https://gitorious.org/home-automation/walldisplay
You also need to install software for controlling the display from here: https://github.com/Gekkio/samsung-photo-frame-ctrl
See rc.local file for an example how to run the application. Path to database and path to frame-ctrl program must be given as arguments. The database creation command is in the readme.txt file.
Does it only support JPG or also some more useful “lossless” image format?
Unfortunately not. The Samsung photo frame I used only accepts JPG images.
Great post!!
I have a Samsung SPF-107H pictureframe which I want to use a bit more actively – like you.
However, i am having a hard time making it work. I have been trying your script and inserted the correct productIds for my frame which are 2035 and 2036. I am running a Raspberry PI and Rasbian, and have installed PyUSB. The frame has the latest firmware installed.
If I run the script when the frame is in Mass Storage mode, it is detected and switches the frame to Mini Monitor mode, but fails after doing so. (I added some tracing to your script)
pi@raspberrypi ~ $ sudo python frame-ctrl.py HD\ Sportster\ Forty\ Eight\ copy\ 2.jpg
Custom case…
Found something
After conf
Sending setup commands to device
Warning: Expected [3] but got [1]
After dispay mode setup
After write image
Found SPF-107H in storage mode
Setting device to display mode
Traceback (most recent call last):
File “frame-ctrl.py”, line 83, in
storageToDisplay(dev)
File “frame-ctrl.py”, line 28, in storageToDisplay
raise e
usb.core.USBError: Input/output error
Do you have any suggestions to what I am doing wrong?
The code for SPF-107H is untested and I can’t check since I don’t have that type of a display. Try to select mini monitor mode and immediately after run the script (after couple of seconds display will exit monitor mode) and see if you get different results.
I have tried running the script when in Mass Storage mode. The result is the trace above.
– Detects the device
– Changes to Mini Monitor mode (Which it visually does after a couple of seconds)
– usb.core.USBError: Input/output error
I will try your suggestion.
Thanks for the reply.
Another thing to try, if it actually manages to switch to mini monitor mode is to put pass to exception handling to prevent the crash and maybe instead add a small delay and the see if it would continue working.
I finally made it work.
The script still gets the exception after switching the display to Mini mode, but if I run it again right away the image is transferred as expected.
I will have a look at the exception handling, for automatic switching.
Thanks again for the help.
Now to create a program which can use the script. I haven’t programmed using Python before, so that will be interesting.
Sounds like a plan.
Thanks.
Is your frame listed when you run lsusb in Mini Monitor mode? Mine is not.
For 107h, changed the product id’s ‘SPF-107H’: (0x2035, 0x2036).
Change the the contents of the following method to make it work all fine:
def storageToDisplay(dev):
print “Setting device to display mode”
try:
dev.ctrl_transfer(CTRL_TYPE_STANDARD | CTRL_IN | CTRL_RECIPIENT_DEVICE, 0x06, 0xfe, 0xfe, 254)
except usb.core.USBError as e:
errorStr = str(e)
if errorStr == ‘[Errno 5] Input/output error’:
time.sleep(2)
elif errorStr != ‘[Errno 19] No such device (it may have been disconnected)’:
print str(e)
raise e