Skip to content

Commit

Permalink
#20 Compile
Browse files Browse the repository at this point in the history
  • Loading branch information
Peyton-McKee committed Jan 11, 2024
1 parent 47b832b commit 13decd2
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 40 deletions.
69 changes: 57 additions & 12 deletions oxy/RustSynth.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,79 @@
from structs.CANField import CANField
from structs.CANMsg import CANMsg
from structs.Messages import Messages
from structs.Result import Result

class RustSynth:
'''
A class to synthesize Rust from a given CANMsg spec.
'''

imports: str = "use super::data::{Data,FormatData as fd, ProcessData as pd}; \n"
return_type: str = "Vec::<Data>"
inst_hashmap: str = f" let mut result = {return_type}::new();"
closing: str = " result\n}"
decode_data_import: str = "use super::data::{Data,FormatData as fd, ProcessData as pd}; \n"

decode_return_type: str = "Vec::<Data>"
decode_return_value: str = f" let mut result = {decode_return_type}::new();"
decode_closing: str = " result\n}"

decode_mock: str = """
pub fn decode_mock(_data: &[u8]) -> Vec::<Data> {
let mut result = Vec::<Data>::new();
result.push(Data::new(0.0, "Mock", ""));
result
}
"""

master_mapping_import: str = "use super::decode_data::*; \nuse super::data::Data; \n"

master_mapping_signature: str = "pub fn get_message_info(id: &u32) -> MessageInfo { \n match id {"

master_mapping_closing: str = " _ => MessageInfo::new(decode_mock), \n }\n}"

message_info = """
pub struct MessageInfo {
pub decoder: fn(data: &[u8]) -> Vec<Data>,
}
impl MessageInfo {
pub fn new(decoder: fn(data: &[u8]) -> Vec<Data>) -> Self {
Self {
decoder
}
}
}
"""

def parse_messages(self, msgs: Messages) -> Result:
result = Result("", "")
result.decode_data += self.decode_data_import
result.decode_data += self.decode_mock

result.master_mapping += self.master_mapping_import
result.master_mapping += self.message_info
result.master_mapping += self.master_mapping_signature

def parse_messages(self, msgs: Messages) -> str:
str = ""
str += self.imports
for msg in msgs.msgs:
str += self.synthesize(msg) + "\n"
return str
result.decode_data += self.synthesize(msg) + "\n"
result.master_mapping += self.map_msg_to_decoder(msg)

result.master_mapping += self.master_mapping_closing
return result

def map_msg_to_decoder(self, msg: CANMsg) -> str:
return f" {msg.id} => MessageInfo::new({self.function_name(msg.desc)}),\n"

def synthesize(self, msg: CANMsg) -> str:
signature: str = self.signature(msg.desc)
generated_lines: list[str] = []
for field in msg.fields:
generated_lines.append(self.finalize_line(field.name, field.unit, f"{self.format_data(field, self.parse_decoders(field))}"))
total_list: list[str] = [signature, self.inst_hashmap] + generated_lines + [self.closing]
total_list: list[str] = [signature, self.decode_return_value] + generated_lines + [self.decode_closing]
return "\n".join(total_list)

def function_name(self, desc: str) -> str:
return f"decode_{desc.replace(' ', '_').lower()}"

def signature(self, to_decode: str) -> str:
return f"pub fn decode_{to_decode.replace(' ', '_').lower()}(data: &[u8]) -> {self.return_type} {{"
def signature(self, desc: str) -> str:
return f"pub fn {self.function_name(desc)}(data: &[u8]) -> {self.decode_return_type} {{"

def finalize_line(self, topic: str, unit: str, val: str) -> str:
return f" result.push(Data::new({val}, \"{topic}\", \"{unit}\"));"
Expand Down
8 changes: 8 additions & 0 deletions oxy/structs/Result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

class Result:
decode_data: str
master_mapping: str

def __init__(self, decode_data: str, master_mapping: str):
self.decode_data = decode_data
self.master_mapping = master_mapping
11 changes: 8 additions & 3 deletions oxy/typedpoc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from YAMLParser import YAMLParser
from RustSynth import RustSynth

f = open("../src/decode_data.rs", "w")
decode_data = open("../src/decode_data.rs", "w")
master_mapping = open("../src/master_mapping.rs", "w")

f.write(RustSynth().parse_messages(YAMLParser().parse(open("mapping.yaml", "r"))))
result = RustSynth().parse_messages(YAMLParser().parse(open("mapping.yaml", "r")))

f.close()
decode_data.write(result.decode_data)
decode_data.close()

master_mapping.write(result.master_mapping)
master_mapping.close()
20 changes: 10 additions & 10 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,27 +126,27 @@ impl FormatData {
-value
}

pub fn frequency(value: i64) -> f32 {
value as f32 / 10.0
pub fn frequency(value: f32) -> f32 {
value / 10.0
}

pub fn power(value: i32) -> f32 {
value as f32 / 10.0
pub fn power(value: f32) -> f32 {
value / 10.0
}

pub fn timer(value: i32) -> f32 {
value as f32 * 0.003
pub fn timer(value: f32) -> f32 {
value * 0.003
}

pub fn flux(value: i64) -> f32 {
value as f32 / 1000.0
pub fn flux(value: f32) -> f32 {
value / 1000.0
}

pub fn cell_voltage(value: f32) -> f32 {
value as f32 / 10000.0
value / 10000.0
}

pub fn acceleration(value: f32) -> f32 {
value as f32 * 0.0029
value * 0.0029
}
}
6 changes: 6 additions & 0 deletions src/decode_data.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use super::data::{Data,FormatData as fd, ProcessData as pd};

pub fn decode_mock(_data: &[u8]) -> Vec::<Data> {
let mut result = Vec::<Data>::new();
result.push(Data::new(0.0, "Mock", ""));
result
}
pub fn decode_accumulator_status(data: &[u8]) -> Vec::<Data> {
let mut result = Vec::<Data>::new();
result.push(Data::new(fd::high_voltage(pd::big_endian(&data[0..2] as &[u8], 8) as f32), "BMS/Pack/Voltage", "V"));
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod data;
pub mod decode_data;
pub mod message;
pub mod mqtt;
pub mod master_mapping;
10 changes: 2 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use std::{
process::{self, Command},
};

use calypso::{client::Client, message::Message, mqtt::MqttClient, socket::IPCConnection};
use chrono::{DateTime, Utc};
use calypso::{client::Client, message::Message, mqtt::MqttClient};
use socketcan::CANSocket;

fn configure_can() {
Expand Down Expand Up @@ -64,9 +63,8 @@ fn read_can(mut publisher: Box<dyn Client + Send>) {
continue;
}
};
let date: DateTime<Utc> = Utc::now();
let data = msg.data();
let message = Message::new(date, msg.id(), data.to_vec());
let message = Message::new(msg.id(), data.to_vec());
let decoded_data = message.decode();
for (_i, data) in decoded_data.iter().enumerate() {
publisher.publish(data)
Expand Down Expand Up @@ -96,10 +94,6 @@ fn parse_args() -> (String, Box<dyn Client + 'static + Send>) {
String::from(path),
Box::new(MqttClient::new()) as Box<dyn Client + 'static + Send>,
),
"ipc" => (
String::from(path),
Box::new(IPCConnection::new()) as Box<dyn Client + 'static + Send>,
),
_ => {
println!("Please provide a valid client type");
process::exit(1);
Expand Down
27 changes: 27 additions & 0 deletions src/master_mapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::decode_data::*;
use super::data::Data;

pub struct MessageInfo {
pub decoder: fn(data: &[u8]) -> Vec<Data>,
}

impl MessageInfo {
pub fn new(decoder: fn(data: &[u8]) -> Vec<Data>) -> Self {
Self {
decoder
}
}
}
pub fn get_message_info(id: &u32) -> MessageInfo {
match id { 0x80 => MessageInfo::new(decode_accumulator_status),
0x81 => MessageInfo::new(decode_bms_status),
0x82 => MessageInfo::new(decode_shutdown_control),
0x83 => MessageInfo::new(decode_cell_data),
0x84 => MessageInfo::new(decode_cell_temperatures),
0x85 => MessageInfo::new(decode_segment_temperatures),
0x500 => MessageInfo::new(decode_nerduino_acceleromter),
0x501 => MessageInfo::new(decode_mpu_status),
0x680 => MessageInfo::new(decode_wheel_state),
_ => MessageInfo::new(decode_mock),
}
}
11 changes: 4 additions & 7 deletions src/message.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use chrono::{DateTime, Utc};

use super::data::Data;

use super::master_mapping::get_message_info;
/**
* Wrapper class for an individual message.
*/
pub struct Message {
timestamp: DateTime<Utc>,
id: u32,
data: Vec<u8>,
}
Expand All @@ -18,9 +16,8 @@ impl Message {
/**
* Creates a new message with the given timestamp, id, and data.
*/
pub fn new(timestamp: DateTime<Utc>, id: u32, data: Vec<u8>) -> Self {
pub fn new(id: u32, data: Vec<u8>) -> Self {
Self {
timestamp,
id,
data,
}
Expand All @@ -30,7 +27,7 @@ impl Message {
* Decodes the message and returns a vector of Data objects.
*/
pub fn decode(&self) -> Vec<Data> {
self.decode_message(self.timestamp, &self.id, &self.data)
Message::decode_message(&self.id, &self.data)
}

/**
Expand All @@ -41,7 +38,7 @@ impl Message {
* param data: The data of the message.
* return: A vector of Data objects.
*/
fn decode_message(&self, timestamp: DateTime<Utc>, id: &u32, data: &[u8]) -> Vec<Data> {
fn decode_message(id: &u32, data: &[u8]) -> Vec<Data> {
let decoder = get_message_info(id).decoder;
let mut decoded_data: Vec<Data> = Vec::new();
let result = decoder(data);
Expand Down

0 comments on commit 13decd2

Please sign in to comment.