Skip to content

Commit

Permalink
Merge pull request #77 from us-irs/update-spacepackets
Browse files Browse the repository at this point in the history
Update spacepackets
  • Loading branch information
robamu committed Apr 23, 2024
2 parents bcbb918 + a750a92 commit 719d90f
Show file tree
Hide file tree
Showing 21 changed files with 325 additions and 292 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

# [unreleased]

# [v0.24.0] 2024-04-23

## Removed

- Global configuration module for TC and TM APID was removed.

## Changed

- ECSS PUS telemetry time handling is now more generic and low level: Constructors expect
a simple `bytes` type while unpackers/readers expect the length of the timestamp. A helper
constant for the offset of the timestamp is exposed which can help with determining the
length of the timestamp.
- `CdsShortTimestamp.from_now` renamed to `now`.
- The ECSS TMTC APID field must not be set explicitely in the class constructors.

## Added

- `spacepackets.ecss.tm.PUS_TM_TIMESTAMP_OFFSET` constant which can be used as a look-ahead to
determine the timestamp length from a raw PUS TM packet.
- `spacepackets.ccsds.CCSDS_HEADER_LEN` constant.

# [v0.23.1] 2024-04-22

## Added
Expand Down
18 changes: 6 additions & 12 deletions docs/api/ecss.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ ECSS Package
:undoc-members:
:show-inheritance:

.. automodule:: spacepackets.ecss.defs
:members:
:undoc-members:
:show-inheritance:

ECSS PUS Telecommand Module
--------------------------------
----------------------------

:ref:`api/ecss_tc:ECSS Telecommand Module`

Expand All @@ -16,17 +21,6 @@ ECSS PUS Telemetry Module

:ref:`api/ecss_tm:ECSS Telemetry Module`

ECSS Configuration Submodule
----------------------------------

This module can be used to configure common default values so these don't have to be specified
each time anymore when creating ECSS packets

.. automodule:: spacepackets.ecss.conf
:members:
:undoc-members:
:show-inheritance:

ECSS Fields Submodule
----------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ PUS ping telemetry reply without a timestamp.
cmd_as_bytes = ping_cmd.pack()
print(f"Ping telecommand [17,1] (hex): [{cmd_as_bytes.hex(sep=',')}]")

ping_reply = PusTm(service=17, subservice=2, apid=0x01, time_provider=None)
ping_reply = PusTm(service=17, subservice=2, apid=0x01, timestamp=bytes())
tm_as_bytes = ping_reply.pack()
print(f"Ping reply [17,2] (hex): [{tm_as_bytes.hex(sep=',')}]")

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "spacepackets"
description = "Various CCSDS and ECSS packet implementations"
readme = "README.md"
version = "0.23.1"
version = "0.24.0"
requires-python = ">=3.8"
license = {text = "Apache-2.0"}
authors = [
Expand Down
21 changes: 12 additions & 9 deletions spacepackets/ccsds/spacepacket.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@

from spacepackets.exceptions import BytesTooShortError

SPACE_PACKET_HEADER_SIZE: Final = 6
SEQ_FLAG_MASK = 0xC000
APID_MASK = 0x7FF
PACKET_ID_MASK = 0x1FFF
CCSDS_HEADER_LEN: Final[int] = 6
SPACE_PACKET_HEADER_SIZE: Final[int] = CCSDS_HEADER_LEN
SEQ_FLAG_MASK: Final[int] = 0xC000
APID_MASK: Final[int] = 0x7FF
PACKET_ID_MASK: Final[int] = 0x1FFF
MAX_SEQ_COUNT: Final[int] = pow(2, 14) - 1
MAX_APID: Final[int] = pow(2, 11) - 1


class PacketType(enum.IntEnum):
Expand All @@ -34,7 +37,7 @@ class PacketSeqCtrl:
"""

def __init__(self, seq_flags: SequenceFlags, seq_count: int):
if seq_count > pow(2, 14) - 1 or seq_count < 0:
if seq_count > MAX_SEQ_COUNT or seq_count < 0:
raise ValueError(
f"Sequence count larger than allowed {pow(2, 14) - 1} or negative"
)
Expand Down Expand Up @@ -205,7 +208,7 @@ def __init__(
:param data_len: Contains a length count C that equals one fewer than the length of the
packet data field. Should not be larger than 65535 bytes
:param ccsds_version:
:param sec_header_flag: Secondary header flag, 1 or True by default
:param sec_header_flag: Secondary header flag, or False by default.
:param seq_flags:
:raises ValueError: On invalid parameters
"""
Expand Down Expand Up @@ -299,7 +302,7 @@ def seq_flags(self, value):

@property
def header_len(self) -> int:
return SPACE_PACKET_HEADER_SIZE
return CCSDS_HEADER_LEN

@apid.setter
def apid(self, apid):
Expand All @@ -311,7 +314,7 @@ def packet_len(self) -> int:
:return: Size of the TM packet based on the space packet header data length field.
"""
return SPACE_PACKET_HEADER_SIZE + self.data_len + 1
return CCSDS_HEADER_LEN + self.data_len + 1

@classmethod
def unpack(cls, data: bytes) -> SpacePacketHeader:
Expand Down Expand Up @@ -500,7 +503,7 @@ def parse_space_packets(
# Packet ID detected
while True:
# Can't even parse CCSDS header. Wait for more data to arrive.
if current_idx + SPACE_PACKET_HEADER_SIZE >= len(concatenated_packets):
if current_idx + CCSDS_HEADER_LEN >= len(concatenated_packets):
break
current_packet_id = (
struct.unpack("!H", concatenated_packets[current_idx : current_idx + 2])[0]
Expand Down
55 changes: 42 additions & 13 deletions spacepackets/ccsds/time/cds.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ def _calculate_unix_seconds(self):

def _calculate_date_time(self):
if self._unix_seconds < 0:
self._date_time = datetime.datetime(
self._datetime = datetime.datetime(
1970, 1, 1, tzinfo=datetime.timezone.utc
) + datetime.timedelta(seconds=self._unix_seconds)
else:
self._date_time = datetime.datetime.fromtimestamp(
self._datetime = datetime.datetime.fromtimestamp(
self._unix_seconds, tz=datetime.timezone.utc
)

Expand All @@ -108,7 +108,7 @@ def ccsds_days(self) -> int:
def ms_of_day(self) -> int:
return self._ms_of_day

def pack(self) -> bytearray:
def pack(self) -> bytes:
cds_packet = bytearray()
cds_packet.extend(self.__p_field)
cds_packet.extend(struct.pack("!H", self._ccsds_days))
Expand Down Expand Up @@ -169,12 +169,14 @@ def __repr__(self):
)

def __str__(self):
return f"Date {self._date_time!r} with representation {self!r}"
return f"Date {self._datetime!r} with representation {self!r}"

def __eq__(self, other: CdsShortTimestamp):
return (self.ccsds_days == other.ccsds_days) and (
self.ms_of_day == other.ms_of_day
)
def __eq__(self, other: object):
if isinstance(other, CdsShortTimestamp):
return (self.ccsds_days == other.ccsds_days) and (
self.ms_of_day == other.ms_of_day
)
return False

def __add__(self, timedelta: datetime.timedelta):
"""Allows adding timedelta to the CDS timestamp provider.
Expand All @@ -200,23 +202,33 @@ def __add__(self, timedelta: datetime.timedelta):
return self

@classmethod
def from_now(cls) -> CdsShortTimestamp:
def now(cls) -> CdsShortTimestamp:
"""Returns a seven byte CDS short timestamp with the current time."""
return cls.from_date_time(datetime.datetime.now(tz=datetime.timezone.utc))

@classmethod
@deprecation.deprecated(
deprecated_in="0.24.0",
current_version=get_version(),
details="use now instead",
)
def from_now(cls) -> CdsShortTimestamp:
"""Returns a seven byte CDS short timestamp with the current time."""
return cls.now()

@classmethod
@deprecation.deprecated(
deprecated_in="0.14.0rc1",
current_version=get_version(),
details="use from_now instead",
)
def from_current_time(cls) -> CdsShortTimestamp:
return cls.from_now()
return cls.now()

@classmethod
def from_date_time(cls, dt: datetime.datetime) -> CdsShortTimestamp:
def from_datetime(cls, dt: datetime.datetime) -> CdsShortTimestamp:
instance = cls.empty(False)
instance._date_time = dt
instance._datetime = dt
instance._unix_seconds = dt.timestamp()
full_unix_secs = int(math.floor(instance._unix_seconds))
subsec_millis = int((instance._unix_seconds - full_unix_secs) * 1000)
Expand All @@ -226,6 +238,15 @@ def from_date_time(cls, dt: datetime.datetime) -> CdsShortTimestamp:
instance._ccsds_days = convert_unix_days_to_ccsds_days(unix_days)
return instance

@classmethod
@deprecation.deprecated(
deprecated_in="0.24.0",
current_version=get_version(),
details="use from_datetime instead",
)
def from_date_time(cls, dt: datetime.datetime) -> CdsShortTimestamp:
return cls.from_datetime(dt)

@staticmethod
def ms_of_today(seconds_since_epoch: Optional[float] = None):
if seconds_since_epoch is None:
Expand All @@ -238,5 +259,13 @@ def ms_of_today(seconds_since_epoch: Optional[float] = None):
def as_unix_seconds(self) -> float:
return self._unix_seconds

def as_datetime(self) -> datetime.datetime:
return self._datetime

@deprecation.deprecated(
deprecated_in="0.24.0",
current_version=get_version(),
details="use as_datetime instead",
)
def as_date_time(self) -> datetime.datetime:
return self._date_time
return self.as_datetime()
2 changes: 1 addition & 1 deletion spacepackets/ccsds/time/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def len(self) -> int:
return self.len_packed

@abstractmethod
def pack(self) -> bytearray:
def pack(self) -> bytes:
pass

@abstractmethod
Expand Down
4 changes: 2 additions & 2 deletions spacepackets/ecss/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from crcmod.predefined import mkPredefinedCrcFun

from .tc import PusVersion, PusTelecommand, PusTc, PusTcDataFieldHeader
from .tc import PusTc, PusTelecommand, PusTcDataFieldHeader
from .tm import PusTm, PusTelemetry, PusTmSecondaryHeader
from .fields import (
PacketFieldEnum,
Expand All @@ -13,7 +13,7 @@
PfcSigned,
PfcUnsigned,
)
from .defs import PusService
from .defs import PusService, PusVersion
from .req_id import RequestId
from .pus_verificator import PusVerificator

Expand Down
46 changes: 0 additions & 46 deletions spacepackets/ecss/conf.py

This file was deleted.

9 changes: 9 additions & 0 deletions spacepackets/ecss/defs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import enum


class PusVersion(enum.IntEnum):
# ESA PSS-07-101. Not supported by this package!
ESA_PUS = 0
# ECSS-E-70-41A
PUS_A = 1
# ECSS-E-ST-70-41C
PUS_C = 2


class PusService(enum.IntEnum):
S1_VERIFICATION = 1
S2_RAW_CMD = 2
Expand Down

0 comments on commit 719d90f

Please sign in to comment.