ruleway 0.1.1 copy "ruleway: ^0.1.1" to clipboard
ruleway: ^0.1.1 copied to clipboard

A lightweight embeddable rule engine for device automation and edge applications.

RuleWay #

RuleWay is a lightweight embeddable rule engine for Dart applications, device automation, and edge Linux devices. It is designed for workloads where rules are driven by device attributes, attribute changes, rule-level time windows, and explicit action handlers.

Features #

  • Device attribute state and previous-state tracking.
  • device_expr and attr_change triggers.
  • Multi-device rules through targets and target_index.
  • duration and cooldown windows.
  • Rule-level multi-segment time_windows with weekday repeat.
  • time, date, and six-field second-level cron triggers.
  • Global actions and per-device device_actions with action parameters.
  • Action registration with built-in emit_alarm.
  • Optional SQLite rule storage using compact JSON columns.

Usage #

import 'package:ruleway/ruleway.dart';

Future<void> main() async {
  final engine = RuleEngine(
    timeZone: 'Asia/Shanghai',
    rules: [
      Rule(
        targets: ['AC01'],
        triggers: [
          Trigger(
            type: TriggerType.deviceExpr,
            targetIndex: 0,
            attr: 'temperature',
            op: '>',
            value: 30,
          ),
        ],
        actions: [
          ActionConfig(type: 'emit_alarm', params: {'reason': 'too hot'}),
        ],
      ),
    ],
  );

  engine.onAlarm.listen((alarm) => print(alarm.toJson()));
  await engine.postAttrUpdate('AC01', {'temperature': '31'});
  engine.dispose();
}

postAttrUpdate() and tick() return futures because registered actions may be asynchronous. Await them when deterministic action completion is required.

Event Context and Actions #

Attach request, session, or source metadata to an attribute update without storing it as device state:

engine.registerAction('notify', (action, context) async {
  final requestId = context.context['request_id'];
  await sendNotification(requestId, action.params);
});

await engine.postAttrUpdate(
  'AC01',
  {'temperature': 31},
  context: {'request_id': 'req-42'},
);

For rules with duration > 0, RuleWay preserves the context from the event that started the duration window. Calling tick() continues evaluating eligible duration rules even when no new attribute event arrives. attr_change rules still require a new edge event and are not completed by a timer tick.

Rule JSON #

{
  "rules": [
    {
      "id": 1,
      "enabled": true,
      "duration": 0,
      "cooldown": 5,
      "targets": [{"id": "AC01"}, {"id": "Door01"}],
      "time_windows": [
        {"start": "08:00:00", "end": "09:00:00", "week_repeat": [0, 1, 2, 3, 4]},
        {"start": "20:00:00", "end": "21:00:00", "week_repeat": [0, 1, 2, 3, 4]}
      ],
      "triggers": [
        {
          "type": "attr_change",
          "target_index": 0,
          "attr": "has_person",
          "from": 0,
          "to": 1
        }
      ],
      "conditions": [
        {
          "type": "device_expr",
          "target_index": 1,
          "attr": "door_open",
          "op": "==",
          "value": true
        }
      ],
      "actions": [{"type": "emit_alarm", "reason": "person at open door"}],
      "device_actions": [
        {
          "target_index": 1,
          "actions": [
            {"type": "set_property", "power": true},
            {"type": "set_property", "brightness": 80}
          ]
        }
      ]
    }
  ]
}

week_repeat uses 0..6 for Monday..Sunday. Empty or missing means every day. time_windows is optional; if omitted, the rule is always active. All time_windows, time, date in_weekday, and cron calculations use the timezone passed to RuleEngine(timeZone: ...); they never use the host machine's local timezone. device_actions is optional and runs after global actions.

SQLite Storage #

final storage = RuleStorage('/tmp/ruleway.db');
storage.init();
storage.importJsonFile('rules.json', reload: true);
final rules = storage.loadRules();

CLI #

dart run ruleway:ruleway_cli --timezone Asia/Shanghai rules.json

Input events as:

AC01.temperature=31
Door01.door_open=true
1
likes
140
points
8
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A lightweight embeddable rule engine for device automation and edge applications.

Repository (GitHub)
View/report issues

Topics

#rules #automation #iot #edge #sqlite

License

MIT (license)

Dependencies

sqlite3, timezone

More

Packages that depend on ruleway