photOS icon indicating copy to clipboard operation
photOS copied to clipboard

Add OTG device mode to use as usbstick in combination with existing photoframe

Open jscmidt opened this issue 4 years ago • 9 comments

Hi, I really like the idea of this project, especially the webdav sync. I wanted to customize it a little bit in order to not display the pictures on the HDMI-Port but let the Raspi emulate an USB-Stick to work with any normal digital photo frame. Unfortunately, I’m a little bit confused because it looks like systemctl ist not set up on photOS. Am I right with this assumption? Is there any systemctl alternative running on photoOS? Thanks in advance!

jscmidt avatar Apr 07 '21 10:04 jscmidt

This sounds like a very intersting approach to make exiting picture frames connected. Do you have some information how this can be implemented? The images from webdav are locally synced into /data/photoframe/images_local and it should be easily exported as mass storage.

Regarding your question: The underlying thingOS uses init.d. To start the mass storage service, you have to add a script into /etc/init.d. How does your systemd unit file looks like?

avanc avatar Apr 07 '21 12:04 avanc

I haven’t tested it yet because I don’t have a Pi Zero, but I think I understood how it is working. I’ve read multiple (german) tutorials, and think the most modular one is this. When it comes to the Hardware, the beginning of this tutorial is helpful.

I came to the following steps to theoretically make photOS to a smart USB stick:

  1. Add dtoverlay=dwc2 to /boot/config.txt
  2. Add dwc2 to /etc/modules
  3. Separate the mass-storage from the sd card: sudo dd bs=1M if=/dev/zero of=/piusb.bin count=4096
  4. Format it as FAT32: sudo mkdosfs /piusb.bin -F 32 -I
  5. Create directory for mount: sudo mkdir /mnt/usb_share
  6. Add /piusb.bin /mnt /usb_share vfat users,umask=000 0 2 to /etc/fstab, then sudo mount -a
  7. reboot
  8. download this script to /usr/local/share (curl https://gist.githubusercontent.com/davidhoness/0f45ef6a41bac6311614f109acbf92db/raw/970badd0ae4b097e3af8d5142e65c34b21f5cfab/usb_share.py --output usb_share.py ). It refreshes the virtual usb stick regularly or if something was changed.
  9. sudo chmod +x usb_share.py to make it executable
  10. This script requires the following python library: sudo apt-get install python-watchdog
  11. For this script I needed the systemd service. A really simple one should be fine:
[Unit]
Description=Raspi USB Stick Refresh

[Service]
Type=Simple
ExecStart=/usr/local/share/usb_share.py
Restart=Always

[Install]
WantedBy=multi-user.target

Of course some chances in the photoframe.sh would be needed: display on: sync pictures in the local picture directory with the pictures on the usb stick display off: delete all images from the usb stick and put only a complete black image in the usb partition, so that the digital photoframe has to display this black picture and saves energy. sync: sync webdav with the pictures in the local directory, like it is already. Then, if the last command sent to photoframe.sh was display on, also sync the local pictures directory with the pictures on the usb stick. If the last used command was display off, just leave the black image on the usb stick. For this purpose, the script has to save the last state of PhotoFrame every time the display on or off command is used. test: I think this is not longer needed, since it only executes the get_image function, and this random logic is now done by the digital photoframe itself. Start/Stopp: I think this is not longer needed

Since I’m new to programming it would take some time until I get this to work. If I’m done this maybe could be included as an option in photOS, if you want so. Or you set it up yourself and directly include it into photOS.

jscmidt avatar Apr 07 '21 18:04 jscmidt

Thanks for this great summary. The dwc2 module and mkdosfs are already available. Only python-watchdog is not within the image, but it is available in buildroot. So it can be easily integrated. And changing that simple systemd unit file into an init.d script should be straight forward.

As I'm currently focusing on integrating syncthing (https://github.com/avanc/photOS/issues/12), I don't have time to implement this approach right now. However, if you want to give this a try, here are some additional hints:

  • config.txt: https://github.com/avanc/photOS/blob/master/board/raspberrypi/config.txt
  • /etc/modules: https://github.com/avanc/photOS/blob/master/board/raspberrypi/overlay/etc/modules
  • Creating piusb.bin should be done on first boot on the data partition (/data/somewhere)
  • As first shot you can add the usb_share.py script within https://github.com/avanc/photOS/tree/master/board/raspberrypi/overlay/usr/bin
    • Final solution might be creating a separate package for it or extend https://github.com/avanc/photOS/tree/master/package/photoframe

I would gladly integrate it into photOS...

avanc avatar Apr 07 '21 20:04 avanc

Thanks for the information! I think I will give it a try in a fork and then later implement it to photOS if it‘s working.

jscmidt avatar Apr 08 '21 19:04 jscmidt

Great! Just leave a comment or drop a mail if you get stuck.

avanc avatar Apr 09 '21 09:04 avanc

I’m almost done now. Unfortunately, my RPi Zero is still on shipping, so I could only test it on a Raspberry 1 B, without the OTG functionality. But even with not finally knowing if it’s working, I already came to some points that aren’t optimal solved yet in my opinion:

  1. The Fstab.extra, where the virtual USB stick is mounted, is in the common directory and not in the board directory. Can I just delete it from the common directory and create an own fstab.extra in every board directory or is it more complicated?
  2. I decided to use the Fstab.extra . What do you think, is this the right Fstab or should I use another one?
  3. I think Fstab.extra runs before the container Piusb.bin and the used mount directory are created at the first boot. Is a restart required to get this later created container mounted or does it just retry mounting the container later again, without the need of a reboot?
  4. I mounted in /data/photoframe/images_usb to keep the existing structure. Is it fine like this or should I use /mnt ?

jscmidt avatar Apr 11 '21 12:04 jscmidt

I also thought about how to integrate in into photOS later if it’s working. I think the most simple way is, like you already said, creating a new package, e.g. photoframeusb, and adding a “new board”, e.g. raspberrypiusb, that includes the photoframeusb package (and the python-watchdog) instead of the photoframe package. If I get the fstab like mentioned above out of the common directory, this should work fine, but of course creating a new board isn’t the “cleanest” solution. What do you think?

jscmidt avatar Apr 11 '21 13:04 jscmidt

Great, you are making quick progress. Here are some thoughts:

  • package/photoframeusb
    • It's a good idea to have the code in a separate package.
    • As a longterm goal I would not see this feature as new board but hope to integrate it directly into the rapsberrypi release and make it optional configurable and activate it within the webui
  • fstab.extra
    • I don't like to have package stuff in the overlay. However, I also didn't found a good solution and doing the mount "by hand" without fstab: https://github.com/avanc/photOS/blob/21f1e3f6b99111964d9b74b9c8bb5a3c19e677d4/package/photoframe/photoframe.sh#L35
      • Also not the best solution and requires root
    • If going for fstab.extra (which is also ok), you might try what happens if you have a board specific fstab.extra AND the common fstab.extra. Maybe the common is overwritten and you don't have to change common. (Makes merging updates from thingOS easier).
    • Regarding your concerns mounting before firstboot, you can add noauto to the fstab to avoid automatically mounting (https://linux.die.net/man/8/mount) and do at on your own later in S79usb_share.

avanc avatar Apr 11 '21 19:04 avanc

Thanks for sharing your thoughts! Making it configurable via the Webserver sounds good, unfortunately I have no idea yet how the Webserver in photOS is working.

Fstab: I also wasn't sure if it is a good idea to put package stuff into the overlay. But I also don't think that mounting and unmounting it every time is a good idea, since the Python script is watching this directory and might get confused by that. An option would be to mount it like you do it by hand in one of the init scripts, without unmounting it later. Would that work?

Also, right now /etc/modules and /boot/config.txt is edited directly in the overlay too, and I think also the crontab is.

As a final goal I could write a script (or integrate it into the photoframe(usb).sh) to configure/unconfigure usb mode with a reboot afterwards, that also does overlays stuff like remounting the partitions rw and adding/removing those lines in /etc/modules and /etc/config.txt . This scripts then could be executed by the Webserver to switch between the modes.

jscmidt avatar Apr 12 '21 14:04 jscmidt