mecha10_behavior_runtime/actions/
sensing.rs1use crate::{BehaviorNode, Context, NodeStatus};
4use async_trait::async_trait;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8#[derive(Debug)]
26pub struct SensorCheckNode {
27 #[allow(dead_code)] topic: String,
29 field: String,
30 operator: ComparisonOperator,
31 threshold: f64,
32}
33
34#[derive(Debug, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36enum ComparisonOperator {
37 LessThan,
38 GreaterThan,
39 Equal,
40}
41
42#[derive(Debug, Serialize, Deserialize)]
43struct SensorCheckConfig {
44 topic: String,
45 field: String,
46 operator: ComparisonOperator,
47 threshold: f64,
48}
49
50impl SensorCheckNode {
51 pub fn from_json(config: Value) -> anyhow::Result<Self> {
53 let cfg: SensorCheckConfig = serde_json::from_value(config)?;
54 Ok(Self {
55 topic: cfg.topic,
56 field: cfg.field,
57 operator: cfg.operator,
58 threshold: cfg.threshold,
59 })
60 }
61}
62
63#[async_trait]
64impl BehaviorNode for SensorCheckNode {
65 async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
66 tracing::debug!(
69 "SensorCheckNode: checking {} {} {}",
70 self.field,
71 match self.operator {
72 ComparisonOperator::LessThan => "<",
73 ComparisonOperator::GreaterThan => ">",
74 ComparisonOperator::Equal => "==",
75 },
76 self.threshold
77 );
78 Ok(NodeStatus::Success)
79 }
80
81 fn name(&self) -> &str {
82 "SensorCheckNode"
83 }
84}