Added structures for MQTT JSON messages

master
noah metz 2024-01-18 14:58:54 -07:00
parent fe3b476556
commit 0b33a9e580
3 changed files with 218 additions and 38 deletions

45
Cargo.lock generated

@ -241,6 +241,12 @@ dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "libc"
version = "0.2.152"
@ -568,6 +574,12 @@ dependencies = [
"untrusted",
]
[[package]]
name = "ryu"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "schannel"
version = "0.1.23"
@ -616,6 +628,37 @@ dependencies = [
"libc",
]
[[package]]
name = "serde"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -746,6 +789,8 @@ dependencies = [
"prost-types",
"protoc",
"rumqttc",
"serde",
"serde_json",
]
[[package]]

@ -13,3 +13,5 @@ prost-build = "0.12.3"
prost = "0.12.3"
prost-types = "0.12.3"
rumqttc = "0.23.0"
serde = { version = "1.0.195", features = ["derive"]}
serde_json = "1.0.111"

@ -1,6 +1,9 @@
use rumqttc::{MqttOptions, Client, QoS};
use std::time::Duration;
use std::thread;
use prost::Message;
use std::io::Cursor;
use serde::{Serialize, Deserialize};
// TODO:
// 1) Represent state of division/fieldset/field/match(maybe save/load)
@ -21,50 +24,56 @@ use std::thread;
//
// Notice protobuf:
// message Notice {
// optional .NoticeId id = 1;
// optional .MatchTuple affectedMatch = 2;
// optional .ElimAlliance elimAlliance = 3;
// optional .SideChallengeScore sideChallengeScore = 4;
// optional .EventConfig eventConfig = 5;
// optional .FieldHwState fieldState = 6;
// optional .FieldTime fieldTime = 7;
// optional .Field field = 8;
// optional .MatchTimeSchedList matchTimeSchedList = 9;
// optional .MatchTimeSchedList matchTimeSched = 10;
// optional .FieldSetList fieldSetList = 11;
// optional .PitDisplayList pitDisplayList = 12;
// optional .DisplayState displayState = 13;
// optional .AssignedObjectType.AssignedObjectEnum assignedType = 15;
// optional .PublishOptions publishOptions = 16;
// optional .Division division = 17;
// optional .MatchScore matchScore = 18;
// optional .Rankings rankings = 19;
// optional .MatchRound affectedRound = 20;
// optional .Award award = 21;
// optional .FieldSet fieldSet = 22;
// optional .TeamInfo teamInfo = 23;
// optional tm.NoticeId id = 1;
// optional tm.MatchTuple affectedMatch = 2;
// optional tm.ElimAlliance elimAlliance = 3;
// optional tm.SideChallengeScore sideChallengeScore = 4;
// optional tm.EventConfig eventConfig = 5;
// optional tm.FieldHwState fieldState = 6;
// optional tm.FieldTime fieldTime = 7;
// optional tm.Field field = 8;
// optional tm.MatchTimeSchedList matchTimeSchedList = 9;
// optional tm.MatchTimeSchedList matchTimeSched = 10;
// optional tm.FieldSetList fieldSetList = 11;
// optional tm.PitDisplayList pitDisplayList = 12;
// optional tm.DisplayState displayState = 13;
// optional tm.AssignedObjectType.AssignedObjectEnum assignedType = 15;
// optional tm.PublishOptions publishOptions = 16;
// optional tm.Division division = 17;
// optional tm.MatchScore matchScore = 18;
// optional tm.Rankings rankings = 19;
// optional tm.MatchRound affectedRound = 20;
// optional tm.Award award = 21;
// optional tm.FieldSet fieldSet = 22;
// optional tm.TeamInfo teamInfo = 23;
// optional double obsolete_serverTime = 24;
// optional .TeamInspection teamInspection = 25;
// optional tm.TeamInspection teamInspection = 25;
// optional int32 obsolete_serverTimeZoneInSecs = 27;
// optional .ElimQueueList elimQueueList = 28;
// optional .TextMessageNotice textMessage = 29;
// optional tm.ElimQueueList elimQueueList = 28;
// optional tm.TextMessageNotice textMessage = 29;
// optional string originatingClient = 30;
// optional bool isLocal = 31;
// optional .DisplaySlide displaySlide = 32;
// optional .AssignedMatchList assignedMatchList = 33;
// optional .MobileDeviceMatchLockList mobileMatchLocks = 34;
// optional .ElimWinsToAdvanceList elimWinsToAdvanceList = 35;
// optional tm.DisplaySlide displaySlide = 32;
// optional tm.AssignedMatchList assignedMatchList = 33;
// optional tm.MobileDeviceMatchLockList mobileMatchLocks = 34;
// optional tm.ElimWinsToAdvanceList elimWinsToAdvanceList = 35;
// optional string temporaryCode = 36;
// optional .MatchScoreList matchScoreLog = 37;
// optional .PublishStatus publishStatus = 38;
// optional .MatchInfo matchInfo = 39;
// optional .AwardList awardList = 40;
// optional tm.MatchScoreList matchScoreLog = 37;
// optional tm.PublishStatus publishStatus = 38;
// optional tm.MatchInfo matchInfo = 39;
// optional tm.AwardList awardList = 40;
// optional string eventName = 41;
// optional .FieldControlStatus fieldControlStatus = 42;
// optional tm.FieldControlStatus fieldControlStatus = 42;
// }
use prost::Message;
use std::io::Cursor;
//
// MQTT Topics:
// - division/{division_id}
// - division/{division_id}/ranking
// - arena/{arena_id}/score
// - arena/{arena_id}/state
// - arena/{arena_id}
// - game/{division_id}/{game_id}/score
// - team/{team_string}
pub mod tm_proto {
include!(concat!(env!("OUT_DIR"), "/tm.rs"));
@ -74,9 +83,133 @@ pub fn deserialize_notice(buf: &[u8]) -> Result<tm_proto::Notice, prost::DecodeE
tm_proto::Notice::decode(&mut Cursor::new(buf))
}
#[derive(Serialize, Deserialize, Debug)]
struct DivisionInfo {
arena: String,
game_id: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct DivisionRankingInfo {
rankings: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug)]
enum GameSide {
Red,
Blue,
}
#[derive(Serialize, Deserialize, Debug)]
enum ElevationTier {
A = 0,
B = 1,
C = 2,
D = 3,
E = 4,
F = 5,
G = 6,
H = 7,
I = 8,
J = 9,
}
#[derive(Serialize, Deserialize, Debug)]
struct AllianceScore {
team_goal: usize,
team_zone: usize,
green_goal: usize,
green_zone: usize,
elevation_tiers: [Option<ElevationTier>; 2],
}
#[derive(Serialize, Deserialize, Debug)]
struct GameScore {
autonomous_winner: Option<GameSide>,
red_score: AllianceScore,
red_total: usize,
blue_score: AllianceScore,
blue_total: usize,
}
#[derive(Serialize, Deserialize, Debug)]
enum GameState {
Scheduled,
Timeout,
Driver,
Driverdone,
Autonomous,
AutonomousDone,
Abandoned,
}
#[derive(Serialize, Deserialize, Debug)]
struct ArenaStateInfo {
state: Option<GameState>,
start_s: usize,
start_ns: usize,
}
#[derive(Serialize, Deserialize, Debug)]
enum Round {
None = 0,
Practice = 1,
Qualification = 2,
QuarterFinals = 3,
SemiFinals = 4,
Finals = 5,
RoundOf16 = 6,
RoundOf32 = 7,
RoundOf64 = 8,
RoundOf128 = 9,
TopN = 15,
RoundRobin = 16,
PreEliminations = 20,
Eliminations = 21,
}
#[derive(Serialize, Deserialize, Debug)]
struct MatchTuple {
division: String,
round: Round,
instance: usize,
match_num: usize,
session: usize,
}
#[derive(Serialize, Deserialize, Debug)]
struct ArenaInfo {
red_teams: [String; 2],
blue_teams: [String; 2],
match_tuple: MatchTuple,
}
fn main() {
let score = GameScore{
autonomous_winner: None,
red_score: AllianceScore{
team_goal: 0,
team_zone: 0,
green_goal: 0,
green_zone: 0,
elevation_tiers: [None, None],
},
blue_score: AllianceScore{
team_goal: 0,
team_zone: 0,
green_goal: 0,
green_zone: 0,
elevation_tiers: [None, None],
},
red_total: 0,
blue_total: 0,
};
let serialized = serde_json::to_string(&score).unwrap();
println!("Serialized = {}", serialized);
// Set client options
let mut mqttoptions = MqttOptions::new("rumqttc", "localhost", 1883);
let mut mqttoptions = MqttOptions::new("vex-bridge", "localhost", 1883);
mqttoptions.set_keep_alive(Duration::from_secs(5));
// Create a new client(10 is bounded channel capacity?)