Screenly OSE install notes

For: My Michelle – Sprint 7


Download OS here:

Instructions to burn image here:

the short of it is:

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.


Use the Screenly UI. Nothing else seemed to work. Connect by instructions on the screen.

Which wireless network?


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.


See here

$ cd ~/screenly
$ git pull
$ ./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:

---	2018-10-24 14:34:22.076759685 -0400
+++	2018-10-24 14:33:24.427157304 -0400
@@ -155,6 +155,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:
@@ -164,12 +170,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...