Packages
grizzly
7.1.0
9.1.4
9.1.2
9.1.1
9.1.0
9.0.0
8.15.3
8.15.2
8.15.1
8.15.0
8.14.0
8.13.0
8.12.0
8.11.3
8.11.2
8.11.1
8.11.0
8.10.0
8.9.0
8.8.1
8.8.0
8.7.1
8.7.0
8.6.12
8.6.11
8.6.10
8.6.9
8.6.8
8.6.7
retired
8.6.6
8.6.5
8.6.4
8.6.3
8.6.2
8.6.1
8.6.0
8.5.3
8.5.2
8.5.1
8.5.0
8.4.0
8.3.0
8.2.3
8.2.2
8.2.1
8.2.0
8.1.0
8.0.1
8.0.0
7.4.3
7.4.2
7.4.1
7.4.0
7.3.0
7.2.0
7.1.4
7.1.3
7.1.2
7.1.1
7.1.0
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.8.8
6.8.7
6.8.6
6.8.5
6.8.4
6.8.3
6.8.2
6.8.1
6.8.0
6.7.1
6.7.0
6.6.1
6.6.0
6.5.1
6.5.0
6.4.0
6.3.0
6.2.0
6.1.1
6.1.0
6.0.1
6.0.0
5.4.1
5.4.0
5.3.0
5.2.8
5.2.7
5.2.6
5.2.5
5.2.4
5.2.3
5.2.2
5.2.1
5.2.0
5.1.2
5.1.1
5.1.0
5.0.2
5.0.1
5.0.0
4.0.1
4.0.0
3.0.0
2.1.0
2.0.0
1.0.1
1.0.0
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.2
0.20.1
0.20.0
0.19.1
0.19.0
0.18.3
0.18.2
0.18.1
0.18.0
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.9.0-rc.4
0.9.0-rc.3
0.9.0-rc.2
0.9.0-rc.1
0.9.0-rc.0
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
Elixir Z-Wave library
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/zwave.gen.command.ex
defmodule Mix.Tasks.Zwave.Gen.Command do
@moduledoc """
Generates the scaffolding for a new Z-Wave Command
mix zwave.gen.command ThermostatModeSet Thermostat mode
The pattern is
mix zwave.gen.command CommandModuleName CommandClassModule params....
Flags:
* `--no-save` - will print the generated module out to the console
* `--target-dir <path>` - will generate the new module at the provided path
* `--no_test` - if set, will not generate a test file
"""
use Mix.Task
@shortdoc "Generates the scaffolding for a new Z-Wave Command"
@switches [no_save: :boolean, target_dir: :string, no_test: :boolean]
def run(args) do
{opts, args, _} =
OptionParser.parse(args, switches: @switches)
command_name = args |> Enum.at(0) |> maybe_prompt("Command:")
command_id = args |> Enum.at(1) |> maybe_prompt_for_command_id()
command_class = args |> Enum.at(2) |> maybe_prompt("Command Class:")
params =
args
|> Enum.drop(3)
|> Enum.reverse()
|> Enum.map(&{&1, "any()"})
|> prompt_for_params(true)
|> Enum.reverse()
target_defs = build_target_defs(command_name, opts)
copy_files(target_defs, command_name, command_id, command_class, params, opts)
end
defp maybe_prompt(value, prompt) do
value = value || String.trim(Mix.shell().prompt(prompt))
if value == "" or not is_binary(value) do
maybe_prompt("", prompt)
else
value
end
end
defp maybe_prompt_for_command_id(id \\ nil) do
id = id || String.trim(Mix.shell().prompt("Command ID (hex):"))
case Regex.run(~r/^0?x?([0-9A-Fa-f]{2})$/, id) do
[_, id] -> "0x" <> String.upcase(id)
_ -> maybe_prompt_for_command_id()
end
end
defp print_param_help() do
Mix.shell().info("")
Mix.shell().info("Enter one of the following commands to add command parameters:")
Mix.shell().info("")
Mix.shell().info(["* ", :bright, "a <name> [<type>]", :reset, " - add a parameter"])
Mix.shell().info(["* ", :bright, "d <name>", :reset, " - delete a parameter by name"])
Mix.shell().info(["* ", :bright, "v", :reset, " - show parameter list"])
Mix.shell().info(["* ", :bright, "x", :reset, " - done entering parameters"])
Mix.shell().info(["* ", :bright, "?", :reset, " - display this message again"])
end
defp print_params(params) do
params
|> Enum.reverse()
|> Enum.each(fn {n, t} ->
Mix.shell().info(["* ", :green, :bright, ":#{n}", :reset, " :: ", :yellow, "#{t}", :reset])
end)
end
defp prompt_for_params(params, print_help \\ false) do
if print_help do
print_param_help()
end
Mix.shell().info("")
cmd =
Mix.shell().prompt(">")
|> String.trim()
|> String.downcase()
|> String.split(~r/\s+/)
case cmd do
["a", name, type] ->
type = if(String.ends_with?(type, "()"), do: type, else: type <> "()")
params = [{name, type} | params]
prompt_for_params(params)
["a", name] ->
params = [{name, "any()"} | params]
prompt_for_params(params)
["d", name] ->
params = Enum.reject(params, fn {n, _} -> n == name end)
prompt_for_params(params)
["v"] ->
print_params(params)
prompt_for_params(params)
["?"] ->
prompt_for_params(params, true)
["x"] ->
params
_ ->
prompt_for_params(params)
end
end
defp copy_files(target_defs, command_name, command_id, command_class, params, opts) do
command_module = Module.concat(Grizzly.ZWave.Commands, command_name)
command_name_snakecase = String.to_atom(Macro.underscore(command_name))
command_class_module = Module.concat(Grizzly.ZWave.CommandClasses, command_class)
bindings = [
params: params,
command_name: command_name_snakecase,
command_id: command_id,
command_module: command_module,
command_module_short: command_name,
command_class_module: command_class_module,
command_class_module_short: Module.concat([String.to_atom(command_class)])
]
Enum.each(target_defs, fn target_def ->
to_out(target_def, bindings, opts)
end)
end
defp to_out({:target, target_file, template_file}, bindings, opts) do
evaled = EEx.eval_file(template_file, bindings, trim: true)
evaled =
try do
Code.format_string!(evaled)
rescue
_ -> evaled
end
if Keyword.has_key?(opts, :no_save) do
IO.puts(evaled)
else
Mix.Generator.create_file(target_file, evaled)
end
:ok
end
defp to_out({:target_test, test_file, test_template_file}, bindings, opts) do
if Keyword.has_key?(opts, :no_test) || Keyword.has_key?(opts, :no_save) do
:ok
else
Mix.Generator.create_file(test_file, EEx.eval_file(test_template_file, bindings))
end
end
defp get_target(file_name, opts) do
case Keyword.get(opts, :target_dir) do
nil ->
Path.join([
File.cwd!(),
"lib",
"grizzly",
"zwave",
"commands",
"#{file_name}.ex"
])
target_dir ->
Path.join([File.cwd!(), "lib", target_dir, "#{file_name}.ex"])
end
end
defp get_test_target(file_name, opts) do
case Keyword.get(opts, :target_dir) do
nil ->
Path.join([
File.cwd!(),
"test",
"grizzly",
"zwave",
"commands",
"#{file_name}_test.exs"
])
target_dir ->
Path.join([File.cwd!(), "test", target_dir, "#{file_name}_test.exs"])
end
end
defp build_target_defs(command_name, opts) do
command_name_str = Macro.underscore(command_name)
grizzly_path = Application.app_dir(:grizzly)
target = get_target(command_name_str, opts)
test_target = get_test_target(command_name_str, opts)
target_template = Path.join(grizzly_path, "/priv/templates/zwave.gen/command.eex")
test_template = Path.join(grizzly_path, "/priv/templates/zwave.gen/command_test.eex")
[
{:target, target, target_template},
{:target_test, test_target, test_template}
]
end
end