Changing the display brightness via software is really difficult to do from a Raspberry Pi. It works with some selected displays, but for the large majority, it doesn’t. But there is a workaround.
With a digital picture frame, you may want to automatically dim the screen a little bit in the evening so that it doesn’t shine too bright in the room.
Fortunately, this functionality is now available in the latest release of the PictureFrame image viewer.
Tested with: Raspberry Pi OS March 2021 version, Raspberry Pi 2, 3, and 4, Pi3D 2.43, PictureFrame 2021.03.20, 1080p and 4K displays.
How it works
In my Raspberry Pi digital picture frame setup tutorial, I mention the Pi3D PictureFrame image viewer, which produces those wonderful crossfading image transitions.
It turns out that the same image algorithms can be used to reduce the brightness of an image.
The brightness can be controlled via MQTT or Home Assistant, which means that you can remote control it from mobile devices or simply through a time-controlled Python script.
In this article, I will show you how to do it either way.
Remote control via MQTT
The new parameter to control the brightness variable is unsurprisingly called “brightness”.
The payload value can range from “0.0” (nothing to see here) to “1.0” (full brightness).
So, if your device ID is called “picframe”, and you wanted to dim your screen to 80%, you would send a message like
mosquitto_pub -h localhost -t picframe/brightness -m "0.8"
If you want to know how this works with Apple devices, check here, for Android, here.
Control the brightness automatically with sunrise/sunset
Rather than manually changing the screen’s brightness, in most cases, an automation will be fine for most of the cases.
This is easy to do with a Python script.
First install the astral package.
sudo pip install astral
Create a new file and paste this code. Save as “brightness_automation.py”.
#!/usr/bin/python3
import logging
import time
import traceback
from datetime import datetime
import paho.mqtt.client as mqtt
from astral import LocationInfo
from astral.sun import sun
from pytz import timezone
logging.basicConfig(filename="log.txt",format="%(asctime)s-%(levelname)s-%(message)s",level=logging.DEBUG)
MQTT_HOST="localhost" #enter your MQTT server here
MQTT_PORT=1883
#MQTT_USER=""
#MQTT_PASWD=""
completed=False
connected=False
def on_connect(client, userdata, flags, rc):
print("Connected. %d." % (rc))
global connected
connected=True
update_brightness()
def update_brightness():
city = LocationInfo(name="Bad Soden am Taunus", region="Germany", timezone="Europe/Berlin", latitude=50.1420634310433, longitude=8.496851921081545) #enter your location info here
c_data = sun(city.observer, tzinfo=city.timezone)
dawn=str(c_data["dawn"])
sunrise=str(c_data["sunrise"])
sunset=str(c_data["sunset"])
dusk=str(c_data["dusk"])
current_local_time=datetime.now(tz=timezone(city.timezone))
print("Current Time: ",current_local_time)
print("Dawn: " + dawn)
print("Sunrise: " + sunrise)
print("Sunset: " + sunset)
print("Dusk: " + dusk)
dawn=datetime.fromisoformat(dawn)
sunrise=datetime.fromisoformat(sunrise)
sunset=datetime.fromisoformat(sunset)
dusk=datetime.fromisoformat(dusk)
bright_val=1.0
if current_local_time>=dawn and current_local_time<sunrise: #this is where you adjust your brightness settings depending on sunrise and sunset
bright_val=0.9
elif current_local_time>=sunrise and current_local_time<sunset:
bright_val=1.0
elif current_local_time>=sunset and current_local_time<dusk:
bright_val=0.9
else:
bright_val=0.8
print("Brightness: ",bright_val)
# publish screen brightness value
client.publish("picframe/brightness", bright_val, qos=0, retain=True)
global completed
completed=True
if __name__ == "__main__":
try:
# MQTT Broker
client = mqtt.Client()
client.on_connect=on_connect
client.username_pw_set(username=MQTT_USER,password=MQTT_PASWD)
client.connect(host=MQTT_HOST,port=MQTT_PORT,keepalive=60)
client.loop_start()
while completed!=True:
time.sleep(0.01)
if not connected:
print(".",end="")
except:
traceback.print_exc()
logging.error("Error",exc_info=True)
Adjust the values in your script as it works best with your screen and the room environment.
To start it automatically at boot and keep it running in the background, create a service with systemd.
Enter
sudo nano /etc/systemd/system/brightness_control.service
Paste the following text into the editor window
[Unit]
Description=Control display brightness automatically
After=multi-user.target
[Service]
Type=idle
User=root
ExecStart=/usr/bin/python3 /home/pi/brightness_automation.py
Restart=always
RestartSec=300
[Install]
WantedBy=multi-user.target
Save and close.
Now change the file permissions with
sudo chmod 644 /etc/systemd/system/brightness_control.service
and update the services with
sudo systemctl daemon-reload
sudo systemctl enable brightness_control.service
Reboot.
Conclusion
Being able to soft-control your screen’s brightness through the Pi3D image viewer allows you to hide any monitor controls that you would otherwise need access to.
You could obviously also attach a brightness sensor, but I didn’t want to drill a hole in the frame. But if someone has a great idea how to do this without showing a fat sensor on the front of the frame, please contact me.
Thank You, Paddy, for a great addition to the PictureFrame script.
Was this article helpful?
Thank you for your support and motivation.
Related Articles
- Personalizing Pi3D PictureFrame: How to localize your photo geodata in any language
- How to automatically remove duplicate images from your Pictures folder (2024 Edition)
- How to only show portrait photos on your Raspberry Pi photo frame
- Celebrate birthdays and anniversaries with auto-themed photos on your digital frame