Skip to content

About

Gladys Assistant external integration to read and control RFlink devices. (accès anticipé BETA : DEV en cours)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Gladys RFLink integration

External integration bringing 433 MHz / 868 MHz devices into Gladys Assistant through an RFLink gateway, built on the official JavaScript SDK @gladysassistant/integration-sdk and the official integration template.

Wall plugs, dimmers, remotes, weather stations, motion and smoke detectors, energy meters and doorbells — whatever RFLink decodes becomes a Gladys device with the right category, type and unit.

User documentation: docs/en.md · docs/fr.md.

How it works

RFLink is a listening integration, not an enumerable one: a 433 MHz device is invisible until it transmits. The integration therefore builds its device list from the air, and remembers it across restarts.

RF device ──433MHz──▶ RFLink gateway ──TCP──▶ gateway.js ──▶ protocol.js
                                                                  │
                                                            featureMap.js
                                                                  │
                                                             registry.js
                                                                  │
                                          Gladys ◀── index.js ────┘
File Responsibility
index.js SDK wiring only: handlers, gateway lifecycle, configuration
src/rflink/protocol.js The wire format: parse a line, build a command. Pure, no I/O
src/rflink/gateway.js The TCP link: framing, reconnection, paced writes, keepalive, request()
src/devices/featureMap.js RFLink measurement → Gladys category / type / unit / decoder
src/devices/registry.js The devices heard on the air: identity, features, discovery payload
src/devices/roles.js What a switch-like frame actually is, when the chip does not say
src/pipeline.js Frames → published states, Gladys commands → RFLink command lines
src/store.js Persistence of the learned devices in /data
src/actions.js The buttons of the Configuration screen
src/config.js Defaults, normalization, protocol ignore list

index.js self-executes (it connects to Gladys on import), so it holds no logic of its own: everything worth testing lives in src/.

Why TCP and not the serial port

A Gladys external integration runs in a sandboxed container, and the only hardware a manifest can request is coral-usb, coral-pcie, gpu or video — there is no way to ask for /dev/ttyUSB0. The gateway is therefore reached over the network, which covers both real-world setups: an RFLink32 board on ESP8266/ESP32 (native TCP server) and a USB RFLink bridged with ser2net. docs/en.md has the step by step.

Design decisions worth knowing

  • The unit is part of the identity. The four buttons of a remote share one ID= and differ by their SWITCH=, so each becomes its own Gladys device.
  • has_feedback: false everywhere. 433 MHz is one-way and unacknowledged: claiming a confirmation we cannot provide would leave Gladys waiting.
  • Writes are paced. Two RF commands sent back to back are physically dropped by the receiver, so the gateway queue spaces them out.
  • The registry is persisted. Without it, a restart would empty the Discovery screen until each device happens to transmit again — which, for a remote nobody presses, is never.
  • Devices are recoverable without the cache. The RF address is also stored as device params, so a wiped /data volume does not break your commands.
  • Discovery has a ceiling and an ignore list. A 433 MHz receiver hears the whole neighbourhood.
  • Ambiguous chips are typed by the user, never guessed. EV1527 and PT2262 carry an address and four bits — a PIR, a door contact and a wall plug send the identical frame. A device role (roles.js) overrides the category, keeps the feature key so the history survives, and brings the automatic reset a detector needs: a PIR that never sends OFF would otherwise stay "on" for ever, and no scene could trigger again.
  • A device the gateway only transmits to can still be declared. Listening leaves one gap: an address hand-paired into a receiver is never heard. RFLink covers it itself with the ECHO node (11;), which replays a payload as if a remote had been pressed — so the declared device travels the ordinary reception path instead of a parallel creation path.
  • A newly added device is never blank. The last reading heard before the user added it is replayed on onDeviceCreated, timestamped when it was measured — except for pulsed sensors, where a past detection is an event, not a state to restore.

Adding support for a new measurement

Add one entry to RFLINK_FIELDS in src/devices/featureMap.js — the Gladys category/type/unit and a decoder — and nothing else changes. Two traps:

  • The radix. The reference annotates a field "(hexadecimal)" when it is one and says nothing otherwise; getting it backwards produces a temperature of 180 instead of 18.0, and the wrong reading is usually just as plausible as the right one. Nine fields (CHIME, CO2, SOUND, VOLT, CURRENT×3, METER, DIST) carry no annotation at all and are assumed decimal — unconfirmed.
  • The (category, type) pair. Gladys resolves a feature's icon and its translated label by the exact pair, falling back to a generic slider and to the raw feature name. A pair Gladys does not register renders as a nameless, iconless line even though the value arrives perfectly — humidity-sensor exists only as decimal, never integer. The pairs in use are pinned by CATEGORY_TYPE_CONTRACT in test/featureMap.test.js; check a new one against front/src/utils/consts.js and front/src/config/i18n/en.json in GladysAssistant/Gladys.

Development

npm install
GLADYS_HOST_API_URL="http://localhost:1443" \
GLADYS_INTEGRATION_TOKEN="<token>" \
GLADYS_INTEGRATION_SELECTOR="rflink" \
RFLINK_DATA_DIR="./data" \
LOG_LEVEL=debug \
npm start

The three GLADYS_* variables are injected by the Gladys supervisor when the integration runs inside its container; RFLINK_DATA_DIR overrides the /data volume so it can run outside Docker.

Quality checks

The same three gates run on every push and pull request (.github/workflows/ci.yml):

npm run format:check   # Prettier
npm run lint           # ESLint
npm test               # Unit tests, via the built-in `node --test` runner

The suite covers the protocol (framing, radix, signed temperatures, command injection), the feature mapping, the registry (identity, growth, persistence, recovery), the store, the full pipeline in both directions (a raw RFLink line in, published states out; a Gladys command in, an RFLink line out), and the gateway itself — the last one against a real local TCP server, so chunk reassembly, reconnection and write pacing are actually exercised.

Validate before publishing

npx github:GladysAssistant/integration-store .

Runs the exact checks of the store indexer — manifest schema, Docker image availability, cover image, documentation — and reports every problem at once.

Release

Actions → Release → Run workflow, pick patch, minor or major. The workflow bumps the version in package.json and in the manifest (version and docker_image), pushes the vX.Y.Z tag and builds the linux/amd64 + linux/arm64 image to ghcr.io. The decentralized indexer then offers the update in every Gladys.

License

Apache-2.0

About

Gladys Assistant external integration to read and control RFlink devices. (accès anticipé BETA : DEV en cours)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages