"""Archive Event module for the ArchiveEvent class."""
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
from epicsarchiver.common.date_util import (
NANO_PER_SECOND,
ResponseTimestamp,
year_start_epoch_seconds,
)
if TYPE_CHECKING:
from datetime import datetime
@dataclass
[docs]
class FieldValue:
"""Basic representation of a changed field value from an archive event.
Returns:
FieldValue: Pair of name and value
"""
@dataclass
[docs]
ArchiveEventsData = tuple[dict[int, ArchiveEventsMeta], list["ArchiveEvent"]]
@dataclass
[docs]
class ArchiveEvent:
"""One Event, retrieved from the AA, representing a change in value of a PV."""
[docs]
val: int | float | str | list[str] | list[int] | list[float] | bytes
[docs]
field_values: list[FieldValue] | None
@property
[docs]
def timestamp_ns(self) -> int:
"""Nanoseconds since Unix epoch.
Returns:
int: nanoseconds since Unix epoch, compatible with pl.Datetime("ns", "UTC")
"""
return (
year_start_epoch_seconds(self.year) + self.secondsintoyear
) * NANO_PER_SECOND + self.nanos
@property
[docs]
def timestamp(self) -> datetime:
"""UTC datetime (microsecond precision), derived from timestamp_ns.
Returns:
datetime.datetime: UTC datetime
"""
return ResponseTimestamp(self.timestamp_ns).datetime
@property
[docs]
def field_values_dict(self) -> dict[str, str]:
"""Provides a dict of field values.
Returns:
dict[str, str]: dict of field names and values
"""
if not self.field_values:
return {}
return {
field.name: field.value or "" for field in self.field_values if field.name
}