# generated by datamodel-codegen:
#   filename:  sensor_state.schema.json
#   timestamp: 2023-03-07T10:21:48+00:00

from __future__ import annotations

from datetime import datetime
from enum import Enum
from ipaddress import IPv4Address
from typing import Dict, List, Optional

from pydantic import (
    AnyUrl,
    BaseModel,
    Extra,
    Field,
    PositiveFloat,
    PositiveInt,
    confloat,
    conint,
    constr,
)


class SamplingRate(Enum):
    integer_100 = 100
    integer_200 = 200


class Gain(Enum):
    integer_1 = 1
    integer_2 = 2
    integer_4 = 4


class Filter(Enum):
    remez = "remez"
    average = "average"


class AD7779Config(BaseModel):
    sampling_rate: Optional[SamplingRate] = Field(100, title="Sampling Rate")
    gain: Optional[Gain] = Field(1, title="Gain")
    filter: Optional[Filter] = Field("remez", title="Filter")


class AD7779Environment(BaseModel):
    class Config:
        extra = Extra.forbid

    spi_speed: Optional[int] = Field(3600000, title="Spi Speed")
    spi_port: Optional[int] = Field(0, title="Spi Port")
    spi_chip_select: Optional[int] = Field(0, title="Spi Chip Select")
    line_drdy: Optional[int] = Field(25, title="Line Drdy")
    line_reset: Optional[int] = Field(23, title="Line Reset")
    line_sync_in: Optional[int] = Field(24, title="Line Sync In")
    clock_hz: Optional[int] = Field(4096000, title="Clock Hz")


class AD7779Statistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("sensor", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({"sensor": "ad7779"}, title="Tags")
    active: Optional[bool] = Field(False, title="Active")
    nsamples: Optional[int] = Field(0, title="Nsamples")
    crc_errors: Optional[int] = Field(0, title="Crc Errors")
    gain: Optional[int] = Field(1, title="Gain")
    sampling_rate: Optional[int] = Field(0, title="Sampling Rate")
    delay: Optional[float] = Field(0.0, title="Delay")


class AD7779State(BaseModel):
    config: Optional[AD7779Config] = Field(
        default_factory=lambda: AD7779Config.parse_obj(
            {"sampling_rate": 100, "gain": 1, "filter": "remez"}
        ),
        title="Config",
    )
    environment: Optional[AD7779Environment] = Field(
        default_factory=lambda: AD7779Environment.parse_obj(
            {
                "spi_speed": 3600000,
                "spi_port": 0,
                "spi_chip_select": 0,
                "line_drdy": 25,
                "line_reset": 23,
                "line_sync_in": 24,
                "clock_hz": 4096000,
            }
        ),
        title="Environment",
    )
    stats: Optional[AD7779Statistics] = Field(
        default_factory=lambda: AD7779Statistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.407894+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "sensor",
                "tags": {"sensor": "ad7779", "uid": "SUB54I40", "platform": "unknown"},
                "active": False,
                "nsamples": 0,
                "crc_errors": 0,
                "gain": 1,
                "sampling_rate": 0,
                "delay": 0.0,
            }
        ),
        title="Stats",
    )
    type: Optional[str] = Field("", title="Type")


class Range(Enum):
    integer_2 = 2
    integer_4 = 4
    integer_8 = 8


class Filter1(Enum):
    remez = "remez"
    none = "none"


class ADXL355Config(BaseModel):
    sampling_rate: Optional[SamplingRate] = Field(100, title="Sampling Rate")
    range: Optional[Range] = Field(2, title="Range")
    filter: Optional[Filter1] = Field("remez", title="Filter")


class ADXL355Statistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("sensor", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({"sensor": "adxl355"}, title="Tags")
    active: Optional[bool] = Field(False, title="Active")
    temperature: Optional[float] = Field(0.0, title="Temperature")
    nsamples: Optional[int] = Field(0, title="Nsamples")
    crc_errors: Optional[int] = Field(0, title="Crc Errors")
    range: Optional[int] = Field(0, title="Range")
    sampling_rate: Optional[int] = Field(0, title="Sampling Rate")
    delay: Optional[float] = Field(0.0, title="Delay")


class ADXL355Environment(BaseModel):
    class Config:
        extra = Extra.forbid

    spi_speed: Optional[int] = Field(3600000, title="Spi Speed")
    port: Optional[int] = Field(0, title="Port")
    chip_select: Optional[int] = Field(0, title="Chip Select")
    drdy_int: Optional[int] = Field(22, title="Drdy Int")


class ADXL355State(BaseModel):
    config: Optional[ADXL355Config] = Field(
        default_factory=lambda: ADXL355Config.parse_obj(
            {"sampling_rate": 100, "range": 2, "filter": "remez"}
        ),
        title="Config",
    )
    stats: Optional[ADXL355Statistics] = Field(
        default_factory=lambda: ADXL355Statistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.410687+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "sensor",
                "tags": {"sensor": "adxl355", "uid": "SUB54I40", "platform": "unknown"},
                "active": False,
                "temperature": 0.0,
                "nsamples": 0,
                "crc_errors": 0,
                "range": 0,
                "sampling_rate": 0,
                "delay": 0.0,
            }
        ),
        title="Stats",
    )
    environment: Optional[ADXL355Environment] = Field(
        default_factory=lambda: ADXL355Environment.parse_obj(
            {"spi_speed": 3600000, "port": 0, "chip_select": 0, "drdy_int": 22}
        ),
        title="Environment",
    )
    type: Optional[str] = Field("adxl355", title="Type")


class SamplingRate2(Enum):
    integer_100 = 100
    integer_200 = 200
    integer_400 = 400


class BMA456Config(BaseModel):
    sampling_rate: Optional[SamplingRate2] = Field(100, title="Sampling Rate")
    range: Optional[Range] = Field(2, title="Range")


class BMA456Statistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("sensor", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({"sensor": "bma456"}, title="Tags")
    active: Optional[bool] = Field(False, title="Active")
    temperature: Optional[float] = Field(0.0, title="Temperature")
    nsamples: Optional[int] = Field(0, title="Nsamples")
    crc_errors: Optional[int] = Field(0, title="Crc Errors")
    range: Optional[int] = Field(0, title="Range")
    sampling_rate: Optional[int] = Field(0, title="Sampling Rate")
    delay: Optional[float] = Field(0.0, title="Delay")
    ndevices: Optional[int] = Field(0, title="Ndevices")


class BMA456State(BaseModel):
    config: Optional[BMA456Config] = Field(
        default_factory=lambda: BMA456Config.parse_obj(
            {"sampling_rate": 100, "range": 2}
        ),
        title="Config",
    )
    stats: Optional[BMA456Statistics] = Field(
        default_factory=lambda: BMA456Statistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.413111+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "sensor",
                "tags": {"sensor": "bma456", "uid": "SUB54I40", "platform": "unknown"},
                "active": False,
                "temperature": 0.0,
                "nsamples": 0,
                "crc_errors": 0,
                "range": 0,
                "sampling_rate": 0,
                "delay": 0.0,
                "ndevices": 0,
            }
        ),
        title="Stats",
    )
    type: Optional[str] = Field("", title="Type")
    soft_interrupt: Optional[bool] = Field(False, title="Soft Interrupt")


class DataProductDispatcherConfig(BaseModel):
    size_max_bytes: Optional[conint(ge=1048576)] = Field(
        10485760, title="Size Max Bytes"
    )
    enable_gzip: Optional[bool] = Field(True, title="Enable Gzip")


class DataProductDispatcherStats(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("dataproduct_dispatcher", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    database_size_bytes: Optional[int] = Field(0, title="Database Size Bytes")
    dataproducts_stored: Optional[int] = Field(0, title="Dataproducts Stored")


class DataProductStats(BaseModel):
    name: str = Field(..., title="Name")
    nitems: int = Field(..., title="Nitems")
    size_bytes: int = Field(..., title="Size Bytes")


class DataProductDispatcherState(BaseModel):
    config: Optional[DataProductDispatcherConfig] = Field(
        default_factory=lambda: DataProductDispatcherConfig.parse_obj(
            {"size_max_bytes": 10485760, "enable_gzip": True}
        ),
        title="Config",
    )
    statistics: Optional[DataProductDispatcherStats] = Field(
        default_factory=lambda: DataProductDispatcherStats.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.100329+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "dataproduct_dispatcher",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "database_size_bytes": 0,
                "dataproducts_stored": 0,
            }
        ),
        title="Statistics",
    )
    last_cleanup: Optional[datetime] = Field(None, title="Last Cleanup")
    dataproduct_stats: Optional[List[DataProductStats]] = Field(
        [], title="Dataproduct Stats"
    )


class EventRecorderConfig(BaseModel):
    record_blink_led: Optional[bool] = Field(True, title="Record Blink Led")
    seconds_before_trigger: Optional[PositiveFloat] = Field(
        60.0, title="Seconds Before Trigger"
    )
    seconds_after_trigger: Optional[PositiveFloat] = Field(
        180.0, title="Seconds After Trigger"
    )


class EventRecorderState(BaseModel):
    config: Optional[EventRecorderConfig] = Field(
        default_factory=lambda: EventRecorderConfig.parse_obj(
            {
                "record_blink_led": True,
                "seconds_before_trigger": 60.0,
                "seconds_after_trigger": 180.0,
            }
        ),
        title="Config",
    )
    recording: Optional[bool] = Field(False, title="Recording")


class HTTPServerConfig(BaseModel):
    host: Optional[IPv4Address] = Field("0.0.0.0", title="Host")
    port: Optional[conint(ge=1000, le=65535)] = Field(5533, title="Port")
    update_interval: Optional[confloat(ge=0.5, le=10.0)] = Field(
        5.0, title="Update Interval"
    )


class HTTPServerState(BaseModel):
    config: Optional[HTTPServerConfig] = Field(
        default_factory=lambda: HTTPServerConfig.parse_obj(
            {"host": "0.0.0.0", "port": 5533, "update_interval": 5.0}
        ),
        title="Config",
    )
    websockets_connected: Optional[int] = Field(0, title="Websockets Connected")


class TimeNormalization(Enum):
    mute_median = "mute-median"
    none = "none"


class HVSpectraConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=20.0, le=120.0)] = Field(
        30.0, title="Window Length Seconds"
    )
    spectra_stack_size: Optional[conint(ge=1, le=50)] = Field(
        20, title="Spectra Stack Size"
    )
    min_frequency: Optional[confloat(ge=0.02, le=10.0)] = Field(
        0.05, title="Min Frequency"
    )
    max_frequency: Optional[confloat(ge=10.0, le=40.0)] = Field(
        20.0, title="Max Frequency"
    )
    smoothing_filter_bandwidth_hz: Optional[confloat(ge=5.0, le=40.0)] = Field(
        30.0, title="Smoothing Filter Bandwidth Hz"
    )
    time_normalization: Optional[TimeNormalization] = Field(
        "mute-median", title="Time Normalization"
    )
    mute_median_level: Optional[confloat(ge=1.0, le=5.0)] = Field(
        3.0, title="Mute Median Level"
    )
    spectra_nsamples: Optional[conint(ge=100, le=200, multiple_of=10)] = Field(
        150, title="Spectra Nsamples"
    )
    normalize_spectra: Optional[bool] = Field(True, title="Normalize Spectra")


class HVContinuousSpectraState(BaseModel):
    config: Optional[HVSpectraConfig] = Field(
        default_factory=lambda: HVSpectraConfig.parse_obj(
            {
                "enabled": True,
                "window_length_seconds": 30.0,
                "spectra_stack_size": 20,
                "min_frequency": 0.05,
                "max_frequency": 20.0,
                "smoothing_filter_bandwidth_hz": 30.0,
                "time_normalization": "mute-median",
                "mute_median_level": 3.0,
                "spectra_nsamples": 150,
                "normalize_spectra": True,
            }
        ),
        title="Config",
    )
    spectra_calculated: Optional[int] = Field(0, title="Spectra Calculated")
    coefficients_cache_size_bytes: Optional[int] = Field(
        0, title="Coefficients Cache Size Bytes"
    )
    status: Optional[str] = Field("", title="Status")


class JMAIntensityConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=10.0, le=120.0)] = Field(
        60.0, title="Window Length Seconds"
    )


class JMAIntensityMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("rt_jma_intensity", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    intensity: Optional[float] = Field(0.0, title="Intensity")


class JMAIntensityState(BaseModel):
    config: Optional[JMAIntensityConfig] = Field(
        default_factory=lambda: JMAIntensityConfig.parse_obj(
            {"enabled": True, "window_length_seconds": 60.0}
        ),
        title="Config",
    )
    measurement: Optional[JMAIntensityMeasurement] = Field(
        default_factory=lambda: JMAIntensityMeasurement.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.438078+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "rt_jma_intensity",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "intensity": 0.0,
            }
        ),
        title="Measurement",
    )


class LocationConfig(BaseModel):
    network: Optional[constr(regex=r"[a-zA-Z0-9]*", max_length=2)] = Field(
        "QS", title="Network"
    )
    station: Optional[constr(regex=r"[A-Z0-9]*", max_length=5)] = Field(
        "SUB54", title="Station"
    )
    location: Optional[constr(regex=r"[A-Z0-9]*", max_length=2)] = Field(
        "", title="Location"
    )
    channel_mapping: Optional[
        Dict[
            constr(regex=r"[A-Z0-9]"),
            constr(regex=r"[A-Z0-9]", min_length=3, max_length=3),
        ]
    ] = Field({}, title="Channel Mapping")
    station_name_readable: Optional[str] = Field("", title="Station Name Readable")
    lat: Optional[confloat(ge=-90.0, le=90.0)] = Field(0.0, title="Lat")
    lon: Optional[confloat(ge=-180.0, le=180.0)] = Field(0.0, title="Lon")
    elevation: Optional[float] = Field(0.0, title="Elevation")
    depth: Optional[float] = Field(0.0, title="Depth")
    floor: Optional[int] = Field(0, title="Floor")
    building_type: Optional[str] = Field("", title="Building Type")
    address: Optional[str] = Field("", title="Address")
    region: Optional[str] = Field("", title="Region")
    country: Optional[str] = Field("", title="Country")
    comment: Optional[str] = Field("", title="Comment")
    osm_building_id: Optional[str] = Field("", title="Osm Building Id")
    measurement_method: Optional[str] = Field("manual", title="Measurement Method")
    mozilla_api_key: Optional[str] = Field("test", title="Mozilla Api Key")
    jitter_network_location: Optional[float] = Field(
        0.0, title="Jitter Network Location"
    )
    last_edited: Optional[datetime] = Field(None, title="Last Edited")


class Method(Enum):
    wifi = "wifi"
    geo_ip = "geo-ip"


class NetworkLocation(BaseModel):
    method: Method = Field(..., title="Method")
    lat: float = Field(..., title="Lat")
    lon: float = Field(..., title="Lon")
    accuracy: Optional[float] = Field(None, title="Accuracy")
    timestamp: Optional[datetime] = Field(None, title="Timestamp")


class LocationState(BaseModel):
    config: Optional[LocationConfig] = Field(
        default_factory=lambda: LocationConfig.parse_obj(
            {
                "network": "QS",
                "station": "SUB54",
                "location": "",
                "channel_mapping": {},
                "station_name_readable": "",
                "lat": 0.0,
                "lon": 0.0,
                "elevation": 0.0,
                "depth": 0.0,
                "floor": 0,
                "building_type": "",
                "address": "",
                "region": "",
                "country": "",
                "comment": "",
                "osm_building_id": "",
                "measurement_method": "manual",
                "mozilla_api_key": "test",
                "jitter_network_location": 0.0,
                "last_edited": "2023-03-07T09:17:51.459013+00:00",
            }
        ),
        title="Config",
    )
    network_location: Optional[NetworkLocation] = None


class LoggingDequeConfig(BaseModel):
    capacity: Optional[PositiveInt] = Field(1000, title="Capacity")


class LoggingDequeStats(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("logging_deque", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    ingested_logs: Optional[int] = Field(0, title="Ingested Logs")


class LoggingDequeState(BaseModel):
    config: Optional[LoggingDequeConfig] = Field(
        default_factory=lambda: LoggingDequeConfig.parse_obj({"capacity": 1000}),
        title="Config",
    )
    stats: Optional[LoggingDequeStats] = Field(
        default_factory=lambda: LoggingDequeStats.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.161774+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "logging_deque",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "ingested_logs": 0,
            }
        ),
        title="Stats",
    )
    nlogs_stored: Optional[int] = Field(0, title="Nlogs Stored")


class Protocol(Enum):
    mqtt = "mqtt"
    mqtts = "mqtts"


class MqttLoggerLevel(Enum):
    integer_10 = 10
    integer_20 = 20
    integer_30 = 30
    integer_40 = 40
    integer_50 = 50


class MQTTClientConfig(BaseModel):
    token: Optional[str] = Field("", title="Token")
    host: Optional[str] = Field("localhost", title="Host")
    port: Optional[conint(ge=1, le=65535)] = Field(1883, title="Port")
    protocol: Optional[Protocol] = Field("mqtt", title="Protocol")
    keepalive: Optional[PositiveInt] = Field(10, title="Keepalive")
    message_expiry_interval: Optional[PositiveInt] = Field(
        60, title="Message Expiry Interval"
    )
    reconnect_retries: Optional[conint(ge=-1)] = Field(-1, title="Reconnect Retries")
    reconnect_delay: Optional[PositiveFloat] = Field(20.0, title="Reconnect Delay")
    mqtt_logger_enabled: Optional[bool] = Field(True, title="Mqtt Logger Enabled")
    mqtt_logger_level: Optional[MqttLoggerLevel] = Field(20, title="Mqtt Logger Level")
    provider_url: Optional[AnyUrl] = Field(None, title="Provider Url")
    provider_config_received: Optional[datetime] = Field(
        None, title="Provider Config Received"
    )


class MQTTClientStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("mqtt_client", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    bytes_sent: Optional[int] = Field(0, title="Bytes Sent")
    bytes_recv: Optional[int] = Field(0, title="Bytes Recv")
    nmessages_sent: Optional[int] = Field(0, title="Nmessages Sent")
    nmessages_recv: Optional[int] = Field(0, title="Nmessages Recv")
    nmessages_failed: Optional[int] = Field(0, title="Nmessages Failed")
    connect_count: Optional[int] = Field(0, title="Connect Count")
    unsend_messages: Optional[int] = Field(0, title="Unsend Messages")


class MQTTClientState(BaseModel):
    config: Optional[MQTTClientConfig] = Field(
        default_factory=lambda: MQTTClientConfig.parse_obj(
            {
                "token": "",
                "host": "localhost",
                "port": 1883,
                "protocol": "mqtt",
                "keepalive": 10,
                "message_expiry_interval": 60,
                "reconnect_retries": -1,
                "reconnect_delay": 20.0,
                "mqtt_logger_enabled": True,
                "mqtt_logger_level": 20,
                "provider_url": None,
                "provider_config_received": None,
            }
        ),
        title="Config",
    )
    stats: Optional[MQTTClientStatistics] = Field(
        default_factory=lambda: MQTTClientStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.300186+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "mqtt_client",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "bytes_sent": 0,
                "bytes_recv": 0,
                "nmessages_sent": 0,
                "nmessages_recv": 0,
                "nmessages_failed": 0,
                "connect_count": 0,
                "unsend_messages": 0,
            }
        ),
        title="Stats",
    )
    latency: Optional[float] = Field(0.0, title="Latency")
    connected: Optional[bool] = Field(False, title="Connected")
    client_registered: Optional[bool] = Field(False, title="Client Registered")


class ModuleConfig(BaseModel):
    pass


class MenderInformation(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    mac: Optional[str] = Field(None, title="Mac")
    cpu_serial: Optional[str] = Field(None, title="Cpu Serial")
    artifact: Optional[str] = Field(None, title="Artifact")


class NetworkDispatcherConfig(BaseModel):
    send_measurements_interval: Optional[float] = Field(
        30.0, title="Send Measurements Interval"
    )
    send_state_interval: Optional[float] = Field(300.0, title="Send State Interval")
    state_subscription_delay: Optional[float] = Field(
        5.0, title="State Subscription Delay"
    )
    measurement_collection_jitter: Optional[float] = Field(
        0.5, title="Measurement Collection Jitter"
    )


class NetworkDispatcherStats(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("network_dispatcher", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    data_products_sent: Optional[int] = Field(0, title="Data Products Sent")
    configs_received: Optional[int] = Field(0, title="Configs Received")
    actions_received: Optional[int] = Field(0, title="Actions Received")


class NetworkDispatcherState(BaseModel):
    config: Optional[NetworkDispatcherConfig] = Field(
        default_factory=lambda: NetworkDispatcherConfig.parse_obj(
            {
                "send_measurements_interval": 30.0,
                "send_state_interval": 300.0,
                "state_subscription_delay": 5.0,
                "measurement_collection_jitter": 0.5,
            }
        ),
        title="Config",
    )
    stats: Optional[NetworkDispatcherStats] = Field(
        default_factory=lambda: NetworkDispatcherStats.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.460961+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "network_dispatcher",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "data_products_sent": 0,
                "configs_received": 0,
                "actions_received": 0,
            }
        ),
        title="Stats",
    )


class TimeNormalization1(Enum):
    one_bit = "one-bit"
    mute_median = "mute-median"
    none = "none"


class StackingMethod(Enum):
    linear = "linear"
    phase_weighted_stack = "phase-weighted-stack"


class NoiseAutocorrelationConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=60.0, le=300.0)] = Field(
        120.0, title="Window Length Seconds"
    )
    window_taper_fraction: Optional[confloat(ge=0.05, le=0.1)] = Field(
        0.05, title="Window Taper Fraction"
    )
    time_normalization: Optional[TimeNormalization1] = Field(
        "one-bit", title="Time Normalization"
    )
    stacking_method: Optional[StackingMethod] = Field("linear", title="Stacking Method")
    stack_rms_normalization: Optional[bool] = Field(
        False, title="Stack Rms Normalization"
    )
    max_lagtime: Optional[confloat(ge=5.0, le=60.0)] = Field(20.0, title="Max Lagtime")
    min_frequency: Optional[confloat(ge=0.05, le=1.0)] = Field(
        0.3, title="Min Frequency"
    )
    max_frequency: Optional[confloat(le=6.0, gt=0.5)] = Field(
        1.0, title="Max Frequency"
    )
    correlation_stack_size: Optional[conint(ge=1, le=50)] = Field(
        50, title="Correlation Stack Size"
    )


class NoiseAutocorrelationState(BaseModel):
    config: Optional[NoiseAutocorrelationConfig] = Field(
        default_factory=lambda: NoiseAutocorrelationConfig.parse_obj(
            {
                "enabled": True,
                "window_length_seconds": 120.0,
                "window_taper_fraction": 0.05,
                "time_normalization": "one-bit",
                "stacking_method": "linear",
                "stack_rms_normalization": False,
                "max_lagtime": 20.0,
                "min_frequency": 0.3,
                "max_frequency": 1.0,
                "correlation_stack_size": 50,
            }
        ),
        title="Config",
    )


class PeakGroundMotionConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=5.0, le=60.0)] = Field(
        30.0, title="Window Length Seconds"
    )
    pga_lowpass: Optional[confloat(ge=1.0, le=20.0)] = Field(10.0, title="Pga Lowpass")
    pgv_highpass: Optional[confloat(ge=0.0, le=20.0)] = Field(
        0.075, title="Pgv Highpass"
    )
    pga_trigger_enabled: Optional[bool] = Field(False, title="Pga Trigger Enabled")
    pga_trigger_threshold: Optional[PositiveFloat] = Field(
        0.5, title="Pga Trigger Threshold"
    )


class PGMMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("rt_peak_ground_motion", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    pga: Optional[float] = Field(0.0, title="Peak ground acceleration")
    pha: Optional[float] = Field(0.0, title="Peak horizontal acceleration")
    pgv: Optional[float] = Field(0.0, title="Peak ground velocity")
    mod_mercalli_intensity: Optional[float] = Field(
        0.0, title="Modified mercalli intensity"
    )
    cwb_intensity: Optional[int] = Field(0, title="CWB intensity")
    jma_intensity: Optional[float] = Field(0.0, title="JMA intensity")


class PeakGroundMotionState(BaseModel):
    config: Optional[PeakGroundMotionConfig] = Field(
        default_factory=lambda: PeakGroundMotionConfig.parse_obj(
            {
                "enabled": True,
                "window_length_seconds": 30.0,
                "pga_lowpass": 10.0,
                "pgv_highpass": 0.075,
                "pga_trigger_enabled": False,
                "pga_trigger_threshold": 0.5,
            }
        ),
        title="Config",
    )
    measurement: Optional[PGMMeasurement] = Field(
        default_factory=lambda: PGMMeasurement.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.445752+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "rt_peak_ground_motion",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "pga": 0.0,
                "pha": 0.0,
                "pgv": 0.0,
                "mod_mercalli_intensity": 0.0,
                "cwb_intensity": 0,
                "jma_intensity": 0.0,
            }
        ),
        title="Measurement",
    )


class RMSAmplitudeConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=1.0, le=30.0)] = Field(
        10.0, title="Window Length Seconds"
    )


class RMSAmplitudeMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("rms_amplitude", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    rms_amplitude: Optional[float] = Field(0.0, title="Rms Amplitude")


class RMSAmplitudeState(BaseModel):
    config: Optional[RMSAmplitudeConfig] = Field(
        default_factory=lambda: RMSAmplitudeConfig.parse_obj(
            {"enabled": True, "window_length_seconds": 10.0}
        ),
        title="Config",
    )
    measurement: Optional[RMSAmplitudeMeasurement] = None


class RingbufferStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("ringbuffer", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    ready: Optional[bool] = Field(False, title="Ready")
    deltat_input: Optional[float] = Field(0.0, title="Deltat Input")
    nsamples: Optional[int] = Field(0, title="Nsamples")
    percent_used: Optional[float] = Field(0.0, title="Percent Used")
    nsamples_buffer: Optional[int] = Field(0, title="Nsamples Buffer")
    bytes_used: Optional[int] = Field(0, title="Bytes Used")
    bytes_capacity: Optional[int] = Field(0, title="Bytes Capacity")
    pos_head: Optional[int] = Field(0, title="Pos Head")
    tmin: Optional[float] = Field(0.0, title="Tmin")
    tmax: Optional[float] = Field(0.0, title="Tmax")
    nlisteners: Optional[int] = Field(0, title="Nlisteners")


class RingbufferState(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    stats: Optional[RingbufferStatistics] = Field(
        default_factory=lambda: RingbufferStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.415085+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "ringbuffer",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "ready": False,
                "deltat_input": 0.0,
                "nsamples": 0,
                "percent_used": 0.0,
                "nsamples_buffer": 0,
                "bytes_used": 0,
                "bytes_capacity": 0,
                "pos_head": 0,
                "tmin": 0.0,
                "tmax": 0.0,
                "nlisteners": 0,
            }
        ),
        title="Stats",
    )
    window: str = Field(..., title="Window")
    window_size: int = Field(..., title="Window Size")
    filter_length: int = Field(..., title="Filter Length")


class STALTAConfig(BaseModel):
    enabled: Optional[bool] = Field(False, title="Enabled")
    trigger_enabled: Optional[bool] = Field(False, title="Trigger Enabled")
    trigger_threshold: Optional[PositiveFloat] = Field(1.2, title="Trigger Threshold")
    nsta: Optional[conint(ge=20, le=300)] = Field(50, title="Nsta")
    nlta: Optional[conint(ge=50, le=900)] = Field(300, title="Nlta")
    overlap_percent: Optional[conint(ge=10, le=90)] = Field(20, title="Overlap Percent")


class STALTAMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("sta_lta", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    sta_lta: Optional[float] = Field(0.0, title="Current STA/LTA")


class STALTAState(BaseModel):
    config: Optional[STALTAConfig] = Field(
        default_factory=lambda: STALTAConfig.parse_obj(
            {
                "enabled": False,
                "trigger_enabled": False,
                "trigger_threshold": 1.2,
                "nsta": 50,
                "nlta": 300,
                "overlap_percent": 20,
            }
        ),
        title="Config",
    )
    measurement: Optional[STALTAMeasurement] = Field(
        default_factory=lambda: STALTAMeasurement.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.455563+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "sta_lta",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "sta_lta": 0.0,
            }
        ),
        title="Measurement",
    )


class SeedLinkServerConfig(BaseModel):
    enabled: Optional[bool] = Field(False, title="Enabled")
    host: Optional[IPv4Address] = Field("0.0.0.0", title="Host")
    port: Optional[conint(ge=1000, le=65335)] = Field(18000, title="Port")
    nsamples: Optional[conint(ge=50, le=1000)] = Field(50, title="Nsamples")


class SeedLinkServerStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("seedlink_server", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    latency: Optional[float] = Field(0.0, title="Latency")
    packet_efficiency: Optional[float] = Field(0.0, title="Packet Efficiency")
    clients_connected: Optional[int] = Field(0, title="Clients Connected")
    bytes_sent: Optional[int] = Field(0, title="Bytes Sent")
    end_sequence: Optional[int] = Field(0, title="End Sequence")
    begin_sequence: Optional[int] = Field(0, title="Begin Sequence")


class SeedLinkServerState(BaseModel):
    config: Optional[SeedLinkServerConfig] = Field(
        default_factory=lambda: SeedLinkServerConfig.parse_obj(
            {"enabled": False, "host": "0.0.0.0", "port": 18000, "nsamples": 50}
        ),
        title="Config",
    )
    stats: Optional[SeedLinkServerStatistics] = Field(
        default_factory=lambda: SeedLinkServerStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.184306+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "seedlink_server",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "latency": 0.0,
                "packet_efficiency": 0.0,
                "clients_connected": 0,
                "bytes_sent": 0,
                "end_sequence": 0,
                "begin_sequence": 0,
            }
        ),
        title="Stats",
    )


class SpectralIntensityConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=10.0, le=120.0)] = Field(
        60.0, title="Window Length Seconds"
    )
    duration_fade: Optional[confloat(ge=0.0)] = Field(0.5, title="Duration Fade")
    fmin: Optional[confloat(ge=0.0, le=20.0)] = Field(0.1, title="Min. Frequency")
    fmax: Optional[confloat(ge=0.0, le=20.0)] = Field(0.4, title="Max. Frequency")


class SpectralIntensityMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("rt_spectral_intensity", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    spectral_intensity: Optional[float] = Field(0.0, title="Spectral Intensity")


class SpectralIntensityState(BaseModel):
    config: Optional[SpectralIntensityConfig] = Field(
        default_factory=lambda: SpectralIntensityConfig.parse_obj(
            {
                "enabled": True,
                "window_length_seconds": 60.0,
                "duration_fade": 0.5,
                "fmin": 0.1,
                "fmax": 0.4,
            }
        ),
        title="Config",
    )
    measurement: Optional[SpectralIntensityMeasurement] = None


class StreamWaveformsTrigger(BaseModel):
    nsamples: Optional[conint(ge=50, le=1000)] = Field(50, title="Nsamples")


class StreamWaveformsState(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    trigger: Optional[StreamWaveformsTrigger] = None
    streaming: Optional[bool] = Field(False, title="Streaming")
    latency: Optional[float] = Field(0.0, title="Latency")
    packet_efficiency: Optional[float] = Field(0.0, title="Packet Efficiency")
    current_sequence_number: Optional[int] = Field(0, title="Current Sequence Number")


class SystemEnvironmentConfig(BaseModel):
    class Config:
        extra = Extra.forbid

    BME280_PORT: Optional[PositiveInt] = Field(1, title="Bme280 Port")
    BME280_ADDRESS: Optional[PositiveInt] = Field(118, title="Bme280 Address")


class SystemEnvironmentMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("system_environment", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    pressure: Optional[float] = Field(0.0, title="Pressure")
    humidity: Optional[float] = Field(0.0, title="Humidity")
    temperature: Optional[float] = Field(0.0, title="Temperature")


class SystemEnvironmentStatus(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    chip_config: Optional[SystemEnvironmentConfig] = Field(
        default_factory=lambda: SystemEnvironmentConfig.parse_obj(
            {"BME280_PORT": 1, "BME280_ADDRESS": 118}
        ),
        title="Chip Config",
    )
    environment: Optional[SystemEnvironmentMeasurement] = Field(
        default_factory=lambda: SystemEnvironmentMeasurement.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.189377+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "system_environment",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "pressure": 0.0,
                "humidity": 0.0,
                "temperature": 0.0,
            }
        ),
        title="Environment",
    )


class MemoryStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("memory", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    total: Optional[int] = Field(0, title="Total")
    available: Optional[int] = Field(0, title="Available")
    percent: Optional[float] = Field(0.0, title="Percent")
    used: Optional[int] = Field(0, title="Used")
    free: Optional[int] = Field(0, title="Free")
    active: Optional[int] = Field(0, title="Active")
    inactive: Optional[int] = Field(0, title="Inactive")
    buffers: Optional[int] = Field(0, title="Buffers")
    cached: Optional[int] = Field(0, title="Cached")
    shared: Optional[int] = Field(0, title="Shared")
    slab: Optional[int] = Field(0, title="Slab")


class CPUStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("cpu", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    user: Optional[float] = Field(0.0, title="User")
    nice: Optional[float] = Field(0.0, title="Nice")
    system: Optional[float] = Field(0.0, title="System")
    idle: Optional[float] = Field(0.0, title="Idle")
    iowait: Optional[float] = Field(0.0, title="Iowait")
    irq: Optional[float] = Field(0.0, title="Irq")
    softirq: Optional[float] = Field(0.0, title="Softirq")
    steal: Optional[float] = Field(0.0, title="Steal")
    guest: Optional[float] = Field(0.0, title="Guest")
    guest_nice: Optional[float] = Field(0.0, title="Guest Nice")
    cpu_usage_percent: Optional[float] = Field(0.0, title="Cpu Usage Percent")
    cpu_temperature: Optional[float] = Field(0.0, title="Cpu Temperature")


class ProcessMemoryStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("process_memory", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    rss: Optional[int] = Field(0, title="Rss")
    vms: Optional[int] = Field(0, title="Vms")
    shared: Optional[int] = Field(0, title="Shared")
    text: Optional[int] = Field(0, title="Text")
    lib: Optional[int] = Field(0, title="Lib")
    data: Optional[int] = Field(0, title="Data")
    dirty: Optional[int] = Field(0, title="Dirty")
    uss: Optional[int] = Field(0, title="Uss")
    pss: Optional[int] = Field(0, title="Pss")
    swap: Optional[int] = Field(0, title="Swap")


class ProcessStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("process", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    pid: Optional[int] = Field(0, title="Pid")
    fds: Optional[int] = Field(0, title="Fds")
    cpu_percent: Optional[float] = Field(0.0, title="Cpu Percent")
    create_time: Optional[float] = Field(0.0, title="Create Time")
    num_threads: Optional[int] = Field(0, title="Num Threads")
    connections: Optional[int] = Field(0, title="Connections")


class DiskStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("disk", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    total: Optional[int] = Field(0, title="Total")
    used: Optional[int] = Field(0, title="Used")
    free: Optional[int] = Field(0, title="Free")
    percent: Optional[float] = Field(0.0, title="Percent")


class NetworkStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("network", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    bytes_sent: Optional[int] = Field(0, title="Bytes Sent")
    bytes_recv: Optional[int] = Field(0, title="Bytes Recv")
    packets_sent: Optional[int] = Field(0, title="Packets Sent")
    packets_recv: Optional[int] = Field(0, title="Packets Recv")
    errin: Optional[int] = Field(0, title="Errin")
    errout: Optional[int] = Field(0, title="Errout")
    dropin: Optional[int] = Field(0, title="Dropin")
    dropout: Optional[int] = Field(0, title="Dropout")
    ip_address: Optional[str] = Field("", title="Ip Address")
    ssid: Optional[str] = Field(None, title="Ssid")


class ChronyStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("chrony", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    reference_id: Optional[str] = Field("", title="Reference Id")
    server_ip: Optional[str] = Field("", title="Server Ip")
    stratum: Optional[int] = Field(0, title="Stratum")
    ref_time_utc: Optional[float] = Field(0.0, title="Ref Time Utc")
    system_time: Optional[float] = Field(0.0, title="System Time")
    last_offset: Optional[float] = Field(0.0, title="Last Offset")
    rms_offset: Optional[float] = Field(0.0, title="Rms Offset")
    frequency: Optional[float] = Field(0.0, title="Frequency")
    residual_freq: Optional[float] = Field(0.0, title="Residual Freq")
    skew: Optional[float] = Field(0.0, title="Skew")
    root_delay: Optional[float] = Field(0.0, title="Root Delay")
    root_dispersion: Optional[float] = Field(0.0, title="Root Dispersion")
    update_interval: Optional[float] = Field(0.0, title="Update Interval")
    leap_status: Optional[str] = Field("", title="Leap Status")


class KernelStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("kernel", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    load1: Optional[float] = Field(0.0, title="Load1")
    load5: Optional[float] = Field(0.0, title="Load5")
    load15: Optional[float] = Field(0.0, title="Load15")
    boot_time: Optional[float] = Field(0.0, title="Boot Time")
    ctx_switches: Optional[int] = Field(0, title="Ctx Switches")
    interrupts: Optional[int] = Field(0, title="Interrupts")
    soft_interrupts: Optional[int] = Field(0, title="Soft Interrupts")
    syscalls: Optional[int] = Field(0, title="Syscalls")


class SystemInformation(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    platform_model: Optional[str] = Field(None, title="Platform Model")
    software_version: Optional[str] = Field("0.3.0+f102e7d", title="Software Version")
    boot_time: Optional[datetime] = Field(None, title="Boot Time")
    memory_stats: Optional[MemoryStatistics] = Field(
        default_factory=lambda: MemoryStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204524+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "memory",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "total": 0,
                "available": 0,
                "percent": 0.0,
                "used": 0,
                "free": 0,
                "active": 0,
                "inactive": 0,
                "buffers": 0,
                "cached": 0,
                "shared": 0,
                "slab": 0,
            }
        ),
        title="Memory Stats",
    )
    cpu_stats: Optional[CPUStatistics] = Field(
        default_factory=lambda: CPUStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204582+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "cpu",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "user": 0.0,
                "nice": 0.0,
                "system": 0.0,
                "idle": 0.0,
                "iowait": 0.0,
                "irq": 0.0,
                "softirq": 0.0,
                "steal": 0.0,
                "guest": 0.0,
                "guest_nice": 0.0,
                "cpu_usage_percent": 0.0,
                "cpu_temperature": 0.0,
            }
        ),
        title="Cpu Stats",
    )
    process_memory_stats: Optional[ProcessMemoryStatistics] = Field(
        default_factory=lambda: ProcessMemoryStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204608+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "process_memory",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "rss": 0,
                "vms": 0,
                "shared": 0,
                "text": 0,
                "lib": 0,
                "data": 0,
                "dirty": 0,
                "uss": 0,
                "pss": 0,
                "swap": 0,
            }
        ),
        title="Process Memory Stats",
    )
    process_stats: Optional[ProcessStatistics] = Field(
        default_factory=lambda: ProcessStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204630+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "process",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "pid": 0,
                "fds": 0,
                "cpu_percent": 0.0,
                "create_time": 0.0,
                "num_threads": 0,
                "connections": 0,
            }
        ),
        title="Process Stats",
    )
    disk_stats: Optional[DiskStatistics] = Field(
        default_factory=lambda: DiskStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204650+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "disk",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "total": 0,
                "used": 0,
                "free": 0,
                "percent": 0.0,
            }
        ),
        title="Disk Stats",
    )
    network_stats: Optional[NetworkStatistics] = Field(
        default_factory=lambda: NetworkStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204668+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "network",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "bytes_sent": 0,
                "bytes_recv": 0,
                "packets_sent": 0,
                "packets_recv": 0,
                "errin": 0,
                "errout": 0,
                "dropin": 0,
                "dropout": 0,
                "ip_address": "",
                "ssid": None,
            }
        ),
        title="Network Stats",
    )
    chrony_stats: Optional[ChronyStatistics] = Field(
        default_factory=lambda: ChronyStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204691+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "chrony",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "reference_id": "",
                "server_ip": "",
                "stratum": 0,
                "ref_time_utc": 0.0,
                "system_time": 0.0,
                "last_offset": 0.0,
                "rms_offset": 0.0,
                "frequency": 0.0,
                "residual_freq": 0.0,
                "skew": 0.0,
                "root_delay": 0.0,
                "root_dispersion": 0.0,
                "update_interval": 0.0,
                "leap_status": "",
            }
        ),
        title="Chrony Stats",
    )
    kernel_stats: Optional[KernelStatistics] = Field(
        default_factory=lambda: KernelStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.204712+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "kernel",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "load1": 0.0,
                "load5": 0.0,
                "load15": 0.0,
                "boot_time": 0.0,
                "ctx_switches": 0,
                "interrupts": 0,
                "soft_interrupts": 0,
                "syscalls": 0,
            }
        ),
        title="Kernel Stats",
    )


class SystemPowerConfig(BaseModel):
    class Config:
        extra = Extra.forbid

    LTC4151_PORT: Optional[PositiveInt] = Field(1, title="Ltc4151 Port")
    LTC4151_ADDRESS: Optional[PositiveInt] = Field(103, title="Ltc4151 Address")
    RESISTOR: Optional[PositiveFloat] = Field(0.02, title="Resistor")


class SystemPowerSupply(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("system_power", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    supply_voltage: Optional[float] = Field(0.0, title="Supply Voltage")
    current: Optional[float] = Field(0.0, title="Current")
    voltage_ext: Optional[float] = Field(0.0, title="Voltage Ext")


class SystemPowerState(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    chip_config: Optional[SystemPowerConfig] = Field(
        default_factory=lambda: SystemPowerConfig.parse_obj(
            {"LTC4151_PORT": 1, "LTC4151_ADDRESS": 103, "RESISTOR": 0.02}
        ),
        title="Chip Config",
    )
    power: Optional[SystemPowerSupply] = Field(
        default_factory=lambda: SystemPowerSupply.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.208061+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "system_power",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "supply_voltage": 0.0,
                "current": 0.0,
                "voltage_ext": 0.0,
            }
        ),
        title="Power",
    )


class TimeMonitorConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    blink_interval: Optional[confloat(ge=1.0, le=120.0)] = Field(
        5.0, title="Blink Interval"
    )
    flash_duration: Optional[confloat(ge=0.05, le=1.0)] = Field(
        0.1, title="Flash Duration"
    )


class TimeMonitorState(BaseModel):
    config: Optional[TimeMonitorConfig] = Field(
        default_factory=lambda: TimeMonitorConfig.parse_obj(
            {"enabled": True, "blink_interval": 5.0, "flash_duration": 0.1}
        ),
        title="Config",
    )


class Profile(Enum):
    tmate_io = "tmate.io"
    ssh_quakesaver_net = "ssh.quakesaver.net"


class TmateConfig(BaseModel):
    enabled: Optional[bool] = Field(False, title="Enabled")
    api_key: Optional[str] = Field("", title="Api Key")
    profile: Optional[Profile] = Field("tmate.io", title="Profile")


class TmateState(BaseModel):
    config: Optional[TmateConfig] = Field(
        default_factory=lambda: TmateConfig.parse_obj(
            {"enabled": False, "api_key": "", "profile": "tmate.io"}
        ),
        title="Config",
    )
    active: Optional[bool] = Field(False, title="Active")
    session_token: Optional[str] = Field("", title="Session Token")


class InstitutionBranding(Enum):
    QuakeSaver = "QuakeSaver"
    EDream = "EDream"


class UserEnvironmentConfig(BaseModel):
    language: Optional[str] = Field("eng", title="Language")
    instituion: Optional[str] = Field("", title="Instituion")
    institution_branding: Optional[InstitutionBranding] = Field(
        "QuakeSaver", title="Institution Branding"
    )
    contact_person: Optional[str] = Field("", title="Contact Person")
    contact_email: Optional[str] = Field("", title="Contact Email")
    contact_phone: Optional[str] = Field("", title="Contact Phone")


class UserEnvironment(BaseModel):
    config: Optional[UserEnvironmentConfig] = Field(
        default_factory=lambda: UserEnvironmentConfig.parse_obj(
            {
                "language": "eng",
                "instituion": "",
                "institution_branding": "QuakeSaver",
                "contact_person": "",
                "contact_email": "",
                "contact_phone": "",
            }
        ),
        title="Config",
    )


class SamplingRate3(Enum):
    integer_100 = 100
    integer_200 = 200


class VirtualSensorConfig(BaseModel):
    sampling_rate: Optional[SamplingRate3] = Field(100, title="Sampling Rate")


class VirtualSensorStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("sensor", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({"sensor": "virtual"}, title="Tags")
    active: Optional[bool] = Field(False, title="Active")
    sampling_rate: Optional[int] = Field(0, title="Sampling Rate")
    nsamples: Optional[int] = Field(0, title="Nsamples")
    deltat: Optional[float] = Field(0.0, title="Deltat")


class VirtualSensorState(BaseModel):
    config: Optional[VirtualSensorConfig] = Field(
        default_factory=lambda: VirtualSensorConfig.parse_obj({"sampling_rate": 100}),
        title="Config",
    )
    stats: Optional[VirtualSensorStatistics] = Field(
        default_factory=lambda: VirtualSensorStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.462796+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "sensor",
                "tags": {"sensor": "virtual", "uid": "SUB54I40", "platform": "unknown"},
                "active": False,
                "sampling_rate": 0,
                "nsamples": 0,
                "deltat": 0.0,
            }
        ),
        title="Stats",
    )


class WatchdogConfig(BaseModel):
    enabled: Optional[bool] = Field(False, title="Enabled")
    tame_recorded_samples: Optional[PositiveInt] = Field(
        1000, title="Tame Recorded Samples"
    )


class WatchdogEnvironment(BaseModel):
    class Config:
        extra = Extra.forbid

    WATCHDOG_KENNEL: Optional[str] = Field("/dev/watchdog", title="Watchdog Kennel")


class Status(Enum):
    active = "active"
    inactive = "inactive"


class WatchdogState(BaseModel):
    config: Optional[WatchdogConfig] = Field(
        default_factory=lambda: WatchdogConfig.parse_obj(
            {"enabled": False, "tame_recorded_samples": 1000}
        ),
        title="Config",
    )
    environment: Optional[WatchdogEnvironment] = Field(
        default_factory=lambda: WatchdogEnvironment.parse_obj(
            {"WATCHDOG_KENNEL": "/dev/watchdog"}
        ),
        title="Environment",
    )
    status: Optional[Status] = Field("inactive", title="Status")


class RecordLength(Enum):
    integer_256 = 256
    integer_512 = 512
    integer_1024 = 1024
    integer_2048 = 2048
    integer_4096 = 4096
    integer_8192 = 8192
    integer_16384 = 16384
    integer_32768 = 32768
    integer_65536 = 65536
    integer_131072 = 131072
    integer_262144 = 262144
    integer_524288 = 524288


class WaveformArchiveConfig(BaseModel):
    enabled: Optional[bool] = Field(False, title="Enabled")
    record_length: Optional[RecordLength] = Field(4096, title="Record Length")
    time_length: Optional[conint(le=86400)] = Field(600, title="Time Length")
    max_archive_size_percent: Optional[confloat(ge=5.0, le=100.0)] = Field(
        90.0, title="Max Archive Size Percent"
    )
    data_path: Optional[str] = Field(
        "/home/king/quakesaver_data/mseed_data", title="Data Path"
    )


class WaveformArchiveStatistics(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("waveform_archive", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    disk_total_bytes: Optional[int] = Field(0, title="Disk Total Bytes")
    disk_free_bytes: Optional[int] = Field(0, title="Disk Free Bytes")
    disk_usage_percent: Optional[float] = Field(0.0, title="Disk Usage Percent")
    used_bytes: Optional[int] = Field(0, title="Used Bytes")


class WaveformArchiveState(BaseModel):
    config: Optional[WaveformArchiveConfig] = Field(
        default_factory=lambda: WaveformArchiveConfig.parse_obj(
            {
                "enabled": False,
                "record_length": 4096,
                "time_length": 600,
                "max_archive_size_percent": 90.0,
                "data_path": "/home/king/quakesaver_data/mseed_data",
            }
        ),
        title="Config",
    )
    stats: Optional[WaveformArchiveStatistics] = Field(
        default_factory=lambda: WaveformArchiveStatistics.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.417303+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "waveform_archive",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "disk_total_bytes": 0,
                "disk_free_bytes": 0,
                "disk_usage_percent": 0.0,
                "used_bytes": 0,
            }
        ),
        title="Stats",
    )


class WaveformDispatcherConfig(BaseModel):
    max_requests: Optional[PositiveInt] = Field(5, title="Max Requests")
    max_request_time: Optional[float] = Field(300.0, title="Max Request Time")


class WaveformDispatcherStats(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("waveform_dispatcher", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")
    served_requests: Optional[int] = Field(0, title="Served Requests")
    served_chunks: Optional[int] = Field(0, title="Served Chunks")
    served_bytes: Optional[int] = Field(0, title="Served Bytes")


class WaveformDispatcherState(BaseModel):
    config: Optional[WaveformDispatcherConfig] = Field(
        default_factory=lambda: WaveformDispatcherConfig.parse_obj(
            {"max_requests": 5, "max_request_time": 300.0}
        ),
        title="Config",
    )
    stats: Optional[WaveformDispatcherStats] = Field(
        default_factory=lambda: WaveformDispatcherStats.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.420465+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "waveform_dispatcher",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
                "served_requests": 0,
                "served_chunks": 0,
                "served_bytes": 0,
            }
        ),
        title="Stats",
    )
    serving: Optional[bool] = Field(False, title="Serving")
    tasks: Optional[int] = Field(0, title="Tasks")


class WaveformPolarisationConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    window_length_seconds: Optional[confloat(ge=5.0, le=60.0)] = Field(
        20.0, title="Window Length Seconds"
    )
    lowpass_freq: Optional[PositiveFloat] = Field(1.0, title="Lowpass Frequency")


class WaveformPolarisationMeasurement(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    latitude: Optional[float] = Field(None, title="Latitude")
    longitude: Optional[float] = Field(None, title="Longitude")
    measurement: Optional[str] = Field("waveform_polarisation", title="Measurement")
    tags: Optional[Dict[str, str]] = Field({}, title="Tags")


class WaveformPolarisationState(BaseModel):
    config: Optional[WaveformPolarisationConfig] = Field(
        default_factory=lambda: WaveformPolarisationConfig.parse_obj(
            {"enabled": True, "window_length_seconds": 20.0, "lowpass_freq": 1.0}
        ),
        title="Config",
    )
    measurement: Optional[WaveformPolarisationMeasurement] = Field(
        default_factory=lambda: WaveformPolarisationMeasurement.parse_obj(
            {
                "timestamp": "2023-03-07T09:17:51.452541+00:00",
                "latitude": None,
                "longitude": None,
                "measurement": "waveform_polarisation",
                "tags": {"uid": "SUB54I40", "platform": "unknown"},
            }
        ),
        title="Measurement",
    )


class WifiAccessPointState(BaseModel):
    config: Optional[ModuleConfig] = Field({}, title="Config")
    activated: Optional[bool] = Field(False, title="Activated")


class ZMQStreamConfig(BaseModel):
    enabled: Optional[bool] = Field(True, title="Enabled")
    nsamples: Optional[conint(ge=50, le=1000)] = Field(100, title="Nsamples")
    address: Optional[IPv4Address] = Field("0.0.0.0", title="Address")
    port: Optional[conint(ge=1000, le=65335)] = Field(5556, title="Port")


class ZMQStreamState(BaseModel):
    config: Optional[ZMQStreamConfig] = Field(
        default_factory=lambda: ZMQStreamConfig.parse_obj(
            {"enabled": True, "nsamples": 100, "address": "0.0.0.0", "port": 5556}
        ),
        title="Config",
    )


class SensorState(BaseModel):
    timestamp: Optional[datetime] = Field(None, title="Timestamp")
    uid: Optional[str] = Field(None, title="Uid")
    hardware_revision: Optional[str] = Field("unknown", title="Hardware Revision")
    platform_model: Optional[str] = Field("", title="Platform Model")
    software_version: Optional[str] = Field("0.3.0+f102e7d", title="Software Version")
    AD7779State: Optional[AD7779State] = None
    ADXL355State: Optional[ADXL355State] = None
    BMA456State: Optional[BMA456State] = None
    DataProductDispatcherState: Optional[DataProductDispatcherState] = None
    EventRecorderState: Optional[EventRecorderState] = None
    HTTPServerState: Optional[HTTPServerState] = None
    HVContinuousSpectraState: Optional[HVContinuousSpectraState] = None
    JMAIntensityState: Optional[JMAIntensityState] = None
    LocationState: Optional[LocationState] = None
    LoggingDequeState: Optional[LoggingDequeState] = None
    MQTTClientState: Optional[MQTTClientState] = None
    MenderInformation: Optional[MenderInformation] = None
    NetworkDispatcherState: Optional[NetworkDispatcherState] = None
    NoiseAutocorrelationState: Optional[NoiseAutocorrelationState] = None
    PeakGroundMotionState: Optional[PeakGroundMotionState] = None
    RMSAmplitudeState: Optional[RMSAmplitudeState] = None
    RingbufferState: Optional[RingbufferState] = None
    STALTAState: Optional[STALTAState] = None
    SeedLinkServerState: Optional[SeedLinkServerState] = None
    SpectralIntensityState: Optional[SpectralIntensityState] = None
    StreamWaveformsState: Optional[StreamWaveformsState] = None
    SystemEnvironmentStatus: Optional[SystemEnvironmentStatus] = None
    SystemInformation: Optional[SystemInformation] = None
    SystemPowerState: Optional[SystemPowerState] = None
    TimeMonitorState: Optional[TimeMonitorState] = None
    TmateState: Optional[TmateState] = None
    UserEnvironment: Optional[UserEnvironment] = None
    VirtualSensorState: Optional[VirtualSensorState] = None
    WatchdogState: Optional[WatchdogState] = None
    WaveformArchiveState: Optional[WaveformArchiveState] = None
    WaveformDispatcherState: Optional[WaveformDispatcherState] = None
    WaveformPolarisationState: Optional[WaveformPolarisationState] = None
    WifiAccessPointState: Optional[WifiAccessPointState] = None
    ZMQStreamState: Optional[ZMQStreamState] = None
