Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Voltage DataBlock #103

Merged
merged 5 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions modules/telemetry/telemetry_packet.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,9 @@
"coordinates": {
"latitude": { "1": { "9": "latitude" } },
"longitude": { "1": { "9": "longitude" } }
},
"voltage": {
"id": { "1": { "10": "id" } },
"voltage": { "1": { "10": "voltage"} }
}
}
2 changes: 1 addition & 1 deletion modules/telemetry/telemetry_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def parse_radio_block(pkt_version: int, block_header: BlockHeader, hex_block_con
except NotImplementedError:
logger.warning(
f"Block parsing for type {block_header.message_type}, with subtype {block_header.message_subtype} not \
implemented!"
implemented!"
)
return
except v1db.DataBlockException as e:
Expand Down
61 changes: 47 additions & 14 deletions modules/telemetry/v1/data_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class DataBlockSubtype(IntEnum):
ANGULAR_VELOCITY = 0x07
HUMIDITY = 0x08
COORDINATES = 0x09
VOLTAGE = 0x0A

def __str__(self):
match self:
Expand All @@ -53,6 +54,8 @@ def __str__(self):
return "HUMIDITY"
case DataBlockSubtype.COORDINATES:
return "COORDINATES"
case DataBlockSubtype.VOLTAGE:
return "VOLTAGE"


class DataBlock(ABC):
Expand Down Expand Up @@ -105,6 +108,7 @@ def parse(block_subtype: DataBlockSubtype, payload: bytes) -> DataBlock:
DataBlockSubtype.LIN_ACCEL_REL: RelativeLinearAccelerationDB,
DataBlockSubtype.LIN_ACCEL_ABS: AbsoluteLinearAccelerationDB,
DataBlockSubtype.ANGULAR_VELOCITY: AngularVelocityDB,
DataBlockSubtype.VOLTAGE: VoltageDB,
}

subtype = SUBTYPE_CLASSES.get(block_subtype)
Expand Down Expand Up @@ -435,17 +439,46 @@ def __iter__(self):
yield "angular_velocity", {"x": self.x_axis, "y": self.y_axis, "z": self.z_axis, "magnitude": self.magnitude}


# TODO: Remove this function
def parse_data_block(type: DataBlockSubtype, payload: bytes) -> DataBlock:
"""
Parses a bytes payload into the correct data block type.
Args:
type: The type of data block to parse the bytes into.
payload: The bytes payload to parse into a data block.
Returns:
The parse data block.
Raises:
ValueError: Raised if the bytes cannot be parsed into the corresponding type.
"""

return DataBlock.parse(type, payload)
class VoltageDB(DataBlock):
"""Represents a voltage data block"""

def __init__(self, mission_time: int, id: int, voltage: int) -> None:
"""
Constructus a voltage data block.
Args:
mission_time: The mission time the voltage was measured in milliseconds since launch.
id: A numerical id associated with the voltage measurement for identification by the receiver
voltage: The measured voltage in units of millivolts
"""
super().__init__(mission_time)
self.id: int = id
self.voltage: int = voltage

@classmethod
def from_bytes(cls, payload: bytes) -> Self:
"""
Constructs a voltage data block from bytes.
Returns:
A voltage data block.
"""
parts = struct.unpack("<IHh", payload)
return cls(parts[0], parts[1], parts[2])

def __len__(self) -> int:
"""
Get the length of a voltage data block in bytes
Returns:
The length of a voltage data block in bytes not including the block header.
"""
return 8

def __str__(self):
return (
f"""{self.__class__.__name__} -> time: {self.mission_time} ms, id: {self.id}, voltage: {self.voltage} mV"""
)

def __iter__(self):
yield "mission_time", self.mission_time
yield "id", self.id
yield "voltage", self.voltage
30 changes: 29 additions & 1 deletion tests/parsing/test_block_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
__author__ = "Elias Hawa"

import pytest
from modules.telemetry.v1.data_block import PressureDB, TemperatureDB, LinearAccelerationDB, AngularVelocityDB
from modules.telemetry.v1.data_block import (
PressureDB,
TemperatureDB,
LinearAccelerationDB,
AngularVelocityDB,
VoltageDB,
)


@pytest.fixture
Expand Down Expand Up @@ -53,6 +59,19 @@ def angular_velocity_data_content() -> bytes:
return b"\x00\x00\x00\x00\x06\x00\x0b\x00\xfd\xff\x00\x00"


@pytest.fixture
# 9b0d00000200ee0c
# DEBUG:modules.telemetry.telemetry_utils:VoltageDB -> time: 3483 ms, id: 2, voltage: 3310 mV
def voltage_data_content() -> bytes:
"""
Returns a voltage sensor reading with the following attributes
mission time: 3483 ms
id: 2
voltage: 3310 mV
"""
return b"\x9b\x0d\x00\x00\x02\x00\xee\x0c"


def test_pressure_data_block(pressure_data_content: bytes) -> None:
"""Test that the pressure data block is parsed correctly."""
pdb = PressureDB.from_bytes(pressure_data_content)
Expand Down Expand Up @@ -89,3 +108,12 @@ def test_angular_velocity_data_block(angular_velocity_data_content: bytes) -> No
assert ang_vel.y_axis == 1.1
assert ang_vel.z_axis == -0.3
assert ang_vel.magnitude == 1.29


def test_voltage_data_block(voltage_data_content: bytes) -> None:
"""Test that the voltage data block is parsed correctly."""
vdb = VoltageDB.from_bytes(voltage_data_content)

assert vdb.mission_time == 3483
assert vdb.id == 2
assert vdb.voltage == 3310
Loading