Smart Irrigation is not only about saving water or having healthier plants. It is mostly convenience that convinces the consumer to buy a smart irrigation system. Most people don't want to have to worry about their garden. They just want it to be a place to relax.

nymea scripting

As of version 0.18 nymea supports scripting using JavaScript and QML. Scripting can be used to
automate behaviors, similar to rules, but are aimed towards a more advanced usage of nymea. While
scripting requires a basic understanding of the JavaScript programming language, it also features
a much more powerful way to interact with nymea.

It is recommended to install nymea:app on a PC in order to use the script editor.

The recommended way to create and edit scripts is the integrated script editor in nymea:app. It can
be found in the mains screen menu -> Magic using the script icon in the upper right corner.

Introduction

nymea scripts follows the QML syntax. Please refer to the QML Documentation
for details on the QML language.
A script can be thought of like a small app running inside nymea core. As soon as a script has
been deployed to nymea:core it will be loaded and execution starts. The script might then listen
to state changes in the system, or use timer events to trigger execute actions in the system.

The nymea:app script editor will report console output for the script as well as errors in the script:

Basic structure

An example of a simple nymea script looks like this

import QtQuick 2.0
import nymea 1.0
Item {
}

This example script will be functional, but it doesn't actually do anything. Depending on the
purpose of the script, different content may be added inside the Item {} structure. Every script
must have exactly one top level item, the so called root item. This root item might contain any number of
child items.

For example, in order to act on a motion sensor detecting presence, such a block can be added:

This script will log the text "Presence detected: true" into the scripts console when the
motion sensor with the given deviceId detects a person and "Presence detected: false" when the person has left again.

IDs

deviceId

Throughout the nymea scripting, there will be the need to provide values for deviceId properties.
Those must be set to a UUID which refers to a particular thing in the system.

The reason for using ids instead of device/thing names is because the id is persistent. The user might rename
a thing and existing scripts will still continue work. If we'd use the device's name here, the scripts would be
more fragile and break easily.

As those IDs are an implementation detail, they are not easily visible in the app, however, the
nymea:app script editor provides code completion which allows to select things by name and it will
automatically insert the proper UUID for it.

When placing the cursor after the text deviceId: " the script editor will pop up suggestions
for all the devices in the system.

NOTE: Using CTRL+Space (or cmd+Space on macOS) allows to invoke the code auto completion at any point

Selecting an entry will cause the script editor to fill in the appropriate UUID for this device/thing.

In this documentation we'll use <deviceId> as a placeholder for the actual id.

stateName, eventNames, actionNames

Similar to deviceId, there are other properties which describe things in the system. Depending on the
chosen deviceId the possible values for those differ. Please use the nymea:app code completion to get a list
to chose from.

id

the id property is part of the QML language. Every element in QML can have an id property. The value for
this can be defined freely by the script developer as long as it starts with a lowercase letter and does not
contain special characters. Those ids basically give the element a name so that it can be referred to from
other places in the script. It is not mandatory to add such id properties if it's not required to "wire" up
elements.

Available types

The script engine supports all the types as found in the QML Documentation. In addition to those, a set of nymea specific types are supported which are the most important in this
context.

DeviceState

A DeviceState is used to read or modify a certain device's state in the system.

A DeviceSate is required to have deviceId in order ot identify a thing. In addition to that, a
stateName is required to identify a particular state. For example, a light bulb would have a stateName called
power.

Each DeviceState has a value property which contains the actual current value of the state. For instance, a
light bulb will contain true in the value property when it's turned on and false when it's off. Also it
can be turned on or off by setting the value property accordingly.

In order to react on state changes, the onValueChanged signal can be connected.

Example:

DeviceState {
deviceId: "<deviceId>" // ID for the lightbulb
stateName: "power" // The name for the state we're interested in
value: true // This would initialize the value to `true`, turning the light on when nymea starts
onValueChanged: {
if (value == true) {
console.log("the light has been switched on");
} else {
console.log("the light has been switched off");
}
}
}

DeviceEvent

A DeviceEvent is used to react on events in the system.

It requires a deviceId to select the device/thing we're watching for events and an eventName to
select the actual event. For instance, a wall switch would have a pressed event.

DeviceEvents have a signal named triggered which is fired whenever the event happens. Using the
onTriggered handler it is possible to act on those events.

The following example script would write a log warning whenever the switch is
pressed.

Adding more JavaScript

Anywhere in the script, standard JavaScript can be added. For instance we can count the number
of button presses. To execute an action when a button is pressed 5 times within 5 seconds, we can
use such an example:

In this example, the light's power state value is set to the presence sensor's isPresent state's value.
This way, whenever the value for isPresent changes, it will automatically be synced to the power state.

Reacting on events

Devices that have events, e.g. a power wall switch that has a "pressed" event, can be used to execute
an action in the system. Let's turn on a light when a button is pressed, but only if it's dark outside: