Calaos Server

Role

calaos_server is the only component that talks to the hardware. It loads the configuration, instantiates the inputs/outputs, runs the rules engine, records history and exposes an API consumed by every other component.

Repository: calaos_base — written in C++, released under GPL v3.

Building

./autogen.sh
make
sudo make install

Main dependencies:

LibraryUse
libuv (> 1.10)Event loop, networking, timers
jansson (> 2.5)JSON serialisation
libcurl (> 7.20)Outgoing HTTP requests
LuaJITRunning user scripts
sigc++ (> 2.4.1)Signals between objects

And optionally, depending on the target hardware: owfs for 1-Wire, OLA for DMX, knxd for KNX, ImageMagick for processing camera pictures.

The repository also bundles several libraries in src/lib: uvw (a C++ wrapper over libuv), llhttp, exprtk for expression evaluation, sqlite_modern_cpp, libquickmail for sending emails, and sunset.c for computing sunrise and sunset times.

Code layout

The server code lives in src/bin/calaos_server:

LocationContents
Calaos.cppEntry point of the business logic
CalaosConfig.cppLoading and writing the configuration
IO/All input/output drivers
IOBase.cpp, IOFactory.cppBase class for IOs and its factory
Rules/, Rule.cpp, ListeRule.cppRules engine
Scenario/Scenarios
LuaScript/LuaJIT integration
JsonApi.cppAPI implementation
JsonApiHandlerWS.cpp, JsonApiHandlerHttp.cppWebSocket and HTTP transports
HttpServer.cpp, WebSocket.cpp, UDPServer.cppNetwork servers
EventManager.cppBroadcasting events to clients
HistLogger.cpp, DataLogger.cppHistory and measurement recording
NotifManager.cppEmail and push notifications
IPCam/IP cameras
McpServerManager.cppExposing the system to assistants over MCP

Inputs and outputs

Everything Calaos drives is an IO, derived from IOBase and created by IOFactory from the type declared in the configuration.

The generic types depend on no hardware: InputSwitch, InputSwitchLongPress, InputSwitchTriple, InputAnalog, InputTemp, InputTime, InputTimer, InPlageHoraire, IntValue, OutputLight, OutputLightDimmer, OutputLightRGB, OutputShutter, OutputShutterSmart, OutputAnalog, OutputString.

Hardware drivers live in their own subfolders: Wago, KNX, Gpio, OneWire, Mqtt, Hue, OLA, MySensors, Reolink, LAN, Web, RemoteUI. ExternProc additionally allows an IO to be delegated to an external process.

Adding a driver means deriving IOBase, describing its parameters through IODoc, then registering it in IOFactory. IODoc feeds the built-in parameter documentation, which makes the new type immediately usable from Calaos Installer.

The IO/io_types.txt file lists the available types.

Rules, scenarios and scripts

The rules engine ties conditions on input states to actions on outputs. Rules are described in rules.xml and reloaded every time a configuration is uploaded.

For what rules cannot express, LuaScript/ embeds LuaJIT: a script receives the state of the system and acts on the IOs. See Scripts.

Time ranges and solar computations rely on TimeRange, Calendar and sunset.c — hence the importance of setting latitude and longitude.

The JSON API

This is the entry point for every client. It is available over two transports:

TransportAddress
WebSocketws://server:5454/api
HTTPhttp://server:5454/api.php

WebSocket is preferable: it lets the server push state changes to the client, where HTTP forces periodic polling.

How a session goes

  1. login — authentication with the cn_user / cn_pass credentials.
  2. get_home — fetching the structure: rooms, IOs, types, display parameters.
  3. get_state / get_states — reading the current state of the IOs.
  4. set_state — acting on an output.
  5. The server then emits event messages on every change.

Each request carries a msg (the method name) and a msg_id echoed back in the response, which lets responses be matched to requests on a multiplexed connection.

Main methods

AreaMethods
Sessionlogin, change_cred
Stateget_home, get_io, get_state, get_states, set_state, query
Settingsget_param, set_param, del_param
Time rangesget_timerange, set_timerange
Scenariosautoscenario
Historyeventlog, get_stats
Camerasget_camera_pic
Audioget_playlists, get_playlist, get_artists, get_album, get_radios, audio_action
Notificationsregister_push

JsonApiHandlerWS.cpp is the authoritative list; it is the reference to consult before writing a client.

Discovery on the network

A client that does not know the server address broadcasts the message CALAOS_DISCOVER over UDP on port 4545. The server answers with its connection details.

This is the mechanism that lets Calaos Home, the mobile applications and the Remote UI screens find the server with no configuration. See UDPServer.cpp.

Ports

PortProtocolUse
5454TCPJSON API (HTTP and WebSocket), changed with the port_api setting
4545UDPDiscovery
4646UDPListening for Wago PLCs

Logging

Traces go through Logger, with domains allowing one subsystem to be targeted. They are controlled by debug_enabled, debug_level and debug_domains — see Logs.

In the code, one writes for example:

cDebugDom("network") << "Got a CALAOS_DISCOVER";

The companion tools

The same repository provides several utilities, in src/bin/tools:

ToolRole
calaos_configReading and writing settings — see calaos_config
calaos_mailSending emails, used by notifications — see Email
calaos_pictureProcessing camera pictures
wago_testTesting and diagnosing Wago PLCs

To these is added src/bin/calaos_mcp, which exposes the installation to MCP-compatible assistants.