#pragma once // Command-path safety policy for the OneControl integration. // // POLICY: some loads are operated from the physical control panel / OEM app ONLY, // never over CAN. command_blocked() returns true for any node this firmware must // never send a command to. It is the single source of truth for that rule and is // checked in two independent places (the command-entry script and the actual // transmit point), so loosening one does not open the other. // // What it blocks: // * slides / jacks — never automate. Explicit denylist of this rig's nodes // (6A/7F/9C), always blocked, even before we've heard their identity; // * the water pump (61) — winterizing-only; operate it from the panel/app so it // can't be left running (e.g. dry) by accident; // * any movement/motor-class node (device class 0x21) other than the awning // (0x75) — generalizes the slide/jack rule to "any motor that isn't the awning". // // Permitted (NOT blocked here): lights, water heater, and the awning. Whether a // permitted node is actually exposed as an entity is a separate allowlist in the // command-entry script — this gate only enforces the never-allowed set. // // node_type is the page-2 identity byte (device class) for the node, or 0 if not // yet observed. The static denylist covers the not-yet-observed window. #include namespace onecontrol { inline bool command_blocked(uint8_t node, uint8_t node_type) { // Slide / jack / movement-class nodes on this rig — always refused. if (node == 0x6A || node == 0x7F || node == 0x9C) return true; // Water pump — panel/app only (winterizing). if (node == 0x61) return true; // Any movement-class (0x21) node except the awning (0x75). if (node_type == 0x21 && node != 0x75) return true; return false; } } // namespace onecontrol