Current section
Files
Jump to
Current section
Files
lib/mix/tasks/at.ex
defmodule Mix.Tasks.Exbee.At do
@moduledoc false
defmodule Query do
@switches [
serial_port: :string,
speed: :integer,
data_bits: :integer,
stop_bits: :integer,
parity: :integer,
flow_control: :atom
]
@shortdoc "Query AT configuration values."
@moduledoc """
#{@shortdoc}
Depending on the installed firmware, some parameters will respond with `invalid_command`.
Device options can either be passed via switches (ex: `--serial-port`) or they'll be read from
`:exbee` config values
Switch options include:
#{
@switches
|> Keyword.keys()
|> Enum.map(&("\n * --" <> (&1 |> to_string() |> String.replace("_", "-"))))
}
Examples:
Return a list of all AT parameter values:
> mix exbee.at.query --serial-port COM1 --speed 115200
SL: <<0x40, 0xB1, 0x90, 0x74>>
SM: invalid_command
VR: <<0x21, 0xA7>>
SN: <<0x0, 0x1>>
Return a single AT parameter value:
> mix exbee.at.query NJ
NJ: <<0xFF>>
"""
use Mix.Task
alias Exbee.{ATCommands, ATCommandFrame, Request}
def run(args) do
{device_args, commands, _} = OptionParser.parse(args, switches: @switches)
{:ok, response_frames} = commands |> parse_request_frames() |> Request.run(device_args)
for frame <- response_frames do
case frame do
%{command: command, value: value, status: :ok} ->
IO.puts("#{command}: #{inspect(value, base: :hex)}")
%{command: command, status: error_status} ->
IO.puts("#{command}: #{error_status}")
_ ->
nil
end
end
end
defp parse_request_frames([]), do: ATCommands.all() |> Map.keys() |> parse_request_frames()
defp parse_request_frames(commands) do
for command <- commands do
%ATCommandFrame{command: command}
end
end
end
defmodule Set do
@switches [
serial_port: :string,
speed: :integer,
data_bits: :integer,
stop_bits: :integer,
parity: :integer,
flow_control: :atom
]
@shortdoc "Set AT configuration values."
@moduledoc """
#{@shortdoc}
Device options can either be passed via switches (ex: `--serial-port`) or they'll be read from
`:exbee` config values
Switch options include:
#{
@switches
|> Keyword.keys()
|> Enum.map(&("\n * --" <> (&1 |> to_string() |> String.replace("_", "-"))))
}
Examples:
Set a single AT parameter values:
> mix exbee.at.query NJ=1 --serial-port COM1 --speed 115200
NJ: ok
Set multiple AT parameter values
> mix exbee.at.query NJ=255 DL='<<0x0, 0x0, 0xFF, 0xFF>>'
NJ: ok
DL: ok
"""
use Mix.Task
alias Exbee.{ATCommandFrame, Request}
def run(args) do
{device_args, command_pairs, _} = OptionParser.parse(args, switches: [serial_port: :string])
{:ok, response_frames} = command_pairs |> parse_request_frames() |> Request.run(device_args)
for frame <- response_frames do
case frame do
%{command: command, status: status} -> IO.puts("#{command}: #{status}")
other_frame -> IO.puts("#{inspect other_frame}")
end
end
end
def parse_request_frames(command_pairs) do
for command_pair <- command_pairs do
case String.split(command_pair, "=") do
[raw_command, raw_value] ->
{value, _} = Code.eval_string(raw_value)
%ATCommandFrame{command: String.upcase(raw_command), value: value}
_ ->
raise ArgumentError, message: "Unable to parse #{command_pair}."
end
end
end
end
defmodule Options do
@shortdoc "List available AT configuration options."
@moduledoc """
#{@shortdoc}
Example:
> mix exbee.at.options
SL: Serial Number Low
SM: Sleep Mode
VR: Firmware Version
"""
use Mix.Task
alias Exbee.{ATCommands}
def run(_args) do
for {command, description} <- ATCommands.all() do
IO.puts("#{command}: #{description}")
end
end
end
end