|
|
@ -206,21 +206,24 @@ impl Event {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_match_list(self: &mut Event, match_list: tm::MatchList) {
|
|
|
|
fn parse_match_schedule(self: &mut Event, schedule: tm::MatchSchedule) {
|
|
|
|
let mut matches: HashMap<i32, Vec<Match>> = HashMap::new();
|
|
|
|
let mut matches: HashMap<i32, Vec<Match>> = HashMap::new();
|
|
|
|
for m in match_list.matches.iter() {
|
|
|
|
for m in schedule.matches.iter() {
|
|
|
|
let tuple = MatchTuple{
|
|
|
|
let tuple = tm_tuple_to_struct(m.match_tuple.clone().unwrap());
|
|
|
|
division: m.division.unwrap(),
|
|
|
|
let Some(field) = get_field_tuple(&m.assigned_field) else {continue;};
|
|
|
|
round: int_to_round(m.round.unwrap()),
|
|
|
|
let red_1 = m.alliances[0].teams[0].number();
|
|
|
|
instance: m.instance.unwrap(),
|
|
|
|
let red_2 = m.alliances[0].teams[1].number();
|
|
|
|
match_num: m.r#match.unwrap(),
|
|
|
|
let blue_1 = m.alliances[1].teams[0].number();
|
|
|
|
session: m.session.unwrap(),
|
|
|
|
let blue_2 = m.alliances[1].teams[1].number();
|
|
|
|
};
|
|
|
|
|
|
|
|
match matches.get_mut(&tuple.division) {
|
|
|
|
match matches.get_mut(&tuple.division) {
|
|
|
|
Some(match_list) => {
|
|
|
|
Some(match_list) => {
|
|
|
|
match_list.push(Match{
|
|
|
|
match_list.push(Match{
|
|
|
|
state: None,
|
|
|
|
state: None,
|
|
|
|
info: None,
|
|
|
|
info: MatchInfo{
|
|
|
|
|
|
|
|
red_teams: [String::from(red_1), String::from(red_2)],
|
|
|
|
|
|
|
|
blue_teams: [String::from(blue_1), String::from(blue_2)],
|
|
|
|
|
|
|
|
field,
|
|
|
|
|
|
|
|
},
|
|
|
|
score: None,
|
|
|
|
score: None,
|
|
|
|
tuple: tuple.clone(),
|
|
|
|
tuple: tuple.clone(),
|
|
|
|
})
|
|
|
|
})
|
|
|
@ -229,7 +232,11 @@ impl Event {
|
|
|
|
let mut new_match_list = Vec::new();
|
|
|
|
let mut new_match_list = Vec::new();
|
|
|
|
new_match_list.push(Match{
|
|
|
|
new_match_list.push(Match{
|
|
|
|
state: None,
|
|
|
|
state: None,
|
|
|
|
info: None,
|
|
|
|
info: MatchInfo{
|
|
|
|
|
|
|
|
red_teams: [String::from(red_1), String::from(red_2)],
|
|
|
|
|
|
|
|
blue_teams: [String::from(blue_1), String::from(blue_2)],
|
|
|
|
|
|
|
|
field,
|
|
|
|
|
|
|
|
},
|
|
|
|
score: None,
|
|
|
|
score: None,
|
|
|
|
tuple: tuple.clone(),
|
|
|
|
tuple: tuple.clone(),
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -287,7 +294,7 @@ struct MatchInfo {
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
|
|
struct Match {
|
|
|
|
struct Match {
|
|
|
|
state: Option<MatchState>,
|
|
|
|
state: Option<MatchState>,
|
|
|
|
info: Option<MatchInfo>,
|
|
|
|
info: MatchInfo,
|
|
|
|
score: Option<MatchScore>,
|
|
|
|
score: Option<MatchScore>,
|
|
|
|
tuple: MatchTuple,
|
|
|
|
tuple: MatchTuple,
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -737,32 +744,6 @@ fn struct_tuple_to_tm(tuple: MatchTuple) -> tm::MatchTuple {
|
|
|
|
return out;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn get_match_info(connection: &TMConnection, filter: tm::MatchTuple) -> Option<MatchInfo> {
|
|
|
|
|
|
|
|
let mut req = tm::BackendMessageData::default();
|
|
|
|
|
|
|
|
req.match_tuple = Some(filter);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let resp = connection.request(1004, req);
|
|
|
|
|
|
|
|
let Some(schedule) = resp.data.match_schedule else { return None; };
|
|
|
|
|
|
|
|
if schedule.matches.len() != 1 {
|
|
|
|
|
|
|
|
return None;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let Some(field) = &schedule.matches[0].assigned_field else { return None; };
|
|
|
|
|
|
|
|
let red_1 = schedule.matches[0].alliances[0].teams[0].number();
|
|
|
|
|
|
|
|
let red_2 = schedule.matches[0].alliances[0].teams[1].number();
|
|
|
|
|
|
|
|
let blue_1 = schedule.matches[0].alliances[1].teams[0].number();
|
|
|
|
|
|
|
|
let blue_2 = schedule.matches[0].alliances[1].teams[1].number();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Some(MatchInfo{
|
|
|
|
|
|
|
|
red_teams: [String::from(red_1), String::from(red_2)],
|
|
|
|
|
|
|
|
blue_teams: [String::from(blue_1), String::from(blue_2)],
|
|
|
|
|
|
|
|
field: FieldTuple{
|
|
|
|
|
|
|
|
set: field.field_set_id(),
|
|
|
|
|
|
|
|
id: field.id(),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn get_match_score(connection: &TMConnection, filter: tm::MatchTuple) -> Option<MatchScore> {
|
|
|
|
fn get_match_score(connection: &TMConnection, filter: tm::MatchTuple) -> Option<MatchScore> {
|
|
|
|
let mut req = tm::BackendMessageData::default();
|
|
|
|
let mut req = tm::BackendMessageData::default();
|
|
|
|
req.match_tuple = Some(filter);
|
|
|
|
req.match_tuple = Some(filter);
|
|
|
@ -981,16 +962,23 @@ fn on_score_change(notice: tm::Notice, event: &mut Event, _connection: &mut TMCo
|
|
|
|
|
|
|
|
|
|
|
|
fn on_match_list_update(_notice: tm::Notice, event: &mut Event, connection: &mut TMConnection) -> Vec<MQTTMessage> {
|
|
|
|
fn on_match_list_update(_notice: tm::Notice, event: &mut Event, connection: &mut TMConnection) -> Vec<MQTTMessage> {
|
|
|
|
let mut messages = Vec::new();
|
|
|
|
let mut messages = Vec::new();
|
|
|
|
let match_list_resp = connection.request(1002, tm::BackendMessageData::default());
|
|
|
|
let resp = connection.request(1004, tm::BackendMessageData::default());
|
|
|
|
match match_list_resp.data.match_list {
|
|
|
|
match resp.data.match_schedule {
|
|
|
|
None => {},
|
|
|
|
None => {},
|
|
|
|
Some(match_list) => {
|
|
|
|
Some(schedule) => {
|
|
|
|
event.parse_match_list(match_list);
|
|
|
|
event.parse_match_schedule(schedule);
|
|
|
|
for (division_id, division) in &event.divisions {
|
|
|
|
for (division_id, division) in &event.divisions {
|
|
|
|
messages.push(MQTTMessage{
|
|
|
|
messages.push(MQTTMessage{
|
|
|
|
topic: format!("division/{}/schedule", division_id),
|
|
|
|
topic: format!("division/{}/schedule", division_id),
|
|
|
|
payload: serde_json::to_string_pretty(&division.matches).unwrap(),
|
|
|
|
payload: serde_json::to_string_pretty(&division.matches).unwrap(),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
for m in &division.matches {
|
|
|
|
|
|
|
|
let serialized = serde_json::to_string_pretty(&m.info).unwrap();
|
|
|
|
|
|
|
|
messages.push(MQTTMessage{
|
|
|
|
|
|
|
|
topic: m.tuple.topic(""),
|
|
|
|
|
|
|
|
payload: serialized
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1210,10 +1198,10 @@ fn main() {
|
|
|
|
event.parse_field_sets(field_set_resp.data.field_set_list.unwrap());
|
|
|
|
event.parse_field_sets(field_set_resp.data.field_set_list.unwrap());
|
|
|
|
|
|
|
|
|
|
|
|
// Get the match list
|
|
|
|
// Get the match list
|
|
|
|
let match_list_resp = tm_connection.request(1002, tm::BackendMessageData::default());
|
|
|
|
let match_schedule_resp = tm_connection.request(1004, tm::BackendMessageData::default());
|
|
|
|
event.parse_match_list(match_list_resp.data.match_list.unwrap());
|
|
|
|
event.parse_match_schedule(match_schedule_resp.data.match_schedule.unwrap());
|
|
|
|
|
|
|
|
|
|
|
|
// For each match, get the score and info(field & teams)
|
|
|
|
// For each match, get the score
|
|
|
|
for (_, division) in &mut event.divisions {
|
|
|
|
for (_, division) in &mut event.divisions {
|
|
|
|
for m in &mut division.matches {
|
|
|
|
for m in &mut division.matches {
|
|
|
|
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.tuple));
|
|
|
@ -1221,11 +1209,6 @@ fn main() {
|
|
|
|
let serialized = serde_json::to_string_pretty(score).unwrap();
|
|
|
|
let serialized = serde_json::to_string_pretty(score).unwrap();
|
|
|
|
client.publish(m.tuple.topic("/score"), QoS::AtLeastOnce, true, serialized).expect("MQTT publish fail");
|
|
|
|
client.publish(m.tuple.topic("/score"), QoS::AtLeastOnce, true, serialized).expect("MQTT publish fail");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m.info = get_match_info(&tm_connection, struct_tuple_to_tm(m.tuple));
|
|
|
|
|
|
|
|
if let Some(info) = &m.info {
|
|
|
|
|
|
|
|
let serialized = serde_json::to_string_pretty(info).unwrap();
|
|
|
|
|
|
|
|
client.publish(m.tuple.topic(""), QoS::AtLeastOnce, true, serialized).expect("MQTT publish fail");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1248,12 +1231,9 @@ fn main() {
|
|
|
|
let tuple = tm_tuple_to_struct(match_tuple);
|
|
|
|
let tuple = tm_tuple_to_struct(match_tuple);
|
|
|
|
match get_match(&mut event.divisions, tuple) {
|
|
|
|
match get_match(&mut event.divisions, tuple) {
|
|
|
|
None => {},
|
|
|
|
None => {},
|
|
|
|
Some(m) => match &m.info {
|
|
|
|
Some(m) => match field_set.fields.get_mut(&m.info.field.id) {
|
|
|
|
None => {},
|
|
|
|
None => {},
|
|
|
|
Some(info) => match field_set.fields.get_mut(&info.field.id) {
|
|
|
|
Some(field) => field.last_known_match = Some(tuple),
|
|
|
|
None => {},
|
|
|
|
|
|
|
|
Some(field) => field.last_known_match = Some(tuple),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|