Use daily Webserver-Image as Ambience Picture

I would like to set a Webserver-Picture thats changing all 24hours as daily Ambience-Background.
On Webserver-Side i have php-Script that does the exchange all 24 hours and save the Image with the same Filename (Picture.jpg).

So how to archive that on Sailfish Side?

2 Likes

Downloading the picture and updating the ambience

First of all, I would start by creating a script that downloads the picture:

# Set this to the image on your server
url="https://example.org/image.jpg" 
# The path where the image temporarily gets stored
tmp_path="/tmp/image.jpg"
# Download the image from $url to $tmp_path  on your device (-L for following HTTP redirects)
curl -L $url -o $tmp_path

Next, tell the Ambience daemon to change the wallpaper over DBus:

dbus_response=$(busctl --user call com.jolla.ambienced /com/jolla/ambienced com.jolla.ambienced setAmbience s file://$tmp_path)

This will create a new ambiance. The $dbus_response will now contain first a list of return types, in this case x, followed by the values of the return types, in this case an integer containing the ID of the ambience created. You can use this later to remove or modify the ambience you’ve just created.

After this is done, save this script somewhere on your device and make it executable. I’m going to assume that it has been stored as /home/defaultuser/update-ambience.sh for convenience.

Calling the script daily

Next, you will probably want to make this execute every day. This can be done using systemd. You’ll need to create a systemd service that will tell systemd on how to execute the script first. Create in ~/.config/systemd/user with a name that ends in .service, such as ~/.config/systemd/user/update-background.service.

This file should contain the following:

[Unit]
Description=Change wallpaper
Requires=ambienced.service
After=ambienced.service

[Service]
Type=simple
ExecStart=/home/defaultuser/update-ambience.sh

For more documentation on this file, see systemd.service or man systemd.service on a Linux distro that ships documentation.

After having created the systemd service file, a systemd timer service should be created. Give it the same name as your service file, but now use the .timer extension instead of the .service extension. I will use ~/.config/systemd/user/update-background.timer:

[Unit]
Description=Update ambience daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

This will run the update-ambience systemd service every day on 00:00. If it has missed its target time, because the device was off at 00:00, the Persistent=true will ensure it runs the next possible time.

For more information on timer service, see systemd.timer

Next, enable the timer by running systemctl enable --user update-ambience.timer. If you used a different name, change the command accordingly.

FInally

This script isn’t ideal. It will create a new ambience every day and it does not remove the old ones. Removing the old ambiances is trivial* and left as an exercise for the reader :wink: .

Additionally, I assumed the image will always be a JPG image. You might want to modify the script if it does not work for PNG images or whatever image format floats your boat.

Lastly, I haven’t tested every single step, so I’ve might made a mistake. If you run into any trouble, feel free to reply to this post.

*If you are fluent in bash that is, which I’m not sadly.

Useful resources to help you further:

DBus documentation

Since the ambience daemon is controlled over DBus, some DBus knowledge is helpful.

I think that reading this overview document up until the “Bus names” sections should give you a good overview of the terminology used within DBus: DBus Overview

As for a complete DBus documentation, please look at: dbus

DBus introspection of the com.jolla.ambienced interface

This can be obtained by running busctl --user call com.jolla.ambienced /com/jolla/ambienced org.freedesktop.DBus.Introspectable introspect on your device. This lists all the methods, signals and properties this interface supports.

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="com.jolla.ambienced">
    <method name="indexFile">
      <arg direction="in" type="s" name="url"/>
    </method>
    <method name="createAmbience">
      <arg direction="in" type="s" name="url"/>
      <arg direction="out" type="x" name="contentId"/>
    </method>
    <method name="setAmbience">
      <arg direction="in" type="s" name="url"/>
      <arg direction="out" type="x" name="contentId"/>
    </method>
    <method name="remove">
      <arg direction="in" type="i" name="contentType"/>
      <arg direction="in" type="x" name="contentId"/>
    </method>
    <method name="reset">
      <arg direction="in" type="i" name="contentType"/>
      <arg direction="in" type="x" name="contentId"/>
    </method>
    <method name="installPackage">
      <arg direction="in" type="s" name="path"/>
    </method>
    <method name="saveAttributes">
      <arg direction="in" type="i" name="contentType"/>
      <arg direction="in" type="x" name="contentId"/>
      <arg direction="in" type="a{sv}" name="args"/>
      <annotation value="QVariantMap" name="org.qtproject.QtDBus.QtTypeName.In2"/>
    </method>
    <method name="refreshAmbiences"/>
    <method name="setFavorite">
      <arg direction="in" type="s" name="url"/>
      <arg direction="in" type="b" name="value"/>
      <arg direction="out" type="b" name="success"/>
    </method>
    <signal name="contentChanged">
      <arg direction="out" type="i" name="type"/>
    </signal>
  </interface>
  <interface name="org.freedesktop.DBus.Properties">
    <method name="Get">
      <arg name="interface_name" type="s" direction="in"/>
      <arg name="property_name" type="s" direction="in"/>
      <arg name="value" type="v" direction="out"/>
    </method>
    <method name="Set">
      <arg name="interface_name" type="s" direction="in"/>
      <arg name="property_name" type="s" direction="in"/>
      <arg name="value" type="v" direction="in"/>
    </method>
    <method name="GetAll">
      <arg name="interface_name" type="s" direction="in"/>
      <arg name="values" type="a{sv}" direction="out"/>
      <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
    </method>
    <signal name="PropertiesChanged">
      <arg name="interface_name" type="s" direction="out"/>
      <arg name="changed_properties" type="a{sv}" direction="out"/>
      <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
      <arg name="invalidated_properties" type="as" direction="out"/>
    </signal>
  </interface>
  <interface name="org.freedesktop.DBus.Introspectable">
    <method name="Introspect">
      <arg name="xml_data" type="s" direction="out"/>
    </method>
  </interface>
  <interface name="org.freedesktop.DBus.Peer">
    <method name="Ping"/>
    <method name="GetMachineId">
      <arg name="machine_uuid" type="s" direction="out"/>
    </method>
  </interface>
</node>

Additionally, to get an idea of how the system interacts with the ambience service, you can use busctl monitor com.jolla.ambienced to see the method calls and signals over the bus. Try changing the ambience while you keep this command running and you should be able to see what happens.

8 Likes

Thanks for you fast and detailled answer.

Your suggestion brings me to the idea to modify an Ambience in

/usr/share/ambience/test/test.ambience

and place there the local download-path of the downloaded image like:

{
…
“wallpaper” : “/home/defaultuser/Pictures/Daily/Daily.jpg”
…
}

And then use your script/parts of it to archive that.

Maybe it enough to change the Ambience to other and after updating/downloading the Picture change to the DailyPic-Ambience back!?

I come from the Commodore-Amiga and there you just Download the File and do a simple “touch” to a Backpattern.prefs-Config-File in order to change the Background immediately.

I´m using:
rm -f /home/defaultuser/.local/ambienced/wallpapers/*.jpg
before executing the other commands.

Is there an option for the Ambience Daemon to set a Ambience Name over DBus?

dbus-send --session --dest=com.jolla.ambienced --type=method_call /com/jolla/ambienced com.jolla.ambienced.setAmbience string:"file:///usr/share/ambience/fresh/fresh.ambience"

More hints here; D-Bus APIs | Sailfish OS Documentation

1 Like