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"
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.
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
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.
- How to fully integrate your Raspberry Pi digital picture frame into Home Assistant even showing the current image
- Activate the power of the magic matting feature on your Raspberry Pi picture frame
- How to use your Raspberry Pi digital picture frame in portrait orientation
- How to trigger a Home Assistant script through Alexa and make your Raspberry Pi picture frame do (just about) anything