// Package rules holds the generic automation-rule model and condition // evaluation logic. Nothing here knows about growboxes, lights, or pumps — // only sensor_type/operator/value, exactly as stored in automation_rules. package rules import "fmt" // Rule mirrors one row of automation_rules, joined against devices so the // device IDs are the external identifiers used by MQTT/Redis/gRPC (not // PostgreSQL's internal bigserial IDs). type Rule struct { ID int64 ZoneID int64 SourceDeviceID string // condition_source_device_id, resolved to devices.external_id ConditionSensorType string ConditionOperator string ConditionValue float64 TargetDeviceID string // target_device_id, resolved to devices.external_id ActionType string ActionParams map[string]any } // Evaluate reports whether value satisfies the rule's condition. func Evaluate(operator string, value, threshold float64) (bool, error) { switch operator { case ">": return value > threshold, nil case "<": return value < threshold, nil case ">=": return value >= threshold, nil case "<=": return value <= threshold, nil case "=": return value == threshold, nil case "!=": return value != threshold, nil default: return false, fmt.Errorf("unknown condition operator %q", operator) } }