

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: blickfeld/system/config/device.proto, blickfeld/system/config/network.proto, blickfeld/system/config/scan_pattern.proto, blickfeld/system/config/time_synchronization.proto
# plugin: python-betterproto
import warnings
from dataclasses import dataclass
from typing import List

import blickfeld_qb2.betterproto as betterproto
import blickfeld_qb2.betterproto.lib.google.protobuf as betterproto_lib_google_protobuf

from ...eye_safety import data as __eye_safety_data__
from ...secure import config as __secure_config__


class DeviceClass(betterproto.Enum):
    """Enum to distinguish different device classes"""

    CLASS_UNKNOWN = 0
    CUBE = 1
    CUBE_RANGE = 2
    QB2 = 3


class NetworkAuthenticationKeyManagement(betterproto.Enum):
    """
    Key management   [NOTE] Only 802.1X for wired network is supported (see
    https://en.wikipedia.org/wiki/IEEE_802.1X).
    """

    KEY_MANAGEMENT_UNSPECIFIED = 0
    """default (no key management)"""

    KEY_MANAGEMENT_PSK = 1
    """PSK (WPA with pre-shared key, common for home Wi-Fi)."""

    KEY_MANAGEMENT_EAP = 2
    """EAP (WPA with EAP, common for enterprise Wi-F)."""

    KEY_MANAGEMENT_EAPSHA256 = 3
    """EAP-SHA256 (used with WPA3-Enterprise)."""

    KEY_MANAGEMENT_EAPSUITEB192 = 4
    """EAP-SUITE-B-192 (used with WPA3-Enterprise)."""

    KEY_MANAGEMENT_SAE = 5
    """SAE (used by WPA3)"""

    KEY_MANAGEMENT_IEEE8021X = 6
    """802.1X (used primarily for wired Ethernet connections)."""


class NetworkAuthenticationEapMethod(betterproto.Enum):
    """The Extensible Authentication Protocol (EAP) method to use."""

    EAP_METHOD_UNSPECIFIED = 0
    """default (unset) - Let the RADIUS server propose a EAP method"""

    EAP_METHOD_TLS = 1
    """Prefer TLS"""

    EAP_METHOD_PEAP = 2
    """Prefer protected EAP (recommended)"""

    EAP_METHOD_LEAP = 3
    """Prefer lightweight EAP"""

    EAP_METHOD_PWD = 4
    """Prefer EAP password"""

    EAP_METHOD_TTLS = 5
    """Prefer tunneled TLS (recommended)"""


class ScanPatternFrameMode(betterproto.Enum):
    """
    The frame mode specifies the point cloud frame's composition and can be
    used to fine tune the LiDAR to specific use cases.
    """

    FRAME_MODE_UNSPECIFIED = 0
    """Unspecified frame mode"""

    FRAME_MODE_UP_DOWN = 1
    """
    The laser will trigger both during up and downramping phase and a point
    cloud frame is the combination of the two. Points that are close in azimuth
    and elevation in both phases will be recorded up to two seconds apart, this
    mode is therefore recommended only for high frame rates or scenes without
    fast objects.
    """

    FRAME_MODE_UP = 2
    """
    The laser will only trigger during the upramping phase. Because no laser is
    fired during the downramping phase, this mode results in a more uniform
    motion deformation for fast objects.
    """

    FRAME_MODE_SEPARATE = 3
    """
    The laser will trigger both during up and downramping phase but separate
    point cloud frames will be emitted, which maximizes frame rate.
    """


@dataclass(eq=False, repr=False)
class Device(betterproto.Message):
    """This message describes a Blickfeld Lidar device"""

    fqdn_or_ip: str = betterproto.string_field(1)
    """Fully-qualified-domain-name / Hostname or IP address"""

    name: str = betterproto.string_field(2)
    """
    Human-readable name of the device Optional: Is filled out by the service if
    not given.
    """

    serial_number: str = betterproto.string_field(3)
    """
    Serial number of the device Optional: Is filled out by the service if not
    given.
    """

    class_: "DeviceClass" = betterproto.enum_field(4)
    """Device class Optional: Is filled out by the service if not given."""


@dataclass(eq=False, repr=False)
class Network(betterproto.Message):
    """
    * The "Network" protocol message allows to define and setup the network
    configuration of the Qb2 device which can be further applied by
    "SetConfig()" service API. The message specifies the desired network
    configuration mode: "dhcp", "link-local","static" or their combination, and
    allows custom static configuration of the device. Modes "dhcp" and "static"
    can be applied together. In this scenario, static configuration will be
    used if DHCP configuration fails. Applied configuration is persistent and
    will be available at Qb2 device boot up.
    """

    hostname: str = betterproto.string_field(1)
    """
    * Specifies the persistent system-wide hostname which should be assigned to
    the network device
    """

    dhcp: bool = betterproto.bool_field(2)
    """
    * This setting enables dynamic "DHCP" network configuration mode. The
    "DHCP" mode is used to dynamically get IPv4/v6 network configuration from
    DHCP server in automatic fashion. Can be used standalone or, if required,
    can be combined with "static" configuration settings.
    """

    manual: "NetworkStatic" = betterproto.message_field(3)
    """
    * This setting enables manual "Static" configuration. The "Static" mode
    allows to create custom static configurations for IPv4, IPv6 or their
    combination.
    """

    link_local: bool = betterproto.bool_field(4)
    """
    * (WIP - attention, no fallbacks!) This settings enables automatic "Link-
    local" network configuration mode. In this scenario, device itself selects
    and assigns IP addresses from a particular range. For IPv4: from
    169.254.0.0 through 169.254.255.255. The IPv6 link-local prefix is
    FE80::/10 and is used to create a link-local IPv6 address on an interface
    """

    wireless: "NetworkWireless" = betterproto.message_field(5)
    """
    If the field is set, the device switches from the Ethernet to the WiFi
    interface.
    """

    authentication: "NetworkAuthentication" = betterproto.message_field(6)
    """
    Authentication configuration for joining a network. If this field is set
    the device starts to communicate with a authentication server (e.g.
    RADIUS).
    """


@dataclass(eq=False, repr=False)
class NetworkStatic(betterproto.Message):
    """
    * Static configuration specifies IP settings configuration for IPv4, IPv6
    or their combination. Settings deliver the list of supported IP addresses,
    netmask, gateway, list of DNS servers and DNS search domain.
    """

    ipv4: "NetworkStaticIpv4" = betterproto.message_field(1)
    """Static IPv4 settings"""

    ipv6: "NetworkStaticIpv6" = betterproto.message_field(2)
    """Static IPv6 settings"""

    dns_domain: str = betterproto.string_field(3)
    """
    * The DNS domain field combined together with the hostname define FQDN
    (fully-qualified domain name), that specifies the exact location of Qb2
    device in the tree hierarchy of Domain Name System.
    """


@dataclass(eq=False, repr=False)
class NetworkStaticIpv4(betterproto.Message):
    ip: List[str] = betterproto.string_field(1)
    """
    * List of IPv4 addresses. Each address should be specified in dot-decimal
    format (quad-dotted notation of four decimal integers, ranging from 0 to
    255 each) including netmask prefix as follows "ip_address/prefix". Where
    netmask prefix should be set in CIDR notation (integer ranging from 0 to
    32).
    """

    gateway: str = betterproto.string_field(2)
    """Gateway IPv4 address"""

    dns_server: List[str] = betterproto.string_field(3)
    """List of IPv4 DNS servers"""


@dataclass(eq=False, repr=False)
class NetworkStaticIpv6(betterproto.Message):
    ip: List[str] = betterproto.string_field(1)
    """
    * List of IPv6 addresses. Each address should be specified as eight groups
    of four hexadecimal digits separated by colons and include netmask prefix
    as follows "ip/prefix". Where prefix should be set in CIDR notation
    (integer ranging from 0 to 128). IPv6 shortening rules are also supported.
    """

    gateway: str = betterproto.string_field(2)
    """Gateway IPv6 address"""

    dns_server: List[str] = betterproto.string_field(3)
    """List of IPv6 DNS servers"""


@dataclass(eq=False, repr=False)
class NetworkWireless(betterproto.Message):
    """
    If set, the device will turn of the Ethernet interface and connect to the
    given wireless access point. The Ethernet and WiFi interface cannot work
    simultanously.   [NOTE] Always use the validate method of the network
    service to ensure that the given credentials are correct. If the
    credentials are incorrect or the wireless access point is down, the
    fallback IP address can be used via the Ethernet interface to reset the
    network configuration.
    """

    ssid: str = betterproto.string_field(1)
    """SSID of the wireless network"""

    password: str = betterproto.string_field(2)
    """
    Password of the wireless network   [NOTE] If the password is not set and
    the SSID did not change, the existing password is used. This mechanism is
    applied as the password is never returned via the GetConfig API.
    """


@dataclass(eq=False, repr=False)
class NetworkAuthentication(betterproto.Message):
    """
    Authentication for networks   Interface to netplan & networkd, see
    https://netplan.readthedocs.io/en/latest/netplan-yaml/#authentication.
    """

    key_management: "NetworkAuthenticationKeyManagement" = betterproto.enum_field(1)
    """Selected key management"""

    password: str = betterproto.string_field(2)
    """
    Password in plain text corresponding the the account identity or username
    """

    eap_method: "NetworkAuthenticationEapMethod" = betterproto.enum_field(3)
    """Selected preferred EAP method"""

    identity: str = betterproto.string_field(4)
    """The account identity or username"""

    anonymous_identity: str = betterproto.string_field(5)
    """anonymous-identity (advanced configuration)"""

    ca_certificate: "__secure_config__.Certificate" = betterproto.message_field(6)
    """
    The RADIUS-server ca-certificate   For EAP-methods TLS, TTLS and PEAP this
    certificate is loaded and validated against the certificate presented from
    the server side.   The expected format is a x509, PEM in binary encoding.
    """

    client_certificate: "__secure_config__.Certificate" = betterproto.message_field(7)
    """
    The Client-certificate   The certificate to be used by the client during
    authentication when EAP-TLS is selected.
    """

    client_key: "__secure_config__.PrivateKey" = betterproto.message_field(8)
    """The client-key   Client key for the configured client certificate."""

    client_key_password: str = betterproto.string_field(9)
    """
    The client-key password   Password to use the configured client key (if
    encrypted).
    """

    phase2_auth: str = betterproto.string_field(10)
    """phase2-auth (advanced configuration)"""


@dataclass(eq=False, repr=False)
class ScanPattern(betterproto.Message):
    """
    * The scan pattern defines the movement of the mirrors. The key parameters
    of the pattern are the horizontal and vertical fields of view (FoV) as well
    as the number of scan lines per frame. The frame rate is defined by the
    total number of scan lines and the oscillation frequency of the mirrors
    which is fixed and device-specific.
    """

    horizontal: "ScanPatternHorizontal" = betterproto.message_field(1)
    vertical: "ScanPatternVertical" = betterproto.message_field(2)
    pulse: "ScanPatternPulse" = betterproto.message_field(3)
    read_only: bool = betterproto.bool_field(4)
    """
    this is an read_only flag and it will be set if this is a default scan
    pattern, which can't be changed or deleted.
    """

    frame_rate: "ScanPatternFrameRate" = betterproto.message_field(5)
    frame_mode: "ScanPatternFrameMode" = betterproto.enum_field(6)


@dataclass(eq=False, repr=False)
class ScanPatternHorizontal(betterproto.Message):
    """
    * This section defines the movement of the horizontal mirror. The mirror
    moves continuously with its own frequency. Each half-oscillation period of
    the mirror results in one scan line.
    """

    field_of_view: float = betterproto.float_field(1)
    """
    * Unit: [rad] – optical field of view of the horizontal mirror. Note: In
    v2.2* and below, this was defined as a mechanical FoV.
    """


@dataclass(eq=False, repr=False)
class ScanPatternVertical(betterproto.Message):
    """
    * This section defines the movement of the vertical mirror within one
    frame. The mirror moves for from 0 degrees to the configured target FoV
    (up-ramping phase) and back to 0 degrees (down-ramping phase) with its
    eigenfrequency. The number of scanlines for each phase can be configured.
    Due to the dynamics of the mirror, a certain number of scan lines are
    required to reach the target FoV and then to reach 0 degrees again.
    Consequently, if the limit is reached, a lower number of scan lines
    requires a reduced FoV. Thus, a higher number of scan lines allows a larger
    vertical FoV. The vertical FoV is limited by the optical components.
    Note: Due to the time required for one scan line, the rounded even number
    of scan lines directly scales inverse proportionally with the frame rate.
    """

    field_of_view: float = betterproto.float_field(1)
    """
    * Unit: [rad] – FoV in the center of the frame. Due to the eye shape of the
    scan pattern, the vertical FoV decreases the outer boundaries of the
    horizontal mirror.
    """

    scanlines_up: int = betterproto.uint32_field(2)
    """
    * Configures the number of scan lines required for the up-ramping phase.
    During the up-ramping phase, the vertical mirror increases its amplitude
    from 0 degrees to the target FoV. Default: 200
    """

    scanlines_down: int = betterproto.uint32_field(3)
    """
    * Configures the amount of scan lines required for the down-ramping phase.
    During the down-ramping phase, the vertical mirror decreases its amplitude
    from the target FoV to 0 degrees. Default: 30
    """

    foveation: "ScanPatternVerticalFoveation" = betterproto.message_field(4)
    """Optionally configures a foveated region."""


@dataclass(eq=False, repr=False)
class ScanPatternVerticalFoveation(betterproto.Message):
    """
    Configures a vertical field of view foveation.   This enables the user to
    specify a region of interest with a different scanline density which is
    defined as the number of scanlines per degree of vertical field of view.
    For constant frame rate this allows increasing the resolution in the region
    of interest without having to reduce the vertical field of view.
    """

    fraction: float = betterproto.float_field(1)
    """
    The fraction of the field of view that the density factor is applies to.
    The allowed value range is [0.15, 0.85].
    """

    density_factor: float = betterproto.float_field(2)
    """
    The foveation density factor defines the ratio of scanline density and
    consequently point density inside the foveated region compared to outside
    of it.
    """

    scanlines: int = betterproto.uint32_field(3)
    """
    Read-only parameter showing the number of scanlines in the foveated region.
    If the frame mode is set to up-down or separate, this applies to both the
    up-ramping and down-ramping phase individually.
    """


@dataclass(eq=False, repr=False)
class ScanPatternPulse(betterproto.Message):
    """
    This section defines the pattern in which the laser pulses and captures
    sample points
    """

    angle_spacing: float = betterproto.float_field(1)
    uniform: "ScanPatternPulseUniform" = betterproto.message_field(2)
    """Optional configure a uniform scan pattern"""

    disable_pre_pulse: bool = betterproto.bool_field(3)
    """
    Disable pre pulse   Circumvents pulse aggregation issues e.g. when retro-
    reflectors appear in more than 70m and cause cross talk in the main pulse
    measurement. Note that this increases the minimum range.
    """


@dataclass(eq=False, repr=False)
class ScanPatternPulseUniform(betterproto.Message):
    """
    Configure the uniform scan pattern   The classic scan pattern does not
    benefit uniformly from increasing the scanline count in a frame. The
    uniform scan pattern is an optimization that tries to provide an optimally
    homogeneous point cloud given the system's constraints. To configure the
    scan pattern, the vertical field of view, the target frame rate and the
    pulse mode are used.
    """

    pulse_mode: "__eye_safety_data__.PulseMode" = betterproto.enum_field(1)
    """
    Pulse mode to use for the uniform scan pattern. This will overwrite the
    horizontal angle spacing.
    """


@dataclass(eq=False, repr=False)
class ScanPatternFrameRate(betterproto.Message):
    """This section defines the frame rate of a scan pattern"""

    target: float = betterproto.double_field(1)
    """
    Target frame rate used to synchronize the point clouds of multiple LiDAR
    devices in a sensor setup
    """

    actual: float = betterproto.double_field(4)
    """
    Read-only parameter for the actual frame rate the LiDAR is currently
    running at
    """

    maximum: float = betterproto.double_field(2)
    """
    IMPORTANT: This field is deprecated. It has been replaced by "actual" and
    will not be supported in future releases.   Read-only parameter for maximum
    achievable frame rate of the scan pattern
    """

    def __post_init__(self) -> None:
        super().__post_init__()
        if self.is_set("maximum"):
            warnings.warn(
                "ScanPatternFrameRate.maximum is deprecated", DeprecationWarning
            )


@dataclass(eq=False, repr=False)
class NamedScanPattern(betterproto.Message):
    """
    Temporary container used for config storage TODO Remove when map type is
    supported.
    """

    name: str = betterproto.string_field(1)
    scan_pattern: "ScanPattern" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class TimeSynchronization(betterproto.Message):
    """
    Conifguration for the system time synchronization   The system time is used
    to fill timestamps in generated output data e.g. point cloud frames.
    """

    ntp: "TimeSynchronizationNtp" = betterproto.message_field(1, group="type")
    """Configuration for NTP time synchronization"""

    manual: "TimeSynchronizationManual" = betterproto.message_field(3, group="type")
    """Manual time configuration"""

    time_zone: str = betterproto.string_field(2)
    """
    Configure time zone of device.   Use ListTimeZones to retrieve the
    available time zones.   Default: UTC
    """


@dataclass(eq=False, repr=False)
class TimeSynchronizationNtp(betterproto.Message):
    """Configuration message for NTP time synchronization"""

    servers: List[str] = betterproto.string_field(1)
    """List of NTP time servers which are to be used"""


@dataclass(eq=False, repr=False)
class TimeSynchronizationManual(betterproto.Message):
    """
    Manual time configuration   [CAUTION] The device has no internal battery
    and no reference clock. Thus the timestamp has to be reconfigured after
    every power cycle and in regular intervals.
    """

    timestamp: int = betterproto.uint64_field(1)
    """
    Unix reference timestamp   [NOTE] The timestamp is ignored when unchanged.
    This prevents unintended time jumps when other configuration properties are
    modified.
    """
