Controlling the device¶
Show a notification, move the rotation, switch the display off, and read or change the device settings from your script.
What you get¶
class Doorbell
def on_button(btn)
if btn == "select"
notify({"text": "Doorbell", "sound": {"rtttl": "d:d=4,o=5,b=120:c,e,g"}})
end
end
def draw()
clear()
text(1, 6, "Ring", 0xFFFFFF)
end
end
return Doorbell()
Press select while the app is shown, and a notification says Doorbell with a short melody.
How it behaves¶
notify()shows a notification like one sent to the API. It interrupts the rotation, and it can wake a switched-off display. Its sound is an alert and plays over your script's own sounds.rotationmoves the apps along now.rotation.pause()keeps the app shown until your script resumes the rotation or the user moves it.display.power()switches the display, a moment later. AWTRIX and its scripts keep running while it is off.settingsreads and changes the device settings, with the keys and checks of the API. A change is saved and stays after your app is gone, like a change in the web UI.- The uppercase setting never changes what a script draws. Read the settings when your app should match the built-in apps.
Show a notification¶
notify() takes a map in the notification payload format, the same
object POST /api/v1/notifications takes. So everything a notification can do works here: hold,
stack, wakeup, a sound, an effect, an overlay, colors, charts. Colors may be numbers:
rgb(), hsv() and 0xRRGGBB all work.
def on_button(btn)
if btn == "select"
notify({"text": "ARMED", "textColor": rgb(255, 0, 0), "hold": true,
"sound": {"rtttl": "s:d=8,o=5,b=200:c,g,c,g", "loop": true}})
end
end
sound takes the same sound as sound.play(), except station.
A plain name finds your script's own sounds first.
The sound is an alert: it plays at the Alerts volume, over your script's own sounds. With
"loop": true it repeats while the notification is shown. For a sound without a notification,
use sound.
notify() returns true when AWTRIX accepted the notification, and false for a malformed
payload or a full queue.
Move the rotation¶
rotation lets a script move the app rotation:
rotation.next() # advance to the next app now
rotation.previous() # step back to the previous app
rotation.show() # bring the rotation to THIS app now
rotation.pause() # freeze the automatic switching
rotation.resume() # let it run again
rotation.close() # end THIS app if it was started from the menu
rotation.show() shows your app now, when you have something to say. It takes no argument:
a script can only show itself. A pause stays in place, so show() then pause() shows your app
and keeps it there.
rotation.pause() stops the automatic switching, so the display stays where it is: during an
animation, or while you wait for something. rotation.next() and rotation.previous() still
work while paused, so your app can step through a sequence itself. Any move by the user, with a
button, the web UI or the API, ends the pause. Call rotation.resume() when you no longer need
it.
rotation.close() ends an @ondemand script that
was started, as holding select does.
Switch the display off¶
display switches the display on and off. AWTRIX and its scripts keep running.
display.power(false) # switch the display off, a moment later
display.power(true) # switch it on again
display.is_on() # is it on right now?
The change happens a moment later, so display.is_on() right after the call may still show the
old state. Nothing is saved: after a reboot the normal display state applies.
Match the device's look¶
Your script draws everything itself. Text you draw without a color follows the device's text
color, but a color you pass stays as it is, and the uppercase setting never changes your text.
White text next to a built-in app tinted amber looks wrong. settings reads the device settings
so you can match them:
class Train
var label, color
def on_show()
self.label = settings.apply_case("Zug 12") # read each time the app appears
self.color = settings.get("textColor")
end
def draw()
clear()
text(1, 6, self.label, self.color)
end
end
return Train()
With the factory settings, the text is white and in capitals, like the text of a pushed app.
settings.apply_case() applies the device's uppercase setting to your text, exactly as for the
app next to yours.
settings.get(key) takes the keys PATCH /api/v1/settings takes:
brightness, textColor, appDurationMs, useCelsius, time24h, volume and all others,
spelled the same as in the REST API and MQTT. Values come in the same form as in the API. Numbers
are numbers, switches are true or false, colors are 0xRRGGBB numbers (like rgb() and
hsv() return), and settings the API names by word (timeSeparatorMode, dateOrder,
transitionEffect, …) are strings:
settings.get("brightness") # 120
settings.get("autoBrightness") # false
settings.get("timeSeparatorMode") # "pulse"
settings.get("gamma") # 1.9
settings.get("textColor") # 16777215
You read what the user configured: settings.get("brightness") is the setting, not the
brightness auto-brightness uses right now.
The five accent colors return nil when the user never picked one. nil means "use
textColor", as the built-in apps do:
Change a setting¶
settings.set() checks values like the REST API does. It returns false, and changes nothing,
for an unknown key, a value of the wrong type, a number out of range or an unknown word:
settings.set("brightness", 40) # true
settings.set("brightness", 999) # false, 0-255
settings.set("timeSeparatorMode", "blink") # true
settings.set("timeSeparatorMode", "wobble") # false
settings.set("textColor", "#FF8800") # true
settings.set("timeColor", nil) # true, clears the accent color
true means accepted: the change takes effect on the next frame and is saved, like a PATCH
from the network.
Change as little as you can. The device belongs to its owner, and a script that quietly changes brightness or turns off sound is hard to track down from the web UI. Change only what your app needs, change it back when done, and prefer reading over writing.
Write to the log¶
log() writes to the AWTRIX log, marked [script:<name>], and shows up in the web UI console. It
accepts any value, not only strings.
Find out which firmware runs¶
version() returns the firmware version as a string, the same one the web UI shows. Log it, so a
problem report says which firmware your script ran on.
To find out whether the clock can do something, ask for the feature itself:
sound.can() for sound, width() and height() for the display, or
an import inside try for a module.
Good to know¶
- Call
notify()once per event. Each call adds a notification to the queue, so a call indraw()or on everyloop()fills it. - A setting you change stays changed, also after your app is gone. Change it back when your app is done.
- Setting keys are spelled as in the API:
textColor, nottextcolor. An unknown key answersniland raises no error. display.is_on()right afterdisplay.power()may still show the old state. The change happens a moment later.- Do not compare versions with
<or>. Berry compares text character by character, so"1.0.9" > "1.0.14"istrue.
Details¶
| Call | Does | Returns |
|---|---|---|
notify(payload) |
shows a notification, in the payload format | true when accepted, false for a malformed payload or a full queue |
rotation.next() |
shows the next app now | |
rotation.previous() |
shows the previous app now | |
rotation.show() |
brings the rotation to this app now | false if your app is not in the rotation |
rotation.pause() |
stops the automatic switching | |
rotation.resume() |
lets it run again | |
rotation.close() |
ends this app if it was started from the menu | false, doing nothing, in any other app |
display.power(on) |
switches the display on or off, a moment later | true when the request was accepted |
display.is_on() |
whether the display is on right now | true or false |
settings.get(key) |
the configured value | the value, or nil |
settings.set(key, value) |
changes a setting and saves it | true when the change was accepted |
settings.apply_case(str) |
your text with the device's uppercase setting applied | the text |
log(value) |
writes to the AWTRIX log, marked [script:<name>] |
|
version() |
the firmware version, the same one the web UI shows | a string |
Notifications: the queue limit and waking from off apply as for a notification from the API.
Rotation:
rotation.show()takes no argument. A pause stays in place.rotation.next()androtation.previous()still work while paused.- Any move by the user, with a button, the web UI or the API, ends the pause, and the rotation runs
normally again. If you forget
rotation.resume(), the next user action ends the pause anyway.
Display power:
display.power()takes onlytrueorfalse.- Nothing is saved: after a reboot the normal display state applies.
- A notification with
wakeup: truecan show while the display is off.display.is_on()still returnsfalseduring that wake-up.
Settings:
- Case matters:
textColor, nottextcolor. An unknown key returnsnil, so a typo reads as "not set" instead of raising an error. - The nested
scrollandweekdayBargroups have no flat key:getreturnsnilandsetreturnsfalse. Use the REST API for those. settings.set()returnsfalse, and changes nothing, for an unknown key, a value of the wrong type, a number out of range or an unknown word.- Setting a value that is already in place returns
trueand does nothing. - The uppercase setting affects pushed apps, never what a script draws.
Related¶
- Sound and music: a sound without a notification
- Your first notification: what a notification can show
- Settings: every key
settings.get()andsettings.set()take - Several apps together: skip a turn, stay longer, start from the menu