Prototype of the first automation stull ugly
This commit is contained in:
@@ -19,6 +19,8 @@ pub enum SensorType {
|
||||
Pressure = 3,
|
||||
Voltage = 4,
|
||||
Current = 5,
|
||||
Presence = 6,
|
||||
Relay = 7,
|
||||
}
|
||||
|
||||
impl SensorType {
|
||||
@@ -29,6 +31,8 @@ impl SensorType {
|
||||
3 => Self::Pressure,
|
||||
4 => Self::Voltage,
|
||||
5 => Self::Current,
|
||||
6 => Self::Presence,
|
||||
7 => Self::Relay,
|
||||
_ => Self::Generic,
|
||||
}
|
||||
}
|
||||
@@ -46,6 +50,8 @@ impl SensorType {
|
||||
Self::Pressure => "pressure",
|
||||
Self::Voltage => "voltage",
|
||||
Self::Current => "current",
|
||||
Self::Presence => "presence",
|
||||
Self::Relay => "relay",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +64,8 @@ impl SensorType {
|
||||
Self::Pressure => "hPa",
|
||||
Self::Voltage => "V",
|
||||
Self::Current => "A",
|
||||
Self::Presence => "s",
|
||||
Self::Relay => "state",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,9 @@ pub(super) fn threshold_for(t: SensorType) -> f64 {
|
||||
SensorType::Temperature => 22.0, // °C — simulator oscillates 15..25
|
||||
SensorType::Humidity => 55.0, // % — 30..70
|
||||
SensorType::Pressure => 1014.0, // hPa — 1008..1018
|
||||
SensorType::Voltage => 230.2, // V — 229.5..230.5
|
||||
SensorType::Voltage => 230.5, // V — 229..231
|
||||
SensorType::Current => 10.5, // A — 8..12
|
||||
SensorType::Presence => 1.0, // s — Trigger threshold
|
||||
SensorType::Relay => f64::INFINITY, // Actuator state, no threshold
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,10 @@ impl Plugin for WorldPlugin {
|
||||
PreUpdate,
|
||||
systems::ingest_system.run_if(in_state(ServerState::Started)),
|
||||
)
|
||||
.add_systems(Update, systems::simulation_system)
|
||||
.add_systems(
|
||||
Update,
|
||||
(systems::simulation_system, systems::automation_system).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
PostUpdate,
|
||||
(systems::export_system, systems::diagnostics_system).chain(),
|
||||
|
||||
@@ -144,6 +144,38 @@ fn upsert_reading(
|
||||
registry.map.insert(key, entity);
|
||||
}
|
||||
|
||||
/// Closed-loop automation triggered by T1/T2 sensor data, affecting a T3 actuator.
|
||||
pub(super) fn automation_system(
|
||||
mut registry: ResMut<SensorRegistry>,
|
||||
mut commands: Commands,
|
||||
mut p: ParamSet<(
|
||||
Query<(&DeviceId, &SensorTypeTag, &RawSensorData), Changed<RawSensorData>>,
|
||||
Query<&mut RawSensorData>,
|
||||
)>,
|
||||
) {
|
||||
let mut triggers = Vec::new();
|
||||
for (dev_id, tag, data) in p.p0().iter() {
|
||||
if tag.0 == SensorType::Presence {
|
||||
// Trigger threshold: 1.0 seconds
|
||||
let relay_state = if data.raw_value < 1.0 { 1.0 } else { 0.0 };
|
||||
triggers.push((dev_id.0, relay_state));
|
||||
}
|
||||
}
|
||||
|
||||
let mut q = p.p1();
|
||||
for (device_id, relay_state) in triggers {
|
||||
let msg = QuicMessage {
|
||||
device_id,
|
||||
sensor_id: 6, // Relay is always 6 in our industrial profile
|
||||
raw_value: relay_state,
|
||||
timestamp_us: now_us(),
|
||||
sequence_number: 0,
|
||||
sensor_type: SensorType::Relay.as_u8(),
|
||||
};
|
||||
upsert_reading(&mut registry, &mut commands, &mut q, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Per-sensor digital-twin transform. Pulls each entity's latest
|
||||
/// `RawSensorData` into a sliding-window mean (`SmoothedValue`), and emits
|
||||
|
||||
Reference in New Issue
Block a user