| Omitting type casts in math | Implicit type handling leads to silent errors | Always cast: PAYLOAD AS DOUBLE, GET TOPIC ... AS DOUBLE — see Operations |
| Triggering models on timestamps | Timestamps update every tick — model fires constantly | Trigger on the primary data field: AS TRIGGER on value, not timestamp — see Schema definition |
| Inconsistent naming across models | sensorID in one model, sensor_id in another | Standardize on snake_case for all field names — see Naming conventions |
| Using Python for native LoT tasks | Python adds overhead for simple publish/get/if operations | Use Python only for math libraries, ML, API calls, or complex parsing |
Handing out permission flags to open up $SYS/# | $SYS carries broker commands and sensitive data, and its access is gated by permission flags — a flag granted for convenience opens the whole namespace | Leave the three flags unset on device and operator accounts; the broker’s locked $SYS rules then deny them. Custom Rules cannot tighten $SYS/# further — see Rules syntax |
| Generic entity names | Action1, Rule1, MyRoute are meaningless in a system with 50 entities | Name by purpose: MonitorPressure, ProtectSysTopics, SensorDatabase |
PUBLISH for internal state | Broadcasts data that only your own Actions need | Use KEEP TOPIC for internal state; PUBLISH for external subscribers — see Writing reusable logic |
| Monolithic Actions | One Action doing 15 things is hard to test and debug | Split into callable Actions with INPUT/OUTPUT — see One Action, One Job |