Fixes to get live display working basic

master
noah metz 2024-01-22 12:38:07 -07:00
parent c98d2bd531
commit 8732193a4c
1 changed files with 64 additions and 39 deletions

@ -158,7 +158,7 @@ fn get_match(divisions: &mut HashMap<i32, Division>, tuple: MatchTuple) -> Optio
None => {}, None => {},
Some(division) => { Some(division) => {
for m in &mut division.matches { for m in &mut division.matches {
if m.tuple == tuple { if m.info.tuple == tuple {
return Some(m); return Some(m);
} }
} }
@ -233,7 +233,7 @@ impl Event {
start: started as f64 / 1000.0, start: started as f64 / 1000.0,
}, },
Some(division) => { Some(division) => {
match division.matches.iter().find(|a| a.tuple == tuple) { match division.matches.iter().find(|a| a.info.tuple == tuple) {
None => match_state = MatchState{ None => match_state = MatchState{
state: GameState::Scheduled, state: GameState::Scheduled,
start: started as f64 / 1000.0, start: started as f64 / 1000.0,
@ -261,12 +261,12 @@ impl Event {
match_list.push(Match{ match_list.push(Match{
state: match_state, state: match_state,
info: MatchInfo{ info: MatchInfo{
tuple: tuple.clone(),
red_teams: [String::from(red_1), String::from(red_2)], red_teams: [String::from(red_1), String::from(red_2)],
blue_teams: [String::from(blue_1), String::from(blue_2)], blue_teams: [String::from(blue_1), String::from(blue_2)],
field, field,
}, },
score: None, score: None,
tuple: tuple.clone(),
}) })
}, },
None => { None => {
@ -274,12 +274,12 @@ impl Event {
new_match_list.push(Match{ new_match_list.push(Match{
state: match_state, state: match_state,
info: MatchInfo{ info: MatchInfo{
tuple: tuple.clone(),
red_teams: [String::from(red_1), String::from(red_2)], red_teams: [String::from(red_1), String::from(red_2)],
blue_teams: [String::from(blue_1), String::from(blue_2)], blue_teams: [String::from(blue_1), String::from(blue_2)],
field, field,
}, },
score: None, score: None,
tuple: tuple.clone(),
}); });
matches.insert(tuple.division, new_match_list); matches.insert(tuple.division, new_match_list);
}, },
@ -327,6 +327,7 @@ struct MatchState {
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
struct MatchInfo { struct MatchInfo {
tuple: MatchTuple,
red_teams: [String; 2], red_teams: [String; 2],
blue_teams: [String; 2], blue_teams: [String; 2],
field: FieldTuple, field: FieldTuple,
@ -337,7 +338,6 @@ struct Match {
state: MatchState, state: MatchState,
info: MatchInfo, info: MatchInfo,
score: Option<MatchScore>, score: Option<MatchScore>,
tuple: MatchTuple,
} }
#[derive(Debug)] #[derive(Debug)]
@ -920,7 +920,7 @@ fn on_score_set(notice: tm::Notice, event: &mut Event, _connection: &mut TMConne
let Some(scores) = notice.match_score else { return Vec::new() }; let Some(scores) = notice.match_score else { return Vec::new() };
let Some(score) = get_game_score(&scores) else { return Vec::new() }; let Some(score) = get_game_score(&scores) else { return Vec::new() };
let Some(division) = &mut event.divisions.get_mut(&tuple.division) else { return Vec::new() }; let Some(division) = &mut event.divisions.get_mut(&tuple.division) else { return Vec::new() };
let Some(m) = &mut division.matches.iter_mut().find(|a| a.tuple == tuple) else { return Vec::new() }; let Some(m) = &mut division.matches.iter_mut().find(|a| a.info.tuple == tuple) else { return Vec::new() };
m.score = Some(score.clone()); m.score = Some(score.clone());
m.state = MatchState{ m.state = MatchState{
@ -930,33 +930,29 @@ fn on_score_set(notice: tm::Notice, event: &mut Event, _connection: &mut TMConne
let score_serialized = serde_json::to_string_pretty(&m.score).unwrap(); let score_serialized = serde_json::to_string_pretty(&m.score).unwrap();
let state_serialized = serde_json::to_string_pretty(&m.state).unwrap(); let state_serialized = serde_json::to_string_pretty(&m.state).unwrap();
let game_score_topic = format!("division/{}/{:?}/{}/score", tuple.division, tuple.round, tuple.match_num);
let game_state_topic = format!("division/{}/{:?}/{}/state", tuple.division, tuple.round, tuple.match_num);
let mut out = Vec::new(); let mut out = Vec::new();
out.push(MQTTMessage{ out.push(MQTTMessage{
topic: game_score_topic, topic: tuple.topic("/score"),
payload: score_serialized.clone(), payload: score_serialized.clone(),
}); });
out.push(MQTTMessage{ out.push(MQTTMessage{
topic: game_state_topic, topic: tuple.topic("/state"),
payload: state_serialized.clone(), payload: state_serialized.clone(),
}); });
for (field_set_id, field_set) in &event.field_sets { for (_, field_set) in &event.field_sets {
for (field_id, field) in &field_set.fields { for (_, field) in &field_set.fields {
match field.last_known_match { match field.last_known_match {
None => {}, None => {},
Some(last_known_match) => { Some(last_known_match) => {
if last_known_match == tuple { if last_known_match == tuple {
let field_score_topic = format!("field/{}/{}/score", field_set_id, field_id);
let field_state_topic = format!("field/{}/{}/state", field_set_id, field_id);
out.push(MQTTMessage{ out.push(MQTTMessage{
topic: field_score_topic, topic: field.tuple.topic("/score"),
payload: score_serialized.clone(), payload: score_serialized.clone(),
}); });
out.push(MQTTMessage{ out.push(MQTTMessage{
topic: field_state_topic, topic: field.tuple.topic("/state"),
payload: state_serialized.clone(), payload: state_serialized.clone(),
}); });
} }
@ -972,26 +968,24 @@ fn on_score_change(notice: tm::Notice, event: &mut Event, _connection: &mut TMCo
let Some(scores) = notice.match_score else { return Vec::new() }; let Some(scores) = notice.match_score else { return Vec::new() };
let Some(score) = get_game_score(&scores) else { return Vec::new() }; let Some(score) = get_game_score(&scores) else { return Vec::new() };
let Some(division) = &mut event.divisions.get_mut(&tuple.division) else { return Vec::new() }; let Some(division) = &mut event.divisions.get_mut(&tuple.division) else { return Vec::new() };
let Some(m) = &mut division.matches.iter_mut().find(|a| a.tuple == tuple) else { return Vec::new() }; let Some(m) = &mut division.matches.iter_mut().find(|a| a.info.tuple == tuple) else { return Vec::new() };
m.score = Some(score.clone()); m.score = Some(score.clone());
let serialized = serde_json::to_string_pretty(&score).unwrap(); let serialized = serde_json::to_string_pretty(&score).unwrap();
let game_topic = format!("division/{}/{:?}/{}/score", tuple.division, tuple.round, tuple.match_num);
let mut out = Vec::new(); let mut out = Vec::new();
out.push(MQTTMessage{ out.push(MQTTMessage{
topic: game_topic, topic: tuple.topic("/score"),
payload: serialized.clone(), payload: serialized.clone(),
}); });
for (field_set_id, field_set) in &event.field_sets { for (_, field_set) in &event.field_sets {
for (field_id, field) in &field_set.fields { for (_, field) in &field_set.fields {
match field.last_known_match { match field.last_known_match {
None => {}, None => {},
Some(last_known_match) => { Some(last_known_match) => {
if last_known_match == tuple { if last_known_match == tuple {
let field_topic = format!("field/{}/{}/score", field_set_id, field_id);
out.push(MQTTMessage{ out.push(MQTTMessage{
topic: field_topic, topic: field.tuple.topic("/score"),
payload: serialized.clone(), payload: serialized.clone(),
}); });
} }
@ -1017,13 +1011,41 @@ fn on_match_list_update(_notice: tm::Notice, event: &mut Event, connection: &mut
for m in &division.matches { for m in &division.matches {
let serialized = serde_json::to_string_pretty(&m.info).unwrap(); let serialized = serde_json::to_string_pretty(&m.info).unwrap();
messages.push(MQTTMessage{ messages.push(MQTTMessage{
topic: m.tuple.topic(""), topic: m.info.tuple.topic(""),
payload: serialized payload: serialized
}); });
let serialized_state = serde_json::to_string_pretty(&m.state).unwrap();
messages.push(MQTTMessage{
topic: m.info.tuple.topic("/state"),
payload: serialized_state,
});
} }
} }
}, },
} }
for (_, field_set) in &event.field_sets {
for (_, field) in &field_set.fields {
match field.last_known_match {
None => {},
Some(tuple) => {
let Some(m) = get_match(&mut event.divisions, tuple) else {continue;};
let serialized_state = serde_json::to_string_pretty(&m.state).unwrap();
let serialized = serde_json::to_string_pretty(&m.info).unwrap();
messages.push(MQTTMessage{
topic: field.tuple.topic(""),
payload: serialized,
});
messages.push(MQTTMessage{
topic: field.tuple.topic("/state"),
payload: serialized_state,
});
},
}
}
}
return messages; return messages;
} }
@ -1048,23 +1070,26 @@ fn on_field_assigned(notice: tm::Notice, event: &mut Event, _connection: &mut TM
let mut messages = Vec::new(); let mut messages = Vec::new();
let serialized = serde_json::to_string_pretty(&m.state).unwrap(); let serialized = serde_json::to_string_pretty(&m.state).unwrap();
let field_topic = field_info.topic("/state"); let serialized_info = serde_json::to_string_pretty(&m.info).unwrap();
let match_topic = tuple.topic("/state");
messages.push(MQTTMessage{ messages.push(MQTTMessage{
topic: field_topic, topic: field_info.topic("/state"),
payload: serialized.clone(), payload: serialized.clone(),
}); });
messages.push(MQTTMessage{ messages.push(MQTTMessage{
topic: match_topic, topic: field_info.topic(""),
payload: serialized_info,
});
messages.push(MQTTMessage{
topic: tuple.topic("/state"),
payload: serialized, payload: serialized,
}); });
if let Some(score) = &m.score { if let Some(score) = &m.score {
let serialized = serde_json::to_string_pretty(&score).unwrap(); let serialized = serde_json::to_string_pretty(&score).unwrap();
let topic = tuple.topic("/score");
messages.push(MQTTMessage{ messages.push(MQTTMessage{
topic, topic: tuple.topic("/score"),
payload: serialized, payload: serialized,
}); });
} }
@ -1245,14 +1270,14 @@ fn main() {
for (_, division) in &mut event.divisions { for (_, division) in &mut event.divisions {
for m in &mut division.matches { for m in &mut division.matches {
let serialized = serde_json::to_string_pretty(&m.info).unwrap(); let serialized = serde_json::to_string_pretty(&m.info).unwrap();
client.publish(m.tuple.topic(""), QoS::AtLeastOnce, true, serialized).unwrap(); client.publish(m.info.tuple.topic(""), QoS::AtLeastOnce, true, serialized).unwrap();
m.score = get_match_score(&tm_connection, struct_tuple_to_tm(m.tuple)); m.score = get_match_score(&tm_connection, struct_tuple_to_tm(m.info.tuple));
let state_serialized = serde_json::to_string_pretty(&m.state).unwrap(); let state_serialized = serde_json::to_string_pretty(&m.state).unwrap();
client.publish(m.tuple.topic("/state"), QoS::AtLeastOnce, true, state_serialized).unwrap(); client.publish(m.info.tuple.topic("/state"), QoS::AtLeastOnce, true, state_serialized).unwrap();
if let Some(score) = &m.score { if let Some(score) = &m.score {
let serialized_score = serde_json::to_string_pretty(score).unwrap(); let serialized_score = serde_json::to_string_pretty(score).unwrap();
client.publish(m.tuple.topic("/score"), QoS::AtLeastOnce, true, serialized_score).unwrap(); client.publish(m.info.tuple.topic("/score"), QoS::AtLeastOnce, true, serialized_score).unwrap();
} }
} }
} }
@ -1280,6 +1305,8 @@ fn main() {
None => {}, None => {},
Some(field) => { Some(field) => {
field.last_known_match = Some(tuple); field.last_known_match = Some(tuple);
let serialized = serde_json::to_string_pretty(&m.info).unwrap();
client.publish(field.tuple.topic(""), QoS::AtLeastOnce, true, serialized).unwrap();
let serialized_score = serde_json::to_string_pretty(&m.score).unwrap(); let serialized_score = serde_json::to_string_pretty(&m.score).unwrap();
client.publish(field.tuple.topic("/score"), QoS::AtLeastOnce, true, serialized_score).unwrap(); client.publish(field.tuple.topic("/score"), QoS::AtLeastOnce, true, serialized_score).unwrap();
let serialized_state = serde_json::to_string_pretty(&m.state).unwrap(); let serialized_state = serde_json::to_string_pretty(&m.state).unwrap();
@ -1324,11 +1351,9 @@ fn main() {
None => log::warn!("Received state change for unknown match {:#?}", state_change.tuple), None => log::warn!("Received state change for unknown match {:#?}", state_change.tuple),
Some(m) => { Some(m) => {
m.state = state_change.next_state.clone(); m.state = state_change.next_state.clone();
let field_state_topic = format!("field/{}/{}/state", state_change.field.set, state_change.field.id); let state_serialized = serde_json::to_vec_pretty(&state_change.next_state).unwrap();
let match_state_topic = format!("division/{}/{:?}/{}/score", state_change.tuple.division, state_change.tuple.round, state_change.tuple.match_num); client.publish(state_change.field.topic("/state"), QoS::AtLeastOnce, true, state_serialized.clone()).expect("Failed MQTT publish");
let payload = serde_json::to_vec_pretty(&state_change.next_state).unwrap(); client.publish(m.info.tuple.topic("/state"), QoS::AtLeastOnce, true, state_serialized).expect("Failed MQTT publish");
client.publish(field_state_topic, QoS::AtLeastOnce, true, payload.clone()).expect("Failed MQTT publish");
client.publish(match_state_topic, QoS::AtLeastOnce, true, payload).expect("Failed MQTT publish");
}, },
} }
}, },