Current section
Files
Jump to
Current section
Files
lib/bacnet/protocol/services/utc_time_synchronization.ex
defmodule BACnet.Protocol.Services.UtcTimeSynchronization do
@moduledoc """
This module represents the BACnet UTC Time Synchronization service.
The UTC Time Synchronization service is used to send the correct UTC date and time onto the BACnet network or to a single recipient.
Service Description (ASHRAE 135):
> The UTCTimeSynchronization service is used by a requesting BACnet-user to notify one or more remote devices of the
> correct Universal Time Coordinated (UTC). This service may be broadcast, multicast, or addressed to a single recipient.
> Its purpose is to notify recipients of the correct UTC so that devices may synchronize their internal clocks with one another.
"""
alias BACnet.Protocol
alias BACnet.Protocol.Constants
require Constants
@behaviour Protocol.Services.Behaviour
# TODO: Docs
# TODO: Add Service Procedure to docs
@type t :: %__MODULE__{
date: Protocol.BACnetDate.t(),
time: Protocol.BACnetTime.t()
}
@fields [
:date,
:time
]
@enforce_keys @fields
defstruct @fields
@service_name Constants.macro_assert_name(
:unconfirmed_service_choice,
:utc_time_synchronization
)
@doc """
Get the service name atom.
"""
@spec get_name() :: atom()
def get_name(), do: @service_name
@doc """
Whether the service is of type confirmed or unconfirmed.
"""
@spec is_confirmed() :: false
def is_confirmed(), do: false
@doc """
Converts the given Unconfirmed Service Request into an UTC Time Synchronization Service.
"""
@spec from_apdu(Protocol.APDU.UnconfirmedServiceRequest.t()) ::
{:ok, t()} | {:error, term()}
def from_apdu(
%Protocol.APDU.UnconfirmedServiceRequest{
service: @service_name
} = request
) do
case request.parameters do
[
{:date, %Protocol.BACnetDate{} = date},
{:time, %Protocol.BACnetTime{} = time}
| _tail
] ->
sync = %__MODULE__{
date: date,
time: time
}
{:ok, sync}
_term ->
{:error, :invalid_request_parameters}
end
end
def from_apdu(%Protocol.APDU.UnconfirmedServiceRequest{} = _request) do
{:error, :invalid_request}
end
@doc """
Get the Unconfirmed Service request for the given UTC Time Synchronization Service.
See the `BACnet.Protocol.Services.Protocol` function documentation for more information.
"""
@spec to_apdu(t(), Keyword.t()) ::
{:ok, Protocol.APDU.UnconfirmedServiceRequest.t()}
| {:error, term()}
def to_apdu(
%__MODULE__{date: %Protocol.BACnetDate{} = date, time: %Protocol.BACnetTime{} = time} =
_service,
_request_data
) do
req = %Protocol.APDU.UnconfirmedServiceRequest{
service: @service_name,
parameters: [{:date, date}, {:time, time}]
}
{:ok, req}
end
defimpl Protocol.Services.Protocol do
alias BACnet.Protocol
alias BACnet.Protocol.Constants
require Constants
@spec get_name(@for.t()) :: atom()
def get_name(%@for{} = _service), do: @for.get_name()
@spec is_confirmed(@for.t()) :: boolean()
def is_confirmed(%@for{} = _service), do: @for.is_confirmed()
@spec to_apdu(@for.t(), Keyword.t()) ::
{:ok, Protocol.APDU.UnconfirmedServiceRequest.t()}
| {:error, term()}
def to_apdu(%@for{} = service, request_data), do: @for.to_apdu(service, request_data)
end
end