use crate::adc::{AdcDataRaw, AdcDataSimple, SampleRate};
use crate::adcqueue::{AdcQueueData, AdcQueueRawData, AdcQueueSample, AdcQueueSampleRaw, GraphSampleRate};
use crate::message::Packet;
use crate::packet::{CtrlHeader, LogicalPacket, RawPacket};
use crate::pd::{PdEvent, PdEventStream, PdStatus};
use bytes::Bytes;
use pyo3::prelude::*;
use pyo3::types::PyBytes;
#[pyfunction]
pub fn parse_raw_adc_data(data: &[u8]) -> PyResult<AdcDataSimple> {
use zerocopy::FromBytes;
let adc_raw = AdcDataRaw::ref_from_bytes(data).map_err(|_| {
PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
"Invalid ADC data size: expected {}, got {}",
std::mem::size_of::<AdcDataRaw>(),
data.len()
))
})?;
let adc_simple = AdcDataSimple::from(*adc_raw);
Ok(adc_simple)
}
#[pyfunction]
pub fn parse_packet(data: &[u8]) -> PyResult<Packet> {
let bytes = Bytes::from(data.to_vec());
let raw_packet =
RawPacket::try_from(bytes).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(format!("{}", e)))?;
let packet =
Packet::try_from(raw_packet).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(format!("{}", e)))?;
Ok(packet)
}
#[pyfunction]
pub fn parse_packet_with_graph_rate(data: &[u8], rate_index: u16) -> PyResult<Packet> {
let rate = GraphSampleRate::try_from(rate_index).map_err(|_| {
pyo3::exceptions::PyValueError::new_err(format!("Invalid graph sample rate index: {rate_index}"))
})?;
let raw_packet = RawPacket::try_from(Bytes::from(data.to_vec()))
.map_err(|error| pyo3::exceptions::PyValueError::new_err(error.to_string()))?;
Packet::from_raw_with_graph_rate(raw_packet, rate)
.map_err(|error| pyo3::exceptions::PyValueError::new_err(error.to_string()))
}
#[pyfunction]
pub fn parse_raw_packet(data: &[u8]) -> PyResult<RawPacket> {
let bytes = Bytes::from(data.to_vec());
let raw_packet =
RawPacket::try_from(bytes).map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(format!("{}", e)))?;
Ok(raw_packet)
}
#[pyfunction]
pub fn get_sample_rates() -> Vec<SampleRate> {
vec![
SampleRate::Sps2,
SampleRate::Sps10,
SampleRate::Sps50,
SampleRate::Sps1000,
SampleRate::Sps10000,
]
}
#[pyfunction]
pub fn create_packet<'py>(py: Python<'py>, packet_type: u8, transaction_id: u8, data: u16) -> Bound<'py, PyBytes> {
let header = CtrlHeader::new()
.with_packet_type(packet_type)
.with_reserved_flag(false)
.with_id(transaction_id)
.with_attribute(data);
PyBytes::new(py, &header.into_bytes())
}
#[pymodule]
fn km003c_lib(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
m.add_class::<AdcDataSimple>()?;
m.add_class::<SampleRate>()?;
m.add_class::<AdcQueueSample>()?;
m.add_class::<AdcQueueData>()?;
m.add_class::<AdcQueueSampleRaw>()?;
m.add_class::<AdcQueueRawData>()?;
m.add_class::<PdStatus>()?;
m.add_class::<PdEvent>()?;
m.add_class::<PdEventStream>()?;
m.add_class::<LogicalPacket>()?;
m.add_function(wrap_pyfunction!(parse_raw_adc_data, m)?)?;
m.add_function(wrap_pyfunction!(parse_packet, m)?)?;
m.add_function(wrap_pyfunction!(parse_packet_with_graph_rate, m)?)?;
m.add_function(wrap_pyfunction!(parse_raw_packet, m)?)?;
m.add_function(wrap_pyfunction!(get_sample_rates, m)?)?;
m.add_function(wrap_pyfunction!(create_packet, m)?)?;
m.add("VID", crate::device::VID)?;
m.add("PID", crate::device::PID)?;
m.add("CMD_SYNC", u8::from(crate::packet::PacketType::Sync))?;
m.add("CMD_CONNECT", u8::from(crate::packet::PacketType::Connect))?;
m.add("CMD_DISCONNECT", u8::from(crate::packet::PacketType::Disconnect))?;
m.add("CMD_ACCEPT", u8::from(crate::packet::PacketType::Accept))?;
m.add("CMD_REJECT", u8::from(crate::packet::PacketType::Rejected))?;
m.add("CMD_GET_DATA", u8::from(crate::packet::PacketType::GetData))?;
m.add("CMD_START_GRAPH", u8::from(crate::packet::PacketType::StartGraph))?;
m.add("CMD_STOP_GRAPH", u8::from(crate::packet::PacketType::StopGraph))?;
m.add("ATT_ADC", u16::from(crate::packet::Attribute::Adc))?;
m.add("ATT_ADC_QUEUE", u16::from(crate::packet::Attribute::AdcQueue))?;
m.add("ATT_ADC_QUEUE_10K", u16::from(crate::packet::Attribute::AdcQueue10k))?;
m.add("ATT_SETTINGS", u16::from(crate::packet::Attribute::Settings))?;
m.add("ATT_PD_PACKET", u16::from(crate::packet::Attribute::PdPacket))?;
m.add("RATE_2_SPS", crate::adcqueue::GraphSampleRate::Sps2 as u16)?;
m.add("RATE_10_SPS", crate::adcqueue::GraphSampleRate::Sps10 as u16)?;
m.add("RATE_50_SPS", crate::adcqueue::GraphSampleRate::Sps50 as u16)?;
m.add("RATE_1000_SPS", crate::adcqueue::GraphSampleRate::Sps1000 as u16)?;
Ok(())
}