Screenly OSE install notes

For: Sprint 9


Download OS here:

Instructions to burn image here:

the short of it is (lsblk to get the right device…):

unzip -p | dd of=/dev/sdc bs=4M status=progress conv=fsync

Install instructions here: Use Option 1.


sudo raspi-config

to change hostname and many other things.


To use the Screenly Wi-Fi UI you need a laptop handy to trigger a Wi-Fi reset and a keyboard to reboot, unless you want to cord-yank. The command line tools recommended for Raspbian Lite don’t work with Screenly. This is because Screenly uses NetworkManager. Use nmcli instead.

nmcli c delete ScreenlyOSE-gavf # to turn hotspot off
# substitute the name of yours...
nmcli device wifi rescan # scan - nothing printedscript 
nmcli device wifi list # show available AP's
nmcli --ask device wifi connect SSID
nmcli device status # show network status
nmcli connection show # show configured connections
# switch connections
nmcli -p con up connection-name - usually SSID

Which wireless network? (Old but good.)


display rotation and offset

Edit /boot/config.txt.

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
# rotate display
display_hdmi_rotate	result
0	no rotation
1	rotate 90 degrees clockwise
2	rotate 180 degrees clockwise
3	rotate 270 degrees clockwise
0x10000	horizontal flip
0x20000	vertical flip

ssh and firewall

Enable ssh if you wish (like any other system.)

Ditto firewall.

# firewall setup rules...
/usr/sbin/ufw enable
/usr/sbin/ufw allow some-port/tcp
/usr/sbin/ufw allow https
/usr/sbin/ufw default allow outgoing
/usr/sbin/ufw default deny incoming
/usr/sbin/ufw logging off
/usr/sbin/ufw status verbose # or numbered


See here

$ cd ~/screenly
$ git pull # this step is not needed for later versions
$ ./bin/


(user name and password). See

Edit /home/pi/.screenly/screenly.conf No quotes.

password = some_password
user = some_user

Afterwards pkill -f to restart server.

turn monitor off


With our Samsung LH32DCE /usr/bin/vcgencmd display_power 0 in the pi user’s crontab worked.

Set the timezone to make this easy… dpkg-reconfigure tzdata

convert pdf to jpg and scroll down a bit.

gs -dNOPAUSE -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -sOutputFile=output%d.jpg -dJPEGQ=100 -r127 -q intput.pdf -c quit

To get the -r number, divide the screen width in px by the pdf width in inches, 1080/8.5 in the case of a flyer, 1080/20.25 ~=54 in the case of a calendar.

Add -dTextAlphaBits=4 -dGraphicsAlphaBits=4 for anti-aliasing.

cloning screens

Clone script, on clone:

/usr/bin/rsync -az --delete pi@master_screen:screenly_assets/ screenly_assets
/usr/bin/rsync -az pi@master_screen:.screenly/screenly.db .screenly

crontab on clone:
# clone
*/5 * * * * /home/pi/

.ssh/config on clone:

Host master_screen
    Port some_port

Modifications to (on clone) to enable reconnecting to database:

---	2019-04-27 04:42:45.614203993 -0400
+++	2019-07-17 12:06:34.462002313 -0400
@@ -174,6 +174,12 @@
         time_cur = datetime.utcnow()
         logging.debug('refresh: counter: (%s) deadline (%s) timecur (%s)', self.counter, self.deadline, time_cur)
         if self.get_db_mtime() > self.last_update_db_mtime:
+	    # testing: reload database
+	    global db_conn
+	    if db_conn != None:
+		db_conn.close()
+	    db_conn = db.conn(settings['database'])
+	    #
             logging.debug('updating playlist due to database modification')
         elif settings['shuffle_playlist'] and self.counter >= 5:
@@ -183,12 +189,15 @@
     def update_playlist(self):
-        self.last_update_db_mtime = self.get_db_mtime()
+	# mtime save was here
         (new_assets, new_deadline) = generate_asset_list()
-        if new_assets == self.assets and new_deadline == self.deadline:
+	# added check to db_mtime
+        if new_assets == self.assets and new_deadline == self.deadline and self.last_update_db_mtime == self.get_db_mtime():
             # If nothing changed, don't disturb the current play-through.
+	    self.last_update_db_mtime = self.get_db_mtime()
+        self.last_update_db_mtime = self.get_db_mtime()
         self.assets, self.deadline = new_assets, new_deadline
         self.counter = 0
         # Try to keep the same position in the play list. E.g. if a new asset is added to the end of the list, we

validate-rsync on master screen:

if [ "$SSH_ORIGINAL_COMMAND" == "rsync --server --sender -logDtprze.iLsfxC . screenly_assets/" -o "$SSH_ORIGINAL_COMMAND" == "rsync --server --sender -logDtprze.iLsfxC . .screenly/screenly.db" ]
  echo "failed `date` $SSH_ORIGINAL_COMMAND" >>/home/pi/soc

.ssh/authorized_keys on master screen:

command="/home/pi/validate-rsync" ssh-rsa A...

why isn’t there any documentation installed in the image or with new packages?

This file /etc/dpkg/dpkg.cfg.d/01_nodoc prevents installation of documentation. I don’t know if documentation for already installed packages would be installed if this file were removed.

upgrade notes

Clients first.

  1. update one client on extra box.
  2. modify database if needed on client, see script below.
  3. swap extra box with production.
  4. same with other client.
  5. server on temp box.
  6. swap.
  7. update server.
  8. swap.

Don’t forget SSL, password on UI for clients.

# add column to database
/usr/bin/sqlite3 /home/pi/.screenly/screenly.db "alter table assets add column skip_asset_check integer default 0;"

Leave a Reply

Your email address will not be published. Required fields are marked *