Current section
Files
Jump to
Current section
Files
lib/cantastic/obd2/request_specification.ex
defmodule Cantastic.OBD2.RequestSpecification do
@moduledoc false
alias Cantastic.OBD2.ParameterSpecification
@behaviour Access
defdelegate fetch(term, key), to: Map
defdelegate get(term, key, default), to: Map
defdelegate get_and_update(term, key, fun), to: Map
defdelegate pop(term, key), to: Map
@authorized_yaml_keys [:name, :request_frame_id, :response_frame_id, :frequency, :mode, :parameters, :anchors]
defstruct [
:name,
:request_frame_id,
:response_frame_id,
:frequency,
:mode,
:parameter_specifications,
:can_interface
]
def from_yaml(network_name, can_interface, yaml_obd2_request_specification) do
validate_keys!(network_name, yaml_obd2_request_specification)
yaml_parameter_specifications = yaml_obd2_request_specification[:parameters] || []
{:ok, parameter_specifications} = parameter_specifications(network_name, yaml_obd2_request_specification.name, yaml_parameter_specifications)
validate_parameter_specifications!(parameter_specifications)
request_specification = %__MODULE__{
name: yaml_obd2_request_specification.name,
request_frame_id: yaml_obd2_request_specification.request_frame_id,
response_frame_id: yaml_obd2_request_specification.response_frame_id,
frequency: yaml_obd2_request_specification.frequency,
mode: yaml_obd2_request_specification.mode,
parameter_specifications: parameter_specifications,
can_interface: can_interface
}
validate_specification!(request_specification)
{:ok, request_specification}
end
defp validate_keys!(network_name, yaml_obd2_request_specification) do
defined_keys = Map.keys(yaml_obd2_request_specification)
invalid_keys = MapSet.difference(MapSet.new(defined_keys), MapSet.new(@authorized_yaml_keys)) |> MapSet.to_list()
if invalid_keys != [] do
throw "[Yaml configuration error] OBD2 Request '#{network_name}.#{yaml_obd2_request_specification.name}' is defining invalid key: #{invalid_keys |> Enum.join(", ")}"
end
end
def validate_specification!(request_specificaton) do
if is_nil(request_specificaton.name) do
throw "[Yaml configuration error] OBD2 Request '#{request_specificaton.network_name}.#{request_specificaton.request_frame_id}' is missing a 'name'."
end
if is_nil(request_specificaton.request_frame_id) do
throw "[Yaml configuration error] OBD2 Request '#{request_specificaton.network_name}.#{request_specificaton.name}' is missing an 'request_frame_id'."
end
if is_nil(request_specificaton.response_frame_id) do
throw "[Yaml configuration error] OBD2 Request '#{request_specificaton.network_name}.#{request_specificaton.name}' is missing an 'response_frame_id'."
end
end
defp parameter_specifications(network_name, request_name, yaml_parameter_specifications) do
computed = yaml_parameter_specifications
|> Enum.map(fn (yaml_parameter_specification) ->
{:ok, parameter_specification} = ParameterSpecification.from_yaml(network_name, request_name, yaml_parameter_specification)
parameter_specification
end)
{:ok, computed}
end
defp validate_parameter_specifications!(parameter_specifications) do
parameter_specifications |> Enum.each(fn(parameter_specification) ->
ParameterSpecification.validate_specification!(parameter_specification)
end)
end
end