JavaScript
JavaScript is the text-based programming view of IOZER basic. It is suitable for compact logic, more complex conditions, reusable processes, and integrations that would become difficult to follow in Blockly.
Like Blockly code, JavaScript is always executed in the context of an event. The program does not run continuously in an endless loop; it starts when the configured trigger occurs.
Event context
When an event starts, the firmware provides context data. In JavaScript, it is available through ioz_event and ioz_event_context. Both names refer to the same context of the currently executing event.
Treat the context as read-only. The available fields depend on the event type.
General fields:
| Field | Meaning |
|---|---|
event_id |
ID of the event currently being executed |
name |
Technical name of the event |
label |
Display name of the event |
trigger_code |
Internal event type |
source_no |
Source number |
timestamp |
Execution timestamp |
Additional fields:
| Trigger | Context fields |
|---|---|
| Datapoint | datapoint_id, datapoint_name, value, last_value, valid, last_valid, state, last_state, unit, classification |
| Schedule | cron_expression |
| Manual | param1 through param4, depending on the configuration of the manual event |
| Error | interface, error_code, error_message for 1-Wire, Modbus, and MQTT errors |
Example of a datapoint event:
if(ioz_event.datapoint_name = "hallway_button" && ioz_event.value = true) {
dp.set("hallway_light", true);
log.info("Hallway light switched on");
}
The event structure is described under Events.
Device functions
JavaScript can interact with the device using IOZER-specific global objects. These objects are provided by the firmware and are available in every event.
For datapoints, ref can be either the numeric datapoint ID or the technical datapoint name. For manual events, ref can be the event ID or event name.
| Object | Purpose |
|---|---|
system |
System functions such as waiting or triggering a restart |
mqtt |
Publishing MQTT messages |
dp |
Reading, writing, toggling, or querying the state of datapoints |
event |
Starting, stopping, or querying manual events |
log |
Writing messages to the program or system log |
Datapoints
The dp object is the primary interface between JavaScript, hardware, protocols, and the web interface.
| Command | Description |
|---|---|
dp.get(ref, fallback?) |
Reads the current value of a datapoint. If the datapoint state is invalid, fallback is returned when specified; otherwise null is returned. |
dp.set(ref, value) |
Writes a value to a datapoint. The value must match the data type or allow a meaningful conversion. Returns true on success. |
dp.toggle(ref) |
Toggles a Boolean datapoint and returns the new value as true or false. |
dp.state(ref) |
Returns a datapoint state object containing fields such as id, name, label, valid, quality, updated, changed, datatype, unit, and value. |
Example:
const temperature = dp.get("room_temperature", null);
if(temperature !== null && temperature > 28) {
dp.set("fan", true);
}
const lightActive = dp.toggle("hallway_light");
log.info("Hallway light: " + String(lightActive));
Use dp.state(ref) when quality, unit, or update time is required in addition to the value.
const state = dp.state("room_temperature");
if(!state.valid) {
log.warn("Room temperature is invalid");
}
MQTT
| Command | Description |
|---|---|
mqtt.publish(topic, payload, qos?, retain?) |
Publishes an MQTT message. payload can be text, a number, or a Boolean. qos is optional and defaults to 0; retain is optional and defaults to false. Returns true on success. |
Example:
mqtt.publish("iozer/status/fan", "active", 0, false);
For normal value publishing, prefer the MQTT functions provided by datapoints. mqtt.publish is useful for additional messages, integration logic, or project-specific topics.
Manual events
The event object works with user-defined manual events. Hardware, interface, and datapoint triggers are not started directly through event.trigger.
| Command | Description |
|---|---|
event.trigger(ref, delayMs?, repeat?, param1?, param2?, param3?, param4?) |
Starts a manual event immediately or after a delay. delayMs is the delay in milliseconds and repeat is the number of executions. Up to four parameters are provided to the target event as ioz_event.param1 through ioz_event.param4. |
event.stop(ref) |
Stops a scheduled manual event. |
event.isRunning(ref) |
Returns true while a scheduled manual event is still active. |
Example:
if(dp.get("hallway_motion", false)) {
event.trigger("light_off_delay", 30000, 1, "hallway");
}
System
| Command | Description |
|---|---|
system.sleep(ms) |
Waits within the currently executing event for the specified number of milliseconds. The value must be greater than 0. |
system.reboot() |
Restarts the device. |
system.sleep blocks execution of the current event. Avoid long waits and use delayed manual events where possible.
Logging
| Command | Description |
|---|---|
log.debug(message) |
Writes a debug message. |
log.info(message) |
Writes an informational message. |
log.warn(message) |
Writes a warning. |
log.error(message) |
Writes an error message. |
Pass the message as text. Explicit conversion is recommended when logging numbers or Boolean values.
log.info("Temperature: " + String(dp.get("room_temperature", "unknown")));
Invalid references, incorrect data types, or failed device actions raise JavaScript errors. Use unique datapoint and event names and validate external values before using them in switching logic.
Typical applications
- Combining multiple conditions compactly
- Calculating, scaling, or limiting values
- Setting datapoints based on interface values
- Starting manual events with parameters
- Creating structured log messages
- Implementing more complex MQTT or Modbus logic using datapoints
Best practices
- Keep events short and clearly named.
- Use datapoints instead of direct hardware dependencies when logic spans multiple interfaces.
- Check values for plausibility before switching outputs.
- Write targeted log messages for states that matter during commissioning or service.
- Avoid permanent loops and long blocking waits.
For visually transparent switching logic, Blockly may be the better choice. Also use datapoints to decouple functional logic from interfaces.