Revert "Publish per-camera Move tracker health"
This reverts commit 00e361aa6e.
This commit is contained in:
parent
00e361aa6e
commit
4d4abe2ef3
2 changed files with 93 additions and 296 deletions
|
|
@ -17,17 +17,18 @@ use cultnet_rs::{
|
|||
CultNetRudpSocketTransportConnection, CultNetRudpSocketTransportOptions, CultNetTransportFrame,
|
||||
CultNetWireContract, decode_cultnet_message_from_slice, encode_cultnet_message_to_vec,
|
||||
};
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
use odin_core::MuninnMoveTrackerHealthRecord;
|
||||
use odin_core::{
|
||||
EVE_PROVIDER_ADVERTISEMENT_SCHEMA, EveProviderAdvertisementRecord, EveSurfaceStateRecord,
|
||||
IdunnDaemonHealthRecord, MUNINN_MOVE_HUE_PROGRAM_SCHEMA, MUNINN_OBS_STREAM_CATALOG_SCHEMA,
|
||||
IdunnDaemonHealthRecord,
|
||||
MUNINN_MOVE_HUE_PROGRAM_SCHEMA,
|
||||
MUNINN_OBS_STREAM_CATALOG_SCHEMA,
|
||||
MuninnCaptureStreamCommandRecord, MuninnCaptureStreamRecord, MuninnCommandBoundaryCompatRecord,
|
||||
MuninnHidControllerStateRecord, MuninnMediaReceiverFeedbackRecord,
|
||||
MuninnMoveControllerStateRecord, MuninnMoveHueProgramRecord, MuninnMoveIdentityRecord,
|
||||
MuninnMoveLightCommandRecord, MuninnMoveMarkerCandidateRecord, MuninnObsStreamCatalogRecord,
|
||||
MuninnQuestAccessRecord, MuninnTelemetrySurfaceRecord, MuninnTransportProfileCompatRecord,
|
||||
OdinDocuments, OdinEndpointQuery, discover_provider_endpoints,
|
||||
MuninnMoveLightCommandRecord,
|
||||
MuninnMoveMarkerCandidateRecord, MuninnObsStreamCatalogRecord, MuninnQuestAccessRecord,
|
||||
MuninnTelemetrySurfaceRecord, MuninnTransportProfileCompatRecord, OdinDocuments,
|
||||
OdinEndpointQuery, discover_provider_endpoints,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
|
|
@ -309,10 +310,7 @@ struct ActiveMoveMarkerCameraSource {
|
|||
frame_source: MoveMarkerFrameSource,
|
||||
sequence: u64,
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
psmoveapi_observations:
|
||||
Option<mpsc::Receiver<Vec<muninn_psmoveapi_tracker::PsmoveApiObservation>>>,
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
psmoveapi_health: Option<mpsc::Receiver<MuninnMoveTrackerHealthRecord>>,
|
||||
psmoveapi_observations: Option<mpsc::Receiver<Vec<muninn_psmoveapi_tracker::PsmoveApiObservation>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
|
@ -458,7 +456,6 @@ fn serve(options: Options) -> Result<()> {
|
|||
&latest_move_controller_states,
|
||||
move_evidence_stream.as_mut(),
|
||||
)?;
|
||||
publish_move_tracker_health(&mut node, &mut active_move_marker_cameras)?;
|
||||
publish_quest_access_if_requested(&mut node, &options)?;
|
||||
let state = if active_stream_ids.is_empty() {
|
||||
"idle"
|
||||
|
|
@ -535,9 +532,9 @@ fn load_or_initialize_move_hue_program(
|
|||
) -> Result<Arc<Mutex<MuninnMoveHueProgramRecord>>> {
|
||||
let key = move_hue_program_key(&options.host_id);
|
||||
let mut node = open_node(options, "muninn-move-hue-program-bootstrap")?;
|
||||
let program = node
|
||||
.get::<MuninnMoveHueProgramRecord>(&key)?
|
||||
.unwrap_or_else(|| bootstrap_move_hue_program(options));
|
||||
let program = node.get::<MuninnMoveHueProgramRecord>(&key)?.unwrap_or_else(|| {
|
||||
bootstrap_move_hue_program(options)
|
||||
});
|
||||
validate_move_hue_program(&program)?;
|
||||
node.put(&key, &program)?;
|
||||
Ok(Arc::new(Mutex::new(program)))
|
||||
|
|
@ -568,10 +565,7 @@ fn validate_move_hue_program(program: &MuninnMoveHueProgramRecord) -> Result<()>
|
|||
program.order_mode.as_str(),
|
||||
"descending" | "ascending" | "bounce" | "rotating-lead" | "golden-permutation"
|
||||
) {
|
||||
return Err(anyhow!(
|
||||
"unsupported Move hue order mode {}",
|
||||
program.order_mode
|
||||
));
|
||||
return Err(anyhow!("unsupported Move hue order mode {}", program.order_mode));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -595,34 +589,32 @@ fn start_move_hue_program_sync_worker(
|
|||
.as_ref()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| options.store_path.clone());
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
let key = move_hue_program_key(&options.host_id);
|
||||
let main_program = open_node(&options, "muninn-move-hue-program-sync")
|
||||
.ok()
|
||||
.and_then(|node| node.get::<MuninnMoveHueProgramRecord>(&key).ok().flatten());
|
||||
let activation_program = open_node(
|
||||
&activation_options,
|
||||
"muninn-move-hue-program-activation-sync",
|
||||
)
|
||||
thread::spawn(move || loop {
|
||||
let key = move_hue_program_key(&options.host_id);
|
||||
let main_program = open_node(&options, "muninn-move-hue-program-sync")
|
||||
.ok()
|
||||
.and_then(|node| node.get::<MuninnMoveHueProgramRecord>(&key).ok().flatten());
|
||||
let program = [main_program, activation_program]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|program| validate_move_hue_program(program).is_ok())
|
||||
.max_by_key(|program| unix_timestamp_sort_key(&program.updated_at));
|
||||
if let Some(program) = program
|
||||
&& let Ok(mut current) = runtime_program.lock()
|
||||
&& *current != program
|
||||
{
|
||||
*current = program.clone();
|
||||
if let Ok(mut node) = open_node(&options, "muninn-move-hue-program-projection") {
|
||||
let _ = node.put(&key, &program);
|
||||
}
|
||||
let activation_program = open_node(
|
||||
&activation_options,
|
||||
"muninn-move-hue-program-activation-sync",
|
||||
)
|
||||
.ok()
|
||||
.and_then(|node| node.get::<MuninnMoveHueProgramRecord>(&key).ok().flatten());
|
||||
let program = [main_program, activation_program]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|program| validate_move_hue_program(program).is_ok())
|
||||
.max_by_key(|program| unix_timestamp_sort_key(&program.updated_at));
|
||||
if let Some(program) = program
|
||||
&& let Ok(mut current) = runtime_program.lock()
|
||||
&& *current != program
|
||||
{
|
||||
*current = program.clone();
|
||||
if let Ok(mut node) = open_node(&options, "muninn-move-hue-program-projection") {
|
||||
let _ = node.put(&key, &program);
|
||||
}
|
||||
thread::sleep(Duration::from_millis(250));
|
||||
}
|
||||
thread::sleep(Duration::from_millis(250));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -650,8 +642,8 @@ fn run_provider_command_ingress(
|
|||
options: Options,
|
||||
runtime_program: Arc<Mutex<MuninnMoveHueProgramRecord>>,
|
||||
) -> Result<()> {
|
||||
let mut transport =
|
||||
CultNetRudpSocketTransportConnection::new(CultNetRudpSocketTransportOptions {
|
||||
let mut transport = CultNetRudpSocketTransportConnection::new(
|
||||
CultNetRudpSocketTransportOptions {
|
||||
runtime_id: format!("muninn-{}-command-ingress", options.host_id),
|
||||
socket,
|
||||
mode: cultnet_rs::CultNetRudpSocketMode::Server,
|
||||
|
|
@ -664,7 +656,8 @@ fn run_provider_command_ingress(
|
|||
max_fragment_bytes: Some(1200),
|
||||
max_pending_reliable_packets: Some(64),
|
||||
media_reliable_expire_after_ms: None,
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
loop {
|
||||
if let Some(frame) = transport.receive_once()?
|
||||
&& frame.channel_id == "schema"
|
||||
|
|
@ -704,10 +697,7 @@ fn apply_provider_command_document(
|
|||
.and_then(serde_json::Value::as_str)
|
||||
.unwrap_or_default();
|
||||
if provider_id != muninn_provider_id(options) {
|
||||
return Err(anyhow!(
|
||||
"Move hue command targets provider {provider_id}, not {}",
|
||||
muninn_provider_id(options)
|
||||
));
|
||||
return Err(anyhow!("Move hue command targets provider {provider_id}, not {}", muninn_provider_id(options)));
|
||||
}
|
||||
let mut program = runtime_program
|
||||
.lock()
|
||||
|
|
@ -1488,10 +1478,9 @@ fn merge_move_state_sources(
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if !sources
|
||||
.iter()
|
||||
.any(|discovered| discovered == source || discovered.move_id == source.move_id)
|
||||
{
|
||||
if !sources.iter().any(|discovered| {
|
||||
discovered == source || discovered.move_id == source.move_id
|
||||
}) {
|
||||
sources.push(source.clone());
|
||||
}
|
||||
}
|
||||
|
|
@ -2986,11 +2975,7 @@ fn publish_move_hue_eve_surface(
|
|||
.unwrap_or_else(|| bootstrap_move_hue_program(options));
|
||||
let provider_id = muninn_provider_id(options);
|
||||
let surface_key = move_hue_surface_key(&options.host_id);
|
||||
let action = |id: &str,
|
||||
label: &str,
|
||||
mode: Option<&str>,
|
||||
order_mode: Option<&str>,
|
||||
cycle_ms: Option<u64>| {
|
||||
let action = |id: &str, label: &str, mode: Option<&str>, order_mode: Option<&str>, cycle_ms: Option<u64>| {
|
||||
json!({
|
||||
"id": format!("{provider_id}.move-hue.{id}"),
|
||||
"kind": "card",
|
||||
|
|
@ -4633,12 +4618,10 @@ fn active_move_marker_camera_sources(
|
|||
.collect::<Vec<_>>();
|
||||
move_roster.sort();
|
||||
move_roster.dedup();
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
let now_ns = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_nanos() as i128;
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
let program = move_hue_program
|
||||
.lock()
|
||||
.map(|program| program.clone())
|
||||
|
|
@ -4653,9 +4636,7 @@ fn active_move_marker_camera_sources(
|
|||
updated_at: "unix-0".to_string(),
|
||||
order_mode: "descending".to_string(),
|
||||
});
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
let program_timestamp_ns = move_hue_program_timestamp_ns(&program, now_ns);
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
let move_colors = move_roster
|
||||
.iter()
|
||||
.filter_map(|identity| {
|
||||
|
|
@ -4679,23 +4660,18 @@ fn active_move_marker_camera_sources(
|
|||
options.host_id, source.camera_id
|
||||
);
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
let (psmoveapi_observations, psmoveapi_health) = if options.move_psmoveapi_tracker {
|
||||
video_device_index(&source.device_path)
|
||||
.and_then(|camera_index| {
|
||||
Some(start_psmoveapi_tracker_worker(
|
||||
options.host_id.clone(),
|
||||
source.camera_id.clone(),
|
||||
camera_index,
|
||||
options.move_tracker_exposure_milli as f32 / 1000.0,
|
||||
move_colors.clone(),
|
||||
Arc::clone(&move_hue_program),
|
||||
))
|
||||
})
|
||||
.map_or((None, None), |(observations, health)| {
|
||||
(Some(observations), Some(health))
|
||||
})
|
||||
let psmoveapi_observations = if options.move_psmoveapi_tracker {
|
||||
video_device_index(&source.device_path).and_then(|camera_index| {
|
||||
Some(start_psmoveapi_tracker_worker(
|
||||
source.camera_id.clone(),
|
||||
camera_index,
|
||||
options.move_tracker_exposure_milli as f32 / 1000.0,
|
||||
move_colors.clone(),
|
||||
Arc::clone(&move_hue_program),
|
||||
))
|
||||
})
|
||||
} else {
|
||||
(None, None)
|
||||
None
|
||||
};
|
||||
ActiveMoveMarkerCameraSource {
|
||||
source: source.clone(),
|
||||
|
|
@ -4721,8 +4697,6 @@ fn active_move_marker_camera_sources(
|
|||
sequence: 0,
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
psmoveapi_observations,
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
psmoveapi_health,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
|
@ -4799,58 +4773,32 @@ static PSMOVE_API_TRACKER_AUTHORITY: Mutex<()> = Mutex::new(());
|
|||
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
fn start_psmoveapi_tracker_worker(
|
||||
host_id: String,
|
||||
camera_id: String,
|
||||
camera_index: i32,
|
||||
exposure: f32,
|
||||
colors: Vec<(String, [u8; 3])>,
|
||||
move_hue_program: Arc<Mutex<MuninnMoveHueProgramRecord>>,
|
||||
) -> (
|
||||
mpsc::Receiver<Vec<muninn_psmoveapi_tracker::PsmoveApiObservation>>,
|
||||
mpsc::Receiver<MuninnMoveTrackerHealthRecord>,
|
||||
) {
|
||||
) -> mpsc::Receiver<Vec<muninn_psmoveapi_tracker::PsmoveApiObservation>> {
|
||||
let (sender, receiver) = mpsc::sync_channel(1);
|
||||
let (health_sender, health_receiver) = mpsc::sync_channel(1);
|
||||
thread::spawn(move || {
|
||||
let mut tracker = match PSMOVE_API_TRACKER_AUTHORITY
|
||||
.lock()
|
||||
.map_err(|_| "PSMoveAPI tracker authority lock was poisoned".to_string())
|
||||
.and_then(|_authority| {
|
||||
muninn_psmoveapi_tracker::PsmoveApiTracker::open(camera_index, exposure, &colors)
|
||||
.map_err(|error| error.to_string())
|
||||
muninn_psmoveapi_tracker::PsmoveApiTracker::open(
|
||||
camera_index,
|
||||
exposure,
|
||||
&colors,
|
||||
)
|
||||
.map_err(|error| error.to_string())
|
||||
}) {
|
||||
Ok(tracker) => tracker,
|
||||
Err(error) => {
|
||||
let _ = health_sender.try_send(MuninnMoveTrackerHealthRecord {
|
||||
health_id: format!("muninn:{host_id}:{camera_id}:move-tracker-health"),
|
||||
host_id: host_id.clone(),
|
||||
camera_id: camera_id.clone(),
|
||||
camera_index,
|
||||
state: "failed".to_string(),
|
||||
camera_name: String::new(),
|
||||
camera_api: String::new(),
|
||||
width: 0,
|
||||
height: 0,
|
||||
exposure,
|
||||
calibrated_controller_count: 0,
|
||||
update_count: 0,
|
||||
observation_count: 0,
|
||||
latest_observation_count: 0,
|
||||
last_observation_at: String::new(),
|
||||
detail: error.clone(),
|
||||
updated_at: timestamp().unwrap_or_else(|_| "unix-0".to_string()),
|
||||
});
|
||||
eprintln!(
|
||||
"Muninn PSMoveAPI tracker failed camera={camera_id} index={camera_index}: {error}"
|
||||
);
|
||||
eprintln!("Muninn PSMoveAPI tracker failed camera={camera_id} index={camera_index}: {error}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let camera_info = tracker.camera_info().clone();
|
||||
let mut last_calibration_at = Instant::now();
|
||||
let mut update_count = 0u64;
|
||||
let mut observation_count = 0u64;
|
||||
let mut last_observation_at = String::new();
|
||||
loop {
|
||||
let Ok(_authority) = PSMOVE_API_TRACKER_AUTHORITY.lock() else {
|
||||
eprintln!("Muninn PSMoveAPI tracker authority lock poisoned camera={camera_id}");
|
||||
|
|
@ -4860,10 +4808,7 @@ fn start_psmoveapi_tracker_worker(
|
|||
tracker.observe_connected();
|
||||
last_calibration_at = Instant::now();
|
||||
}
|
||||
let mut roster = colors
|
||||
.iter()
|
||||
.map(|(identity, _)| identity.clone())
|
||||
.collect::<Vec<_>>();
|
||||
let mut roster = colors.iter().map(|(identity, _)| identity.clone()).collect::<Vec<_>>();
|
||||
roster.sort();
|
||||
let now_ns = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
|
|
@ -4886,78 +4831,17 @@ fn start_psmoveapi_tracker_worker(
|
|||
}
|
||||
}
|
||||
let observations = tracker.update();
|
||||
update_count = update_count.saturating_add(1);
|
||||
observation_count = observation_count.saturating_add(observations.len() as u64);
|
||||
if !observations.is_empty() {
|
||||
last_observation_at = timestamp().unwrap_or_else(|_| "unix-0".to_string());
|
||||
}
|
||||
let health = MuninnMoveTrackerHealthRecord {
|
||||
health_id: format!("muninn:{host_id}:{camera_id}:move-tracker-health"),
|
||||
host_id: host_id.clone(),
|
||||
camera_id: camera_id.clone(),
|
||||
camera_index,
|
||||
state: "running".to_string(),
|
||||
camera_name: camera_info.name.clone(),
|
||||
camera_api: camera_info.api.clone(),
|
||||
width: camera_info.width,
|
||||
height: camera_info.height,
|
||||
exposure: camera_info.exposure,
|
||||
calibrated_controller_count: tracker.tracked_controller_count() as u32,
|
||||
update_count,
|
||||
observation_count,
|
||||
latest_observation_count: observations.len() as u32,
|
||||
last_observation_at: last_observation_at.clone(),
|
||||
detail: String::new(),
|
||||
updated_at: timestamp().unwrap_or_else(|_| "unix-0".to_string()),
|
||||
};
|
||||
match health_sender.try_send(health) {
|
||||
Ok(()) | Err(mpsc::TrySendError::Full(_)) => {}
|
||||
Err(mpsc::TrySendError::Disconnected(_)) => return,
|
||||
}
|
||||
match sender.try_send(observations) {
|
||||
Ok(()) | Err(mpsc::TrySendError::Full(_)) => {}
|
||||
Err(mpsc::TrySendError::Disconnected(_)) => return,
|
||||
}
|
||||
}
|
||||
});
|
||||
(receiver, health_receiver)
|
||||
receiver
|
||||
}
|
||||
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
fn publish_move_tracker_health(
|
||||
node: &mut cultmesh_rs::CultMeshNode,
|
||||
active: &mut [ActiveMoveMarkerCameraSource],
|
||||
) -> Result<()> {
|
||||
for camera in active {
|
||||
let Some(receiver) = camera.psmoveapi_health.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
let mut latest = None;
|
||||
while let Ok(record) = receiver.try_recv() {
|
||||
latest = Some(record);
|
||||
}
|
||||
if let Some(record) = latest {
|
||||
node.put(&record.health_id, &record)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "psmoveapi-tracker"))]
|
||||
fn publish_move_tracker_health(
|
||||
_node: &mut cultmesh_rs::CultMeshNode,
|
||||
_active: &mut [ActiveMoveMarkerCameraSource],
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "psmoveapi-tracker")]
|
||||
fn video_device_index(path: &Path) -> Option<i32> {
|
||||
path.file_name()?
|
||||
.to_str()?
|
||||
.strip_prefix("video")?
|
||||
.parse()
|
||||
.ok()
|
||||
path.file_name()?.to_str()?.strip_prefix("video")?.parse().ok()
|
||||
}
|
||||
|
||||
fn stable_marker_camera_source_hash(source: &MoveMarkerFrameSource) -> u64 {
|
||||
|
|
@ -6499,12 +6383,11 @@ fn scheduled_golden_move_color_with_order(
|
|||
let completed_cycles = completed_steps.div_euclid(roster_len);
|
||||
let completed_in_cycle = completed_steps.rem_euclid(roster_len);
|
||||
let update_order = move_hue_update_order(roster.len(), completed_cycles, order_mode);
|
||||
let order_position = update_order
|
||||
.iter()
|
||||
.position(|index| *index == identity_index as usize)? as i128;
|
||||
let order_position = update_order.iter().position(|index| *index == identity_index as usize)? as i128;
|
||||
let advanced_in_cycle = i128::from(order_position < completed_in_cycle);
|
||||
let sequence_index = identity_index + completed_cycles + advanced_in_cycle;
|
||||
let hue = ((sequence_index as f64 * GOLDEN_RATIO_CONJUGATE).fract() * 360.0).rem_euclid(360.0);
|
||||
let hue = ((sequence_index as f64 * GOLDEN_RATIO_CONJUGATE).fract() * 360.0)
|
||||
.rem_euclid(360.0);
|
||||
Some((
|
||||
hsv_to_rgb(hue, 1.0, 1.0),
|
||||
sequence_index,
|
||||
|
|
@ -9871,7 +9754,8 @@ impl Options {
|
|||
options.move_hue_mode = Some(take_value(&mut args, "--move-hue-mode")?)
|
||||
}
|
||||
"--move-hue-order" => {
|
||||
options.move_hue_order_mode = Some(take_value(&mut args, "--move-hue-order")?)
|
||||
options.move_hue_order_mode =
|
||||
Some(take_value(&mut args, "--move-hue-order")?)
|
||||
}
|
||||
"--command" => options.command_id = Some(take_value(&mut args, "--command")?),
|
||||
"--move-host" => {
|
||||
|
|
@ -9953,9 +9837,7 @@ impl Options {
|
|||
));
|
||||
}
|
||||
if options.move_tracker_exposure_milli > 1000 {
|
||||
return Err(anyhow!(
|
||||
"--move-tracker-exposure-milli must be within 0..=1000"
|
||||
));
|
||||
return Err(anyhow!("--move-tracker-exposure-milli must be within 0..=1000"));
|
||||
}
|
||||
if options.move_psmoveapi_tracker && !cfg!(feature = "psmoveapi-tracker") {
|
||||
return Err(anyhow!(
|
||||
|
|
@ -11650,8 +11532,8 @@ mod tests {
|
|||
client_socket
|
||||
.set_read_timeout(Some(Duration::from_millis(5)))
|
||||
.unwrap();
|
||||
let mut client =
|
||||
CultNetRudpSocketTransportConnection::new(CultNetRudpSocketTransportOptions {
|
||||
let mut client = CultNetRudpSocketTransportConnection::new(
|
||||
CultNetRudpSocketTransportOptions {
|
||||
runtime_id: "muninn-provider-command-test-client".to_string(),
|
||||
socket: client_socket,
|
||||
mode: cultnet_rs::CultNetRudpSocketMode::Client,
|
||||
|
|
@ -11664,8 +11546,9 @@ mod tests {
|
|||
max_fragment_bytes: Some(1200),
|
||||
max_pending_reliable_packets: Some(64),
|
||||
media_reliable_expire_after_ms: None,
|
||||
})
|
||||
.unwrap();
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
client.connect(Vec::new()).unwrap();
|
||||
let deadline = Instant::now() + Duration::from_secs(2);
|
||||
while !client.connected() && Instant::now() < deadline {
|
||||
|
|
@ -11750,15 +11633,8 @@ mod tests {
|
|||
"move-000704a800d0",
|
||||
];
|
||||
let colors = roster.map(default_move_color_for_identity);
|
||||
assert_eq!(
|
||||
colors.into_iter().collect::<HashSet<_>>().len(),
|
||||
roster.len()
|
||||
);
|
||||
assert!(
|
||||
colors
|
||||
.into_iter()
|
||||
.all(|color| color.0.max(color.1).max(color.2) == 255)
|
||||
);
|
||||
assert_eq!(colors.into_iter().collect::<HashSet<_>>().len(), roster.len());
|
||||
assert!(colors.into_iter().all(|color| color.0.max(color.1).max(color.2) == 255));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -11774,11 +11650,7 @@ mod tests {
|
|||
.map(|identity| golden_move_color_for_roster(identity, &roster))
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(colors.iter().copied().collect::<HashSet<_>>().len(), 4);
|
||||
assert!(
|
||||
colors
|
||||
.iter()
|
||||
.all(|color| color.0.max(color.1).max(color.2) == 255)
|
||||
);
|
||||
assert!(colors.iter().all(|color| color.0.max(color.1).max(color.2) == 255));
|
||||
assert!(colors.iter().any(|color| color.0 == 255 && color.1 < 100));
|
||||
assert!(colors.iter().any(|color| color.1 == 255 && color.0 < 100));
|
||||
assert!(colors.iter().any(|color| color.2 == 255 && color.0 < 100));
|
||||
|
|
@ -11786,9 +11658,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn scheduled_golden_colors_shift_window_in_descending_move_order() {
|
||||
let roster = (0..4)
|
||||
.map(|index| format!("move-{index}"))
|
||||
.collect::<Vec<_>>();
|
||||
let roster = (0..4).map(|index| format!("move-{index}")).collect::<Vec<_>>();
|
||||
let state = |millis: i128| {
|
||||
roster
|
||||
.iter()
|
||||
|
|
@ -11806,30 +11676,12 @@ mod tests {
|
|||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
state(0),
|
||||
vec![(0, false), (1, false), (2, false), (3, true)]
|
||||
);
|
||||
assert_eq!(
|
||||
state(249),
|
||||
vec![(0, false), (1, false), (2, false), (3, true)]
|
||||
);
|
||||
assert_eq!(
|
||||
state(250),
|
||||
vec![(0, false), (1, false), (2, true), (4, false)]
|
||||
);
|
||||
assert_eq!(
|
||||
state(500),
|
||||
vec![(0, false), (1, true), (3, false), (4, false)]
|
||||
);
|
||||
assert_eq!(
|
||||
state(750),
|
||||
vec![(0, true), (2, false), (3, false), (4, false)]
|
||||
);
|
||||
assert_eq!(
|
||||
state(1_000),
|
||||
vec![(1, false), (2, false), (3, false), (4, true)]
|
||||
);
|
||||
assert_eq!(state(0), vec![(0, false), (1, false), (2, false), (3, true)]);
|
||||
assert_eq!(state(249), vec![(0, false), (1, false), (2, false), (3, true)]);
|
||||
assert_eq!(state(250), vec![(0, false), (1, false), (2, true), (4, false)]);
|
||||
assert_eq!(state(500), vec![(0, false), (1, true), (3, false), (4, false)]);
|
||||
assert_eq!(state(750), vec![(0, true), (2, false), (3, false), (4, false)]);
|
||||
assert_eq!(state(1_000), vec![(1, false), (2, false), (3, false), (4, true)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -11838,14 +11690,8 @@ mod tests {
|
|||
assert_eq!(move_hue_update_order(4, 0, "ascending"), vec![0, 1, 2, 3]);
|
||||
assert_eq!(move_hue_update_order(4, 0, "bounce"), vec![3, 2, 1, 0]);
|
||||
assert_eq!(move_hue_update_order(4, 1, "bounce"), vec![0, 1, 2, 3]);
|
||||
assert_eq!(
|
||||
move_hue_update_order(4, 0, "rotating-lead"),
|
||||
vec![3, 2, 1, 0]
|
||||
);
|
||||
assert_eq!(
|
||||
move_hue_update_order(4, 1, "rotating-lead"),
|
||||
vec![2, 1, 0, 3]
|
||||
);
|
||||
assert_eq!(move_hue_update_order(4, 0, "rotating-lead"), vec![3, 2, 1, 0]);
|
||||
assert_eq!(move_hue_update_order(4, 1, "rotating-lead"), vec![2, 1, 0, 3]);
|
||||
let first = move_hue_update_order(4, 23, "golden-permutation");
|
||||
assert_eq!(first, move_hue_update_order(4, 23, "golden-permutation"));
|
||||
assert_eq!(first.iter().copied().collect::<HashSet<_>>().len(), 4);
|
||||
|
|
@ -12760,12 +12606,10 @@ Device 00:07:04:A8:00:D0 (public)
|
|||
.value
|
||||
.get("routes")
|
||||
.and_then(|value| value.as_array())
|
||||
.and_then(|routes| {
|
||||
routes.iter().find(|route| {
|
||||
route.get("role").and_then(|value| value.as_str())
|
||||
== Some("muninn provider command ingress")
|
||||
})
|
||||
})
|
||||
.and_then(|routes| routes.iter().find(|route| {
|
||||
route.get("role").and_then(|value| value.as_str())
|
||||
== Some("muninn provider command ingress")
|
||||
}))
|
||||
.expect("provider-owned command route");
|
||||
assert_eq!(
|
||||
command_route.get("uri").and_then(|value| value.as_str()),
|
||||
|
|
@ -13258,10 +13102,7 @@ Device 00:07:04:A8:00:D0 (public)
|
|||
hidraw_path: "/dev/input/js2".to_string(),
|
||||
}];
|
||||
|
||||
assert_eq!(
|
||||
merge_move_state_sources(discovered.clone(), &configured),
|
||||
discovered
|
||||
);
|
||||
assert_eq!(merge_move_state_sources(discovered.clone(), &configured), discovered);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ pub const MUNINN_HID_CONTROLLER_STATE_SCHEMA: &str = "muninn.hid_controller_stat
|
|||
pub const MUNINN_MOVE_IDENTITY_SCHEMA: &str = "muninn.move_identity.v1";
|
||||
pub const MUNINN_MOVE_LIGHT_COMMAND_SCHEMA: &str = "muninn.move_light_command.v1";
|
||||
pub const MUNINN_MOVE_HUE_PROGRAM_SCHEMA: &str = "muninn.move_hue_program.v1";
|
||||
pub const MUNINN_MOVE_TRACKER_HEALTH_SCHEMA: &str = "muninn.move_tracker_health.v1";
|
||||
pub const MUNINN_QUEST_ACCESS_SCHEMA: &str = "muninn.quest_access.v1";
|
||||
pub const MUNINN_COMMAND_BOUNDARY_SCHEMA: &str = "muninn.command_boundary.v1";
|
||||
pub const MUNINN_TRANSPORT_PROFILE_SCHEMA: &str = "muninn.transport_profile.v1";
|
||||
|
|
@ -1196,48 +1195,6 @@ pub struct MuninnMoveHueProgramRecord {
|
|||
pub order_mode: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DatabaseEntry)]
|
||||
#[cultcache(
|
||||
type = "muninn.move_tracker_health",
|
||||
schema = "muninn.move_tracker_health.v1"
|
||||
)]
|
||||
pub struct MuninnMoveTrackerHealthRecord {
|
||||
#[cultcache(key = 0)]
|
||||
pub health_id: String,
|
||||
#[cultcache(key = 1)]
|
||||
pub host_id: String,
|
||||
#[cultcache(key = 2)]
|
||||
pub camera_id: String,
|
||||
#[cultcache(key = 3)]
|
||||
pub camera_index: i32,
|
||||
#[cultcache(key = 4)]
|
||||
pub state: String,
|
||||
#[cultcache(key = 5)]
|
||||
pub camera_name: String,
|
||||
#[cultcache(key = 6)]
|
||||
pub camera_api: String,
|
||||
#[cultcache(key = 7)]
|
||||
pub width: u32,
|
||||
#[cultcache(key = 8)]
|
||||
pub height: u32,
|
||||
#[cultcache(key = 9)]
|
||||
pub exposure: f32,
|
||||
#[cultcache(key = 10)]
|
||||
pub calibrated_controller_count: u32,
|
||||
#[cultcache(key = 11)]
|
||||
pub update_count: u64,
|
||||
#[cultcache(key = 12)]
|
||||
pub observation_count: u64,
|
||||
#[cultcache(key = 13)]
|
||||
pub latest_observation_count: u32,
|
||||
#[cultcache(key = 14)]
|
||||
pub last_observation_at: String,
|
||||
#[cultcache(key = 15)]
|
||||
pub detail: String,
|
||||
#[cultcache(key = 16)]
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)]
|
||||
#[cultcache(type = "muninn.quest_access", schema = "muninn.quest_access.v1")]
|
||||
pub struct MuninnQuestAccessRecord {
|
||||
|
|
@ -1364,7 +1321,6 @@ cultmesh_rs::cultmesh_documents!(OdinDocuments {
|
|||
MuninnMoveIdentityRecord => MUNINN_MOVE_IDENTITY_SCHEMA,
|
||||
MuninnMoveLightCommandRecord => MUNINN_MOVE_LIGHT_COMMAND_SCHEMA,
|
||||
MuninnMoveHueProgramRecord => MUNINN_MOVE_HUE_PROGRAM_SCHEMA,
|
||||
MuninnMoveTrackerHealthRecord => MUNINN_MOVE_TRACKER_HEALTH_SCHEMA,
|
||||
MuninnQuestAccessRecord => MUNINN_QUEST_ACCESS_SCHEMA,
|
||||
MuninnCommandBoundaryCompatRecord => MUNINN_COMMAND_BOUNDARY_SCHEMA,
|
||||
MuninnTransportProfileCompatRecord => MUNINN_TRANSPORT_PROFILE_SCHEMA,
|
||||
|
|
|
|||
Loading…
Reference in a new issue