diff --git a/farmbot_celery_script/lib/farmbot_celery_script/ast.ex b/farmbot_celery_script/lib/farmbot_celery_script/ast.ex index 5fbe7601..3b831697 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/ast.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/ast.ex @@ -77,7 +77,8 @@ defmodule FarmbotCeleryScript.AST do end @spec new(atom, map, [map]) :: t() - def new(kind, args, body, comment \\ nil, meta \\ nil) when is_map(args) and is_list(body) do + def new(kind, args, body, comment \\ nil, meta \\ nil) + when is_map(args) and is_list(body) do %AST{ kind: String.to_atom(to_string(kind)), args: args, diff --git a/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex b/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex index 74d4d0a1..261ee9e5 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/ast/factory.ex @@ -19,12 +19,16 @@ defmodule FarmbotCeleryScript.AST.Factory do def read_pin(%AST{} = ast, pin_number, pin_mode) do ast - |> add_body_node(new(:read_pin, %{pin_number: pin_number, pin_mode: pin_mode})) + |> add_body_node( + new(:read_pin, %{pin_number: pin_number, pin_mode: pin_mode}) + ) end def set_pin_io_mode(%AST{} = ast, pin_number, pin_io_mode) do ast - |> add_body_node(new(:set_pin_io_mode, %{pin_number: pin_number, pin_io_mode: pin_io_mode})) + |> add_body_node( + new(:set_pin_io_mode, %{pin_number: pin_number, pin_io_mode: pin_io_mode}) + ) end def dump_info(%AST{} = ast) do diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex index 532c0d24..40c3a744 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compiler.ex @@ -155,14 +155,20 @@ defmodule FarmbotCeleryScript.Compiler do end end - def send_message(%{args: %{message: msg, message_type: type}, body: channels}, env) do + def send_message( + %{args: %{message: msg, message_type: type}, body: channels}, + env + ) do # body gets turned into a list of atoms. # Example: # [{kind: "channel", args: {channel_name: "email"}}] # is turned into: # [:email] channels = - Enum.map(channels, fn %{kind: :channel, args: %{channel_name: channel_name}} -> + Enum.map(channels, fn %{ + kind: :channel, + args: %{channel_name: channel_name} + } -> String.to_atom(channel_name) end) @@ -218,7 +224,9 @@ defmodule FarmbotCeleryScript.Compiler do def flash_firmware(%{args: %{package: package_name}}, env) do quote location: :keep do - FarmbotCeleryScript.SysCalls.flash_firmware(unquote(compile_ast(package_name, env))) + FarmbotCeleryScript.SysCalls.flash_firmware( + unquote(compile_ast(package_name, env)) + ) end end @@ -242,7 +250,9 @@ defmodule FarmbotCeleryScript.Compiler do def factory_reset(%{args: %{package: package}}, env) do quote location: :keep do - FarmbotCeleryScript.SysCalls.factory_reset(unquote(compile_ast(package, env))) + FarmbotCeleryScript.SysCalls.factory_reset( + unquote(compile_ast(package, env)) + ) end end diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compiler/utils.ex b/farmbot_celery_script/lib/farmbot_celery_script/compiler/utils.ex index bc76fc9d..092838fa 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compiler/utils.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compiler/utils.ex @@ -80,7 +80,8 @@ defmodule FarmbotCeleryScript.Compiler.Utils do var = quote location: :keep do - {unquote(next_scope_var_name), unquote(Compiler.compile_ast(data_value, env))} + {unquote(next_scope_var_name), + unquote(Compiler.compile_ast(data_value, env))} end compile_params_to_function_args(rest, env, [var | acc]) @@ -117,12 +118,19 @@ defmodule FarmbotCeleryScript.Compiler.Utils do parent = Keyword.get(params, :parent, %{x: 100, y: 200, z: 300}) """ - def compile_param_declaration(%{args: %{label: var_name, default_value: default}}, env) do + def compile_param_declaration( + %{args: %{label: var_name, default_value: default}}, + env + ) do var_name = IdentifierSanitizer.to_variable(var_name) quote location: :keep do unquote({var_name, env, __MODULE__}) = - Keyword.get(params, unquote(var_name), unquote(Compiler.compile_ast(default, env))) + Keyword.get( + params, + unquote(var_name), + unquote(Compiler.compile_ast(default, env)) + ) end end @@ -152,11 +160,15 @@ defmodule FarmbotCeleryScript.Compiler.Utils do ] } """ - def compile_param_application(%{args: %{label: var_name, data_value: value}}, env) do + def compile_param_application( + %{args: %{label: var_name, data_value: value}}, + env + ) do var_name = IdentifierSanitizer.to_variable(var_name) quote location: :keep do - unquote({var_name, [], __MODULE__}) = unquote(Compiler.compile_ast(value, env)) + unquote({var_name, [], __MODULE__}) = + unquote(Compiler.compile_ast(value, env)) end end @@ -168,13 +180,16 @@ defmodule FarmbotCeleryScript.Compiler.Utils do end) end - def add_sequence_init_and_complete_logs(steps, sequence_name) when is_binary(sequence_name) do + def add_sequence_init_and_complete_logs(steps, sequence_name) + when is_binary(sequence_name) do # This looks really weird because of the logs before and # after the compiled steps List.flatten([ quote do fn -> - FarmbotCeleryScript.SysCalls.sequence_init_log("Starting #{unquote(sequence_name)}") + FarmbotCeleryScript.SysCalls.sequence_init_log( + "Starting #{unquote(sequence_name)}" + ) end end, steps, @@ -201,7 +216,9 @@ defmodule FarmbotCeleryScript.Compiler.Utils do fn _ -> [ fn -> - FarmbotCeleryScript.SysCalls.sequence_init_log("Starting #{unquote(sequence_name)}") + FarmbotCeleryScript.SysCalls.sequence_init_log( + "Starting #{unquote(sequence_name)}" + ) end ] end diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/assertion_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/assertion_compiler.ex index 076b8780..54ddd9a3 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/assertion_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/assertion_compiler.ex @@ -4,7 +4,11 @@ defmodule FarmbotCeleryScript.Compiler.Assertion do @doc "`Assert` is a internal node useful for self testing." def assertion( %{ - args: %{lua: expression, assertion_type: assertion_type, _then: then_ast}, + args: %{ + lua: expression, + assertion_type: assertion_type, + _then: then_ast + }, comment: comment }, env @@ -80,7 +84,10 @@ defmodule FarmbotCeleryScript.Compiler.Assertion do then_block ++ [ - FarmbotCeleryScript.Compiler.compile(%AST{kind: :abort, args: %{}}, []) + FarmbotCeleryScript.Compiler.compile( + %AST{kind: :abort, args: %{}}, + [] + ) ] end end diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/axis_control_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/axis_control_compiler.ex index 813aeab0..15a81418 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/axis_control_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/axis_control_compiler.ex @@ -1,12 +1,17 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do alias FarmbotCeleryScript.Compiler # Compiles move_absolute - def move_absolute(%{args: %{location: location, offset: offset, speed: speed}}, env) do + def move_absolute( + %{args: %{location: location, offset: offset, speed: speed}}, + env + ) do quote location: :keep do # Extract the location arg - with %{x: locx, y: locy, z: locz} = unquote(Compiler.compile_ast(location, env)), + with %{x: locx, y: locy, z: locz} = + unquote(Compiler.compile_ast(location, env)), # Extract the offset arg - %{x: offx, y: offy, z: offz} = unquote(Compiler.compile_ast(offset, env)) do + %{x: offx, y: offy, z: offz} = + unquote(Compiler.compile_ast(offset, env)) do # Subtract the location from offset. # Note: list syntax here for readability. [x, y, z] = [ @@ -18,7 +23,11 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do x_str = FarmbotCeleryScript.FormatUtil.format_float(x) y_str = FarmbotCeleryScript.FormatUtil.format_float(y) z_str = FarmbotCeleryScript.FormatUtil.format_float(z) - FarmbotCeleryScript.SysCalls.log("Moving to (#{x_str}, #{y_str}, #{z_str})", true) + + FarmbotCeleryScript.SysCalls.log( + "Moving to (#{x_str}, #{y_str}, #{z_str})", + true + ) FarmbotCeleryScript.SysCalls.move_absolute( x, @@ -36,9 +45,12 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do with locx when is_number(locx) <- unquote(Compiler.compile_ast(x, env)), locy when is_number(locy) <- unquote(Compiler.compile_ast(y, env)), locz when is_number(locz) <- unquote(Compiler.compile_ast(z, env)), - curx when is_number(curx) <- FarmbotCeleryScript.SysCalls.get_current_x(), - cury when is_number(cury) <- FarmbotCeleryScript.SysCalls.get_current_y(), - curz when is_number(curz) <- FarmbotCeleryScript.SysCalls.get_current_z() do + curx when is_number(curx) <- + FarmbotCeleryScript.SysCalls.get_current_x(), + cury when is_number(cury) <- + FarmbotCeleryScript.SysCalls.get_current_y(), + curz when is_number(curz) <- + FarmbotCeleryScript.SysCalls.get_current_z() do # Combine them x = locx + curx y = locy + cury @@ -77,8 +89,13 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do # compiles find_home def find_home(%{args: %{axis: axis}}, env) do quote location: :keep do - with axis when axis in ["x", "y", "z"] <- unquote(Compiler.compile_ast(axis, env)) do - FarmbotCeleryScript.SysCalls.log("Finding home on the #{String.upcase(axis)} axis", true) + with axis when axis in ["x", "y", "z"] <- + unquote(Compiler.compile_ast(axis, env)) do + FarmbotCeleryScript.SysCalls.log( + "Finding home on the #{String.upcase(axis)} axis", + true + ) + FarmbotCeleryScript.SysCalls.find_home(axis) else {:error, reason} -> @@ -92,7 +109,8 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do quote location: :keep do FarmbotCeleryScript.SysCalls.log("Going to home on all axes", true) - with speed when is_number(speed) <- unquote(Compiler.compile_ast(speed, env)), + with speed when is_number(speed) <- + unquote(Compiler.compile_ast(speed, env)), :ok <- FarmbotCeleryScript.SysCalls.home("z", speed), :ok <- FarmbotCeleryScript.SysCalls.home("y", speed) do FarmbotCeleryScript.SysCalls.home("x", speed) @@ -103,9 +121,15 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do # compiles home def home(%{args: %{axis: axis, speed: speed}}, env) do quote location: :keep do - with axis when axis in ["x", "y", "z"] <- unquote(Compiler.compile_ast(axis, env)), - speed when is_number(speed) <- unquote(Compiler.compile_ast(speed, env)) do - FarmbotCeleryScript.SysCalls.log("Going to home on the #{String.upcase(axis)} axis", true) + with axis when axis in ["x", "y", "z"] <- + unquote(Compiler.compile_ast(axis, env)), + speed when is_number(speed) <- + unquote(Compiler.compile_ast(speed, env)) do + FarmbotCeleryScript.SysCalls.log( + "Going to home on the #{String.upcase(axis)} axis", + true + ) + FarmbotCeleryScript.SysCalls.home(axis, speed) else {:error, reason} -> @@ -129,8 +153,13 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do # compiles zero def zero(%{args: %{axis: axis}}, env) do quote location: :keep do - with axis when axis in ["x", "y", "z"] <- unquote(Compiler.compile_ast(axis, env)) do - FarmbotCeleryScript.SysCalls.log("Zeroing the #{String.upcase(axis)} axis", true) + with axis when axis in ["x", "y", "z"] <- + unquote(Compiler.compile_ast(axis, env)) do + FarmbotCeleryScript.SysCalls.log( + "Zeroing the #{String.upcase(axis)} axis", + true + ) + FarmbotCeleryScript.SysCalls.zero(axis) else {:error, reason} -> @@ -157,8 +186,13 @@ defmodule FarmbotCeleryScript.Compiler.AxisControl do # compiles calibrate def calibrate(%{args: %{axis: axis}}, env) do quote location: :keep do - with axis when axis in ["x", "y", "z"] <- unquote(Compiler.compile_ast(axis, env)) do - FarmbotCeleryScript.SysCalls.log("Calibrating the #{String.upcase(axis)} axis", true) + with axis when axis in ["x", "y", "z"] <- + unquote(Compiler.compile_ast(axis, env)) do + FarmbotCeleryScript.SysCalls.log( + "Calibrating the #{String.upcase(axis)} axis", + true + ) + FarmbotCeleryScript.SysCalls.calibrate(axis) else {:error, reason} -> diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/data_control_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/data_control_compiler.ex index 276eefac..d95a0457 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/data_control_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/data_control_compiler.ex @@ -42,7 +42,15 @@ defmodule FarmbotCeleryScript.Compiler.DataControl do end def resource_update( - %{args: %{resource_type: kind, resource_id: id, label: label, value: value}, body: body}, + %{ + args: %{ + resource_type: kind, + resource_id: id, + label: label, + value: value + }, + body: body + }, env ) do initial = %{label => value} diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/execute_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/execute_compiler.ex index 120b7cf6..b69ecd07 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/execute_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/execute_compiler.ex @@ -13,7 +13,8 @@ defmodule FarmbotCeleryScript.Compiler.Execute do loop_parameter_appl_ast = Enum.find_value(parameter_applications, fn # check if this parameter_application is a iterable type - %{kind: :parameter_application, args: %{data_value: %{kind: kind}}} = iterable + %{kind: :parameter_application, args: %{data_value: %{kind: kind}}} = + iterable when kind in @iterables -> iterable @@ -38,7 +39,10 @@ defmodule FarmbotCeleryScript.Compiler.Execute do %FarmbotCeleryScript.AST{kind: :sequence} = celery_ast -> celery_args = celery_ast.args - |> Map.put(:sequence_name, celery_ast.args[:name] || celery_ast.meta[:sequence_name]) + |> Map.put( + :sequence_name, + celery_ast.args[:name] || celery_ast.meta[:sequence_name] + ) |> Map.put(:locals, %{ celery_ast.args.locals | body: celery_ast.args.locals.body ++ unquote(param_appls) @@ -53,13 +57,20 @@ defmodule FarmbotCeleryScript.Compiler.Execute do end end - def compile_execute(%{args: %{sequence_id: id}, body: parameter_applications}, env) do + def compile_execute( + %{args: %{sequence_id: id}, body: parameter_applications}, + env + ) do quote location: :keep do # We have to lookup the sequence by it's id. case FarmbotCeleryScript.SysCalls.get_sequence(unquote(id)) do %FarmbotCeleryScript.AST{} = ast -> # compile the ast - env = unquote(compile_params_to_function_args(parameter_applications, env)) + env = + unquote( + compile_params_to_function_args(parameter_applications, env) + ) + FarmbotCeleryScript.Compiler.compile(ast, env) error -> diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/farmware_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/farmware_compiler.ex index 1596e27d..4df17a4f 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/farmware_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/farmware_compiler.ex @@ -30,7 +30,10 @@ defmodule FarmbotCeleryScript.Compiler.Farmware do kvs = Enum.map(pairs, fn %{kind: :pair, args: %{label: key, value: value}} -> quote location: :keep do - FarmbotCeleryScript.SysCalls.set_user_env(unquote(key), unquote(value)) + FarmbotCeleryScript.SysCalls.set_user_env( + unquote(key), + unquote(value) + ) end end) diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/if_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/if_compiler.ex index b3e3b711..12585a59 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/if_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/if_compiler.ex @@ -4,7 +4,15 @@ defmodule FarmbotCeleryScript.Compiler.If do # Compiles an if statement. def unquote(:_if)( - %{args: %{_then: then_ast, _else: else_ast, lhs: lhs_ast, op: op, rhs: rhs}}, + %{ + args: %{ + _then: then_ast, + _else: else_ast, + lhs: lhs_ast, + op: op, + rhs: rhs + } + }, env ) do rhs = Compiler.compile_ast(rhs, env) @@ -30,7 +38,10 @@ defmodule FarmbotCeleryScript.Compiler.If do "pin" <> pin -> quote [location: :keep], - do: FarmbotCeleryScript.SysCalls.read_cached_pin(unquote(String.to_integer(pin))) + do: + FarmbotCeleryScript.SysCalls.read_cached_pin( + unquote(String.to_integer(pin)) + ) # Named pin has two intents here # in this case we want to read the named pin. diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/pin_control_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/pin_control_compiler.ex index 7101ff0a..a8a6632c 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/pin_control_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/pin_control_compiler.ex @@ -1,7 +1,10 @@ defmodule FarmbotCeleryScript.Compiler.PinControl do alias FarmbotCeleryScript.Compiler # compiles write_pin - def write_pin(%{args: %{pin_number: num, pin_mode: mode, pin_value: value}}, env) do + def write_pin( + %{args: %{pin_number: num, pin_mode: mode, pin_value: value}}, + env + ) do quote location: :keep do pin = unquote(Compiler.compile_ast(num, env)) mode = unquote(Compiler.compile_ast(mode, env)) @@ -23,7 +26,10 @@ defmodule FarmbotCeleryScript.Compiler.PinControl do end # compiles set_servo_angle - def set_servo_angle(%{args: %{pin_number: pin_number, pin_value: pin_value}}, env) do + def set_servo_angle( + %{args: %{pin_number: pin_number, pin_value: pin_value}}, + env + ) do quote location: :keep do pin = unquote(Compiler.compile_ast(pin_number, env)) angle = unquote(Compiler.compile_ast(pin_value, env)) @@ -33,7 +39,10 @@ defmodule FarmbotCeleryScript.Compiler.PinControl do end # compiles set_pin_io_mode - def set_pin_io_mode(%{args: %{pin_number: pin_number, pin_io_mode: mode}}, env) do + def set_pin_io_mode( + %{args: %{pin_number: pin_number, pin_io_mode: mode}}, + env + ) do quote location: :keep do pin = unquote(Compiler.compile_ast(pin_number, env)) mode = unquote(Compiler.compile_ast(mode, env)) diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/sequence_compiler.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/sequence_compiler.ex index 8da27458..b03b0197 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/sequence_compiler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/sequence_compiler.ex @@ -10,7 +10,8 @@ defmodule FarmbotCeleryScript.Compiler.Sequence do loop_parameter_appl_ast = Enum.find_value(params_or_iterables, fn # check if this parameter_application is a iterable type - %{kind: :parameter_application, args: %{data_value: %{kind: kind}}} = iterable + %{kind: :parameter_application, args: %{data_value: %{kind: kind}}} = + iterable when kind in @iterables -> iterable @@ -25,22 +26,38 @@ defmodule FarmbotCeleryScript.Compiler.Sequence do def compile_sequence_iterable( loop_parameter_appl_ast, - %{args: %{locals: %{body: params} = locals} = sequence_args, meta: sequence_meta} = - sequence_ast, + %{ + args: %{locals: %{body: params} = locals} = sequence_args, + meta: sequence_meta + } = sequence_ast, env ) do - sequence_name = sequence_meta[:sequence_name] || sequence_args[:sequence_name] + sequence_name = + sequence_meta[:sequence_name] || sequence_args[:sequence_name] # remove the iterable from the parameter applications, # since it will be injected after this. _params = Enum.reduce(params, [], fn # Remove point_group from parameter appls - %{kind: :parameter_application, args: %{data_value: %{kind: :point_group}}}, acc -> acc + %{ + kind: :parameter_application, + args: %{data_value: %{kind: :point_group}} + }, + acc -> + acc + # Remove every_point from parameter appls - %{kind: :parameter_application, args: %{data_value: %{kind: :every_point}}}, acc -> acc + %{ + kind: :parameter_application, + args: %{data_value: %{kind: :every_point}} + }, + acc -> + acc + # Everything else gets added back - ast, acc -> acc ++ [ast] + ast, acc -> + acc ++ [ast] end) # will be a point_group or every_point node @@ -59,7 +76,8 @@ defmodule FarmbotCeleryScript.Compiler.Sequence do total = Enum.count(point_group.point_ids) # Map over all the points returned by `get_point_group/1` {body, _} = - Enum.reduce(point_group.point_ids, {[], 1}, fn point_id, {acc, index} -> + Enum.reduce(point_group.point_ids, {[], 1}, fn point_id, + {acc, index} -> # check if it's an every_point node first, if not fall back go generic pointer pointer_type = group_ast.args[:every_point_type] || "GenericPointer" @@ -83,7 +101,10 @@ defmodule FarmbotCeleryScript.Compiler.Sequence do %{name: name, x: x, y: y, z: z} -> pos = FarmbotCeleryScript.FormatUtil.format_coord(x, y, z) - "unnamed iterable sequence [#{index} / #{total}] - #{name} #{pos}" + + "unnamed iterable sequence [#{index} / #{total}] - #{name} #{ + pos + }" _ -> "unknown iterable [#{index} / #{total}]" @@ -113,7 +134,10 @@ defmodule FarmbotCeleryScript.Compiler.Sequence do end end - def compile_sequence(%{args: %{locals: %{body: params}} = args, body: block, meta: meta}, env) do + def compile_sequence( + %{args: %{locals: %{body: params}} = args, body: block, meta: meta}, + env + ) do # Sort the args.body into two arrays. # The `params` side gets turned into # a keyword list. These `params` are passed in from a previous sequence. diff --git a/farmbot_celery_script/lib/farmbot_celery_script/compilers/variable_declaration.ex b/farmbot_celery_script/lib/farmbot_celery_script/compilers/variable_declaration.ex index 6e367852..70ec7ed9 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/compilers/variable_declaration.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/compilers/variable_declaration.ex @@ -2,7 +2,10 @@ defmodule FarmbotCeleryScript.Compiler.VariableDeclaration do alias FarmbotCeleryScript.{Compiler, Compiler.IdentifierSanitizer} @doc "Compiles a variable asignment" - def variable_declaration(%{args: %{label: var_name, data_value: data_value_ast}}, env) do + def variable_declaration( + %{args: %{label: var_name, data_value: data_value_ast}}, + env + ) do # Compiles the `data_value` # and assigns the result to a variable named `label` # Example: @@ -26,7 +29,8 @@ defmodule FarmbotCeleryScript.Compiler.VariableDeclaration do var_name = IdentifierSanitizer.to_variable(var_name) quote location: :keep do - unquote({var_name, [], nil}) = unquote(Compiler.compile_ast(data_value_ast, env)) + unquote({var_name, [], nil}) = + unquote(Compiler.compile_ast(data_value_ast, env)) end end end diff --git a/farmbot_celery_script/lib/farmbot_celery_script/corpus.ex b/farmbot_celery_script/lib/farmbot_celery_script/corpus.ex index f0511047..88b574c8 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/corpus.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/corpus.ex @@ -18,14 +18,18 @@ defmodule FarmbotCeleryScript.Corpus do @corpus_tag tag # Load and decode each arg in the json into an Arg struct - @args Enum.map(args, fn %{"name" => name, "allowed_values" => allowed_values} = a -> + @args Enum.map(args, fn %{"name" => name, "allowed_values" => allowed_values} = + a -> %Arg{name: name, allowed_values: allowed_values, doc: a["doc"]} end) # Load and decode each node in the json into a Node struct. # This also expands the `allowed_args` into their respective Arg relationship. - @nodes Enum.map(@nodes, fn %{"name" => name, "allowed_args" => aa, "allowed_body_types" => abt} = - n -> + @nodes Enum.map(@nodes, fn %{ + "name" => name, + "allowed_args" => aa, + "allowed_body_types" => abt + } = n -> allowed_args = Enum.map(aa, fn arg_name -> Enum.find(@args, fn @@ -34,7 +38,12 @@ defmodule FarmbotCeleryScript.Corpus do end) || Mix.raise("Unknown CeleryScript argument: #{arg_name}") end) - %Node{name: name, allowed_args: allowed_args, allowed_body_types: abt, doc: n["doc"]} + %Node{ + name: name, + allowed_args: allowed_args, + allowed_body_types: abt, + doc: n["doc"] + } end) # Struct should never be created manually. diff --git a/farmbot_celery_script/lib/farmbot_celery_script/scheduler.ex b/farmbot_celery_script/lib/farmbot_celery_script/scheduler.ex index 51f35c47..36fd46a7 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/scheduler.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/scheduler.ex @@ -67,7 +67,12 @@ defmodule FarmbotCeleryScript.Scheduler do Calls are executed in a first in first out buffer, with things being added by `execute/2` taking priority. """ - @spec schedule(GenServer.server(), AST.t() | [Compiler.compiled()], DateTime.t(), map()) :: + @spec schedule( + GenServer.server(), + AST.t() | [Compiler.compiled()], + DateTime.t(), + map() + ) :: {:ok, reference()} def schedule(scheduler_pid \\ __MODULE__, celery_script, at, data) @@ -171,7 +176,9 @@ defmodule FarmbotCeleryScript.Scheduler do # now is late, but less than the grace period late diff_ms when diff_ms >= 0 when diff_ms <= @grace_period_ms -> - Logger.info("Next execution is ready for execution: #{Timex.from_now(at)}") + Logger.info( + "Next execution is ready for execution: #{Timex.from_now(at)}" + ) state |> execute_next() @@ -179,8 +186,15 @@ defmodule FarmbotCeleryScript.Scheduler do end end - def handle_info({:step_complete, {scheduled_at, executed_at, pid}, result}, state) do - send(pid, {FarmbotCeleryScript, {:scheduled_execution, scheduled_at, executed_at, result}}) + def handle_info( + {:step_complete, {scheduled_at, executed_at, pid}, result}, + state + ) do + send( + pid, + {FarmbotCeleryScript, + {:scheduled_execution, scheduled_at, executed_at, result}} + ) state |> pop_next() @@ -194,7 +208,9 @@ defmodule FarmbotCeleryScript.Scheduler do scheduler_pid = self() scheduled_pid = - spawn(fn -> StepRunner.step(scheduler_pid, {at, DateTime.utc_now(), pid}, compiled) end) + spawn(fn -> + StepRunner.step(scheduler_pid, {at, DateTime.utc_now(), pid}, compiled) + end) %{state | scheduled_pid: scheduled_pid} end @@ -291,7 +307,8 @@ defmodule FarmbotCeleryScript.Scheduler do %{state | monitors: monitors} end - @spec add(state(), compiled_ast(), DateTime.t(), data :: map(), pid()) :: state() + @spec add(state(), compiled_ast(), DateTime.t(), data :: map(), pid()) :: + state() defp add(state, compiled, at, data, pid) do %{state | compiled: [{compiled, at, data, pid} | state.compiled]} |> index_next() diff --git a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex index 19ea800a..d6a348f9 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls.ex @@ -21,7 +21,11 @@ defmodule FarmbotCeleryScript.SysCalls do @type resource_id :: integer() @callback calibrate(axis) :: ok_or_error - @callback change_ownership(email :: String.t(), secret :: binary(), server :: String.t()) :: + @callback change_ownership( + email :: String.t(), + secret :: binary(), + server :: String.t() + ) :: ok_or_error @callback check_update() :: ok_or_error @callback coordinate(x :: number, y :: number, z :: number) :: @@ -48,26 +52,39 @@ defmodule FarmbotCeleryScript.SysCalls do %{x: number(), y: number(), z: number()} | error() @callback home(axis, speed :: number()) :: ok_or_error @callback install_first_party_farmware() :: ok_or_error - @callback move_absolute(x :: number(), y :: number(), z :: number(), speed :: number()) :: + @callback move_absolute( + x :: number(), + y :: number(), + z :: number(), + speed :: number() + ) :: ok_or_error # ? - @callback named_pin(named_pin_type :: String.t(), resource_id) :: map() | integer | error() + @callback named_pin(named_pin_type :: String.t(), resource_id) :: + map() | integer | error() @callback nothing() :: any() @callback point(point_type :: String.t(), resource_id) :: number() | error() @callback power_off() :: ok_or_error - @callback read_pin(pin_num :: number(), pin_mode :: number()) :: number | error() + @callback read_pin(pin_num :: number(), pin_mode :: number()) :: + number | error() @callback read_cached_pin(pin_num :: number()) :: number | error() @callback toggle_pin(pin_num :: number()) :: ok_or_error @callback read_status() :: ok_or_error @callback reboot() :: ok_or_error @callback resource_update(String.t(), resource_id, map()) :: ok_or_error - @callback send_message(type :: String.t(), message :: String.t(), [atom]) :: ok_or_error + @callback send_message(type :: String.t(), message :: String.t(), [atom]) :: + ok_or_error @callback set_servo_angle(pin :: number(), value :: number()) :: ok_or_error @callback set_pin_io_mode(pin :: number(), mode :: number()) :: ok_or_error - @callback set_user_env(env_name :: String.t(), env_value :: String.t()) :: ok_or_error + @callback set_user_env(env_name :: String.t(), env_value :: String.t()) :: + ok_or_error @callback sync() :: ok_or_error @callback wait(millis :: number()) :: ok_or_error - @callback write_pin(pin_num :: number(), pin_mode :: number(), pin_value :: number) :: + @callback write_pin( + pin_num :: number(), + pin_mode :: number(), + pin_value :: number + ) :: ok_or_error @callback zero(axis) :: ok_or_error @@ -77,7 +94,9 @@ defmodule FarmbotCeleryScript.SysCalls do @callback eval_assertion(comment :: String.t(), expression :: String.t()) :: true | false | error() - @callback get_point_group(String.t() | resource_id) :: %{required(:point_ids) => [resource_id]} + @callback get_point_group(String.t() | resource_id) :: %{ + required(:point_ids) => [resource_id] + } def get_point_group(sys_calls \\ @sys_calls, point_group_id) do point_group_or_error(sys_calls, :get_point_group, [point_group_id]) @@ -90,14 +109,18 @@ defmodule FarmbotCeleryScript.SysCalls do def format_lhs(_sys_calls, "z"), do: "current z position" def format_lhs(_sys_calls, "pin" <> num), do: "Pin #{num} value" - def format_lhs(sys_calls, %{kind: :named_pin, args: %{pin_type: type, pin_id: pin_id}}) do + def format_lhs(sys_calls, %{ + kind: :named_pin, + args: %{pin_type: type, pin_id: pin_id} + }) do case named_pin(sys_calls, type, pin_id) do %{label: label} -> label {:error, _reason} -> "unknown left hand side" end end - def eval_assertion(sys_calls \\ @sys_calls, comment, expression) when is_binary(expression) do + def eval_assertion(sys_calls \\ @sys_calls, comment, expression) + when is_binary(expression) do case sys_calls.eval_assertion(comment, expression) do true -> true @@ -121,11 +144,13 @@ defmodule FarmbotCeleryScript.SysCalls do apply(@sys_calls, :log, [message, force?]) end - def sequence_init_log(sys_calls \\ @sys_calls, message) when is_binary(message) do + def sequence_init_log(sys_calls \\ @sys_calls, message) + when is_binary(message) do apply(sys_calls, :sequence_init_log, [message]) end - def sequence_complete_log(sys_calls \\ @sys_calls, message) when is_binary(message) do + def sequence_complete_log(sys_calls \\ @sys_calls, message) + when is_binary(message) do apply(sys_calls, :sequence_complete_log, [message]) end @@ -160,11 +185,13 @@ defmodule FarmbotCeleryScript.SysCalls do ok_or_error(sys_calls, :emergency_unlock, []) end - def execute_script(sys_calls \\ @sys_calls, package, %{} = env) when is_binary(package) do + def execute_script(sys_calls \\ @sys_calls, package, %{} = env) + when is_binary(package) do ok_or_error(sys_calls, :execute_script, [package, env]) end - def update_farmware(sys_calls \\ @sys_calls, package) when is_binary(package) do + def update_farmware(sys_calls \\ @sys_calls, package) + when is_binary(package) do ok_or_error(sys_calls, :update_farmware, [package]) end @@ -336,8 +363,14 @@ defmodule FarmbotCeleryScript.SysCalls do defp coord_or_error(sys_calls, fun, args) do case apply(sys_calls, fun, args) do - %{x: x, y: y, z: z} = coord when is_number(x) when is_number(y) when is_number(z) -> coord - error -> or_error(sys_calls, fun, args, error) + %{x: x, y: y, z: z} = coord + when is_number(x) + when is_number(y) + when is_number(z) -> + coord + + error -> + or_error(sys_calls, fun, args, error) end end @@ -348,7 +381,8 @@ defmodule FarmbotCeleryScript.SysCalls do end end - defp or_error(_sys_calls, _fun, _args, {:error, reason}) when is_binary(reason) do + defp or_error(_sys_calls, _fun, _args, {:error, reason}) + when is_binary(reason) do {:error, reason} end diff --git a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex index 9d3eb7aa..e6d6b09e 100644 --- a/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex +++ b/farmbot_celery_script/lib/farmbot_celery_script/sys_calls/stubs.ex @@ -77,25 +77,29 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do def get_sequence(resource_id), do: error(:get_sequence, [resource_id]) @impl true - def get_toolslot_for_tool(resource_id), do: error(:get_toolslot_for_tool, [resource_id]) + def get_toolslot_for_tool(resource_id), + do: error(:get_toolslot_for_tool, [resource_id]) @impl true def home(axis, speed), do: error(:home, [axis, speed]) @impl true - def install_first_party_farmware(), do: error(:install_first_party_farmware, []) + def install_first_party_farmware(), + do: error(:install_first_party_farmware, []) @impl true def move_absolute(x, y, z, speed), do: error(:move_absolute, [x, y, z, speed]) @impl true - def named_pin(named_pin_type, resource_id), do: error(:named_pin, [named_pin_type, resource_id]) + def named_pin(named_pin_type, resource_id), + do: error(:named_pin, [named_pin_type, resource_id]) @impl true def nothing(), do: error(:nothing, []) @impl true - def point(point_type, resource_id), do: error(:point, [point_type, resource_id]) + def point(point_type, resource_id), + do: error(:point, [point_type, resource_id]) @impl true def get_point_group(id_or_type), do: error(:get_point_group, [id_or_type]) @@ -123,7 +127,8 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do do: error(:resource_update, [kind, resource_id, data]) @impl true - def send_message(type, message, channels), do: error(:send_message, [type, message, channels]) + def send_message(type, message, channels), + do: error(:send_message, [type, message, channels]) @impl true def set_servo_angle(pin, value), do: error(:set_servo_angle, [pin, value]) @@ -132,7 +137,8 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do def set_pin_io_mode(pin, mode), do: error(:set_pin_io_mode, [pin, mode]) @impl true - def set_user_env(env_name, env_value), do: error(:set_user_env, [env_name, env_value]) + def set_user_env(env_name, env_value), + do: error(:set_user_env, [env_name, env_value]) @impl true def sync(), do: error(:sync, []) @@ -148,7 +154,8 @@ defmodule FarmbotCeleryScript.SysCalls.Stubs do def zero(axis), do: error(:zero, [axis]) @impl true - def eval_assertion(comment, expression), do: error(:eval_assertion, [comment, expression]) + def eval_assertion(comment, expression), + do: error(:eval_assertion, [comment, expression]) defp error(fun, _args) do msg = """ diff --git a/farmbot_celery_script/mix.exs b/farmbot_celery_script/mix.exs index 16636003..22de73da 100644 --- a/farmbot_celery_script/mix.exs +++ b/farmbot_celery_script/mix.exs @@ -1,7 +1,12 @@ defmodule FarmbotCeleryScript.MixProject do use Mix.Project - @version Path.join([__DIR__, "..", "VERSION"]) |> File.read!() |> String.trim() - @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) |> File.read!() |> String.trim() + + @version Path.join([__DIR__, "..", "VERSION"]) + |> File.read!() + |> String.trim() + @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) + |> File.read!() + |> String.trim() def project do [ @@ -39,7 +44,11 @@ defmodule FarmbotCeleryScript.MixProject do end def elixirc_paths(:test), - do: ["lib", Path.expand("./test/support"), Path.expand("../test/support/celery_script")] + do: [ + "lib", + Path.expand("./test/support"), + Path.expand("../test/support/celery_script") + ] def elixirc_paths(_), do: ["lib"] @@ -57,7 +66,8 @@ defmodule FarmbotCeleryScript.MixProject do {:jason, "~> 1.1"}, {:timex, "~> 3.4"}, {:excoveralls, "~> 0.10", only: [:test], targets: [:host]}, - {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], targets: [:host], runtime: false}, + {:dialyxir, "~> 1.0.0-rc.3", + only: [:dev], targets: [:host], runtime: false}, {:ex_doc, "~> 0.21.2", only: [:dev], targets: [:host], runtime: false} ] end diff --git a/farmbot_celery_script/test/farmbot_celery_script/compiler_test.exs b/farmbot_celery_script/test/farmbot_celery_script/compiler_test.exs index 5ab648af..409c981b 100644 --- a/farmbot_celery_script/test/farmbot_celery_script/compiler_test.exs +++ b/farmbot_celery_script/test/farmbot_celery_script/compiler_test.exs @@ -34,7 +34,10 @@ defmodule FarmbotCeleryScript.CompilerTest do # The compiler expects the `env` argument to be already sanatized. # When supplying the env for this test, we need to make sure the # `provided_by_caller` variable name is sanatized - sanatized_env = [{IdentifierSanitizer.to_variable("provided_by_caller"), 900}] + sanatized_env = [ + {IdentifierSanitizer.to_variable("provided_by_caller"), 900} + ] + [body_item] = Compiler.compile(sequence, sanatized_env) assert body_item.() == 900 @@ -48,7 +51,9 @@ defmodule FarmbotCeleryScript.CompilerTest do } ] - compiled_celery_env = Compiler.Utils.compile_params_to_function_args(celery_env, []) + compiled_celery_env = + Compiler.Utils.compile_params_to_function_args(celery_env, []) + [body_item] = Compiler.compile(sequence, compiled_celery_env) assert body_item.() == 600 end @@ -79,7 +84,10 @@ defmodule FarmbotCeleryScript.CompilerTest do identifier_ast = AST.Factory.new("identifier", label: label) parameter_application_ast = - AST.Factory.new("parameter_application", label: label, data_value: value_ast) + AST.Factory.new("parameter_application", + label: label, + data_value: value_ast + ) celery_ast = %AST{ kind: :sequence, diff --git a/farmbot_celery_script/test/farmbot_celery_script/scheduler_test.exs b/farmbot_celery_script/test/farmbot_celery_script/scheduler_test.exs index 4c7d8e61..c98bff0c 100644 --- a/farmbot_celery_script/test/farmbot_celery_script/scheduler_test.exs +++ b/farmbot_celery_script/test/farmbot_celery_script/scheduler_test.exs @@ -5,7 +5,10 @@ defmodule FarmbotCeleryScript.SchedulerTest do setup do {:ok, shim} = TestSysCalls.checkout() - {:ok, sch} = Scheduler.start_link([registry_name: :"#{:random.uniform()}"], []) + + {:ok, sch} = + Scheduler.start_link([registry_name: :"#{:random.uniform()}"], []) + [shim: shim, sch: sch] end @@ -26,6 +29,7 @@ defmodule FarmbotCeleryScript.SchedulerTest do scheduled_time = DateTime.utc_now() |> DateTime.add(100, :millisecond) {:ok, _} = Scheduler.schedule(sch, ast, scheduled_time, %{}) + # Hack to force the scheduler to checkup instead of waiting the normal 15 seconds send(sch, :checkup) assert_receive {:read_pin, [9, 0]}, 1000 diff --git a/farmbot_celery_script/test/farmbot_celery_script/sys_calls_test.exs b/farmbot_celery_script/test/farmbot_celery_script/sys_calls_test.exs index ca22ba64..46fa00cf 100644 --- a/farmbot_celery_script/test/farmbot_celery_script/sys_calls_test.exs +++ b/farmbot_celery_script/test/farmbot_celery_script/sys_calls_test.exs @@ -10,12 +10,16 @@ defmodule FarmbotCeleryScript.SysCallsTest do test "point", %{shim: shim} do :ok = shim_fun_ok(shim, %{x: 100, y: 200, z: 300}) - assert %{x: 100, y: 200, z: 300} = SysCalls.point(TestSysCalls, "Peripheral", 1) + + assert %{x: 100, y: 200, z: 300} = + SysCalls.point(TestSysCalls, "Peripheral", 1) + assert_receive {:point, ["Peripheral", 1]} :ok = shim_fun_error(shim, "point error") - assert {:error, "point error"} == SysCalls.point(TestSysCalls, "Peripheral", 1) + assert {:error, "point error"} == + SysCalls.point(TestSysCalls, "Peripheral", 1) end test "move_absolute", %{shim: shim} do @@ -25,7 +29,8 @@ defmodule FarmbotCeleryScript.SysCallsTest do :ok = shim_fun_error(shim, "move failed!") - assert {:error, "move failed!"} == SysCalls.move_absolute(TestSysCalls, 1, 2, 3, 4) + assert {:error, "move failed!"} == + SysCalls.move_absolute(TestSysCalls, 1, 2, 3, 4) end test "get current positions", %{shim: shim} do @@ -48,8 +53,12 @@ defmodule FarmbotCeleryScript.SysCallsTest do test "write_pin", %{shim: shim} do :ok = shim_fun_ok(shim) assert :ok = SysCalls.write_pin(TestSysCalls, 1, 0, 1) - assert :ok = SysCalls.write_pin(TestSysCalls, %{type: "boxled", id: 4}, 0, 1) - assert :ok = SysCalls.write_pin(TestSysCalls, %{type: "boxled", id: 3}, 1, 123) + + assert :ok = + SysCalls.write_pin(TestSysCalls, %{type: "boxled", id: 4}, 0, 1) + + assert :ok = + SysCalls.write_pin(TestSysCalls, %{type: "boxled", id: 3}, 1, 123) assert_receive {:write_pin, [1, 0, 1]} assert_receive {:write_pin, [%{type: "boxled", id: 4}, 0, 1]} @@ -57,7 +66,8 @@ defmodule FarmbotCeleryScript.SysCallsTest do :ok = shim_fun_error(shim, "firmware error") - assert {:error, "firmware error"} == SysCalls.write_pin(TestSysCalls, 1, 0, 1) + assert {:error, "firmware error"} == + SysCalls.write_pin(TestSysCalls, 1, 0, 1) end test "read_pin", %{shim: shim} do @@ -86,10 +96,14 @@ defmodule FarmbotCeleryScript.SysCallsTest do # BoxLed is on the GPIO :ok = shim_fun_ok(shim, %{type: "BoxLed", id: 3}) - assert %{type: "BoxLed", id: 3} == SysCalls.named_pin(TestSysCalls, "BoxLed", 3) + + assert %{type: "BoxLed", id: 3} == + SysCalls.named_pin(TestSysCalls, "BoxLed", 3) :ok = shim_fun_ok(shim, %{type: "BoxLed", id: 4}) - assert %{type: "BoxLed", id: 4} == SysCalls.named_pin(TestSysCalls, "BoxLed", 4) + + assert %{type: "BoxLed", id: 4} == + SysCalls.named_pin(TestSysCalls, "BoxLed", 4) assert_receive {:named_pin, ["Peripheral", 5]} assert_receive {:named_pin, ["Sensor", 1999]} @@ -104,13 +118,20 @@ defmodule FarmbotCeleryScript.SysCallsTest do test "send_message", %{shim: shim} do :ok = shim_fun_ok(shim) - assert :ok = SysCalls.send_message(TestSysCalls, "success", "hello world", ["email"]) + + assert :ok = + SysCalls.send_message(TestSysCalls, "success", "hello world", [ + "email" + ]) + assert_receive {:send_message, ["success", "hello world", ["email"]]} :ok = shim_fun_error(shim, "email machine broke") assert {:error, "email machine broke"} == - SysCalls.send_message(TestSysCalls, "error", "goodbye world", ["email"]) + SysCalls.send_message(TestSysCalls, "error", "goodbye world", [ + "email" + ]) end test "find_home", %{shim: shim} do @@ -130,7 +151,8 @@ defmodule FarmbotCeleryScript.SysCallsTest do :ok = shim_fun_error(shim, "not installed") - assert {:error, "not installed"} == SysCalls.execute_script(TestSysCalls, "take-photo", %{}) + assert {:error, "not installed"} == + SysCalls.execute_script(TestSysCalls, "take-photo", %{}) end test "set_servo_angle errors", %{shim: shim} do @@ -141,7 +163,9 @@ defmodule FarmbotCeleryScript.SysCallsTest do arg1 = [40, -5] :ok = shim_fun_error(shim, "boom") - assert {:error, "boom"} == SysCalls.set_servo_angle(TestSysCalls, "set_servo_angle", arg1) + + assert {:error, "boom"} == + SysCalls.set_servo_angle(TestSysCalls, "set_servo_angle", arg1) end test "get_sequence", %{shim: shim} do @@ -156,7 +180,8 @@ defmodule FarmbotCeleryScript.SysCallsTest do :ok = shim_fun_error(shim, "sequence not found") - assert {:error, "sequence not found"} == SysCalls.get_sequence(TestSysCalls, 123) + assert {:error, "sequence not found"} == + SysCalls.get_sequence(TestSysCalls, 123) end def shim_fun_ok(shim, val \\ :ok) do diff --git a/farmbot_celery_script/test/farmbot_celery_script_test.exs b/farmbot_celery_script/test/farmbot_celery_script_test.exs index 334e7a35..56fcd7fd 100644 --- a/farmbot_celery_script/test/farmbot_celery_script_test.exs +++ b/farmbot_celery_script/test/farmbot_celery_script_test.exs @@ -83,8 +83,11 @@ defmodule FarmbotCeleryScriptTest do :read_pin, _ -> {:error, "failed to read pin!"} end) - assert {:error, "failed to read pin!"} = FarmbotCeleryScript.execute(execute_ast, execute_ast) - assert_receive {:step_complete, ^execute_ast, {:error, "failed to read pin!"}} + assert {:error, "failed to read pin!"} = + FarmbotCeleryScript.execute(execute_ast, execute_ast) + + assert_receive {:step_complete, ^execute_ast, + {:error, "failed to read pin!"}} end test "regular exceptions still occur" do @@ -103,7 +106,9 @@ defmodule FarmbotCeleryScriptTest do :read_pin, _ -> raise("big oops") end) - assert {:error, "big oops"} == FarmbotCeleryScript.execute(execute_ast, execute_ast) + assert {:error, "big oops"} == + FarmbotCeleryScript.execute(execute_ast, execute_ast) + assert_receive {:step_complete, ^execute_ast, {:error, "big oops"}} end end diff --git a/farmbot_core/config/config.exs b/farmbot_core/config/config.exs index 9cc5a196..b6be4ce8 100644 --- a/farmbot_core/config/config.exs +++ b/farmbot_core/config/config.exs @@ -1,28 +1,34 @@ use Mix.Config -config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmEvent, checkup_time_ms: 10_000 +config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmEvent, + checkup_time_ms: 10_000 config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.RegimenInstance, checkup_time_ms: 10_000 -config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmwareInstallation, - error_retry_time_ms: 30_000, - install_dir: "/tmp/farmware" +config :farmbot_core, + FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmwareInstallation, + error_retry_time_ms: 30_000, + install_dir: "/tmp/farmware" -config :farmbot_core, FarmbotCore.FarmwareRuntime, runtime_dir: "/tmp/farmware_runtime" +config :farmbot_core, FarmbotCore.FarmwareRuntime, + runtime_dir: "/tmp/farmware_runtime" config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.PinBinding, gpio_handler: FarmbotCore.PinBindingWorker.StubGPIOHandler, error_retry_time_ms: 30_000 -config :farmbot_core, Elixir.FarmbotCore.AssetWorker.FarmbotCore.Asset.PublicKey, - ssh_handler: FarmbotCore.PublicKeyHandler.StubSSHHandler +config :farmbot_core, + Elixir.FarmbotCore.AssetWorker.FarmbotCore.Asset.PublicKey, + ssh_handler: FarmbotCore.PublicKeyHandler.StubSSHHandler config :farmbot_core, FarmbotCore.AssetMonitor, checkup_time_ms: 30_000 -config :farmbot_core, FarmbotCore.Leds, gpio_handler: FarmbotCore.Leds.StubHandler +config :farmbot_core, FarmbotCore.Leds, + gpio_handler: FarmbotCore.Leds.StubHandler -config :farmbot_core, FarmbotCore.JSON, json_parser: FarmbotCore.JSON.JasonParser +config :farmbot_core, FarmbotCore.JSON, + json_parser: FarmbotCore.JSON.JasonParser config :farmbot_core, FarmbotCore.BotState.FileSystem, root_dir: "/tmp/farmbot", @@ -36,7 +42,10 @@ config :farmbot_core, FarmbotCore.EctoMigrator, default_ntp_server_1: "0.pool.ntp.org", default_ntp_server_2: "1.pool.ntp.org", default_currently_on_beta: - String.contains?(to_string(:os.cmd('git rev-parse --abbrev-ref HEAD')), "beta") + String.contains?( + to_string(:os.cmd('git rev-parse --abbrev-ref HEAD')), + "beta" + ) config :farmbot_core, FarmbotCore.FirmwareTTYDetector, expected_names: [] diff --git a/farmbot_core/config/ecto.exs b/farmbot_core/config/ecto.exs index 855b780d..26010b51 100644 --- a/farmbot_core/config/ecto.exs +++ b/farmbot_core/config/ecto.exs @@ -2,7 +2,11 @@ use Mix.Config config :ecto, json_library: FarmbotCore.JSON config :farmbot_core, - ecto_repos: [FarmbotCore.Config.Repo, FarmbotCore.Logger.Repo, FarmbotCore.Asset.Repo] + ecto_repos: [ + FarmbotCore.Config.Repo, + FarmbotCore.Logger.Repo, + FarmbotCore.Asset.Repo + ] config :farmbot_core, FarmbotCore.Config.Repo, adapter: Sqlite.Ecto2, diff --git a/farmbot_core/config/test.exs b/farmbot_core/config/test.exs index 0bdffe0e..8d150ddb 100644 --- a/farmbot_core/config/test.exs +++ b/farmbot_core/config/test.exs @@ -4,7 +4,8 @@ use Mix.Config # To ensure other timers have time to timeout config :farmbot_core, FarmbotCore.AssetMonitor, checkup_time_ms: 500 -config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmEvent, checkup_time_ms: 1000 +config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmEvent, + checkup_time_ms: 1000 config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.RegimenInstance, checkup_time_ms: 1000 diff --git a/farmbot_core/mix.exs b/farmbot_core/mix.exs index b261db01..cd3f0740 100644 --- a/farmbot_core/mix.exs +++ b/farmbot_core/mix.exs @@ -1,9 +1,15 @@ defmodule FarmbotCore.MixProject do use Mix.Project @target System.get_env("MIX_TARGET") || "host" - @version Path.join([__DIR__, "..", "VERSION"]) |> File.read!() |> String.trim() - @branch System.cmd("git", ~w"rev-parse --abbrev-ref HEAD") |> elem(0) |> String.trim() - @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) |> File.read!() |> String.trim() + @version Path.join([__DIR__, "..", "VERSION"]) + |> File.read!() + |> String.trim() + @branch System.cmd("git", ~w"rev-parse --abbrev-ref HEAD") + |> elem(0) + |> String.trim() + @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) + |> File.read!() + |> String.trim() defp commit do System.cmd("git", ~w"rev-parse --verify HEAD") |> elem(0) |> String.trim() @@ -59,7 +65,8 @@ defmodule FarmbotCore.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:farmbot_celery_script, path: "../farmbot_celery_script", env: Mix.env()}, + {:farmbot_celery_script, + path: "../farmbot_celery_script", env: Mix.env()}, {:farmbot_firmware, path: "../farmbot_firmware", env: Mix.env()}, {:farmbot_telemetry, path: "../farmbot_telemetry", env: Mix.env()}, {:elixir_make, "~> 0.6", runtime: false}, @@ -68,7 +75,8 @@ defmodule FarmbotCore.MixProject do {:jason, "~> 1.1"}, {:muontrap, "~> 0.5"}, {:excoveralls, "~> 0.10", only: [:test], targets: [:host]}, - {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], targets: [:host], runtime: false}, + {:dialyxir, "~> 1.0.0-rc.3", + only: [:dev], targets: [:host], runtime: false}, {:ex_doc, "~> 0.21.2", only: [:dev], targets: [:host], runtime: false} ] end diff --git a/farmbot_core/priv/asset/migrations/20181022002450_create_persistent_regimens_table.exs b/farmbot_core/priv/asset/migrations/20181022002450_create_persistent_regimens_table.exs index 3994b57d..e7973ed3 100644 --- a/farmbot_core/priv/asset/migrations/20181022002450_create_persistent_regimens_table.exs +++ b/farmbot_core/priv/asset/migrations/20181022002450_create_persistent_regimens_table.exs @@ -8,13 +8,29 @@ defmodule FarmbotCore.Asset.Repo.Migrations.CreateRegimenInstancesTable do add(:epoch, :utc_datetime) add(:next, :utc_datetime) add(:next_sequence_id, :id) - add(:regimen_id, references("regimens", type: :binary_id, column: :local_id)) - add(:farm_event_id, references("farm_events", type: :binary_id, column: :local_id)) + + add( + :regimen_id, + references("regimens", type: :binary_id, column: :local_id) + ) + + add( + :farm_event_id, + references("farm_events", type: :binary_id, column: :local_id) + ) + add(:monitor, :boolean, default: true) timestamps(inserted_at: :created_at, type: :utc_datetime) end - create(unique_index("persistent_regimens", [:local_id, :regimen_id, :farm_event_id])) + create( + unique_index("persistent_regimens", [ + :local_id, + :regimen_id, + :farm_event_id + ]) + ) + create(unique_index("persistent_regimens", :started_at)) create(unique_index("persistent_regimens", :epoch)) end diff --git a/farmbot_core/priv/asset/migrations/20191212210054_resync_firmware_config.exs b/farmbot_core/priv/asset/migrations/20191212210054_resync_firmware_config.exs index f6b76236..97e4df90 100644 --- a/farmbot_core/priv/asset/migrations/20191212210054_resync_firmware_config.exs +++ b/farmbot_core/priv/asset/migrations/20191212210054_resync_firmware_config.exs @@ -9,6 +9,8 @@ defmodule FarmbotCore.Asset.Repo.Migrations.ResyncFirmwareConfig do end # will resync the firmware params - execute("UPDATE firmware_configs SET updated_at = \"1970-11-07 16:52:31.618000\"") + execute( + "UPDATE firmware_configs SET updated_at = \"1970-11-07 16:52:31.618000\"" + ) end end diff --git a/farmbot_core/priv/config/migrations/20170922221449_seed_groups.exs b/farmbot_core/priv/config/migrations/20170922221449_seed_groups.exs index 722f2352..91eb618e 100644 --- a/farmbot_core/priv/config/migrations/20170922221449_seed_groups.exs +++ b/farmbot_core/priv/config/migrations/20170922221449_seed_groups.exs @@ -5,7 +5,9 @@ defmodule FarmbotCore.Config.Repo.Migrations.SeedGroups do import Ecto.Query, only: [from: 2] @group_names ["authorization", "hardware_params", "settings"] - @default_server Application.get_env(:farmbot_core, Farmbot.EctoMigrator)[:default_server] || + @default_server Application.get_env(:farmbot_core, Farmbot.EctoMigrator)[ + :default_server + ] || "https://my.farm.bot" def change do @@ -23,14 +25,18 @@ defmodule FarmbotCore.Config.Repo.Migrations.SeedGroups do defp populate_config_values do for name <- @group_names do - [group_id] = from(g in Group, where: g.group_name == ^name, select: g.id) |> Repo.all() + [group_id] = + from(g in Group, where: g.group_name == ^name, select: g.id) + |> Repo.all() populate_config_values(name, group_id) end end defp populate_config_values("authorization", group_id) do - create_value(StringValue, @default_server) |> create_config(group_id, "server") + create_value(StringValue, @default_server) + |> create_config(group_id, "server") + create_value(StringValue, nil) |> create_config(group_id, "email") create_value(StringValue, nil) |> create_config(group_id, "password") create_value(StringValue, nil) |> create_config(group_id, "token") @@ -38,17 +44,32 @@ defmodule FarmbotCore.Config.Repo.Migrations.SeedGroups do defp populate_config_values("settings", group_id) do create_value(BoolValue, true) |> create_config(group_id, "os_auto_update") - create_value(BoolValue, true) |> create_config(group_id, "ignore_external_logs") + + create_value(BoolValue, true) + |> create_config(group_id, "ignore_external_logs") + create_value(BoolValue, true) |> create_config(group_id, "first_boot") create_value(BoolValue, true) |> create_config(group_id, "first_sync") create_value(StringValue, "A") |> create_config(group_id, "current_repo") - create_value(BoolValue, true) |> create_config(group_id, "first_party_farmware") + + create_value(BoolValue, true) + |> create_config(group_id, "first_party_farmware") + create_value(BoolValue, false) |> create_config(group_id, "auto_sync") - create_value(StringValue, nil) |> create_config(group_id, "firmware_hardware") + + create_value(StringValue, nil) + |> create_config(group_id, "firmware_hardware") + create_value(StringValue, nil) |> create_config(group_id, "timezone") create_value(StringValue, "{}") |> create_config(group_id, "user_env") - fpf_url = Application.get_env(:farmbot_core, :farmware)[:first_part_farmware_manifest_url] - create_value(StringValue, fpf_url) |> create_config(group_id, "first_party_farmware_url") + + fpf_url = + Application.get_env(:farmbot_core, :farmware)[ + :first_part_farmware_manifest_url + ] + + create_value(StringValue, fpf_url) + |> create_config(group_id, "first_party_farmware_url") end defp populate_config_values("hardware_params", group_id) do @@ -56,90 +77,250 @@ defmodule FarmbotCore.Config.Repo.Migrations.SeedGroups do create_value(FloatValue, nil) |> create_config(group_id, "param_test") create_value(FloatValue, nil) |> create_config(group_id, "param_config_ok") create_value(FloatValue, nil) |> create_config(group_id, "param_use_eeprom") - create_value(FloatValue, nil) |> create_config(group_id, "param_e_stop_on_mov_err") - create_value(FloatValue, nil) |> create_config(group_id, "param_mov_nr_retry") - create_value(FloatValue, nil) |> create_config(group_id, "movement_timeout_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_timeout_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_timeout_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_keep_active_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_keep_active_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_keep_active_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_at_boot_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_at_boot_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_at_boot_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_invert_endpoints_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_invert_endpoints_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_invert_endpoints_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_enable_endpoints_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_enable_endpoints_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_enable_endpoints_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_invert_motor_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_invert_motor_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_invert_motor_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_secondary_motor_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_secondary_motor_invert_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_steps_acc_dec_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_steps_acc_dec_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_steps_acc_dec_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_stop_at_home_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_stop_at_home_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_stop_at_home_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_up_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_up_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_up_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_step_per_mm_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_step_per_mm_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_step_per_mm_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_min_spd_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_min_spd_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_min_spd_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_spd_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_spd_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_home_spd_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_max_spd_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_max_spd_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_max_spd_z") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_enabled_x") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_enabled_y") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_enabled_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "param_e_stop_on_mov_err") + + create_value(FloatValue, nil) + |> create_config(group_id, "param_mov_nr_retry") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_timeout_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_timeout_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_timeout_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_keep_active_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_keep_active_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_keep_active_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_at_boot_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_at_boot_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_at_boot_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_invert_endpoints_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_invert_endpoints_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_invert_endpoints_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_enable_endpoints_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_enable_endpoints_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_enable_endpoints_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_invert_motor_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_invert_motor_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_invert_motor_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_secondary_motor_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_secondary_motor_invert_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_steps_acc_dec_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_steps_acc_dec_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_steps_acc_dec_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_stop_at_home_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_stop_at_home_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_stop_at_home_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_up_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_up_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_up_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_step_per_mm_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_step_per_mm_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_step_per_mm_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_min_spd_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_min_spd_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_min_spd_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_spd_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_spd_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_home_spd_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_max_spd_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_max_spd_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_max_spd_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_enabled_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_enabled_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_enabled_z") + create_value(FloatValue, nil) |> create_config(group_id, "encoder_type_x") create_value(FloatValue, nil) |> create_config(group_id, "encoder_type_y") create_value(FloatValue, nil) |> create_config(group_id, "encoder_type_z") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_missed_steps_max_x") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_missed_steps_max_y") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_missed_steps_max_z") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_scaling_x") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_scaling_y") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_scaling_z") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_missed_steps_decay_x") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_missed_steps_decay_y") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_missed_steps_decay_z") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_use_for_pos_x") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_use_for_pos_y") - create_value(FloatValue, nil) |> create_config(group_id, "encoder_use_for_pos_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_missed_steps_max_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_missed_steps_max_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_missed_steps_max_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_scaling_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_scaling_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_scaling_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_missed_steps_decay_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_missed_steps_decay_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_missed_steps_decay_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_use_for_pos_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_use_for_pos_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "encoder_use_for_pos_z") + create_value(FloatValue, nil) |> create_config(group_id, "encoder_invert_x") create_value(FloatValue, nil) |> create_config(group_id, "encoder_invert_y") create_value(FloatValue, nil) |> create_config(group_id, "encoder_invert_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_axis_nr_steps_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_axis_nr_steps_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_axis_nr_steps_z") - create_value(FloatValue, nil) |> create_config(group_id, "movement_stop_at_max_x") - create_value(FloatValue, nil) |> create_config(group_id, "movement_stop_at_max_y") - create_value(FloatValue, nil) |> create_config(group_id, "movement_stop_at_max_z") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_1_pin_nr") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_1_time_out") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_1_active_state") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_2_pin_nr") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_2_time_out") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_2_active_state") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_3_pin_nr") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_3_time_out") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_3_active_state") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_4_pin_nr") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_4_time_out") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_4_active_state") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_5_pin_nr") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_5_time_out") - create_value(FloatValue, nil) |> create_config(group_id, "pin_guard_5_active_state") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_axis_nr_steps_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_axis_nr_steps_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_axis_nr_steps_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_stop_at_max_x") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_stop_at_max_y") + + create_value(FloatValue, nil) + |> create_config(group_id, "movement_stop_at_max_z") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_1_pin_nr") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_1_time_out") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_1_active_state") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_2_pin_nr") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_2_time_out") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_2_active_state") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_3_pin_nr") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_3_time_out") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_3_active_state") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_4_pin_nr") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_4_time_out") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_4_active_state") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_5_pin_nr") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_5_time_out") + + create_value(FloatValue, nil) + |> create_config(group_id, "pin_guard_5_active_state") end end diff --git a/farmbot_core/priv/config/migrations/20171208205940_add_firmware_io_log.exs b/farmbot_core/priv/config/migrations/20171208205940_add_firmware_io_log.exs index 8f536891..6552a730 100644 --- a/farmbot_core/priv/config/migrations/20171208205940_add_firmware_io_log.exs +++ b/farmbot_core/priv/config/migrations/20171208205940_add_firmware_io_log.exs @@ -3,12 +3,22 @@ defmodule FarmbotCore.Config.Repo.Migrations.AddFirmwareIoLog do import FarmbotCore.Config.MigrationHelpers - @default_firmware_io_logs Application.get_env(:farmbot_core, Farmbot.EctoMigrator)[ - :default_firmware_io_logs - ] || false + @default_firmware_io_logs Application.get_env( + :farmbot_core, + Farmbot.EctoMigrator + )[:default_firmware_io_logs] || false def change do - create_settings_config("firmware_input_log", :bool, @default_firmware_io_logs) - create_settings_config("firmware_output_log", :bool, @default_firmware_io_logs) + create_settings_config( + "firmware_input_log", + :bool, + @default_firmware_io_logs + ) + + create_settings_config( + "firmware_output_log", + :bool, + @default_firmware_io_logs + ) end end diff --git a/farmbot_core/priv/config/migrations/20180416165217_add_beta_state.exs b/farmbot_core/priv/config/migrations/20180416165217_add_beta_state.exs index 1e46b6d3..924655b2 100644 --- a/farmbot_core/priv/config/migrations/20180416165217_add_beta_state.exs +++ b/farmbot_core/priv/config/migrations/20180416165217_add_beta_state.exs @@ -2,14 +2,20 @@ defmodule FarmbotCore.Config.Repo.Migrations.AddBetaState do use Ecto.Migration import FarmbotCore.Config.MigrationHelpers - @default_currently_on_beta Application.get_env(:farmbot_core, FarmbotCore.EctoMigrator)[ - :default_currently_on_beta - ] + @default_currently_on_beta Application.get_env( + :farmbot_core, + FarmbotCore.EctoMigrator + )[:default_currently_on_beta] if is_nil(@default_currently_on_beta), - do: Mix.raise("Missing application env config: `:default_currently_on_beta`") + do: + Mix.raise("Missing application env config: `:default_currently_on_beta`") def change do - create_settings_config("currently_on_beta", :bool, @default_currently_on_beta) + create_settings_config( + "currently_on_beta", + :bool, + @default_currently_on_beta + ) end end diff --git a/farmbot_core/priv/config/migrations/20180702143518_add_ntp_and_dns_configs.exs b/farmbot_core/priv/config/migrations/20180702143518_add_ntp_and_dns_configs.exs index ce7f3280..daaeb9d5 100644 --- a/farmbot_core/priv/config/migrations/20180702143518_add_ntp_and_dns_configs.exs +++ b/farmbot_core/priv/config/migrations/20180702143518_add_ntp_and_dns_configs.exs @@ -2,12 +2,14 @@ defmodule FarmbotCore.Config.Repo.Migrations.AddNtpAndDnsConfigs do use Ecto.Migration import FarmbotCore.Config.MigrationHelpers - @default_ntp_server_1 Application.get_env(:farmbot_core, FarmbotCore.EctoMigrator)[ - :default_ntp_server_1 - ] - @default_ntp_server_2 Application.get_env(:farmbot_core, FarmbotCore.EctoMigrator)[ - :default_ntp_server_2 - ] + @default_ntp_server_1 Application.get_env( + :farmbot_core, + FarmbotCore.EctoMigrator + )[:default_ntp_server_1] + @default_ntp_server_2 Application.get_env( + :farmbot_core, + FarmbotCore.EctoMigrator + )[:default_ntp_server_2] @default_dns_name Application.get_env(:farmbot_core, FarmbotCore.EctoMigrator)[ :default_dns_name ] @@ -30,8 +32,18 @@ defmodule FarmbotCore.Config.Repo.Migrations.AddNtpAndDnsConfigs do do: raise(@config_error) def change do - create_settings_config("default_ntp_server_1", :string, @default_ntp_server_1) - create_settings_config("default_ntp_server_2", :string, @default_ntp_server_2) + create_settings_config( + "default_ntp_server_1", + :string, + @default_ntp_server_1 + ) + + create_settings_config( + "default_ntp_server_2", + :string, + @default_ntp_server_2 + ) + create_settings_config("default_dns_name", :string, @default_dns_name) end end diff --git a/farmbot_core/priv/config/migrations/20180724200909_migrate_secret.exs b/farmbot_core/priv/config/migrations/20180724200909_migrate_secret.exs index 954ec883..b3abdbdb 100644 --- a/farmbot_core/priv/config/migrations/20180724200909_migrate_secret.exs +++ b/farmbot_core/priv/config/migrations/20180724200909_migrate_secret.exs @@ -5,7 +5,9 @@ defmodule FarmbotCore.Config.Repo.Migrations.MigrateSecret do def change do group = FarmbotCore.Config.Repo.one!( - from(g in FarmbotCore.Config.Group, where: g.group_name == "authorization") + from(g in FarmbotCore.Config.Group, + where: g.group_name == "authorization" + ) ) pass_ref = @@ -17,17 +19,23 @@ defmodule FarmbotCore.Config.Repo.Migrations.MigrateSecret do sec_ref = FarmbotCore.Config.Repo.one!( - from(c in FarmbotCore.Config.Config, where: c.key == "secret" and c.group_id == ^group.id) + from(c in FarmbotCore.Config.Config, + where: c.key == "secret" and c.group_id == ^group.id + ) ) pass = FarmbotCore.Config.Repo.one!( - from(s in FarmbotCore.Config.StringValue, where: s.id == ^pass_ref.string_value_id) + from(s in FarmbotCore.Config.StringValue, + where: s.id == ^pass_ref.string_value_id + ) ) sec = FarmbotCore.Config.Repo.one!( - from(s in FarmbotCore.Config.StringValue, where: s.id == ^sec_ref.string_value_id) + from(s in FarmbotCore.Config.StringValue, + where: s.id == ^sec_ref.string_value_id + ) ) if pass.value do diff --git a/farmbot_core/priv/config/migrations/20191022175032_set_firmware_flash_true.exs b/farmbot_core/priv/config/migrations/20191022175032_set_firmware_flash_true.exs index 60d56702..fc574148 100644 --- a/farmbot_core/priv/config/migrations/20191022175032_set_firmware_flash_true.exs +++ b/farmbot_core/priv/config/migrations/20191022175032_set_firmware_flash_true.exs @@ -2,10 +2,20 @@ defmodule FarmbotCore.Config.Repo.Migrations.SetFirmwareFlashTrue do use Ecto.Migration def up do - FarmbotCore.Config.update_config_value(:bool, "settings", "firmware_needs_flash", true) + FarmbotCore.Config.update_config_value( + :bool, + "settings", + "firmware_needs_flash", + true + ) end def down do - FarmbotCore.Config.update_config_value(:bool, "settings", "firmware_needs_flash", true) + FarmbotCore.Config.update_config_value( + :bool, + "settings", + "firmware_needs_flash", + true + ) end end diff --git a/farmbot_core/test/asset/command_test.exs b/farmbot_core/test/asset/command_test.exs index 8c1923ca..03a80528 100644 --- a/farmbot_core/test/asset/command_test.exs +++ b/farmbot_core/test/asset/command_test.exs @@ -31,8 +31,16 @@ defmodule FarmbotCore.Asset.CommandTest do test "update farm_event" do id = id() regimen_id = id() - :ok = Command.update("FarmEvent", id, %{id: id, executable_type: "Sequence", monitor: false}) - :ok = Command.update("Regimen", regimen_id, %{id: regimen_id, monitor: false}) + + :ok = + Command.update("FarmEvent", id, %{ + id: id, + executable_type: "Sequence", + monitor: false + }) + + :ok = + Command.update("Regimen", regimen_id, %{id: regimen_id, monitor: false}) :ok = Command.update("FarmEvent", id, %{ @@ -49,7 +57,12 @@ defmodule FarmbotCore.Asset.CommandTest do id = id() :ok = - Command.update("FarmEvent", id, %{id: id, executable_id: id(), name: "abc", monitor: false}) + Command.update("FarmEvent", id, %{ + id: id, + executable_id: id(), + name: "abc", + monitor: false + }) :ok = Command.update("FarmEvent", id, nil) refute Asset.get_farm_event(id) diff --git a/farmbot_core/test/asset_test.exs b/farmbot_core/test/asset_test.exs index a8a37d09..e17ddf25 100644 --- a/farmbot_core/test/asset_test.exs +++ b/farmbot_core/test/asset_test.exs @@ -7,7 +7,10 @@ defmodule FarmbotCore.AssetTest do describe "regimen instances" do test "creates a regimen instance" do seq = sequence() - reg = regimen(%{regimen_items: [%{time_offset: 100, sequence_id: seq.id}]}) + + reg = + regimen(%{regimen_items: [%{time_offset: 100, sequence_id: seq.id}]}) + event = regimen_event(reg) assert %RegimenInstance{} = Asset.new_regimen_instance!(event) end diff --git a/farmbot_core/test/bot_state/filesystem_test.exs b/farmbot_core/test/bot_state/filesystem_test.exs index 965392e5..cf0de99c 100644 --- a/farmbot_core/test/bot_state/filesystem_test.exs +++ b/farmbot_core/test/bot_state/filesystem_test.exs @@ -4,13 +4,20 @@ defmodule FarmbotCore.BotState.FileSystemTest do describe "serializer" do test "arrays not aloud" do - assert_raise RuntimeError, "Arrays can not be serialized to filesystem nodes", fn -> - FileSystem.serialize_state(%{key: [:value, :nope]}, "/") - end + assert_raise RuntimeError, + "Arrays can not be serialized to filesystem nodes", + fn -> + FileSystem.serialize_state(%{key: [:value, :nope]}, "/") + end end test "serializes a map to the filesystem" do - root_dir = Path.join([System.tmp_dir!(), Ecto.UUID.generate(), "-farmbot-map-serializer"]) + root_dir = + Path.join([ + System.tmp_dir!(), + Ecto.UUID.generate(), + "-farmbot-map-serializer" + ]) fixture = %{ a_string: "hello", @@ -54,11 +61,21 @@ defmodule FarmbotCore.BotState.FileSystemTest do describe "server" do test "serializes state to fs" do - root_dir = Path.join([System.tmp_dir!(), Ecto.UUID.generate(), "-farmbot-bot-state"]) + root_dir = + Path.join([ + System.tmp_dir!(), + Ecto.UUID.generate(), + "-farmbot-bot-state" + ]) + {:ok, bot_state_pid} = BotState.start_link([], []) {:ok, _pid} = - FileSystem.start_link(root_dir: root_dir, bot_state: bot_state_pid, sleep_time: 0) + FileSystem.start_link( + root_dir: root_dir, + bot_state: bot_state_pid, + sleep_time: 0 + ) _ = BotState.subscribe(bot_state_pid) :ok = BotState.set_pin_value(bot_state_pid, 1, 1) diff --git a/farmbot_core/test/bot_state_ng_test.exs b/farmbot_core/test/bot_state_ng_test.exs index dceb8c55..e4ac780e 100644 --- a/farmbot_core/test/bot_state_ng_test.exs +++ b/farmbot_core/test/bot_state_ng_test.exs @@ -47,13 +47,17 @@ defmodule FarmbotCore.BotStateNGTest do assert orig.informational_settings.update_available == false mut1 = - BotStateNG.changeset(orig, %{informational_settings: %{update_available: true}}) + BotStateNG.changeset(orig, %{ + informational_settings: %{update_available: true} + }) |> Ecto.Changeset.apply_changes() assert mut1.informational_settings.update_available == true mut2 = - BotStateNG.changeset(orig, %{informational_settings: %{update_available: false}}) + BotStateNG.changeset(orig, %{ + informational_settings: %{update_available: false} + }) |> Ecto.Changeset.apply_changes() assert mut2.informational_settings.update_available == false @@ -83,7 +87,9 @@ defmodule FarmbotCore.BotStateNGTest do orig = BotStateNG.new() mut = - BotStateNG.changeset(orig, %{informational_settings: %{memory_usage: 512}}) + BotStateNG.changeset(orig, %{ + informational_settings: %{memory_usage: 512} + }) |> Ecto.Changeset.apply_changes() assert mut.informational_settings.memory_usage == 512 @@ -93,7 +99,9 @@ defmodule FarmbotCore.BotStateNGTest do orig = BotStateNG.new() mut = - BotStateNG.changeset(orig, %{informational_settings: %{scheduler_usage: 10}}) + BotStateNG.changeset(orig, %{ + informational_settings: %{scheduler_usage: 10} + }) |> Ecto.Changeset.apply_changes() assert mut.informational_settings.scheduler_usage == 10 diff --git a/farmbot_firmware/lib/farmbot_firmware.ex b/farmbot_firmware/lib/farmbot_firmware.ex index afcd88eb..74a78248 100644 --- a/farmbot_firmware/lib/farmbot_firmware.ex +++ b/farmbot_firmware/lib/farmbot_firmware.ex @@ -257,7 +257,9 @@ defmodule FarmbotFirmware do nil tape_path -> - {:ok, vcr_fd} = File.open(tape_path, [:binary, :append, :exclusive, :write]) + {:ok, vcr_fd} = + File.open(tape_path, [:binary, :append, :exclusive, :write]) + vcr_fd end @@ -293,14 +295,24 @@ defmodule FarmbotFirmware do end def handle_info(:timeout, %{status: :transport_boot, reset_pid: nil} = state) do - case GenServer.start_link(state.reset, state.transport_args, name: state.reset) do + case GenServer.start_link(state.reset, state.transport_args, + name: state.reset + ) do {:ok, pid} -> - Logger.debug("Firmware reset #{state.reset} started. #{inspect(state.transport_args)}") + Logger.debug( + "Firmware reset #{state.reset} started. #{ + inspect(state.transport_args) + }" + ) + {:noreply, %{state | reset_pid: pid}} # TODO(Rick): I have no idea what's going on here. {:error, {:already_started, pid}} -> - Logger.debug("Firmware reset complete. #{inspect(state.transport_args)}") + Logger.debug( + "Firmware reset complete. #{inspect(state.transport_args)}" + ) + {:noreply, %{state | reset_pid: pid}} error -> @@ -320,7 +332,9 @@ defmodule FarmbotFirmware do ref = Process.monitor(pid) Logger.debug( - "Firmware Transport #{state.transport} started. #{inspect(state.transport_args)}" + "Firmware Transport #{state.transport} started. #{ + inspect(state.transport_args) + }" ) state = goto(%{state | transport_pid: pid, transport_ref: ref}, :boot) @@ -336,11 +350,22 @@ defmodule FarmbotFirmware do # @spec handle_info(:timeout, state) :: {:noreply, state} def handle_info( :timeout, - %{command_queue: [{pid, {tag, {:command_emergency_lock, []} = code}} | _]} = state + %{ + command_queue: [ + {pid, {tag, {:command_emergency_lock, []} = code}} | _ + ] + } = state ) do case GenServer.call(state.transport_pid, {tag, code}) do :ok -> - new_state = %{state | tag: tag, current: code, command_queue: [], caller_pid: pid} + new_state = %{ + state + | tag: tag, + current: code, + command_queue: [], + caller_pid: pid + } + _ = side_effects(new_state, :handle_output_gcode, [{state.tag, code}]) _ = vcr_write(state, :out, {state.tag, code}) @@ -367,18 +392,33 @@ defmodule FarmbotFirmware do end def handle_info(:timeout, %{current: c} = state) when is_tuple(c) do - if state.caller_pid, do: send(state.caller_pid, {state.tag, {:report_busy, []}}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + if state.caller_pid, + do: send(state.caller_pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) + # Logger.debug "Got checkup message when current command still executing" {:noreply, state} end - def handle_info(:timeout, %{command_queue: [{pid, {tag, code}} | rest]} = state) do - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + def handle_info( + :timeout, + %{command_queue: [{pid, {tag, code}} | rest]} = state + ) do + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) case GenServer.call(state.transport_pid, {tag, code}) do :ok -> - new_state = %{state | tag: tag, current: code, command_queue: rest, caller_pid: pid} + new_state = %{ + state + | tag: tag, + current: code, + command_queue: rest, + caller_pid: pid + } + _ = side_effects(new_state, :handle_output_gcode, [{state.tag, code}]) _ = vcr_write(state, :out, {state.tag, code}) for {pid, _code} <- rest, do: send(pid, {state.tag, {:report_busy, []}}) @@ -401,7 +441,8 @@ defmodule FarmbotFirmware do # Closing the transport will purge the buffer of queued commands in both # the `configuration_queue` and in the `command_queue`. - def handle_call(:close_transport, _from, %{status: s} = state) when s != :transport_boot do + def handle_call(:close_transport, _from, %{status: s} = state) + when s != :transport_boot do true = Process.demonitor(state.transport_ref) :ok = GenServer.stop(state.transport_pid, :normal) @@ -442,12 +483,17 @@ defmodule FarmbotFirmware do {:reply, :ok, next_state} end - def handle_call({:open_transport, _module, _args}, _from, %{status: s} = state) do + def handle_call( + {:open_transport, _module, _args}, + _from, + %{status: s} = state + ) do {:reply, {:error, s}, state} end def handle_call({:enter_vcr_mode, tape_path}, _from, state) do - with {:ok, vcr_fd} <- File.open(tape_path, [:binary, :append, :exclusive, :write]) do + with {:ok, vcr_fd} <- + File.open(tape_path, [:binary, :append, :exclusive, :write]) do {:reply, :ok, %{state | vcr_fd: vcr_fd}} else error -> @@ -460,23 +506,37 @@ defmodule FarmbotFirmware do end @doc false - @spec handle_command(GCODE.t(), GenServer.from(), state()) :: {:reply, term(), state()} + @spec handle_command(GCODE.t(), GenServer.from(), state()) :: + {:reply, term(), state()} # EmergencyLock should be ran immediately - def handle_command({tag, {:command_emergency_lock, []}} = code, {pid, _ref}, state) do - if state.caller_pid, do: send(state.caller_pid, {state.tag, {:report_emergency_lock, []}}) + def handle_command( + {tag, {:command_emergency_lock, []}} = code, + {pid, _ref}, + state + ) do + if state.caller_pid, + do: send(state.caller_pid, {state.tag, {:report_emergency_lock, []}}) for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_emergency_lock, []}}) send(self(), :timeout) - {:reply, {:ok, tag}, %{state | command_queue: [{pid, code}], configuration_queue: []}} + + {:reply, {:ok, tag}, + %{state | command_queue: [{pid, code}], configuration_queue: []}} end # EmergencyUnLock should be ran immediately - def handle_command({tag, {:command_emergency_unlock, []}} = code, {pid, _ref}, state) do + def handle_command( + {tag, {:command_emergency_unlock, []}} = code, + {pid, _ref}, + state + ) do send(self(), :timeout) - {:reply, {:ok, tag}, %{state | command_queue: [{pid, code}], configuration_queue: []}} + + {:reply, {:ok, tag}, + %{state | command_queue: [{pid, code}], configuration_queue: []}} end # If not in an acceptable state, return an error immediately. @@ -518,7 +578,8 @@ defmodule FarmbotFirmware do end @doc false - @spec handle_report({GCODE.report_kind(), GCODE.args()}, state) :: {:noreply, state()} + @spec handle_report({GCODE.report_kind(), GCODE.args()}, state) :: + {:noreply, state()} def handle_report({:report_emergency_lock, []} = code, state) do Logger.info("Emergency lock") if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) @@ -588,7 +649,9 @@ defmodule FarmbotFirmware do else: to_process send(self(), :timeout) - {:noreply, goto(%{state | tag: tag, configuration_queue: to_process}, :configuration)} + + {:noreply, + goto(%{state | tag: tag, configuration_queue: to_process}, :configuration)} end def handle_report({:report_debug_message, msg}, state) do @@ -603,15 +666,21 @@ defmodule FarmbotFirmware do # an idle report while there is a current command running # should not count. - def handle_report({:report_idle, []}, %{current: c} = state) when is_tuple(c) do - if state.caller_pid, do: send(state.caller_pid, {state.tag, {:report_busy, []}}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + def handle_report({:report_idle, []}, %{current: c} = state) + when is_tuple(c) do + if state.caller_pid, + do: send(state.caller_pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) + {:noreply, state} end # report_idle => goto(_, :idle) def handle_report({:report_idle, []}, %{status: _} = state) do - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_busy, [false]) side_effects(state, :handle_idle, [true]) @@ -621,14 +690,18 @@ defmodule FarmbotFirmware do def handle_report({:report_begin, []} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) {:noreply, goto(state, :begin)} end def handle_report({:report_success, []} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) new_state = %{state | current: nil, caller_pid: nil} side_effects(state, :handle_busy, [false]) @@ -638,15 +711,22 @@ defmodule FarmbotFirmware do def handle_report({:report_busy, []} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_busy, [true]) {:noreply, goto(state, :busy)} end - def handle_report({:report_error, _} = code, %{status: :configuration} = state) do + def handle_report( + {:report_error, _} = code, + %{status: :configuration} = state + ) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_busy, [false]) {:stop, {:error, state.current}, state} @@ -654,43 +734,59 @@ defmodule FarmbotFirmware do def handle_report({:report_error, _} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_busy, [false]) send(self(), :timeout) {:noreply, %{state | caller_pid: nil, current: nil}} end - def handle_report({:report_invalid, []} = code, %{status: :configuration} = state) do + def handle_report( + {:report_invalid, []} = code, + %{status: :configuration} = state + ) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) {:stop, {:error, state.current}, state} end def handle_report({:report_invalid, []} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) send(self(), :timeout) {:noreply, %{state | caller_pid: nil, current: nil}} end - def handle_report({:report_retry, []} = code, %{status: :configuration} = state) do + def handle_report( + {:report_retry, []} = code, + %{status: :configuration} = state + ) do Logger.warn("Retrying configuration command: #{inspect(code)}") {:noreply, state} end def handle_report({:report_retry, []} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) {:noreply, state} end def handle_report({:report_parameter_value, param} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_parameter_value, [param]) {:noreply, state} @@ -701,11 +797,19 @@ defmodule FarmbotFirmware do side_effects(state, :handle_parameter_value, [param]) side_effects(state, :handle_parameter_calibration_value, [param]) send(self(), :timeout) - {:noreply, goto(%{state | tag: state.tag, configuration_queue: to_process}, :configuration)} + + {:noreply, + goto( + %{state | tag: state.tag, configuration_queue: to_process}, + :configuration + )} end # report_parameters_complete => goto(:configuration, :idle) - def handle_report({:report_parameters_complete, []}, %{status: status} = state) + def handle_report( + {:report_parameters_complete, []}, + %{status: status} = state + ) when status in [:begin, :configuration] do {:noreply, goto(state, :idle)} end @@ -716,7 +820,9 @@ defmodule FarmbotFirmware do def handle_report({:report_position, position} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_position, [position]) {:noreply, state} @@ -724,7 +830,9 @@ defmodule FarmbotFirmware do def handle_report({:report_load, load} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_load, [load]) {:noreply, state} @@ -732,7 +840,9 @@ defmodule FarmbotFirmware do def handle_report({:report_axis_state, axis_state} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_axis_state, [axis_state]) {:noreply, state} @@ -740,15 +850,22 @@ defmodule FarmbotFirmware do def handle_report({:report_axis_timeout, [axis]} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_axis_timeout, [axis]) {:noreply, state} end - def handle_report({:report_calibration_state, calibration_state} = code, state) do + def handle_report( + {:report_calibration_state, calibration_state} = code, + state + ) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_calibration_state, [calibration_state]) {:noreply, state} @@ -756,7 +873,9 @@ defmodule FarmbotFirmware do def handle_report({:report_home_complete, axis} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_home_complete, axis) {:noreply, state} @@ -764,7 +883,9 @@ defmodule FarmbotFirmware do def handle_report({:report_position_change, position} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_position_change, [position]) {:noreply, state} @@ -772,7 +893,9 @@ defmodule FarmbotFirmware do def handle_report({:report_encoders_scaled, encoders} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_encoders_scaled, [encoders]) {:noreply, state} @@ -780,7 +903,9 @@ defmodule FarmbotFirmware do def handle_report({:report_encoders_raw, encoders} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_encoders_raw, [encoders]) {:noreply, state} @@ -788,7 +913,9 @@ defmodule FarmbotFirmware do def handle_report({:report_end_stops, end_stops} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_end_stops, [end_stops]) {:noreply, state} @@ -796,7 +923,9 @@ defmodule FarmbotFirmware do def handle_report({:report_pin_value, value} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_pin_value, [value]) {:noreply, state} @@ -804,7 +933,9 @@ defmodule FarmbotFirmware do def handle_report({:report_software_version, version} = code, state) do if state.caller_pid, do: send(state.caller_pid, {state.tag, code}) - for {pid, _code} <- state.command_queue, do: send(pid, {state.tag, {:report_busy, []}}) + + for {pid, _code} <- state.command_queue, + do: send(pid, {state.tag, {:report_busy, []}}) side_effects(state, :handle_software_version, [version]) {:noreply, state} @@ -861,7 +992,9 @@ defmodule FarmbotFirmware do @spec side_effects(state, atom, GCODE.args()) :: any() defp side_effects(%{side_effects: nil}, _function, _args), do: nil - defp side_effects(%{side_effects: m}, function, args), do: apply(m, function, args) + + defp side_effects(%{side_effects: m}, function, args), + do: apply(m, function, args) @spec vcr_write(state, :in | :out, GCODE.t()) :: :ok defp vcr_write(%{vcr_fd: nil}, _direction, _code), do: :ok @@ -881,7 +1014,12 @@ defmodule FarmbotFirmware do "nil" end - state_data = "#{state.status} | #{current_data} | #{inspect(state.caller_pid)}" - IO.write(state.vcr_fd, direction <> " #{time} " <> data <> " state=" <> state_data <> "\n") + state_data = + "#{state.status} | #{current_data} | #{inspect(state.caller_pid)}" + + IO.write( + state.vcr_fd, + direction <> " #{time} " <> data <> " state=" <> state_data <> "\n" + ) end end diff --git a/farmbot_firmware/lib/farmbot_firmware/command.ex b/farmbot_firmware/lib/farmbot_firmware/command.ex index c39dee09..2fa08062 100644 --- a/farmbot_firmware/lib/farmbot_firmware/command.ex +++ b/farmbot_firmware/lib/farmbot_firmware/command.ex @@ -10,7 +10,10 @@ defmodule FarmbotFirmware.Command do @spec command(GenServer.server(), GCODE.t() | {GCODE.kind(), GCODE.args()}) :: :ok | {:error, - :invalid_command | :firmware_error | :emergency_lock | FarmbotFirmware.status()} + :invalid_command + | :firmware_error + | :emergency_lock + | FarmbotFirmware.status()} def command(firmware_server \\ FarmbotFirmware, code) def command(firmware_server, {_tag, {_, _}} = code) do @@ -70,7 +73,9 @@ defmodule FarmbotFirmware.Command do wait_for_command_result(tag, code, retries, err) after 30_000 -> - raise("Firmware command: #{GCODE.encode(code)} failed to respond within 30 seconds") + raise( + "Firmware command: #{GCODE.encode(code)} failed to respond within 30 seconds" + ) end end diff --git a/farmbot_firmware/lib/farmbot_firmware/gcode.ex b/farmbot_firmware/lib/farmbot_firmware/gcode.ex index cbb95264..f62652af 100644 --- a/farmbot_firmware/lib/farmbot_firmware/gcode.ex +++ b/farmbot_firmware/lib/farmbot_firmware/gcode.ex @@ -62,7 +62,8 @@ defmodule FarmbotFirmware.GCODE do | :software_version_read | :position_write_zero - @type emergency_commands :: :command_emergency_lock | :command_emergency_unlock + @type emergency_commands :: + :command_emergency_lock | :command_emergency_unlock @typedoc "Kind is an atom of the \"name\" of a command. Example: `:write_parameter`" @type kind() :: report_kind | command_kind | read_write_kind | :unknown diff --git a/farmbot_firmware/lib/farmbot_firmware/gcode/decoder.ex b/farmbot_firmware/lib/farmbot_firmware/gcode/decoder.ex index a3ddf01d..62c2909c 100644 --- a/farmbot_firmware/lib/farmbot_firmware/gcode/decoder.ex +++ b/farmbot_firmware/lib/farmbot_firmware/gcode/decoder.ex @@ -13,10 +13,15 @@ defmodule FarmbotFirmware.GCODE.Decoder do def do_decode("R04", []), do: {:report_busy, []} def do_decode("R05", xyz), do: {:report_axis_state, decode_axis_state(xyz)} - def do_decode("R06", xyz), do: {:report_calibration_state, decode_calibration_state(xyz)} + + def do_decode("R06", xyz), + do: {:report_calibration_state, decode_calibration_state(xyz)} def do_decode("R07", []), do: {:report_retry, []} - def do_decode("R08", args), do: {:report_echo, decode_echo(Enum.join(args, " "))} + + def do_decode("R08", args), + do: {:report_echo, decode_echo(Enum.join(args, " "))} + def do_decode("R09", []), do: {:report_invalid, []} def do_decode("R11", []), do: {:report_home_complete, [:x]} @@ -30,14 +35,19 @@ defmodule FarmbotFirmware.GCODE.Decoder do def do_decode("R20", []), do: {:report_parameters_complete, []} def do_decode("R21", pv), do: {:report_parameter_value, decode_pv(pv)} - def do_decode("R23", pv), do: {:report_calibration_parameter_value, decode_pv(pv)} + + def do_decode("R23", pv), + do: {:report_calibration_parameter_value, decode_pv(pv)} + def do_decode("R41", pv), do: {:report_pin_value, decode_ints(pv)} def do_decode("R71", []), do: {:report_axis_timeout, [:x]} def do_decode("R72", []), do: {:report_axis_timeout, [:y]} def do_decode("R73", []), do: {:report_axis_timeout, [:z]} - def do_decode("R81", xxyyzz), do: {:report_end_stops, decode_end_stops(xxyyzz)} + def do_decode("R81", xxyyzz), + do: {:report_end_stops, decode_end_stops(xxyyzz)} + def do_decode("R82", xyzs), do: {:report_position, decode_floats(xyzs)} def do_decode("R83", [version]), do: {:report_software_version, [version]} @@ -48,7 +58,9 @@ defmodule FarmbotFirmware.GCODE.Decoder do def do_decode("R87", []), do: {:report_emergency_lock, []} def do_decode("R88", []), do: {:report_no_config, []} def do_decode("R89", xyz), do: {:report_load, decode_floats(xyz)} - def do_decode("R99", debug), do: {:report_debug_message, [Enum.join(debug, " ")]} + + def do_decode("R99", debug), + do: {:report_debug_message, [Enum.join(debug, " ")]} def do_decode("G00", xyzs), do: {:command_movement, decode_floats(xyzs)} def do_decode("G28", []), do: {:comand_movement_home, [:x, :y, :z]} @@ -62,7 +74,10 @@ defmodule FarmbotFirmware.GCODE.Decoder do def do_decode("F16", []), do: {:command_movement_calibrate, [:z]} def do_decode("F20", []), do: {:parameter_read_all, []} - def do_decode("F21", [param_id]), do: {:parameter_read, [Param.decode(param_id)]} + + def do_decode("F21", [param_id]), + do: {:parameter_read, [Param.decode(param_id)]} + def do_decode("F22", pv), do: {:parameter_write, decode_pv(pv)} def do_decode("F23", pv), do: {:calibration_parameter_write, decode_pv(pv)} @@ -152,7 +167,10 @@ defmodule FarmbotFirmware.GCODE.Decoder do defp decode_end_stops(list, acc \\ []) defp decode_end_stops( - [<>, <> | rest], + [ + <>, + <> | rest + ], acc ) do dc = String.downcase(arg) diff --git a/farmbot_firmware/lib/farmbot_firmware/gcode/encoder.ex b/farmbot_firmware/lib/farmbot_firmware/gcode/encoder.ex index cb56bd0f..9eb0813e 100644 --- a/farmbot_firmware/lib/farmbot_firmware/gcode/encoder.ex +++ b/farmbot_firmware/lib/farmbot_firmware/gcode/encoder.ex @@ -15,7 +15,9 @@ defmodule FarmbotFirmware.GCODE.Encoder do def do_encode(:report_busy, []), do: "R04" def do_encode(:report_axis_state, xyz), do: "R05 " <> encode_axis_state(xyz) - def do_encode(:report_calibration_state, xyz), do: "R06 " <> encode_calibration_state(xyz) + + def do_encode(:report_calibration_state, xyz), + do: "R06 " <> encode_calibration_state(xyz) def do_encode(:report_retry, []), do: "R07" def do_encode(:report_echo, [echo]), do: "R08 * #{echo} *" @@ -25,21 +27,31 @@ defmodule FarmbotFirmware.GCODE.Encoder do def do_encode(:report_home_complete, [:y]), do: "R12" def do_encode(:report_home_complete, [:z]), do: "R13" - def do_encode(:report_position_change, [x: _] = arg), do: "R15 " <> encode_floats(arg) - def do_encode(:report_position_change, [y: _] = arg), do: "R16 " <> encode_floats(arg) - def do_encode(:report_position_change, [z: _] = arg), do: "R16 " <> encode_floats(arg) + def do_encode(:report_position_change, [x: _] = arg), + do: "R15 " <> encode_floats(arg) + + def do_encode(:report_position_change, [y: _] = arg), + do: "R16 " <> encode_floats(arg) + + def do_encode(:report_position_change, [z: _] = arg), + do: "R16 " <> encode_floats(arg) def do_encode(:report_parameters_complete, []), do: "R20" def do_encode(:report_parameter_value, pv), do: "R21 " <> encode_pv(pv) - def do_encode(:report_calibration_parameter_value, pv), do: "R23 " <> encode_pv(pv) + + def do_encode(:report_calibration_parameter_value, pv), + do: "R23 " <> encode_pv(pv) + def do_encode(:report_pin_value, pv), do: "R41 " <> encode_ints(pv) def do_encode(:report_axis_timeout, [:x]), do: "R71" def do_encode(:report_axis_timeout, [:y]), do: "R72" def do_encode(:report_axis_timeout, [:z]), do: "R73" - def do_encode(:report_end_stops, xxyyzz), do: "R81 " <> encode_end_stops(xxyyzz) + def do_encode(:report_end_stops, xxyyzz), + do: "R81 " <> encode_end_stops(xxyyzz) + def do_encode(:report_position, xyzs), do: "R82 " <> encode_floats(xyzs) def do_encode(:report_software_version, [version]), do: "R83 " <> version @@ -54,9 +66,15 @@ defmodule FarmbotFirmware.GCODE.Encoder do def do_encode(:command_movement, xyzs), do: "G00 " <> encode_floats(xyzs) def do_encode(:command_movement_home, [:x, :y, :z]), do: "G28" - def do_encode(:command_movement_home, [:x]), do: "G00 " <> encode_floats(x: 0.0) - def do_encode(:command_movement_home, [:y]), do: "G00 " <> encode_floats(y: 0.0) - def do_encode(:command_movement_home, [:z]), do: "G00 " <> encode_floats(z: 0.0) + + def do_encode(:command_movement_home, [:x]), + do: "G00 " <> encode_floats(x: 0.0) + + def do_encode(:command_movement_home, [:y]), + do: "G00 " <> encode_floats(y: 0.0) + + def do_encode(:command_movement_home, [:z]), + do: "G00 " <> encode_floats(z: 0.0) def do_encode(:command_movement_find_home, [:x]), do: "F11" def do_encode(:command_movement_find_home, [:y]), do: "F12" @@ -67,7 +85,9 @@ defmodule FarmbotFirmware.GCODE.Encoder do def do_encode(:command_movement_calibrate, [:z]), do: "F16" def do_encode(:parameter_read_all, []), do: "F20" - def do_encode(:parameter_read, [parameter]), do: "F21 P#{Param.encode(parameter)}" + + def do_encode(:parameter_read, [parameter]), + do: "F21 P#{Param.encode(parameter)}" def do_encode(:parameter_write, pv), do: "F22 " <> encode_pv(pv) def do_encode(:calibration_parameter_write, pv), do: "F23 " <> encode_pv(pv) diff --git a/farmbot_firmware/lib/farmbot_firmware/package_utils.ex b/farmbot_firmware/lib/farmbot_firmware/package_utils.ex index 073bb155..163ea848 100644 --- a/farmbot_firmware/lib/farmbot_firmware/package_utils.ex +++ b/farmbot_firmware/lib/farmbot_firmware/package_utils.ex @@ -3,23 +3,28 @@ defmodule FarmbotFirmware.PackageUtils do def find_hex_file(package) def find_hex_file("arduino") do - Application.app_dir(:farmbot_firmware, ["priv", "arduino_firmware.hex"]) |> assert_exists() + Application.app_dir(:farmbot_firmware, ["priv", "arduino_firmware.hex"]) + |> assert_exists() end def find_hex_file("farmduino") do - Application.app_dir(:farmbot_firmware, ["priv", "farmduino.hex"]) |> assert_exists() + Application.app_dir(:farmbot_firmware, ["priv", "farmduino.hex"]) + |> assert_exists() end def find_hex_file("farmduino_k14") do - Application.app_dir(:farmbot_firmware, ["priv", "farmduino_k14.hex"]) |> assert_exists() + Application.app_dir(:farmbot_firmware, ["priv", "farmduino_k14.hex"]) + |> assert_exists() end def find_hex_file("farmduino_k15") do - Application.app_dir(:farmbot_firmware, ["priv", "farmduino_k15.hex"]) |> assert_exists() + Application.app_dir(:farmbot_firmware, ["priv", "farmduino_k15.hex"]) + |> assert_exists() end def find_hex_file("express_k10") do - Application.app_dir(:farmbot_firmware, ["priv", "express_k10.hex"]) |> assert_exists() + Application.app_dir(:farmbot_firmware, ["priv", "express_k10.hex"]) + |> assert_exists() end def find_hex_file(hardware) when is_binary(hardware), diff --git a/farmbot_firmware/lib/farmbot_firmware/request.ex b/farmbot_firmware/lib/farmbot_firmware/request.ex index 272f2042..24706e3b 100644 --- a/farmbot_firmware/lib/farmbot_firmware/request.ex +++ b/farmbot_firmware/lib/farmbot_firmware/request.ex @@ -9,7 +9,8 @@ defmodule FarmbotFirmware.Request do @spec request(GenServer.server(), GCODE.t()) :: {:ok, GCODE.t()} - | {:error, :invalid_command | :firmware_error | FarmbotFirmware.status()} + | {:error, + :invalid_command | :firmware_error | FarmbotFirmware.status()} def request(firmware_server \\ FarmbotFirmware, code) def request(firmware_server, {_tag, {kind, _}} = code) do diff --git a/farmbot_firmware/lib/farmbot_firmware/side_effects.ex b/farmbot_firmware/lib/farmbot_firmware/side_effects.ex index e3b3f9db..558abfe1 100644 --- a/farmbot_firmware/lib/farmbot_firmware/side_effects.ex +++ b/farmbot_firmware/lib/farmbot_firmware/side_effects.ex @@ -17,7 +17,14 @@ defmodule FarmbotFirmware.SideEffects do @callback handle_encoders_raw(x: float(), y: float(), z: float()) :: any() @callback handle_parameter_value([{Param.t(), float()}]) :: any() @callback handle_parameter_calibration_value([{Param.t(), float()}]) :: any() - @callback handle_end_stops(xa: 0 | 1, xb: 0 | 1, ya: 0 | 1, yb: 0 | 1, za: 0 | 1, zb: 0 | 1) :: + @callback handle_end_stops( + xa: 0 | 1, + xb: 0 | 1, + ya: 0 | 1, + yb: 0 | 1, + za: 0 | 1, + zb: 0 | 1 + ) :: any() @callback handle_emergency_lock() :: any() @callback handle_emergency_unlock() :: any() @@ -26,7 +33,8 @@ defmodule FarmbotFirmware.SideEffects do @callback handle_busy(boolean()) :: any() @callback handle_idle(boolean()) :: any() - @type axis_state :: :stop | :idle | :begin | :crawl | :decelerate | :accelerate + @type axis_state :: + :stop | :idle | :begin | :crawl | :decelerate | :accelerate @callback handle_axis_state([{axis(), axis_state}]) :: any() @callback handle_axis_timeout(axis()) :: any() diff --git a/farmbot_firmware/lib/farmbot_firmware/transports/stub_transport.ex b/farmbot_firmware/lib/farmbot_firmware/transports/stub_transport.ex index 10c2eaae..a5332829 100644 --- a/farmbot_firmware/lib/farmbot_firmware/transports/stub_transport.ex +++ b/farmbot_firmware/lib/farmbot_firmware/transports/stub_transport.ex @@ -30,7 +30,10 @@ defmodule FarmbotFirmware.StubTransport do end def handle_info(:timeout, %{status: :boot} = state) do - state.handle_gcode.(GCODE.new(:report_debug_message, ["ARDUINO STARTUP COMPLETE"])) + state.handle_gcode.( + GCODE.new(:report_debug_message, ["ARDUINO STARTUP COMPLETE"]) + ) + {:noreply, goto(state, :no_config), 0} end @@ -79,7 +82,8 @@ defmodule FarmbotFirmware.StubTransport do end def handle_call( - {tag, {:parameter_write, [{:param_config_ok = param, 1.0 = value}]}} = code, + {tag, {:parameter_write, [{:param_config_ok = param, 1.0 = value}]}} = + code, _from, state ) do @@ -94,7 +98,11 @@ defmodule FarmbotFirmware.StubTransport do {:reply, :ok, goto(new_state, :idle), {:continue, resp_codes}} end - def handle_call({tag, {:parameter_write, [{param, value}]}} = code, _from, state) do + def handle_call( + {tag, {:parameter_write, [{param, value}]}} = code, + _from, + state + ) do new_state = %{state | params: Keyword.put(state.params, param, value)} resp_codes = [ @@ -132,7 +140,11 @@ defmodule FarmbotFirmware.StubTransport do {:reply, :ok, state, {:continue, resp_codes}} end - def handle_call({tag, {:position_write_zero, [:x, :y, :z]}} = code, _from, state) do + def handle_call( + {tag, {:position_write_zero, [:x, :y, :z]}} = code, + _from, + state + ) do position = [ x: 0.0, y: 0.0, @@ -166,7 +178,11 @@ defmodule FarmbotFirmware.StubTransport do {:reply, :ok, state, {:continue, resp_codes}} end - def handle_call({tag, {:command_movement_calibrate, [axis]}} = code, _from, state) do + def handle_call( + {tag, {:command_movement_calibrate, [axis]}} = code, + _from, + state + ) do position = [x: 0.0, y: 0.0, z: 0.0] state = %{state | position: position} param_nr_steps = :"movement_axis_nr_steps_#{axis}" @@ -182,8 +198,12 @@ defmodule FarmbotFirmware.StubTransport do GCODE.new(:report_calibration_state, [:idle]), GCODE.new(:report_calibration_state, [:home]), GCODE.new(:report_calibration_state, [:end]), - GCODE.new(:report_calibration_parameter_value, [{param_nr_steps, param_nr_steps_val}]), - GCODE.new(:report_calibration_parameter_value, [{param_endpoints, param_endpoints_val}]), + GCODE.new(:report_calibration_parameter_value, [ + {param_nr_steps, param_nr_steps_val} + ]), + GCODE.new(:report_calibration_parameter_value, [ + {param_endpoints, param_endpoints_val} + ]), GCODE.new(:report_position, state.position), GCODE.new(:report_success, [], tag) ] @@ -203,7 +223,11 @@ defmodule FarmbotFirmware.StubTransport do end # Everything under this clause should be blocked if emergency_locked - def handle_call({_tag, {_, _}} = code, _from, %{status: :emergency_lock} = state) do + def handle_call( + {_tag, {_, _}} = code, + _from, + %{status: :emergency_lock} = state + ) do Logger.error("Stub Transport emergency lock") resp_codes = [ @@ -291,7 +315,11 @@ defmodule FarmbotFirmware.StubTransport do {:reply, :ok, state, {:continue, resp_codes}} end - def handle_call({tag, {:command_movement_home, [:x, :y, :z]}} = code, _from, state) do + def handle_call( + {tag, {:command_movement_home, [:x, :y, :z]}} = code, + _from, + state + ) do position = [ x: 0.0, y: 0.0, @@ -326,7 +354,11 @@ defmodule FarmbotFirmware.StubTransport do {:reply, :ok, state, {:continue, resp_codes}} end - def handle_call({tag, {:command_movement_find_home, [axis]}} = code, _from, state) do + def handle_call( + {tag, {:command_movement_find_home, [axis]}} = code, + _from, + state + ) do position = Keyword.put(state.position, axis, 0.0) |> ensure_order() state = %{state | position: position} @@ -342,7 +374,9 @@ defmodule FarmbotFirmware.StubTransport do end def handle_call({tag, {_, _}} = code, _from, state) do - Logger.error("STUB HANDLER: unknown code: #{inspect(code)} for state: #{state.status}") + Logger.error( + "STUB HANDLER: unknown code: #{inspect(code)} for state: #{state.status}" + ) resp_codes = [ GCODE.new(:report_echo, [GCODE.encode(code)]), diff --git a/farmbot_firmware/lib/farmbot_firmware/transports/uart_transport.ex b/farmbot_firmware/lib/farmbot_firmware/transports/uart_transport.ex index 782f76eb..b32031e6 100644 --- a/farmbot_firmware/lib/farmbot_firmware/transports/uart_transport.ex +++ b/farmbot_firmware/lib/farmbot_firmware/transports/uart_transport.ex @@ -15,7 +15,15 @@ defmodule FarmbotFirmware.UARTTransport do handle_gcode = Keyword.fetch!(args, :handle_gcode) reset = Keyword.get(args, :reset) {:ok, uart} = uart_adapter().start_link() - {:ok, %{uart: uart, device: device, open: false, handle_gcode: handle_gcode, reset: reset}, 0} + + {:ok, + %{ + uart: uart, + device: device, + open: false, + handle_gcode: handle_gcode, + reset: reset + }, 0} end def terminate(_, %{uart: uart}) do diff --git a/farmbot_firmware/mix.exs b/farmbot_firmware/mix.exs index 10420626..0e10df1e 100644 --- a/farmbot_firmware/mix.exs +++ b/farmbot_firmware/mix.exs @@ -1,7 +1,12 @@ defmodule FarmbotFirmware.MixProject do use Mix.Project - @version Path.join([__DIR__, "..", "VERSION"]) |> File.read!() |> String.trim() - @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) |> File.read!() |> String.trim() + + @version Path.join([__DIR__, "..", "VERSION"]) + |> File.read!() + |> String.trim() + @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) + |> File.read!() + |> String.trim() defp arduino_commit do opts = [cd: Path.join("c_src", "farmbot-arduino-firmware")] @@ -51,7 +56,8 @@ defmodule FarmbotFirmware.MixProject do {:farmbot_telemetry, path: "../farmbot_telemetry", env: Mix.env()}, {:circuits_uart, "~> 1.4.0"}, {:excoveralls, "~> 0.10", only: [:test], targets: [:host]}, - {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], targets: [:host], runtime: false}, + {:dialyxir, "~> 1.0.0-rc.3", + only: [:dev], targets: [:host], runtime: false}, {:mox, "~> 0.5.1", only: :test}, {:ex_doc, "~> 0.21.2", only: [:dev], targets: [:host], runtime: false} ] diff --git a/farmbot_firmware/test/farmbot_firmware/transports/uart_transport_test.exs b/farmbot_firmware/test/farmbot_firmware/transports/uart_transport_test.exs index 5df46de3..e1bd609e 100644 --- a/farmbot_firmware/test/farmbot_firmware/transports/uart_transport_test.exs +++ b/farmbot_firmware/test/farmbot_firmware/transports/uart_transport_test.exs @@ -67,7 +67,9 @@ defmodule FarmbotFirmware.UARTTransportTest do {:error, "Simulated UART failure. This is OK"} end) - {:noreply, state2, retry_timeout} = UARTTransport.handle_info(:timeout, state) + {:noreply, state2, retry_timeout} = + UARTTransport.handle_info(:timeout, state) + assert retry_timeout == 5000 assert state.open == state2.open end @@ -77,7 +79,9 @@ defmodule FarmbotFirmware.UARTTransportTest do provided_reason = "Simulated failure (circuits UART)" info = {:circuits_uart, nil, {:error, provided_reason}} - {:stop, {:uart_error, reason}, state2} = UARTTransport.handle_info(info, state) + {:stop, {:uart_error, reason}, state2} = + UARTTransport.handle_info(info, state) + assert reason == provided_reason assert state == state2 end diff --git a/farmbot_firmware/test/farmbot_firmware_test.exs b/farmbot_firmware/test/farmbot_firmware_test.exs index 28d69842..780fd3ec 100644 --- a/farmbot_firmware/test/farmbot_firmware_test.exs +++ b/farmbot_firmware/test/farmbot_firmware_test.exs @@ -6,7 +6,8 @@ defmodule FarmbotFirmwareTest do pid = start_supervised!({ FarmbotFirmware, - transport: FarmbotFirmware.StubTransport, side_effects: FarmbotCore.FirmwareSideEffects + transport: FarmbotFirmware.StubTransport, + side_effects: FarmbotCore.FirmwareSideEffects }) # WIP diff --git a/farmbot_firmware/test/gcode_test.exs b/farmbot_firmware/test/gcode_test.exs index 9cd56e9e..b8f99bb5 100644 --- a/farmbot_firmware/test/gcode_test.exs +++ b/farmbot_firmware/test/gcode_test.exs @@ -44,7 +44,10 @@ defmodule FarmbotFirmware.GCODETest do assert {nil, {:report_error, [:emergency_lock]}} = GCODE.decode("R03 V1") assert {nil, {:report_error, [:timeout]}} = GCODE.decode("R03 V2") assert {nil, {:report_error, [:stall_detected]}} = GCODE.decode("R03 V3") - assert {nil, {:report_error, [:invalid_command]}} = GCODE.decode("R03 V14") + + assert {nil, {:report_error, [:invalid_command]}} = + GCODE.decode("R03 V14") + assert {nil, {:report_error, [:no_config]}} = GCODE.decode("R03 V15") assert {"100", {:report_error, [:no_error]}} = GCODE.decode("R03 Q100") @@ -63,149 +66,323 @@ defmodule FarmbotFirmware.GCODETest do test "axis state" do assert {nil, {:report_axis_state, [x: :idle]}} = GCODE.decode("R05 X0") assert {nil, {:report_axis_state, [x: :begin]}} = GCODE.decode("R05 X1") - assert {nil, {:report_axis_state, [x: :accelerate]}} = GCODE.decode("R05 X2") + + assert {nil, {:report_axis_state, [x: :accelerate]}} = + GCODE.decode("R05 X2") + assert {nil, {:report_axis_state, [x: :cruise]}} = GCODE.decode("R05 X3") - assert {nil, {:report_axis_state, [x: :decelerate]}} = GCODE.decode("R05 X4") + + assert {nil, {:report_axis_state, [x: :decelerate]}} = + GCODE.decode("R05 X4") + assert {nil, {:report_axis_state, [x: :stop]}} = GCODE.decode("R05 X5") assert {nil, {:report_axis_state, [x: :crawl]}} = GCODE.decode("R05 X6") - assert {"12", {:report_axis_state, [x: :idle]}} = GCODE.decode("R05 X0 Q12") - assert {"12", {:report_axis_state, [x: :begin]}} = GCODE.decode("R05 X1 Q12") - assert {"12", {:report_axis_state, [x: :accelerate]}} = GCODE.decode("R05 X2 Q12") - assert {"12", {:report_axis_state, [x: :cruise]}} = GCODE.decode("R05 X3 Q12") - assert {"12", {:report_axis_state, [x: :decelerate]}} = GCODE.decode("R05 X4 Q12") - assert {"12", {:report_axis_state, [x: :stop]}} = GCODE.decode("R05 X5 Q12") - assert {"12", {:report_axis_state, [x: :crawl]}} = GCODE.decode("R05 X6 Q12") + assert {"12", {:report_axis_state, [x: :idle]}} = + GCODE.decode("R05 X0 Q12") + + assert {"12", {:report_axis_state, [x: :begin]}} = + GCODE.decode("R05 X1 Q12") + + assert {"12", {:report_axis_state, [x: :accelerate]}} = + GCODE.decode("R05 X2 Q12") + + assert {"12", {:report_axis_state, [x: :cruise]}} = + GCODE.decode("R05 X3 Q12") + + assert {"12", {:report_axis_state, [x: :decelerate]}} = + GCODE.decode("R05 X4 Q12") + + assert {"12", {:report_axis_state, [x: :stop]}} = + GCODE.decode("R05 X5 Q12") + + assert {"12", {:report_axis_state, [x: :crawl]}} = + GCODE.decode("R05 X6 Q12") assert "R05 X0" = GCODE.encode({nil, {:report_axis_state, [x: :idle]}}) assert "R05 X1" = GCODE.encode({nil, {:report_axis_state, [x: :begin]}}) - assert "R05 X2" = GCODE.encode({nil, {:report_axis_state, [x: :accelerate]}}) + + assert "R05 X2" = + GCODE.encode({nil, {:report_axis_state, [x: :accelerate]}}) + assert "R05 X3" = GCODE.encode({nil, {:report_axis_state, [x: :cruise]}}) - assert "R05 X4" = GCODE.encode({nil, {:report_axis_state, [x: :decelerate]}}) + + assert "R05 X4" = + GCODE.encode({nil, {:report_axis_state, [x: :decelerate]}}) + assert "R05 X5" = GCODE.encode({nil, {:report_axis_state, [x: :stop]}}) assert "R05 X6" = GCODE.encode({nil, {:report_axis_state, [x: :crawl]}}) - assert "R05 X0 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :idle]}}) - assert "R05 X1 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :begin]}}) - assert "R05 X2 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :accelerate]}}) - assert "R05 X3 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :cruise]}}) - assert "R05 X4 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :decelerate]}}) - assert "R05 X5 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :stop]}}) - assert "R05 X6 Q12" = GCODE.encode({"12", {:report_axis_state, [x: :crawl]}}) + assert "R05 X0 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :idle]}}) + + assert "R05 X1 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :begin]}}) + + assert "R05 X2 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :accelerate]}}) + + assert "R05 X3 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :cruise]}}) + + assert "R05 X4 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :decelerate]}}) + + assert "R05 X5 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :stop]}}) + + assert "R05 X6 Q12" = + GCODE.encode({"12", {:report_axis_state, [x: :crawl]}}) assert {nil, {:report_axis_state, [y: :idle]}} = GCODE.decode("R05 Y0") assert {nil, {:report_axis_state, [y: :begin]}} = GCODE.decode("R05 Y1") - assert {nil, {:report_axis_state, [y: :accelerate]}} = GCODE.decode("R05 Y2") + + assert {nil, {:report_axis_state, [y: :accelerate]}} = + GCODE.decode("R05 Y2") + assert {nil, {:report_axis_state, [y: :cruise]}} = GCODE.decode("R05 Y3") - assert {nil, {:report_axis_state, [y: :decelerate]}} = GCODE.decode("R05 Y4") + + assert {nil, {:report_axis_state, [y: :decelerate]}} = + GCODE.decode("R05 Y4") + assert {nil, {:report_axis_state, [y: :stop]}} = GCODE.decode("R05 Y5") assert {nil, {:report_axis_state, [y: :crawl]}} = GCODE.decode("R05 Y6") - assert {"13", {:report_axis_state, [y: :idle]}} = GCODE.decode("R05 Y0 Q13") - assert {"13", {:report_axis_state, [y: :begin]}} = GCODE.decode("R05 Y1 Q13") - assert {"13", {:report_axis_state, [y: :accelerate]}} = GCODE.decode("R05 Y2 Q13") - assert {"13", {:report_axis_state, [y: :cruise]}} = GCODE.decode("R05 Y3 Q13") - assert {"13", {:report_axis_state, [y: :decelerate]}} = GCODE.decode("R05 Y4 Q13") - assert {"13", {:report_axis_state, [y: :stop]}} = GCODE.decode("R05 Y5 Q13") - assert {"13", {:report_axis_state, [y: :crawl]}} = GCODE.decode("R05 Y6 Q13") + assert {"13", {:report_axis_state, [y: :idle]}} = + GCODE.decode("R05 Y0 Q13") + + assert {"13", {:report_axis_state, [y: :begin]}} = + GCODE.decode("R05 Y1 Q13") + + assert {"13", {:report_axis_state, [y: :accelerate]}} = + GCODE.decode("R05 Y2 Q13") + + assert {"13", {:report_axis_state, [y: :cruise]}} = + GCODE.decode("R05 Y3 Q13") + + assert {"13", {:report_axis_state, [y: :decelerate]}} = + GCODE.decode("R05 Y4 Q13") + + assert {"13", {:report_axis_state, [y: :stop]}} = + GCODE.decode("R05 Y5 Q13") + + assert {"13", {:report_axis_state, [y: :crawl]}} = + GCODE.decode("R05 Y6 Q13") assert "R05 Y0" = GCODE.encode({nil, {:report_axis_state, [y: :idle]}}) assert "R05 Y1" = GCODE.encode({nil, {:report_axis_state, [y: :begin]}}) - assert "R05 Y2" = GCODE.encode({nil, {:report_axis_state, [y: :accelerate]}}) + + assert "R05 Y2" = + GCODE.encode({nil, {:report_axis_state, [y: :accelerate]}}) + assert "R05 Y3" = GCODE.encode({nil, {:report_axis_state, [y: :cruise]}}) - assert "R05 Y4" = GCODE.encode({nil, {:report_axis_state, [y: :decelerate]}}) + + assert "R05 Y4" = + GCODE.encode({nil, {:report_axis_state, [y: :decelerate]}}) + assert "R05 Y5" = GCODE.encode({nil, {:report_axis_state, [y: :stop]}}) assert "R05 Y6" = GCODE.encode({nil, {:report_axis_state, [y: :crawl]}}) - assert "R05 Y0 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :idle]}}) - assert "R05 Y1 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :begin]}}) - assert "R05 Y2 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :accelerate]}}) - assert "R05 Y3 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :cruise]}}) - assert "R05 Y4 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :decelerate]}}) - assert "R05 Y5 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :stop]}}) - assert "R05 Y6 Q13" = GCODE.encode({"13", {:report_axis_state, [y: :crawl]}}) + assert "R05 Y0 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :idle]}}) + + assert "R05 Y1 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :begin]}}) + + assert "R05 Y2 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :accelerate]}}) + + assert "R05 Y3 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :cruise]}}) + + assert "R05 Y4 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :decelerate]}}) + + assert "R05 Y5 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :stop]}}) + + assert "R05 Y6 Q13" = + GCODE.encode({"13", {:report_axis_state, [y: :crawl]}}) assert {nil, {:report_axis_state, [z: :idle]}} = GCODE.decode("R05 Z0") assert {nil, {:report_axis_state, [z: :begin]}} = GCODE.decode("R05 Z1") - assert {nil, {:report_axis_state, [z: :accelerate]}} = GCODE.decode("R05 Z2") + + assert {nil, {:report_axis_state, [z: :accelerate]}} = + GCODE.decode("R05 Z2") + assert {nil, {:report_axis_state, [z: :cruise]}} = GCODE.decode("R05 Z3") - assert {nil, {:report_axis_state, [z: :decelerate]}} = GCODE.decode("R05 Z4") + + assert {nil, {:report_axis_state, [z: :decelerate]}} = + GCODE.decode("R05 Z4") + assert {nil, {:report_axis_state, [z: :stop]}} = GCODE.decode("R05 Z5") assert {nil, {:report_axis_state, [z: :crawl]}} = GCODE.decode("R05 Z6") - assert {"14", {:report_axis_state, [z: :idle]}} = GCODE.decode("R05 Z0 Q14") - assert {"14", {:report_axis_state, [z: :begin]}} = GCODE.decode("R05 Z1 Q14") - assert {"14", {:report_axis_state, [z: :accelerate]}} = GCODE.decode("R05 Z2 Q14") - assert {"14", {:report_axis_state, [z: :cruise]}} = GCODE.decode("R05 Z3 Q14") - assert {"14", {:report_axis_state, [z: :decelerate]}} = GCODE.decode("R05 Z4 Q14") - assert {"14", {:report_axis_state, [z: :stop]}} = GCODE.decode("R05 Z5 Q14") - assert {"14", {:report_axis_state, [z: :crawl]}} = GCODE.decode("R05 Z6 Q14") + assert {"14", {:report_axis_state, [z: :idle]}} = + GCODE.decode("R05 Z0 Q14") + + assert {"14", {:report_axis_state, [z: :begin]}} = + GCODE.decode("R05 Z1 Q14") + + assert {"14", {:report_axis_state, [z: :accelerate]}} = + GCODE.decode("R05 Z2 Q14") + + assert {"14", {:report_axis_state, [z: :cruise]}} = + GCODE.decode("R05 Z3 Q14") + + assert {"14", {:report_axis_state, [z: :decelerate]}} = + GCODE.decode("R05 Z4 Q14") + + assert {"14", {:report_axis_state, [z: :stop]}} = + GCODE.decode("R05 Z5 Q14") + + assert {"14", {:report_axis_state, [z: :crawl]}} = + GCODE.decode("R05 Z6 Q14") assert "R05 Z0" = GCODE.encode({nil, {:report_axis_state, [z: :idle]}}) assert "R05 Z1" = GCODE.encode({nil, {:report_axis_state, [z: :begin]}}) - assert "R05 Z2" = GCODE.encode({nil, {:report_axis_state, [z: :accelerate]}}) + + assert "R05 Z2" = + GCODE.encode({nil, {:report_axis_state, [z: :accelerate]}}) + assert "R05 Z3" = GCODE.encode({nil, {:report_axis_state, [z: :cruise]}}) - assert "R05 Z4" = GCODE.encode({nil, {:report_axis_state, [z: :decelerate]}}) + + assert "R05 Z4" = + GCODE.encode({nil, {:report_axis_state, [z: :decelerate]}}) + assert "R05 Z5" = GCODE.encode({nil, {:report_axis_state, [z: :stop]}}) assert "R05 Z6" = GCODE.encode({nil, {:report_axis_state, [z: :crawl]}}) - assert "R05 Z0 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :idle]}}) - assert "R05 Z1 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :begin]}}) - assert "R05 Z2 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :accelerate]}}) - assert "R05 Z3 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :cruise]}}) - assert "R05 Z4 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :decelerate]}}) - assert "R05 Z5 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :stop]}}) - assert "R05 Z6 Q14" = GCODE.encode({"14", {:report_axis_state, [z: :crawl]}}) + assert "R05 Z0 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :idle]}}) + + assert "R05 Z1 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :begin]}}) + + assert "R05 Z2 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :accelerate]}}) + + assert "R05 Z3 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :cruise]}}) + + assert "R05 Z4 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :decelerate]}}) + + assert "R05 Z5 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :stop]}}) + + assert "R05 Z6 Q14" = + GCODE.encode({"14", {:report_axis_state, [z: :crawl]}}) end test "calibration" do - assert {nil, {:report_calibration_state, [x: :idle]}} = GCODE.decode("R06 X0") - assert {nil, {:report_calibration_state, [x: :home]}} = GCODE.decode("R06 X1") - assert {nil, {:report_calibration_state, [x: :end]}} = GCODE.decode("R06 X2") + assert {nil, {:report_calibration_state, [x: :idle]}} = + GCODE.decode("R06 X0") - assert {"1", {:report_calibration_state, [x: :idle]}} = GCODE.decode("R06 X0 Q1") - assert {"1", {:report_calibration_state, [x: :home]}} = GCODE.decode("R06 X1 Q1") - assert {"1", {:report_calibration_state, [x: :end]}} = GCODE.decode("R06 X2 Q1") + assert {nil, {:report_calibration_state, [x: :home]}} = + GCODE.decode("R06 X1") - assert "R06 X0" = GCODE.encode({nil, {:report_calibration_state, [x: :idle]}}) - assert "R06 X1" = GCODE.encode({nil, {:report_calibration_state, [x: :home]}}) - assert "R06 X2" = GCODE.encode({nil, {:report_calibration_state, [x: :end]}}) + assert {nil, {:report_calibration_state, [x: :end]}} = + GCODE.decode("R06 X2") - assert "R06 X0 Q1" = GCODE.encode({"1", {:report_calibration_state, [x: :idle]}}) - assert "R06 X1 Q1" = GCODE.encode({"1", {:report_calibration_state, [x: :home]}}) - assert "R06 X2 Q1" = GCODE.encode({"1", {:report_calibration_state, [x: :end]}}) + assert {"1", {:report_calibration_state, [x: :idle]}} = + GCODE.decode("R06 X0 Q1") - assert {nil, {:report_calibration_state, [y: :idle]}} = GCODE.decode("R06 Y0") - assert {nil, {:report_calibration_state, [y: :home]}} = GCODE.decode("R06 Y1") - assert {nil, {:report_calibration_state, [y: :end]}} = GCODE.decode("R06 Y2") + assert {"1", {:report_calibration_state, [x: :home]}} = + GCODE.decode("R06 X1 Q1") - assert {"1", {:report_calibration_state, [y: :idle]}} = GCODE.decode("R06 Y0 Q1") - assert {"1", {:report_calibration_state, [y: :home]}} = GCODE.decode("R06 Y1 Q1") - assert {"1", {:report_calibration_state, [y: :end]}} = GCODE.decode("R06 Y2 Q1") + assert {"1", {:report_calibration_state, [x: :end]}} = + GCODE.decode("R06 X2 Q1") - assert "R06 Y0" = GCODE.encode({nil, {:report_calibration_state, [y: :idle]}}) - assert "R06 Y1" = GCODE.encode({nil, {:report_calibration_state, [y: :home]}}) - assert "R06 Y2" = GCODE.encode({nil, {:report_calibration_state, [y: :end]}}) + assert "R06 X0" = + GCODE.encode({nil, {:report_calibration_state, [x: :idle]}}) - assert "R06 Y0 Q1" = GCODE.encode({"1", {:report_calibration_state, [y: :idle]}}) - assert "R06 Y1 Q1" = GCODE.encode({"1", {:report_calibration_state, [y: :home]}}) - assert "R06 Y2 Q1" = GCODE.encode({"1", {:report_calibration_state, [y: :end]}}) + assert "R06 X1" = + GCODE.encode({nil, {:report_calibration_state, [x: :home]}}) - assert {nil, {:report_calibration_state, [z: :idle]}} = GCODE.decode("R06 Z0") - assert {nil, {:report_calibration_state, [z: :home]}} = GCODE.decode("R06 Z1") - assert {nil, {:report_calibration_state, [z: :end]}} = GCODE.decode("R06 Z2") + assert "R06 X2" = + GCODE.encode({nil, {:report_calibration_state, [x: :end]}}) - assert {"1", {:report_calibration_state, [z: :idle]}} = GCODE.decode("R06 Z0 Q1") - assert {"1", {:report_calibration_state, [z: :home]}} = GCODE.decode("R06 Z1 Q1") - assert {"1", {:report_calibration_state, [z: :end]}} = GCODE.decode("R06 Z2 Q1") + assert "R06 X0 Q1" = + GCODE.encode({"1", {:report_calibration_state, [x: :idle]}}) - assert "R06 Z0" = GCODE.encode({nil, {:report_calibration_state, [z: :idle]}}) - assert "R06 Z1" = GCODE.encode({nil, {:report_calibration_state, [z: :home]}}) - assert "R06 Z2" = GCODE.encode({nil, {:report_calibration_state, [z: :end]}}) + assert "R06 X1 Q1" = + GCODE.encode({"1", {:report_calibration_state, [x: :home]}}) - assert "R06 Z0 Q1" = GCODE.encode({"1", {:report_calibration_state, [z: :idle]}}) - assert "R06 Z1 Q1" = GCODE.encode({"1", {:report_calibration_state, [z: :home]}}) - assert "R06 Z2 Q1" = GCODE.encode({"1", {:report_calibration_state, [z: :end]}}) + assert "R06 X2 Q1" = + GCODE.encode({"1", {:report_calibration_state, [x: :end]}}) + + assert {nil, {:report_calibration_state, [y: :idle]}} = + GCODE.decode("R06 Y0") + + assert {nil, {:report_calibration_state, [y: :home]}} = + GCODE.decode("R06 Y1") + + assert {nil, {:report_calibration_state, [y: :end]}} = + GCODE.decode("R06 Y2") + + assert {"1", {:report_calibration_state, [y: :idle]}} = + GCODE.decode("R06 Y0 Q1") + + assert {"1", {:report_calibration_state, [y: :home]}} = + GCODE.decode("R06 Y1 Q1") + + assert {"1", {:report_calibration_state, [y: :end]}} = + GCODE.decode("R06 Y2 Q1") + + assert "R06 Y0" = + GCODE.encode({nil, {:report_calibration_state, [y: :idle]}}) + + assert "R06 Y1" = + GCODE.encode({nil, {:report_calibration_state, [y: :home]}}) + + assert "R06 Y2" = + GCODE.encode({nil, {:report_calibration_state, [y: :end]}}) + + assert "R06 Y0 Q1" = + GCODE.encode({"1", {:report_calibration_state, [y: :idle]}}) + + assert "R06 Y1 Q1" = + GCODE.encode({"1", {:report_calibration_state, [y: :home]}}) + + assert "R06 Y2 Q1" = + GCODE.encode({"1", {:report_calibration_state, [y: :end]}}) + + assert {nil, {:report_calibration_state, [z: :idle]}} = + GCODE.decode("R06 Z0") + + assert {nil, {:report_calibration_state, [z: :home]}} = + GCODE.decode("R06 Z1") + + assert {nil, {:report_calibration_state, [z: :end]}} = + GCODE.decode("R06 Z2") + + assert {"1", {:report_calibration_state, [z: :idle]}} = + GCODE.decode("R06 Z0 Q1") + + assert {"1", {:report_calibration_state, [z: :home]}} = + GCODE.decode("R06 Z1 Q1") + + assert {"1", {:report_calibration_state, [z: :end]}} = + GCODE.decode("R06 Z2 Q1") + + assert "R06 Z0" = + GCODE.encode({nil, {:report_calibration_state, [z: :idle]}}) + + assert "R06 Z1" = + GCODE.encode({nil, {:report_calibration_state, [z: :home]}}) + + assert "R06 Z2" = + GCODE.encode({nil, {:report_calibration_state, [z: :end]}}) + + assert "R06 Z0 Q1" = + GCODE.encode({"1", {:report_calibration_state, [z: :idle]}}) + + assert "R06 Z1 Q1" = + GCODE.encode({"1", {:report_calibration_state, [z: :home]}}) + + assert "R06 Z2 Q1" = + GCODE.encode({"1", {:report_calibration_state, [z: :end]}}) end test "retry" do @@ -241,14 +418,23 @@ defmodule FarmbotFirmware.GCODETest do end test "position change" do - assert {nil, {:report_position_change, [{:x, 200.0}]}} = GCODE.decode("R15 X200") - assert {"33", {:report_position_change, [{:x, 200.0}]}} = GCODE.decode("R15 X200 Q33") + assert {nil, {:report_position_change, [{:x, 200.0}]}} = + GCODE.decode("R15 X200") - assert {nil, {:report_position_change, [{:y, 200.0}]}} = GCODE.decode("R16 Y200") - assert {"33", {:report_position_change, [{:y, 200.0}]}} = GCODE.decode("R17 Y200 Q33") + assert {"33", {:report_position_change, [{:x, 200.0}]}} = + GCODE.decode("R15 X200 Q33") - assert {nil, {:report_position_change, [{:z, 200.0}]}} = GCODE.decode("R15 Z200") - assert {"33", {:report_position_change, [{:z, 200.0}]}} = GCODE.decode("R15 Z200 Q33") + assert {nil, {:report_position_change, [{:y, 200.0}]}} = + GCODE.decode("R16 Y200") + + assert {"33", {:report_position_change, [{:y, 200.0}]}} = + GCODE.decode("R17 Y200 Q33") + + assert {nil, {:report_position_change, [{:z, 200.0}]}} = + GCODE.decode("R15 Z200") + + assert {"33", {:report_position_change, [{:z, 200.0}]}} = + GCODE.decode("R15 Z200 Q33") end test "parameter report complete" do @@ -268,7 +454,8 @@ defmodule FarmbotFirmware.GCODETest do end test "end stops" do - assert {nil, {:report_end_stops, [xa: 1, xb: 0, ya: 0, yb: 1, za: 1, zb: 0]}} = + assert {nil, + {:report_end_stops, [xa: 1, xb: 0, ya: 0, yb: 1, za: 1, zb: 0]}} = GCODE.decode("R81 XA1 XB0 YA0 YB1 ZA1 ZB0") end @@ -279,29 +466,41 @@ defmodule FarmbotFirmware.GCODETest do assert {"1", {:report_position, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = GCODE.decode("R82 X100 Y200 Z400 Q1") - assert {nil, {:report_position, [{:x, 100.0}, {:z, 12.0}]}} = GCODE.decode("R82 X100 Z12") + assert {nil, {:report_position, [{:x, 100.0}, {:z, 12.0}]}} = + GCODE.decode("R82 X100 Z12") + assert {nil, {:report_position, [{:z, 5.0}]}} = GCODE.decode("R82 Z5") end test "version" do - assert {nil, {:report_software_version, ["6.5.0.G"]}} = GCODE.decode("R83 6.5.0.G") - assert {"900", {:report_software_version, ["6.5.0.G"]}} = GCODE.decode("R83 6.5.0.G Q900") + assert {nil, {:report_software_version, ["6.5.0.G"]}} = + GCODE.decode("R83 6.5.0.G") - assert "R83 6.5.0.G" = GCODE.encode({nil, {:report_software_version, ["6.5.0.G"]}}) - assert "R83 6.5.0.G Q900" = GCODE.encode({"900", {:report_software_version, ["6.5.0.G"]}}) + assert {"900", {:report_software_version, ["6.5.0.G"]}} = + GCODE.decode("R83 6.5.0.G Q900") + + assert "R83 6.5.0.G" = + GCODE.encode({nil, {:report_software_version, ["6.5.0.G"]}}) + + assert "R83 6.5.0.G Q900" = + GCODE.encode({"900", {:report_software_version, ["6.5.0.G"]}}) end test "encoders" do - assert {nil, {:report_encoders_scaled, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = + assert {nil, + {:report_encoders_scaled, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = GCODE.decode("R84 X100 Y200 Z400") - assert {"1", {:report_encoders_scaled, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = + assert {"1", + {:report_encoders_scaled, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = GCODE.decode("R84 X100 Y200 Z400 Q1") - assert {nil, {:report_encoders_raw, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = + assert {nil, + {:report_encoders_raw, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = GCODE.decode("R85 X100 Y200 Z400") - assert {"1", {:report_encoders_raw, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = + assert {"1", + {:report_encoders_raw, [{:x, 100.0}, {:y, 200.0}, {:z, 400.0}]}} = GCODE.decode("R85 X100 Y200 Z400 Q1") end @@ -314,8 +513,11 @@ defmodule FarmbotFirmware.GCODETest do end test "debug message" do - assert {nil, {:report_debug_message, ["Hello, World!"]}} = GCODE.decode("R99 Hello, World!") - assert "R99 Hello, World!" = GCODE.encode({nil, {:report_debug_message, ["Hello, World!"]}}) + assert {nil, {:report_debug_message, ["Hello, World!"]}} = + GCODE.decode("R99 Hello, World!") + + assert "R99 Hello, World!" = + GCODE.encode({nil, {:report_debug_message, ["Hello, World!"]}}) end end end diff --git a/farmbot_os/config/config.exs b/farmbot_os/config/config.exs index 402b5c42..a02f74ca 100644 --- a/farmbot_os/config/config.exs +++ b/farmbot_os/config/config.exs @@ -1,24 +1,29 @@ use Mix.Config -config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmEvent, checkup_time_ms: 10_000 +config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmEvent, + checkup_time_ms: 10_000 config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.RegimenInstance, checkup_time_ms: 10_000 -config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmwareInstallation, - error_retry_time_ms: 30_000, - install_dir: "/tmp/farmware" +config :farmbot_core, + FarmbotCore.AssetWorker.FarmbotCore.Asset.FarmwareInstallation, + error_retry_time_ms: 30_000, + install_dir: "/tmp/farmware" -config :farmbot_core, Elixir.FarmbotCore.AssetWorker.FarmbotCore.Asset.PublicKey, - ssh_handler: FarmbotCore.PublicKeyHandler.StubSSHHandler +config :farmbot_core, + Elixir.FarmbotCore.AssetWorker.FarmbotCore.Asset.PublicKey, + ssh_handler: FarmbotCore.PublicKeyHandler.StubSSHHandler config :farmbot_core, FarmbotCore.AssetWorker.FarmbotCore.Asset.PinBinding, gpio_handler: FarmbotCore.PinBindingWorker.StubGPIOHandler, error_retry_time_ms: 30_000 -config :farmbot_core, FarmbotCore.Leds, gpio_handler: FarmbotCore.Leds.StubHandler +config :farmbot_core, FarmbotCore.Leds, + gpio_handler: FarmbotCore.Leds.StubHandler -config :farmbot_core, FarmbotCore.JSON, json_parser: FarmbotCore.JSON.JasonParser +config :farmbot_core, FarmbotCore.JSON, + json_parser: FarmbotCore.JSON.JasonParser # Customize non-Elixir parts of the firmware. See # https://hexdocs.pm/nerves/advanced-configuration.html for details. @@ -36,25 +41,37 @@ config :farmbot_core, FarmbotCore.EctoMigrator, default_ntp_server_2: "1.pool.ntp.org", default_dns_name: "my.farm.bot", default_currently_on_beta: - String.contains?(to_string(:os.cmd('git rev-parse --abbrev-ref HEAD')), "beta") + String.contains?( + to_string(:os.cmd('git rev-parse --abbrev-ref HEAD')), + "beta" + ) -config :farmbot_celery_script, FarmbotCeleryScript.SysCalls, sys_calls: FarmbotOS.SysCalls +config :farmbot_celery_script, FarmbotCeleryScript.SysCalls, + sys_calls: FarmbotOS.SysCalls config :farmbot_core, FarmbotCore.BotState.FileSystem, root_dir: "/tmp/farmbot_state", sleep_time: 200 -config :farmbot_core, FarmbotCore.FarmwareRuntime, runtime_dir: "/tmp/farmware_runtime" +config :farmbot_core, FarmbotCore.FarmwareRuntime, + runtime_dir: "/tmp/farmware_runtime" config :ecto, json_library: FarmbotCore.JSON config :farmbot_core, - ecto_repos: [FarmbotCore.Config.Repo, FarmbotCore.Logger.Repo, FarmbotCore.Asset.Repo] + ecto_repos: [ + FarmbotCore.Config.Repo, + FarmbotCore.Logger.Repo, + FarmbotCore.Asset.Repo + ] -config :farmbot_ext, FarmbotExt.API.Preloader, preloader_impl: FarmbotExt.API.Preloader.HTTP +config :farmbot_ext, FarmbotExt.API.Preloader, + preloader_impl: FarmbotExt.API.Preloader.HTTP config :farmbot, FarmbotOS.FileSystem, data_path: "/tmp/farmbot" -config :farmbot, FarmbotOS.System, system_tasks: FarmbotOS.Platform.Host.SystemTasks + +config :farmbot, FarmbotOS.System, + system_tasks: FarmbotOS.Platform.Host.SystemTasks config :farmbot, FarmbotOS.Configurator, data_layer: FarmbotOS.Configurator.ConfigDataLayer, diff --git a/farmbot_os/config/host/dev.exs b/farmbot_os/config/host/dev.exs index e65bad6d..0c85b983 100644 --- a/farmbot_os/config/host/dev.exs +++ b/farmbot_os/config/host/dev.exs @@ -30,7 +30,11 @@ config :farmbot, FarmbotOS.Init.Supervisor, ] config :farmbot, - ecto_repos: [FarmbotCore.Config.Repo, FarmbotCore.Logger.Repo, FarmbotCore.Asset.Repo] + ecto_repos: [ + FarmbotCore.Config.Repo, + FarmbotCore.Logger.Repo, + FarmbotCore.Asset.Repo + ] config :farmbot_core, FarmbotCore.FirmwareTTYDetector, expected_names: [ diff --git a/farmbot_os/config/host/test.exs b/farmbot_os/config/host/test.exs index 7437d240..ae105c6e 100644 --- a/farmbot_os/config/host/test.exs +++ b/farmbot_os/config/host/test.exs @@ -22,7 +22,11 @@ config :farmbot_core, FarmbotCore.Asset.Repo, database: Path.join(data_path, "asset-#{Mix.env()}.sqlite3") config :farmbot, - ecto_repos: [FarmbotCore.Config.Repo, FarmbotCore.Logger.Repo, FarmbotCore.Asset.Repo], + ecto_repos: [ + FarmbotCore.Config.Repo, + FarmbotCore.Logger.Repo, + FarmbotCore.Asset.Repo + ], platform_children: [ {Farmbot.Platform.Host.Configurator, []} ] diff --git a/farmbot_os/config/target/dev.exs b/farmbot_os/config/target/dev.exs index 42fd3243..890ae616 100644 --- a/farmbot_os/config/target/dev.exs +++ b/farmbot_os/config/target/dev.exs @@ -51,7 +51,13 @@ config :mdns_lite, ] config :shoehorn, - init: [:nerves_runtime, :vintage_net, :nerves_firmware_ssh, :farmbot_core, :farmbot_ext], + init: [ + :nerves_runtime, + :vintage_net, + :nerves_firmware_ssh, + :farmbot_core, + :farmbot_ext + ], handler: FarmbotOS.Platform.Target.ShoehornHandler, app: :farmbot @@ -90,7 +96,8 @@ config :farmbot_core, FarmbotCore.Asset.Repo, pool_size: 1, database: Path.join(data_path, "asset-prod.sqlite3") -config :farmbot_telemetry, file: to_charlist(Path.join(data_path, 'farmbot-telemetry.dets')) +config :farmbot_telemetry, + file: to_charlist(Path.join(data_path, 'farmbot-telemetry.dets')) config :farmbot, FarmbotOS.Platform.Supervisor, platform_children: [ @@ -104,7 +111,8 @@ config :farmbot, FarmbotOS.Platform.Supervisor, config :farmbot, FarmbotOS.Configurator, network_layer: FarmbotOS.Platform.Target.Configurator.VintageNetworkLayer -config :farmbot, FarmbotOS.System, system_tasks: FarmbotOS.Platform.Target.SystemTasks +config :farmbot, FarmbotOS.System, + system_tasks: FarmbotOS.Platform.Target.SystemTasks config :nerves_hub, client: FarmbotOS.Platform.Target.NervesHubClient, diff --git a/farmbot_os/config/target/prod.exs b/farmbot_os/config/target/prod.exs index ea33bbe7..916e6c2f 100644 --- a/farmbot_os/config/target/prod.exs +++ b/farmbot_os/config/target/prod.exs @@ -51,7 +51,13 @@ config :mdns_lite, ] config :shoehorn, - init: [:nerves_runtime, :vintage_net, :nerves_firmware_ssh, :farmbot_core, :farmbot_ext], + init: [ + :nerves_runtime, + :vintage_net, + :nerves_firmware_ssh, + :farmbot_core, + :farmbot_ext + ], handler: FarmbotOS.Platform.Target.ShoehornHandler, app: :farmbot @@ -90,7 +96,8 @@ config :farmbot_core, FarmbotCore.Asset.Repo, pool_size: 1, database: Path.join(data_path, "asset-#{Mix.env()}.sqlite3") -config :farmbot_telemetry, file: to_charlist(Path.join(data_path, 'farmbot-telemetry.dets')) +config :farmbot_telemetry, + file: to_charlist(Path.join(data_path, 'farmbot-telemetry.dets')) config :farmbot, FarmbotOS.Platform.Supervisor, platform_children: [ @@ -104,7 +111,8 @@ config :farmbot, FarmbotOS.Platform.Supervisor, config :farmbot, FarmbotOS.Configurator, network_layer: FarmbotOS.Platform.Target.Configurator.VintageNetworkLayer -config :farmbot, FarmbotOS.System, system_tasks: FarmbotOS.Platform.Target.SystemTasks +config :farmbot, FarmbotOS.System, + system_tasks: FarmbotOS.Platform.Target.SystemTasks config :nerves_hub, client: FarmbotOS.Platform.Target.NervesHubClient, diff --git a/farmbot_os/config/target/rpi.exs b/farmbot_os/config/target/rpi.exs index be53c3c4..da5ba893 100644 --- a/farmbot_os/config/target/rpi.exs +++ b/farmbot_os/config/target/rpi.exs @@ -1,8 +1,10 @@ use Mix.Config -config :farmbot_core, FarmbotCore.FirmwareTTYDetector, expected_names: ["ttyUSB0", "ttyAMA0"] +config :farmbot_core, FarmbotCore.FirmwareTTYDetector, + expected_names: ["ttyUSB0", "ttyAMA0"] -config :farmbot_firmware, FarmbotFirmware, reset: FarmbotOS.Platform.Target.FirmwareReset.GPIO +config :farmbot_firmware, FarmbotFirmware, + reset: FarmbotOS.Platform.Target.FirmwareReset.GPIO config :farmbot, FarmbotOS.Init.Supervisor, init_children: [ diff --git a/farmbot_os/config/target/rpi0.exs b/farmbot_os/config/target/rpi0.exs index 24bf09dd..ffc236c9 100644 --- a/farmbot_os/config/target/rpi0.exs +++ b/farmbot_os/config/target/rpi0.exs @@ -1,10 +1,12 @@ use Mix.Config -config :farmbot_core, FarmbotCore.FirmwareTTYDetector, expected_names: ["ttyUSB0", "ttyAMA0"] +config :farmbot_core, FarmbotCore.FirmwareTTYDetector, + expected_names: ["ttyUSB0", "ttyAMA0"] config :farmbot_core, FarmbotCore.FirmwareOpenTask, attempt_threshold: 50 -config :farmbot_firmware, FarmbotFirmware, reset: FarmbotOS.Platform.Target.FirmwareReset.GPIO +config :farmbot_firmware, FarmbotFirmware, + reset: FarmbotOS.Platform.Target.FirmwareReset.GPIO config :farmbot, FarmbotOS.Init.Supervisor, init_children: [ diff --git a/farmbot_os/config/target/rpi3.exs b/farmbot_os/config/target/rpi3.exs index 0a76c2af..e5fe4f37 100644 --- a/farmbot_os/config/target/rpi3.exs +++ b/farmbot_os/config/target/rpi3.exs @@ -1,6 +1,7 @@ use Mix.Config -config :farmbot_core, FarmbotCore.FirmwareTTYDetector, expected_names: ["ttyUSB0", "ttyACM0"] +config :farmbot_core, FarmbotCore.FirmwareTTYDetector, + expected_names: ["ttyUSB0", "ttyACM0"] config :farmbot_firmware, FarmbotFirmware, reset: FarmbotFirmware.NullReset diff --git a/farmbot_os/lib/avrdude/muon_trap_adapter.ex b/farmbot_os/lib/avrdude/muon_trap_adapter.ex index 504f87bd..1f0e1915 100644 --- a/farmbot_os/lib/avrdude/muon_trap_adapter.ex +++ b/farmbot_os/lib/avrdude/muon_trap_adapter.ex @@ -8,7 +8,11 @@ defmodule Avrdude.MuonTrapAdapter do @doc false def adapter do - Application.get_env(:farmbot, :muon_trap_adapter, Avrdude.MuonTrapDefaultAdapter) + Application.get_env( + :farmbot, + :muon_trap_adapter, + Avrdude.MuonTrapDefaultAdapter + ) end def cmd(exe, args, options) do diff --git a/farmbot_os/lib/farmbot_os/configurator/config_data_layer.ex b/farmbot_os/lib/farmbot_os/configurator/config_data_layer.ex index 9156f733..ed256aae 100644 --- a/farmbot_os/lib/farmbot_os/configurator/config_data_layer.ex +++ b/farmbot_os/lib/farmbot_os/configurator/config_data_layer.ex @@ -55,9 +55,29 @@ defmodule FarmbotOS.Configurator.ConfigDataLayer do _ = Config.input_network_config!(network_params) # Runtime network configuration - _ = Config.update_config_value(:string, "settings", "default_ntp_server_1", net_config_ntp1) - _ = Config.update_config_value(:string, "settings", "default_ntp_server_2", net_config_ntp2) - _ = Config.update_config_value(:string, "settings", "default_dns_name", net_config_dns_name) + _ = + Config.update_config_value( + :string, + "settings", + "default_ntp_server_1", + net_config_ntp1 + ) + + _ = + Config.update_config_value( + :string, + "settings", + "default_ntp_server_2", + net_config_ntp2 + ) + + _ = + Config.update_config_value( + :string, + "settings", + "default_dns_name", + net_config_dns_name + ) if net_config_ssh_key do Asset.new_public_key!(%{ @@ -68,9 +88,31 @@ defmodule FarmbotOS.Configurator.ConfigDataLayer do # Farmbot specific auth data _ = Config.update_config_value(:string, "authorization", "secret", nil) - _ = Config.update_config_value(:string, "authorization", "email", auth_config_email) - _ = Config.update_config_value(:string, "authorization", "password", auth_config_password) - _ = Config.update_config_value(:string, "authorization", "server", auth_config_server) + + _ = + Config.update_config_value( + :string, + "authorization", + "email", + auth_config_email + ) + + _ = + Config.update_config_value( + :string, + "authorization", + "password", + auth_config_password + ) + + _ = + Config.update_config_value( + :string, + "authorization", + "server", + auth_config_server + ) + :ok end diff --git a/farmbot_os/lib/farmbot_os/configurator/fake_network_layer.ex b/farmbot_os/lib/farmbot_os/configurator/fake_network_layer.ex index 5eb06965..58e8c71f 100644 --- a/farmbot_os/lib/farmbot_os/configurator/fake_network_layer.ex +++ b/farmbot_os/lib/farmbot_os/configurator/fake_network_layer.ex @@ -7,7 +7,10 @@ defmodule FarmbotOS.Configurator.FakeNetworkLayer do @impl FarmbotOS.Configurator.NetworkLayer def list_interfaces() do - [{"eth0", %{mac_address: "not real lol"}}, {"wlan0", %{mac_address: "even more not real"}}] + [ + {"eth0", %{mac_address: "not real lol"}}, + {"wlan0", %{mac_address: "even more not real"}} + ] end @impl FarmbotOS.Configurator.NetworkLayer diff --git a/farmbot_os/lib/farmbot_os/configurator/logger_socket/logger_backend.ex b/farmbot_os/lib/farmbot_os/configurator/logger_socket/logger_backend.ex index 8c31ff11..302ece5b 100644 --- a/farmbot_os/lib/farmbot_os/configurator/logger_socket/logger_backend.ex +++ b/farmbot_os/lib/farmbot_os/configurator/logger_socket/logger_backend.ex @@ -27,7 +27,10 @@ defmodule FarmbotOS.Configurator.LoggerSocket.LoggerBackend do end @impl :gen_event - def handle_event({_level, _pid, {Logger, _msg, _timestamp, _meta}} = log, state) do + def handle_event( + {_level, _pid, {Logger, _msg, _timestamp, _meta}} = log, + state + ) do Registry.dispatch(__MODULE__, :dispatch, fn entries -> for {pid, _} <- entries do send(pid, log) diff --git a/farmbot_os/lib/farmbot_os/configurator/router.ex b/farmbot_os/lib/farmbot_os/configurator/router.ex index 50e9e7a4..4f784dd6 100644 --- a/farmbot_os/lib/farmbot_os/configurator/router.ex +++ b/farmbot_os/lib/farmbot_os/configurator/router.ex @@ -10,14 +10,24 @@ defmodule FarmbotOS.Configurator.Router do plug(Plug.Logger) plug(Plug.Static, from: {:farmbot, "priv/static"}, at: "/") plug(Plug.Parsers, parsers: [:urlencoded, :multipart]) - plug(Plug.Session, store: :ets, key: "_farmbot_session", table: :configurator_session) + + plug(Plug.Session, + store: :ets, + key: "_farmbot_session", + table: :configurator_session + ) + plug(:fetch_session) plug(:match) plug(:dispatch) @data_layer Application.get_env(:farmbot, FarmbotOS.Configurator)[:data_layer] - @network_layer Application.get_env(:farmbot, FarmbotOS.Configurator)[:network_layer] - @telemetry_layer Application.get_env(:farmbot, FarmbotOS.Configurator)[:telemetry_layer] + @network_layer Application.get_env(:farmbot, FarmbotOS.Configurator)[ + :network_layer + ] + @telemetry_layer Application.get_env(:farmbot, FarmbotOS.Configurator)[ + :telemetry_layer + ] # Trigger for captive portal for various operating systems get("/gen_204", do: redir(conn, "/")) @@ -49,7 +59,10 @@ defmodule FarmbotOS.Configurator.Router do if String.contains?(reason, "CeleryScript request.") do redir(conn, "/network") else - render_page(conn, "index", version: version(), last_reset_reason: reason) + render_page(conn, "index", + version: version(), + last_reset_reason: reason + ) end nil -> @@ -246,7 +259,10 @@ defmodule FarmbotOS.Configurator.Router do _ -> conn - |> put_session("__error", "Email, Server, or Password are missing or invalid") + |> put_session( + "__error", + "Email, Server, or Password are missing or invalid" + ) |> redir("/credentials") end end @@ -280,20 +296,34 @@ defmodule FarmbotOS.Configurator.Router do defp render_page(conn, page, info \\ []) do page |> template_file() - |> EEx.eval_file(Keyword.merge([version: version()], info), engine: Phoenix.HTML.Engine) + |> EEx.eval_file(Keyword.merge([version: version()], info), + engine: Phoenix.HTML.Engine + ) |> (fn {:safe, contents} -> send_resp(conn, 200, contents) end).() rescue e -> IO.warn("render error", __STACKTRACE__) - send_resp(conn, 500, "Failed to render page: #{page} error: #{Exception.message(e)}") + + send_resp( + conn, + 500, + "Failed to render page: #{page} error: #{Exception.message(e)}" + ) end defp render_json(conn, data) do conn = put_resp_header(conn, "content-type", "application/json") case FarmbotCore.JSON.encode(data) do - {:ok, json} -> send_resp(conn, 200, json) - _ -> send_resp(conn, 501, FarmbotCore.JSON.encode!(%{error: "failed to render json"})) + {:ok, json} -> + send_resp(conn, 200, json) + + _ -> + send_resp( + conn, + 501, + FarmbotCore.JSON.encode!(%{error: "failed to render json"}) + ) end end diff --git a/farmbot_os/lib/farmbot_os/configurator/scheduler_socket.ex b/farmbot_os/lib/farmbot_os/configurator/scheduler_socket.ex index a0b77448..d111bea9 100644 --- a/farmbot_os/lib/farmbot_os/configurator/scheduler_socket.ex +++ b/farmbot_os/lib/farmbot_os/configurator/scheduler_socket.ex @@ -38,18 +38,25 @@ defmodule FarmbotOS.Configurator.SchedulerSocket do def websocket_info({FarmbotCeleryScript, {:calendar, calendar}}, state) do data = Enum.map(calendar, fn - %Scheduler.Dispatch{data: %FarmEvent{} = farm_event, scheduled_at: datetime} -> + %Scheduler.Dispatch{ + data: %FarmEvent{} = farm_event, + scheduled_at: datetime + } -> json = Jason.encode!(%{ id: farm_event.local_id, type: "FarmEvent", - data: Sequence.render(Asset.get_sequence(farm_event.executable_id)), + data: + Sequence.render(Asset.get_sequence(farm_event.executable_id)), at: datetime }) {:text, json} - %Scheduler.Dispatch{data: %Sequence{} = sequence, scheduled_at: datetime} -> + %Scheduler.Dispatch{ + data: %Sequence{} = sequence, + scheduled_at: datetime + } -> json = Jason.encode!(%{ id: sequence.local_id, diff --git a/farmbot_os/lib/farmbot_os/configurator/supervisor.ex b/farmbot_os/lib/farmbot_os/configurator/supervisor.ex index 31a61369..8085bfe3 100644 --- a/farmbot_os/lib/farmbot_os/configurator/supervisor.ex +++ b/farmbot_os/lib/farmbot_os/configurator/supervisor.ex @@ -13,7 +13,11 @@ defmodule FarmbotOS.Configurator.Supervisor do @impl Supervisor def init(_args) do - :ets.new(:configurator_session, [:named_table, :public, read_concurrency: true]) + :ets.new(:configurator_session, [ + :named_table, + :public, + read_concurrency: true + ]) transport_opts = [ num_acceptors: 1 diff --git a/farmbot_os/lib/farmbot_os/logger_backend_espeak.ex b/farmbot_os/lib/farmbot_os/logger_backend_espeak.ex index 9433349b..50998df4 100644 --- a/farmbot_os/lib/farmbot_os/logger_backend_espeak.ex +++ b/farmbot_os/lib/farmbot_os/logger_backend_espeak.ex @@ -20,11 +20,17 @@ defmodule LoggerBackendEspeak do end @impl :gen_event - def handle_event({_level, _pid, {Logger, _msg, _timestamp, _meta}}, %{port: nil} = state) do + def handle_event( + {_level, _pid, {Logger, _msg, _timestamp, _meta}}, + %{port: nil} = state + ) do {:ok, state} end - def handle_event({_level, _pid, {Logger, msg, _timestamp, meta}}, %{port: espeak} = state) do + def handle_event( + {_level, _pid, {Logger, msg, _timestamp, meta}}, + %{port: espeak} = state + ) do should_espeak? = meta[:channels] == :espeak || Enum.find(meta[:channels] || [], fn @@ -50,7 +56,9 @@ defmodule LoggerBackendEspeak do end def handle_info({:open, exe}, state) do - port = :erlang.open_port({:spawn_executable, to_charlist(exe)}, [:exit_status]) + port = + :erlang.open_port({:spawn_executable, to_charlist(exe)}, [:exit_status]) + Port.command(port, "\n") {:ok, %{state | port: port}} end diff --git a/farmbot_os/lib/farmbot_os/lua.ex b/farmbot_os/lib/farmbot_os/lua.ex index ce13d616..95aa8266 100644 --- a/farmbot_os/lib/farmbot_os/lua.ex +++ b/farmbot_os/lib/farmbot_os/lua.ex @@ -56,7 +56,10 @@ defmodule FarmbotOS.Lua do channels: [:toast] ) - {:error, "failed to parse expression (line:#{line}): #{IO.iodata_to_binary(parse_error)}"} + {:error, + "failed to parse expression (line:#{line}): #{ + IO.iodata_to_binary(parse_error) + }"} error -> error @@ -88,8 +91,14 @@ defmodule FarmbotOS.Lua do |> set_table([:get_device], &DataManipulation.get_device/2) |> set_table([:update_fbos_config], &DataManipulation.update_fbos_config/2) |> set_table([:get_fbos_config], &DataManipulation.get_fbos_config/2) - |> set_table([:update_firmware_config], &DataManipulation.update_firmware_config/2) - |> set_table([:get_firmware_config], &DataManipulation.get_firmware_config/2) + |> set_table( + [:update_firmware_config], + &DataManipulation.update_firmware_config/2 + ) + |> set_table( + [:get_firmware_config], + &DataManipulation.get_firmware_config/2 + ) |> set_table([:new_farmware_env], &DataManipulation.new_farmware_env/2) |> set_table([:new_sensor_reading], &DataManipulation.new_sensor_reading/2) end diff --git a/farmbot_os/lib/farmbot_os/lua/ext/firmware.ex b/farmbot_os/lib/farmbot_os/lua/ext/firmware.ex index 45fafa0c..d371a3d9 100644 --- a/farmbot_os/lib/farmbot_os/lua/ext/firmware.ex +++ b/farmbot_os/lib/farmbot_os/lua/ext/firmware.ex @@ -56,7 +56,8 @@ defmodule FarmbotOS.Lua.Ext.Firmware do end @doc "Moves in a straight line to a location" - def move_absolute([x, y, z], lua) when is_number(x) and is_number(y) and is_number(z) do + def move_absolute([x, y, z], lua) + when is_number(x) and is_number(y) and is_number(z) do move_absolute([x, y, z, 100], lua) end @@ -75,7 +76,8 @@ defmodule FarmbotOS.Lua.Ext.Firmware do move_absolute([table, 100], lua) end - def move_absolute([table, speed], lua) when is_list(table) and is_number(speed) do + def move_absolute([table, speed], lua) + when is_list(table) and is_number(speed) do axis_finder = fn axis, {axis, nil} -> apply(SysCalls, :"get_current_#{axis}", []) axis, {axis, value} -> value @@ -199,7 +201,8 @@ defmodule FarmbotOS.Lua.Ext.Firmware do end end - def coordinate([x, y, z], lua) when is_number(x) and is_number(y) and is_number(z) do + def coordinate([x, y, z], lua) + when is_number(x) and is_number(y) and is_number(z) do {[[{"x", x}, {"y", y}, {"z", z}]], lua} end diff --git a/farmbot_os/lib/farmbot_os/platform_supervisor.ex b/farmbot_os/lib/farmbot_os/platform_supervisor.ex index ac553dc1..0fcb1e4b 100644 --- a/farmbot_os/lib/farmbot_os/platform_supervisor.ex +++ b/farmbot_os/lib/farmbot_os/platform_supervisor.ex @@ -10,7 +10,9 @@ defmodule FarmbotOS.Platform.Supervisor do end def init([]) do - platform_children = Application.get_env(:farmbot, __MODULE__)[:platform_children] + platform_children = + Application.get_env(:farmbot, __MODULE__)[:platform_children] + Supervisor.init(platform_children, strategy: :one_for_all) end end diff --git a/farmbot_os/lib/farmbot_os/sys_calls.ex b/farmbot_os/lib/farmbot_os/sys_calls.ex index 25cd3ed7..6e2da955 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls.ex @@ -262,18 +262,26 @@ defmodule FarmbotOS.SysCalls do with {:ok, sync_changeset} <- API.get_changeset(Sync), :ok <- BotState.set_sync_status("syncing"), _ <- Leds.green(:really_fast_blink), - sync_changeset <- Reconciler.sync_group(sync_changeset, SyncGroup.group_0()), - sync_changeset <- Reconciler.sync_group(sync_changeset, SyncGroup.group_1()), - sync_changeset <- Reconciler.sync_group(sync_changeset, SyncGroup.group_2()), - sync_changeset <- Reconciler.sync_group(sync_changeset, SyncGroup.group_3()), - _sync_changeset <- Reconciler.sync_group(sync_changeset, SyncGroup.group_4()) do + sync_changeset <- + Reconciler.sync_group(sync_changeset, SyncGroup.group_0()), + sync_changeset <- + Reconciler.sync_group(sync_changeset, SyncGroup.group_1()), + sync_changeset <- + Reconciler.sync_group(sync_changeset, SyncGroup.group_2()), + sync_changeset <- + Reconciler.sync_group(sync_changeset, SyncGroup.group_3()), + _sync_changeset <- + Reconciler.sync_group(sync_changeset, SyncGroup.group_4()) do FarmbotCore.Logger.success(3, "Synced") :ok = BotState.set_sync_status("synced") _ = Leds.green(:solid) :ok else error -> - FarmbotTelemetry.event(:asset_sync, :sync_error, nil, error: inspect(error)) + FarmbotTelemetry.event(:asset_sync, :sync_error, nil, + error: inspect(error) + ) + :ok = BotState.set_sync_status("sync_error") _ = Leds.green(:slow_blink) {:error, inspect(error)} diff --git a/farmbot_os/lib/farmbot_os/sys_calls/change_ownership.ex b/farmbot_os/lib/farmbot_os/sys_calls/change_ownership.ex index b36e2ed8..38bed633 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/change_ownership.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/change_ownership.ex @@ -12,12 +12,21 @@ defmodule FarmbotOS.SysCalls.ChangeOwnership do case Authorization.authorize_with_secret(email, secret, server) do {:ok, _token} -> - FarmbotCore.Logger.warn(1, "Farmbot is changing ownership to #{email} - #{server}") + FarmbotCore.Logger.warn( + 1, + "Farmbot is changing ownership to #{email} - #{server}" + ) + :ok = replace_credentials(email, secret, server) _ = clean_assets() _ = clean_farmwares() FarmbotCore.Logger.warn(1, "Going down for reboot") - Supervisor.start_child(:elixir_sup, {Task, &FarmbotOS.System.soft_restart/0}) + + Supervisor.start_child( + :elixir_sup, + {Task, &FarmbotOS.System.soft_restart/0} + ) + :ok {:error, _} -> diff --git a/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex b/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex index d5260df5..9ea901c8 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/dump_info.ex @@ -3,7 +3,14 @@ defmodule FarmbotOS.SysCalls.DumpInfo do require FarmbotCore.Logger require FarmbotTelemetry - alias FarmbotCore.{Asset, Asset.DiagnosticDump, Asset.Private, Config, Project} + + alias FarmbotCore.{ + Asset, + Asset.DiagnosticDump, + Asset.Private, + Config, + Project + } def dump_info do FarmbotCore.Logger.busy(1, "Recording diagnostic dump.") @@ -38,7 +45,10 @@ defmodule FarmbotOS.SysCalls.DumpInfo do :ok {:error, changeset} -> - FarmbotTelemetry.event(:diagnostic_dump, :record_error, nil, error: inspect(changeset)) + FarmbotTelemetry.event(:diagnostic_dump, :record_error, nil, + error: inspect(changeset) + ) + {:error, "error creating diagnostic dump: #{inspect(changeset)}"} end end diff --git a/farmbot_os/lib/farmbot_os/sys_calls/factory_reset.ex b/farmbot_os/lib/farmbot_os/sys_calls/factory_reset.ex index 5f02188f..52b9ae90 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/factory_reset.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/factory_reset.ex @@ -6,7 +6,12 @@ defmodule FarmbotOS.SysCalls.FactoryReset do def factory_reset("farmbot_os") do _ = API.put!(API.client(), "/api/device", %{needs_reset: false}) - FarmbotOS.System.factory_reset("Factory reset requested by Sequence or frontend", true) + + FarmbotOS.System.factory_reset( + "Factory reset requested by Sequence or frontend", + true + ) + :ok end diff --git a/farmbot_os/lib/farmbot_os/sys_calls/flash_firmware.ex b/farmbot_os/lib/farmbot_os/sys_calls/flash_firmware.ex index 14282839..f7aa3029 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/flash_firmware.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/flash_firmware.ex @@ -4,18 +4,29 @@ defmodule FarmbotOS.SysCalls.FlashFirmware do alias FarmbotCore.{Asset, Asset.Private} alias FarmbotFirmware alias FarmbotCore.FirmwareTTYDetector - import FarmbotFirmware.PackageUtils, only: [find_hex_file: 1, package_to_string: 1] + + import FarmbotFirmware.PackageUtils, + only: [find_hex_file: 1, package_to_string: 1] + require FarmbotCore.Logger require Logger def flash_firmware(package) do - FarmbotCore.Logger.busy(2, "Flashing #{package_to_string(package)} firmware") + FarmbotCore.Logger.busy( + 2, + "Flashing #{package_to_string(package)} firmware" + ) with {:ok, hex_file} <- find_hex_file(package), {:ok, tty} <- find_tty(), - _ <- FarmbotCore.Logger.debug(3, "found tty: #{tty} for firmware flash"), + _ <- + FarmbotCore.Logger.debug(3, "found tty: #{tty} for firmware flash"), {:ok, fun} <- find_reset_fun(package), - _ <- FarmbotCore.Logger.debug(3, "closing firmware transport before flash"), + _ <- + FarmbotCore.Logger.debug( + 3, + "closing firmware transport before flash" + ), :ok <- FarmbotFirmware.close_transport(), _ <- FarmbotCore.Logger.debug(3, "starting firmware flash"), {_, 0} <- Avrdude.flash(hex_file, tty, fun) do diff --git a/farmbot_os/lib/farmbot_os/sys_calls/movement.ex b/farmbot_os/lib/farmbot_os/sys_calls/movement.ex index 464fda07..000e5ee7 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/movement.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/movement.ex @@ -119,7 +119,11 @@ defmodule FarmbotOS.SysCalls.Movement do {:error, "emergency_lock"} {:error, reason} -> - FarmbotCore.Logger.error(1, "Movement failed. Retrying up to #{retries} more time(s)") + FarmbotCore.Logger.error( + 1, + "Movement failed. Retrying up to #{retries} more time(s)" + ) + do_move_absolute(x, y, z, speed, retries - 1, [reason | errors]) end end diff --git a/farmbot_os/lib/farmbot_os/sys_calls/pin_control.ex b/farmbot_os/lib/farmbot_os/sys_calls/pin_control.ex index cb6e1ac8..d0f1182d 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/pin_control.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/pin_control.ex @@ -22,7 +22,8 @@ defmodule FarmbotOS.SysCalls.PinControl do def toggle_pin(pin_number) when is_number(pin_number) do peripheral = Asset.get_peripheral_by_pin(pin_number) - with :ok <- FarmbotFirmware.command({:pin_mode_write, [p: pin_number, m: 1]}) do + with :ok <- + FarmbotFirmware.command({:pin_mode_write, [p: pin_number, m: 1]}) do case FarmbotFirmware.request({:pin_read, [p: pin_number, m: 0]}) do {:ok, {_, {:report_pin_value, [p: _, v: 1]}}} -> do_toggle_pin(peripheral || pin_number, 0) @@ -53,7 +54,10 @@ defmodule FarmbotOS.SysCalls.PinControl do end defp do_toggle_pin(%Peripheral{pin: pin_number} = data, value) do - with :ok <- FarmbotFirmware.command({:pin_write, [p: pin_number, v: value, m: 0]}), + with :ok <- + FarmbotFirmware.command( + {:pin_write, [p: pin_number, v: value, m: 0]} + ), value when is_number(value) <- do_read_pin(data, 0) do :ok else @@ -63,7 +67,10 @@ defmodule FarmbotOS.SysCalls.PinControl do end defp do_toggle_pin(pin_number, value) do - with :ok <- FarmbotFirmware.command({:pin_write, [p: pin_number, v: value, m: 0]}), + with :ok <- + FarmbotFirmware.command( + {:pin_write, [p: pin_number, v: value, m: 0]} + ), value when is_number(value) <- do_read_pin(pin_number, 0) do :ok else @@ -121,19 +128,32 @@ defmodule FarmbotOS.SysCalls.PinControl do # digital peripheral - defp do_read_pin(%Peripheral{pin: pin_number, label: label}, 0) when is_number(pin_number) do + defp do_read_pin(%Peripheral{pin: pin_number, label: label}, 0) + when is_number(pin_number) do case FarmbotFirmware.request({:pin_read, [p: pin_number, m: 0]}) do {:ok, {_, {:report_pin_value, [p: _, v: 1]}}} -> - FarmbotCore.Logger.info(2, "The #{label} peripheral value is ON (digital)") + FarmbotCore.Logger.info( + 2, + "The #{label} peripheral value is ON (digital)" + ) + 1 {:ok, {_, {:report_pin_value, [p: _, v: 0]}}} -> - FarmbotCore.Logger.info(2, "The #{label} peripheral value is OFF (digital)") + FarmbotCore.Logger.info( + 2, + "The #{label} peripheral value is OFF (digital)" + ) + 0 # Just in case {:ok, {_, {:report_pin_value, [p: _, v: value]}}} -> - FarmbotCore.Logger.info(2, "The #{label} peripheral value is #{value} (analog)") + FarmbotCore.Logger.info( + 2, + "The #{label} peripheral value is #{value} (analog)" + ) + value {:error, reason} -> @@ -143,10 +163,15 @@ defmodule FarmbotOS.SysCalls.PinControl do # analog peripheral - defp do_read_pin(%Peripheral{pin: pin_number, label: label}, 1) when is_number(pin_number) do + defp do_read_pin(%Peripheral{pin: pin_number, label: label}, 1) + when is_number(pin_number) do case FarmbotFirmware.request({:pin_read, [p: pin_number, m: 1]}) do {:ok, {_, {:report_pin_value, [p: _, v: value]}}} -> - FarmbotCore.Logger.info(2, "The #{label} peripheral value is #{value} (analog)") + FarmbotCore.Logger.info( + 2, + "The #{label} peripheral value is #{value} (analog)" + ) + value {:error, reason} -> @@ -156,7 +181,8 @@ defmodule FarmbotOS.SysCalls.PinControl do # digital sensor - defp do_read_pin(%Sensor{pin: pin_number, label: label}, 0) when is_number(pin_number) do + defp do_read_pin(%Sensor{pin: pin_number, label: label}, 0) + when is_number(pin_number) do case FarmbotFirmware.request({:pin_read, [p: pin_number, m: 0]}) do {:ok, {_, {:report_pin_value, [p: _, v: 1]}}} -> FarmbotCore.Logger.info(2, "The #{label} sensor value is 1 (digital)") @@ -167,7 +193,10 @@ defmodule FarmbotOS.SysCalls.PinControl do 0 {:ok, {_, {:report_pin_value, [p: _, v: value]}}} -> - FarmbotCore.Logger.info(2, "The #{label} sensor value is #{value} (analog)") + FarmbotCore.Logger.info( + 2, + "The #{label} sensor value is #{value} (analog)" + ) {:error, reason} -> {:error, "Firmware error: #{inspect(reason)}"} @@ -176,10 +205,15 @@ defmodule FarmbotOS.SysCalls.PinControl do # analog sensor - defp do_read_pin(%Sensor{pin: pin_number, label: label}, 1) when is_number(pin_number) do + defp do_read_pin(%Sensor{pin: pin_number, label: label}, 1) + when is_number(pin_number) do case FarmbotFirmware.request({:pin_read, [p: pin_number, m: 1]}) do {:ok, {_, {:report_pin_value, [p: _, v: value]}}} -> - FarmbotCore.Logger.info(2, "The #{label} sensor value is #{value} (analog)") + FarmbotCore.Logger.info( + 2, + "The #{label} sensor value is #{value} (analog)" + ) + value {:error, reason} -> @@ -188,7 +222,8 @@ defmodule FarmbotOS.SysCalls.PinControl do end # Catches unsupplied `mode` - defp do_read_pin(%type{mode: mode} = peripheral, nil) when type in [Peripheral, Sensor] do + defp do_read_pin(%type{mode: mode} = peripheral, nil) + when type in [Peripheral, Sensor] do do_read_pin(peripheral, mode) end @@ -284,7 +319,9 @@ defmodule FarmbotOS.SysCalls.PinControl do end def do_write_pin(pin_number, mode, value) do - case FarmbotFirmware.command({:pin_write, [p: pin_number, v: value, m: mode]}) do + case FarmbotFirmware.command( + {:pin_write, [p: pin_number, v: value, m: mode]} + ) do :ok -> :ok diff --git a/farmbot_os/lib/farmbot_os/sys_calls/resource_update.ex b/farmbot_os/lib/farmbot_os/sys_calls/resource_update.ex index d4db7bb7..d6571164 100644 --- a/farmbot_os/lib/farmbot_os/sys_calls/resource_update.ex +++ b/farmbot_os/lib/farmbot_os/sys_calls/resource_update.ex @@ -40,8 +40,12 @@ defmodule FarmbotOS.SysCalls.ResourceUpdate do _ = Private.mark_dirty!(point) :ok else - nil -> {:error, "#{type}.#{id} is not currently synced, so it could not be updated"} - {:error, _changeset} -> {:error, "Failed to update #{type}.#{id}"} + nil -> + {:error, + "#{type}.#{id} is not currently synced, so it could not be updated"} + + {:error, _changeset} -> + {:error, "Failed to update #{type}.#{id}"} end end @@ -54,7 +58,10 @@ defmodule FarmbotOS.SysCalls.ResourceUpdate do {key, rendered} _ -> - Logger.warn("failed to render #{key} => #{value} for resource_update") + Logger.warn( + "failed to render #{key} => #{value} for resource_update" + ) + {key, value} end diff --git a/farmbot_os/lib/mix/tasks.farmbot/env.ex b/farmbot_os/lib/mix/tasks.farmbot/env.ex index f8f12b8e..e853fbaa 100644 --- a/farmbot_os/lib/mix/tasks.farmbot/env.ex +++ b/farmbot_os/lib/mix/tasks.farmbot/env.ex @@ -88,6 +88,7 @@ defmodule Mix.Tasks.Farmbot.Env do @doc false def slack_token do - System.get_env("SLACK_TOKEN") || Mix.raise("No $SLACK_TOKEN environment variable.") + System.get_env("SLACK_TOKEN") || + Mix.raise("No $SLACK_TOKEN environment variable.") end end diff --git a/farmbot_os/lib/mix/tasks.farmbot/firmware/inject_ssh_key.ex b/farmbot_os/lib/mix/tasks.farmbot/firmware/inject_ssh_key.ex index c7a97bd4..013ce852 100644 --- a/farmbot_os/lib/mix/tasks.farmbot/firmware/inject_ssh_key.ex +++ b/farmbot_os/lib/mix/tasks.farmbot/firmware/inject_ssh_key.ex @@ -21,7 +21,11 @@ defmodule Mix.Tasks.Farmbot.InjectSshKey do [key] ]) - {:ok, _} = :rpc.call(farmbot_node, Application, :ensure_all_started, [:nerves_firmware_ssh]) + {:ok, _} = + :rpc.call(farmbot_node, Application, :ensure_all_started, [ + :nerves_firmware_ssh + ]) + :ok = :rpc.call(farmbot_node, GenServer, :stop, [Farmbot.Target.SSHConsole]) end end diff --git a/farmbot_os/lib/mix/tasks.farmbot/firmware/reload.ex b/farmbot_os/lib/mix/tasks.farmbot/firmware/reload.ex index d63c276e..e1b38033 100644 --- a/farmbot_os/lib/mix/tasks.farmbot/firmware/reload.ex +++ b/farmbot_os/lib/mix/tasks.farmbot/firmware/reload.ex @@ -17,7 +17,8 @@ defmodule Mix.Tasks.Farmbot.Firmware.Reload do true = Node.connect(farmbot_node) for module <- mods do - {:ok, [{^farmbot_node, :loaded, ^module}]} = IEx.Helpers.nl([farmbot_node], module) + {:ok, [{^farmbot_node, :loaded, ^module}]} = + IEx.Helpers.nl([farmbot_node], module) end end diff --git a/farmbot_os/lib/mix/tasks.farmbot/firmware/sign.ex b/farmbot_os/lib/mix/tasks.farmbot/firmware/sign.ex index f87ce9fd..c7d69319 100644 --- a/farmbot_os/lib/mix/tasks.farmbot/firmware/sign.ex +++ b/farmbot_os/lib/mix/tasks.farmbot/firmware/sign.ex @@ -20,7 +20,9 @@ defmodule Mix.Tasks.Farmbot.Firmware.Sign do @dialyzer {[:no_return], [error: 0]} defp error do - Mix.raise("Usage: mix farmbot.firmware.sign /path/to/private/key [input.fw] [output.fw]") + Mix.raise( + "Usage: mix farmbot.firmware.sign /path/to/private/key [input.fw] [output.fw]" + ) end defp do_run(private_key_file, input_fw_file, output_fw_file) do @@ -37,6 +39,14 @@ defmodule Mix.Tasks.Farmbot.Firmware.Sign do "Signing: #{input_fw_file} with: #{private_key_file} to: #{output_fw_file}" ]) - System.cmd("fwup", ["-S", "-s", private_key_file, "-i", input_fw_file, "-o", output_fw_file]) + System.cmd("fwup", [ + "-S", + "-s", + private_key_file, + "-i", + input_fw_file, + "-o", + output_fw_file + ]) end end diff --git a/farmbot_os/mix.exs b/farmbot_os/mix.exs index f84e32ec..5b9aa604 100644 --- a/farmbot_os/mix.exs +++ b/farmbot_os/mix.exs @@ -2,12 +2,21 @@ defmodule FarmbotOS.MixProject do use Mix.Project @all_targets [:rpi3, :rpi] - @version Path.join([__DIR__, "..", "VERSION"]) |> File.read!() |> String.trim() - @branch System.cmd("git", ~w"rev-parse --abbrev-ref HEAD") |> elem(0) |> String.trim() - @commit System.cmd("git", ~w"rev-parse --verify HEAD") |> elem(0) |> String.trim() + @version Path.join([__DIR__, "..", "VERSION"]) + |> File.read!() + |> String.trim() + @branch System.cmd("git", ~w"rev-parse --abbrev-ref HEAD") + |> elem(0) + |> String.trim() + @commit System.cmd("git", ~w"rev-parse --verify HEAD") + |> elem(0) + |> String.trim() System.put_env("NERVES_FW_VCS_IDENTIFIER", @commit) System.put_env("NERVES_FW_MISC", @branch) - @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) |> File.read!() |> String.trim() + + @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) + |> File.read!() + |> String.trim() System.put_env("NERVES_FW_VCS_IDENTIFIER", @commit) @@ -93,7 +102,8 @@ defmodule FarmbotOS.MixProject do # Host/test only dependencies. {:excoveralls, "~> 0.10", only: [:test], targets: [:host]}, - {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], targets: [:host], runtime: false}, + {:dialyxir, "~> 1.0.0-rc.3", + only: [:dev], targets: [:host], runtime: false}, {:ex_doc, "~> 0.21.2", only: [:dev], targets: [:host], runtime: false}, {:elixir_make, "~> 0.6", runtime: false}, @@ -114,7 +124,8 @@ defmodule FarmbotOS.MixProject do {:vintage_net_direct, "~> 0.7.0", targets: @all_targets}, {:mdns_lite, "~> 0.6.1", targets: @all_targets}, {:busybox, "~> 0.1.4", targets: @all_targets}, - {:farmbot_system_rpi3, "1.10.0-farmbot.1", runtime: false, targets: :rpi3}, + {:farmbot_system_rpi3, "1.10.0-farmbot.1", + runtime: false, targets: :rpi3}, {:farmbot_system_rpi, "1.10.0-farmbot.1", runtime: false, targets: :rpi} ] end diff --git a/farmbot_os/platform/target/configurator/captive_portal.ex b/farmbot_os/platform/target/configurator/captive_portal.ex index 972ba1bd..fb92763f 100644 --- a/farmbot_os/platform/target/configurator/captive_portal.ex +++ b/farmbot_os/platform/target/configurator/captive_portal.ex @@ -45,7 +45,10 @@ defmodule FarmbotOS.Platform.Target.Configurator.CaptivePortal do VintageNetWiFi.ioctl(ifname, ioctl, args) end - defp dnsmasq(%{ifname: ifname, source_config: %{dnsmasq: config}} = raw_config, opts) do + defp dnsmasq( + %{ifname: ifname, source_config: %{dnsmasq: config}} = raw_config, + opts + ) do tmpdir = Keyword.fetch!(opts, :tmpdir) killall = Keyword.fetch!(opts, :bin_killall) dnsmasq = System.find_executable("dnsmasq") @@ -93,7 +96,8 @@ defmodule FarmbotOS.Platform.Target.Configurator.CaptivePortal do up_cmds: raw_config.up_cmds ++ up_cmds, down_cmds: raw_config.down_cmds ++ down_cmds, cleanup_files: - raw_config.cleanup_files ++ [dnsmasq_conf_path, dnsmasq_lease_file, dnsmasq_pid_file] + raw_config.cleanup_files ++ + [dnsmasq_conf_path, dnsmasq_lease_file, dnsmasq_pid_file] } updated_raw_config diff --git a/farmbot_os/platform/target/configurator/validator.ex b/farmbot_os/platform/target/configurator/validator.ex index c82f9367..bc006776 100644 --- a/farmbot_os/platform/target/configurator/validator.ex +++ b/farmbot_os/platform/target/configurator/validator.ex @@ -90,7 +90,11 @@ defmodule FarmbotOS.Platform.Target.Configurator.Validator do %{method: :dhcp} end - defp to_vintage_net_wifi(%{security: "NONE", ssid: ssid, regulatory_domain: reg_domain}) do + defp to_vintage_net_wifi(%{ + security: "NONE", + ssid: ssid, + regulatory_domain: reg_domain + }) do %{ networks: [ %{ diff --git a/farmbot_os/platform/target/configurator/vintage_network_layer.ex b/farmbot_os/platform/target/configurator/vintage_network_layer.ex index 25eb781c..a0ebe387 100644 --- a/farmbot_os/platform/target/configurator/vintage_network_layer.ex +++ b/farmbot_os/platform/target/configurator/vintage_network_layer.ex @@ -23,7 +23,12 @@ defmodule FarmbotOS.Platform.Target.Configurator.VintageNetworkLayer do def scan(ifname) do {:ok, aps} = do_scan(ifname) - Enum.map(aps, fn %{bssid: bssid, ssid: ssid, signal_percent: signal, flags: flags} -> + Enum.map(aps, fn %{ + bssid: bssid, + ssid: ssid, + signal_percent: signal, + flags: flags + } -> %{ ssid: ssid, bssid: bssid, diff --git a/farmbot_os/platform/target/gpio/circuits_gpio_handler.ex b/farmbot_os/platform/target/gpio/circuits_gpio_handler.ex index a6fb76a9..1f6cf268 100644 --- a/farmbot_os/platform/target/gpio/circuits_gpio_handler.ex +++ b/farmbot_os/platform/target/gpio/circuits_gpio_handler.ex @@ -13,7 +13,9 @@ defmodule FarmbotOS.Platform.Target.PinBindingWorker.CircuitsGPIOHandler do end def terminate(reason, state) do - Logger.warn("CircuitsGPIOHandler #{state.pin_number} crash: #{inspect(reason)}") + Logger.warn( + "CircuitsGPIOHandler #{state.pin_number} crash: #{inspect(reason)}" + ) end def init([pin_number, fun]) do @@ -31,7 +33,10 @@ defmodule FarmbotOS.Platform.Target.PinBindingWorker.CircuitsGPIOHandler do {:noreply, %{state | debounce: nil}} end - def handle_info({:circuits_gpio, pin, _timestamp, _}, %{debounce: timer} = state) + def handle_info( + {:circuits_gpio, pin, _timestamp, _}, + %{debounce: timer} = state + ) when is_reference(timer) do left = Process.read_timer(timer) Logger.info("CircuitsGPIOHandler #{pin} still debounced for #{left} ms") @@ -46,5 +51,6 @@ defmodule FarmbotOS.Platform.Target.PinBindingWorker.CircuitsGPIOHandler do def name(pin_number), do: :"#{__MODULE__}.#{pin_number}" - defp debounce_timer, do: Process.send_after(self(), :timeout, @debounce_timeout_ms) + defp debounce_timer, + do: Process.send_after(self(), :timeout, @debounce_timeout_ms) end diff --git a/farmbot_os/platform/target/gpio/circuits_leds_handler.ex b/farmbot_os/platform/target/gpio/circuits_leds_handler.ex index a8c0c28e..81eb6ac2 100644 --- a/farmbot_os/platform/target/gpio/circuits_leds_handler.ex +++ b/farmbot_os/platform/target/gpio/circuits_leds_handler.ex @@ -60,7 +60,17 @@ defmodule FarmbotOS.Platform.Target.Leds.CircuitsHandler do end def init([]) do - leds = [:red, :blue, :green, :yellow, :white1, :white2, :white3, :white4, :white5] + leds = [ + :red, + :blue, + :green, + :yellow, + :white1, + :white2, + :white3, + :white4, + :white5 + ] state = Map.new(leds, fn color -> @@ -78,7 +88,12 @@ defmodule FarmbotOS.Platform.Target.Leds.CircuitsHandler do :ok = cancel_timer(state[color].blink_timer) {:reply, :ok, - update_color(state, color, %{state[color] | state: 0, blink_timer: nil, status: :off})} + update_color(state, color, %{ + state[color] + | state: 0, + blink_timer: nil, + status: :off + })} end def handle_call({color, :solid}, _from, state) do @@ -86,28 +101,46 @@ defmodule FarmbotOS.Platform.Target.Leds.CircuitsHandler do :ok = cancel_timer(state[color].blink_timer) {:reply, :ok, - update_color(state, color, %{state[color] | state: 1, blink_timer: nil, status: :off})} + update_color(state, color, %{ + state[color] + | state: 1, + blink_timer: nil, + status: :off + })} end def handle_call({color, :slow_blink}, _from, state) do timer = restart_timer(state[color].blink_timer, color, @slow_blink_speed) {:reply, :ok, - update_color(state, color, %{state[color] | blink_timer: timer, status: :slow_blink})} + update_color(state, color, %{ + state[color] + | blink_timer: timer, + status: :slow_blink + })} end def handle_call({color, :fast_blink}, _from, state) do timer = restart_timer(state[color].blink_timer, color, @fast_blink_speed) {:reply, :ok, - update_color(state, color, %{state[color] | blink_timer: timer, status: :fast_blink})} + update_color(state, color, %{ + state[color] + | blink_timer: timer, + status: :fast_blink + })} end def handle_call({color, :really_fast_blink}, _from, state) do - timer = restart_timer(state[color].blink_timer, color, @really_fast_blink_speed) + timer = + restart_timer(state[color].blink_timer, color, @really_fast_blink_speed) {:reply, :ok, - update_color(state, color, %{state[color] | blink_timer: timer, status: :really_fast_blink})} + update_color(state, color, %{ + state[color] + | blink_timer: timer, + status: :really_fast_blink + })} end def handle_info({:blink_timer, color}, state) do @@ -116,21 +149,45 @@ defmodule FarmbotOS.Platform.Target.Leds.CircuitsHandler do %{status: :slow_blink} -> new_led_state = invert(state[color].state) :ok = GPIO.write(state[color].ref, new_led_state) - timer = restart_timer(state[color].blink_timer, color, @slow_blink_speed) - n = %{state[color] | state: new_led_state, blink_timer: timer, status: :slow_blink} + + timer = + restart_timer(state[color].blink_timer, color, @slow_blink_speed) + + n = %{ + state[color] + | state: new_led_state, + blink_timer: timer, + status: :slow_blink + } + update_color(state, color, n) %{status: :fast_blink} -> new_led_state = invert(state[color].state) :ok = GPIO.write(state[color].ref, new_led_state) - timer = restart_timer(state[color].blink_timer, color, @fast_blink_speed) - n = %{state[color] | state: new_led_state, blink_timer: timer, status: :fast_blink} + + timer = + restart_timer(state[color].blink_timer, color, @fast_blink_speed) + + n = %{ + state[color] + | state: new_led_state, + blink_timer: timer, + status: :fast_blink + } + update_color(state, color, n) %{status: :really_fast_blink} -> new_led_state = invert(state[color].state) :ok = GPIO.write(state[color].ref, new_led_state) - timer = restart_timer(state[color].blink_timer, color, @really_fast_blink_speed) + + timer = + restart_timer( + state[color].blink_timer, + color, + @really_fast_blink_speed + ) n = %{ state[color] diff --git a/farmbot_os/platform/target/info_workers/throttle.ex b/farmbot_os/platform/target/info_workers/throttle.ex index 02c7f389..c1187c4c 100644 --- a/farmbot_os/platform/target/info_workers/throttle.ex +++ b/farmbot_os/platform/target/info_workers/throttle.ex @@ -22,7 +22,8 @@ defmodule FarmbotOS.Platform.Target.InfoWorker.Throttle do @impl GenServer def handle_info(:timeout, state) do - {throttled_str, 0} = Nerves.Runtime.cmd("vcgencmd", ["get_throttled"], :return) + {throttled_str, 0} = + Nerves.Runtime.cmd("vcgencmd", ["get_throttled"], :return) throttled = throttled_str diff --git a/farmbot_os/platform/target/info_workers/wifi_level.ex b/farmbot_os/platform/target/info_workers/wifi_level.ex index 72d1ab04..885710b3 100644 --- a/farmbot_os/platform/target/info_workers/wifi_level.ex +++ b/farmbot_os/platform/target/info_workers/wifi_level.ex @@ -44,7 +44,8 @@ defmodule FarmbotOS.Platform.Target.InfoWorker.WifiLevel do end def handle_info( - {VintageNet, ["interface", _, "addresses"], _old, [%{address: address} | _], _meta}, + {VintageNet, ["interface", _, "addresses"], _old, + [%{address: address} | _], _meta}, state ) do FarmbotCore.BotState.set_private_ip(to_string(:inet.ntoa(address))) @@ -52,7 +53,8 @@ defmodule FarmbotOS.Platform.Target.InfoWorker.WifiLevel do end def handle_info( - {VintageNet, ["interface", "wlan0", "wifi", "access_points"], _, new, _meta}, + {VintageNet, ["interface", "wlan0", "wifi", "access_points"], _, new, + _meta}, %{ssid: ssid} = state ) when is_binary(ssid) do diff --git a/farmbot_os/platform/target/nerves_hub_client.ex b/farmbot_os/platform/target/nerves_hub_client.ex index 68e968eb..e5bf28bd 100644 --- a/farmbot_os/platform/target/nerves_hub_client.ex +++ b/farmbot_os/platform/target/nerves_hub_client.ex @@ -94,10 +94,12 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do def uuid, do: Nerves.Runtime.KV.get_active("nerves_fw_uuid") @doc "Loads the cert from storage" - def load_cert, do: Nerves.Runtime.KV.get_active("nerves_hub_cert") |> filter_parens() + def load_cert, + do: Nerves.Runtime.KV.get_active("nerves_hub_cert") |> filter_parens() @doc "Loads the key from storage" - def load_key, do: Nerves.Runtime.KV.get_active("nerves_hub_key") |> filter_parens() + def load_key, + do: Nerves.Runtime.KV.get_active("nerves_hub_key") |> filter_parens() @doc false def write_serial(serial_number) do @@ -143,8 +145,14 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do try do # NervesHub replaces it's own env on startup. Reset it. # Stop Nerves Hub if it is running. - _ = Supervisor.terminate_child(FarmbotOS.Init.Supervisor, NervesHub.Supervisor) - _ = Supervisor.delete_child(FarmbotOS.Init.Supervisor, NervesHub.Supervisor) + _ = + Supervisor.terminate_child( + FarmbotOS.Init.Supervisor, + NervesHub.Supervisor + ) + + _ = + Supervisor.delete_child(FarmbotOS.Init.Supervisor, NervesHub.Supervisor) cert = load_cert() key = load_key() @@ -162,8 +170,15 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do end catch kind, err -> - IO.warn("NervesHub error: #{inspect(kind)} #{inspect(err)}", __STACKTRACE__) - FarmbotCore.Logger.error(1, "OTA service error: #{kind} #{inspect(err)}") + IO.warn( + "NervesHub error: #{inspect(kind)} #{inspect(err)}", + __STACKTRACE__ + ) + + FarmbotCore.Logger.error( + 1, + "OTA service error: #{kind} #{inspect(err)}" + ) end # Start the connection again. @@ -200,7 +215,11 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do @impl GenServer def terminate(reason, state) do - FarmbotCore.Logger.error(1, "Disconnected from NervesHub AMQP channel: #{inspect(reason)}") + FarmbotCore.Logger.error( + 1, + "Disconnected from NervesHub AMQP channel: #{inspect(reason)}" + ) + # If a channel was still open, close it. if state.chan, do: AMQP.Channel.close(state.chan) end @@ -215,7 +234,10 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do {:ok, chan} <- Channel.open(conn), :ok <- Basic.qos(chan, global: true), {:ok, _} <- - Queue.declare(chan, "#{jwt.bot}_nerves_hub", auto_delete: false, durable: true), + Queue.declare(chan, "#{jwt.bot}_nerves_hub", + auto_delete: false, + durable: true + ), :ok <- Queue.bind(chan, "#{jwt.bot}_nerves_hub", @exchange, routing_key: "bot.#{jwt.bot}.nerves_hub" @@ -226,7 +248,11 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do else # happens when no token is configured. {nil, nil} -> - FarmbotCore.Logger.debug(3, "No credentials yet. Can't connect to OTA Server.") + FarmbotCore.Logger.debug( + 3, + "No credentials yet. Can't connect to OTA Server." + ) + Process.send_after(self(), :connect_amqp, 15_000) {:noreply, %{state | conn: nil, chan: nil, jwt: nil}} @@ -242,7 +268,11 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do end def handle_info(:after_connect_amqp, %{key: nil, cert: nil} = state) do - FarmbotCore.Logger.debug(3, "Connected to NervesHub AMQP channel. Fetching certs.") + FarmbotCore.Logger.debug( + 3, + "Connected to NervesHub AMQP channel. Fetching certs." + ) + old_device_cert = Asset.get_device_cert(serial_number: serial_number()) tags = detect_deployment_tags() @@ -263,24 +293,41 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do # DO NOT DO THIS. The api will do it behind the scenes # Asset.update_device!(%{update_channel: detect_update_channel()}) FarmbotCore.Logger.debug(3, "DeviceCert created") - FarmbotCore.Logger.debug(3, "Waiting for cert and key data from AMQP from farmbot api...") + + FarmbotCore.Logger.debug( + 3, + "Waiting for cert and key data from AMQP from farmbot api..." + ) + {:noreply, state} {:error, reason} -> - FarmbotCore.Logger.error(1, "Failed to create device cert: #{inspect(reason)}") + FarmbotCore.Logger.error( + 1, + "Failed to create device cert: #{inspect(reason)}" + ) + Process.send_after(self(), :after_connect_amqp, 5000) {:noreply, state} end end def handle_info(:after_connect_amqp, %{key: _key, cert: _cert} = state) do - FarmbotCore.Logger.debug(3, "Connected to NervesHub AMQP channel. Certs already loaded") + FarmbotCore.Logger.debug( + 3, + "Connected to NervesHub AMQP channel. Certs already loaded" + ) + send(self(), :connect_nerves_hub) {:noreply, state} end def handle_info(:connect_nerves_hub, %{key: nil, cert: nil} = state) do - FarmbotCore.Logger.debug(3, "Can't connect to OTA Service. Certs not loaded") + FarmbotCore.Logger.debug( + 3, + "Can't connect to OTA Service. Certs not loaded" + ) + send(self(), :connect_amqp) {:noreply, state} end @@ -322,7 +369,8 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do device = state.jwt.bot ["bot", ^device, "nerves_hub"] = String.split(key, ".") - with {:ok, %{"cert" => base64_cert, "key" => base64_key}} <- JSON.decode(payload), + with {:ok, %{"cert" => base64_cert, "key" => base64_key}} <- + JSON.decode(payload), {:ok, cert} <- Base.decode64(base64_cert), {:ok, key} <- Base.decode64(base64_key), :ok <- write_cert(cert), @@ -331,7 +379,11 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do {:noreply, %{state | cert: cert, key: key}} else {:error, reason} -> - FarmbotCore.Logger.error(1, "OTA Service failed to configure. #{inspect(reason)}") + FarmbotCore.Logger.error( + 1, + "OTA Service failed to configure. #{inspect(reason)}" + ) + {:stop, reason, state} :error -> @@ -340,7 +392,10 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do end end - def handle_info(:checkup, %{is_applying_update: false, probably_connected: true} = state) do + def handle_info( + :checkup, + %{is_applying_update: false, probably_connected: true} = state + ) do if should_auto_apply_update?() && update_available?() do FarmbotCore.Logger.busy(1, "Applying OTA update") spawn_link(fn -> NervesHub.update() end) @@ -364,7 +419,10 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do end @impl GenServer - def handle_cast({:handle_nerves_hub_error, error}, %{is_applying_update: true} = state) do + def handle_cast( + {:handle_nerves_hub_error, error}, + %{is_applying_update: true} = state + ) do FarmbotCore.Logger.error(1, "Error applying OTA: #{inspect(error)}") {:noreply, state} end @@ -374,7 +432,10 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do {:noreply, state} end - def handle_cast({:handle_nerves_hub_fwup_message, {:progress, percent}}, state) do + def handle_cast( + {:handle_nerves_hub_fwup_message, {:progress, percent}}, + state + ) do _ = set_ota_progress(percent) {:noreply, state} end @@ -397,7 +458,11 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do end @impl GenServer - def handle_call({:handle_nerves_hub_update_available, %{"firmware_url" => url}}, _from, state) do + def handle_call( + {:handle_nerves_hub_update_available, %{"firmware_url" => url}}, + _from, + state + ) do case should_auto_apply_update?() do true -> FarmbotCore.Logger.busy(1, "Applying OTA update") @@ -462,9 +527,9 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do %{hour: now_hour} -> FarmbotCore.Logger.debug( 3, - "current hour: #{now_hour} (utc=#{now.hour}) != ota_hour: #{ota_hour}. auto_update=#{ - auto_update - }" + "current hour: #{now_hour} (utc=#{now.hour}) != ota_hour: #{ + ota_hour + }. auto_update=#{auto_update}" ) false @@ -538,7 +603,13 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do end defp open_connection(email, token, jwt) do - case ConnectionWorker.open_connection(token, email, jwt.bot, jwt.mqtt, jwt.vhost) do + case ConnectionWorker.open_connection( + token, + email, + jwt.bot, + jwt.mqtt, + jwt.vhost + ) do {:ok, conn} -> Process.link(conn.pid) Process.monitor(conn.pid) @@ -550,7 +621,11 @@ defmodule FarmbotOS.Platform.Target.NervesHubClient do err err -> - FarmbotCore.Logger.error(1, "Error opening AMQP connection for OTA certs #{inspect(err)}") + FarmbotCore.Logger.error( + 1, + "Error opening AMQP connection for OTA certs #{inspect(err)}" + ) + err end end diff --git a/farmbot_os/platform/target/network.ex b/farmbot_os/platform/target/network.ex index e438546e..d56a8411 100644 --- a/farmbot_os/platform/target/network.ex +++ b/farmbot_os/platform/target/network.ex @@ -110,9 +110,15 @@ defmodule FarmbotOS.Platform.Target.Network do end end - def handle_info({VintageNet, ["interface", ifname, "type"], _old, type, _meta}, state) + def handle_info( + {VintageNet, ["interface", ifname, "type"], _old, type, _meta}, + state + ) when type in [PreSetup, VintageNet.Technology.Null] do - FarmbotCore.Logger.debug(1, "Network interface needs configuration: #{ifname}") + FarmbotCore.Logger.debug( + 1, + "Network interface needs configuration: #{ifname}" + ) case Config.get_network_config(ifname) do %Config.NetworkInterface{} = config -> @@ -129,10 +135,17 @@ defmodule FarmbotOS.Platform.Target.Network do end vintage_net_config = to_vintage_net(config) - FarmbotTelemetry.event(:network, :interface_configure, nil, interface: ifname) + + FarmbotTelemetry.event(:network, :interface_configure, nil, + interface: ifname + ) + configure_result = VintageNet.configure(config.name, vintage_net_config) - FarmbotCore.Logger.success(3, "#{config.name} setup: #{inspect(configure_result)}") + FarmbotCore.Logger.success( + 3, + "#{config.name} setup: #{inspect(configure_result)}" + ) state = start_network_not_found_timer(state) {:noreply, state} @@ -142,14 +155,27 @@ defmodule FarmbotOS.Platform.Target.Network do end end - def handle_info({VintageNet, ["interface", ifname, "lower_up"], _old, false, _meta}, state) do - FarmbotCore.Logger.error(1, "Interface #{ifname} disconnected from access point") - FarmbotTelemetry.event(:network, :interface_disconnect, nil, interface: ifname) + def handle_info( + {VintageNet, ["interface", ifname, "lower_up"], _old, false, _meta}, + state + ) do + FarmbotCore.Logger.error( + 1, + "Interface #{ifname} disconnected from access point" + ) + + FarmbotTelemetry.event(:network, :interface_disconnect, nil, + interface: ifname + ) + state = start_network_not_found_timer(state) {:noreply, state} end - def handle_info({VintageNet, ["interface", ifname, "lower_up"], _old, true, _meta}, state) do + def handle_info( + {VintageNet, ["interface", ifname, "lower_up"], _old, true, _meta}, + state + ) do FarmbotCore.Logger.success(1, "Interface #{ifname} connected access point") FarmbotTelemetry.event(:network, :interface_connect, nil, interface: ifname) state = cancel_network_not_found_timer(state) @@ -157,16 +183,22 @@ defmodule FarmbotOS.Platform.Target.Network do end def handle_info( - {VintageNet, ["interface", ifname, "connection"], :disconnected, :lan, _meta}, + {VintageNet, ["interface", ifname, "connection"], :disconnected, :lan, + _meta}, state ) do - FarmbotCore.Logger.warn(1, "Interface #{ifname} connected to local area network") + FarmbotCore.Logger.warn( + 1, + "Interface #{ifname} connected to local area network" + ) + FarmbotTelemetry.event(:network, :lan_connect, nil, interface: ifname) {:noreply, state} end def handle_info( - {VintageNet, ["interface", ifname, "connection"], :lan, :internet, _meta}, + {VintageNet, ["interface", ifname, "connection"], :lan, :internet, + _meta}, state ) do FarmbotCore.Logger.warn(1, "Interface #{ifname} connected to internet") @@ -176,10 +208,15 @@ defmodule FarmbotOS.Platform.Target.Network do end def handle_info( - {VintageNet, ["interface", ifname, "connection"], :internet, ifstate, _meta}, + {VintageNet, ["interface", ifname, "connection"], :internet, ifstate, + _meta}, state ) do - FarmbotCore.Logger.warn(1, "Interface #{ifname} disconnected from the internet: #{ifstate}") + FarmbotCore.Logger.warn( + 1, + "Interface #{ifname} disconnected from the internet: #{ifstate}" + ) + FarmbotExt.AMQP.ConnectionWorker.close() FarmbotTelemetry.event(:network, :wan_disconnect, nil, interface: ifname) @@ -192,15 +229,16 @@ defmodule FarmbotOS.Platform.Target.Network do end def handle_info( - {VintageNet, ["interface", _, "wifi", "access_points"], _old, _new, _meta}, + {VintageNet, ["interface", _, "wifi", "access_points"], _old, _new, + _meta}, state ) do {:noreply, state} end def handle_info( - {VintageNet, ["interface", _ifname, "eap_status"], _old, %{status: :success} = eap_status, - _meta}, + {VintageNet, ["interface", _ifname, "eap_status"], _old, + %{status: :success} = eap_status, _meta}, state ) do FarmbotCore.Logger.debug(3, """ @@ -212,7 +250,8 @@ defmodule FarmbotOS.Platform.Target.Network do end def handle_info( - {VintageNet, ["interface", _ifname, "eap_status"], _old, %{status: :failure}, _meta}, + {VintageNet, ["interface", _ifname, "eap_status"], _old, + %{status: :failure}, _meta}, state ) do FarmbotCore.Logger.error(1, """ @@ -292,7 +331,9 @@ defmodule FarmbotOS.Platform.Target.Network do # Stored in minutes minutes = network_not_found_timer_minutes(state) millis = minutes * 60000 - new_timer = Process.send_after(self(), {:network_not_found_timer, minutes}, millis) + + new_timer = + Process.send_after(self(), {:network_not_found_timer, minutes}, millis) FarmbotCore.Logger.warn( 1, @@ -308,13 +349,18 @@ defmodule FarmbotOS.Platform.Target.Network do defp network_not_found_timer_minutes(%{first_connect?: true}), do: 1 defp network_not_found_timer_minutes(_state) do - Asset.fbos_config(:network_not_found_timer) || @default_network_not_found_timer_minutes + Asset.fbos_config(:network_not_found_timer) || + @default_network_not_found_timer_minutes end def reset_ntp do FarmbotTelemetry.event(:ntp, :reset) - ntp_server_1 = Config.get_config_value(:string, "settings", "default_ntp_server_1") - ntp_server_2 = Config.get_config_value(:string, "settings", "default_ntp_server_2") + + ntp_server_1 = + Config.get_config_value(:string, "settings", "default_ntp_server_1") + + ntp_server_2 = + Config.get_config_value(:string, "settings", "default_ntp_server_2") if ntp_server_1 || ntp_server_2 do Logger.info("Setting NTP servers: [#{ntp_server_1}, #{ntp_server_2}]") diff --git a/farmbot_os/platform/target/rtc_worker.ex b/farmbot_os/platform/target/rtc_worker.ex index dc194572..f0d46471 100644 --- a/farmbot_os/platform/target/rtc_worker.ex +++ b/farmbot_os/platform/target/rtc_worker.ex @@ -68,12 +68,17 @@ defmodule FarmbotOS.Platform.Target.RTCWorker do end @doc "Gets a NaiveDateTime from the rtc" - @spec get_time_from_rtc(I2C.bus()) :: {:ok, NaiveDateTime.t()} | {:error, term()} + @spec get_time_from_rtc(I2C.bus()) :: + {:ok, NaiveDateTime.t()} | {:error, term()} def get_time_from_rtc(i2c) do - with {:ok, <<_vl::bits-1, second::bits-7>>} <- I2C.write_read(i2c, 0x51, <<0x02>>, 1), - {:ok, <<_::bits-1, minute::bits-7>>} <- I2C.write_read(i2c, 0x51, <<0x03>>, 1), - {:ok, <<_::bits-2, hour::bits-6>>} <- I2C.write_read(i2c, 0x51, <<0x04>>, 1), - {:ok, <<_::bits-2, day::bits-6>>} <- I2C.write_read(i2c, 0x51, <<0x05>>, 1), + with {:ok, <<_vl::bits-1, second::bits-7>>} <- + I2C.write_read(i2c, 0x51, <<0x02>>, 1), + {:ok, <<_::bits-1, minute::bits-7>>} <- + I2C.write_read(i2c, 0x51, <<0x03>>, 1), + {:ok, <<_::bits-2, hour::bits-6>>} <- + I2C.write_read(i2c, 0x51, <<0x04>>, 1), + {:ok, <<_::bits-2, day::bits-6>>} <- + I2C.write_read(i2c, 0x51, <<0x05>>, 1), {:ok, <<_c::bits-1, _::bits-2, month::bits-5>>} <- I2C.write_read(i2c, 0x51, <<0x07>>, 1), # implied 20XX @@ -178,7 +183,9 @@ defmodule FarmbotOS.Platform.Target.RTCWorker do Logger.error("Not setting system time from RTC. VL bit is unset") error -> - Logger.error("failed to get time from rtc or set system time: #{inspect(error)}") + Logger.error( + "failed to get time from rtc or set system time: #{inspect(error)}" + ) end Process.send_after(self(), :set_rtc_from_ntp, @eleven_minutes) diff --git a/farmbot_os/platform/target/shoehorn_handler.ex b/farmbot_os/platform/target/shoehorn_handler.ex index 2af193af..11be146c 100644 --- a/farmbot_os/platform/target/shoehorn_handler.ex +++ b/farmbot_os/platform/target/shoehorn_handler.ex @@ -17,7 +17,11 @@ defmodule FarmbotOS.Platform.Target.ShoehornHandler do @impl true def application_exited(:nerves_runtime, _, state) do # https://github.com/nerves-project/nerves_runtime/issues/152 - _ = System.cmd("killall", ["-9", "kmsg_tailer"], into: IO.stream(:stdio, :line)) + _ = + System.cmd("killall", ["-9", "kmsg_tailer"], + into: IO.stream(:stdio, :line) + ) + {:continue, state} end @@ -28,7 +32,10 @@ defmodule FarmbotOS.Platform.Target.ShoehornHandler do :farmbot_ext, :farmbot ] do - error_log("Farmbot app: #{app} exited #{count}: #{inspect(reason, limit: :infinity)}") + error_log( + "Farmbot app: #{app} exited #{count}: #{inspect(reason, limit: :infinity)}" + ) + # Force a factory reset. FarmbotOS.System.factory_reset( "Farmbot app: #{app} exited #{count}: #{inspect(reason, limit: :infinity)}" @@ -45,7 +52,10 @@ defmodule FarmbotOS.Platform.Target.ShoehornHandler do :farmbot_ext, :farmbot ] do - error_log("Farmbot app: #{app} exited #{count}: #{inspect(reason, limit: :infinity)}") + error_log( + "Farmbot app: #{app} exited #{count}: #{inspect(reason, limit: :infinity)}" + ) + FarmbotTelemetry.event(:shoehorn, :application_exit, nil, application: app) with {:ok, _} <- Application.ensure_all_started(:farmbot_core), @@ -58,7 +68,10 @@ defmodule FarmbotOS.Platform.Target.ShoehornHandler do end def application_exited(app, reason, state) do - error_log("Application stopped: #{inspect(app)} #{inspect(reason, limit: :infinity)}") + error_log( + "Application stopped: #{inspect(app)} #{inspect(reason, limit: :infinity)}" + ) + FarmbotTelemetry.event(:shoehorn, :application_exit, nil, application: app) # Application.ensure_all_started(app) {:continue, state} diff --git a/farmbot_os/platform/target/ssh_console.ex b/farmbot_os/platform/target/ssh_console.ex index 00b39641..301bb5a8 100644 --- a/farmbot_os/platform/target/ssh_console.ex +++ b/farmbot_os/platform/target/ssh_console.ex @@ -55,7 +55,10 @@ defmodule FarmbotOS.Platform.Target.SSHConsole do end end - def handle_cast({:add_key, %PublicKey{public_key: authorized_key}}, %{ssh: ssh} = state) do + def handle_cast( + {:add_key, %PublicKey{public_key: authorized_key}}, + %{ssh: ssh} = state + ) do _ = stop_ssh(ssh) decoded_authorized_key = do_decode(authorized_key) @@ -65,7 +68,9 @@ defmodule FarmbotOS.Platform.Target.SSHConsole do %{ state | ssh: ssh, - public_keys: [List.first(decoded_authorized_key) | state.public_keys] + public_keys: [ + List.first(decoded_authorized_key) | state.public_keys + ] }} error -> @@ -78,11 +83,13 @@ defmodule FarmbotOS.Platform.Target.SSHConsole do ssh && :ssh.stop_daemon(ssh) end - defp start_ssh(port, decoded_authorized_keys) when is_list(decoded_authorized_keys) do + defp start_ssh(port, decoded_authorized_keys) + when is_list(decoded_authorized_keys) do # Reuse keys from `nerves_firmware_ssh` so that the user only needs one # config.exs entry. nerves_keys = - Application.get_env(:nerves_firmware_ssh, :authorized_keys, []) |> Enum.join("\n") + Application.get_env(:nerves_firmware_ssh, :authorized_keys, []) + |> Enum.join("\n") decoded_nerves_keys = do_decode(nerves_keys) diff --git a/farmbot_os/platform/target/uevent.ex b/farmbot_os/platform/target/uevent.ex index 5d534a3c..4b9c8e36 100644 --- a/farmbot_os/platform/target/uevent.ex +++ b/farmbot_os/platform/target/uevent.ex @@ -74,8 +74,20 @@ defmodule FarmbotOS.Platform.Target.Uevent do FarmbotTelemetry.event(:firmware, :tty_detected, nil, tty: tty) FarmbotCore.Logger.busy(1, "new firmware interfaces detected: #{tty}") FirmwareTTYDetector.set_tty(tty) - Config.update_config_value(:bool, "settings", "firmware_needs_flash", true) - Config.update_config_value(:bool, "settings", "firmware_needs_open", false) + + Config.update_config_value( + :bool, + "settings", + "firmware_needs_flash", + true + ) + + Config.update_config_value( + :bool, + "settings", + "firmware_needs_open", + false + ) tty -> Logger.debug("firmware interface already detected: #{tty}") diff --git a/farmbot_os/test/farmbot_os/configurator/router_test.exs b/farmbot_os/test/farmbot_os/configurator/router_test.exs index 06e5854f..6996443a 100644 --- a/farmbot_os/test/farmbot_os/configurator/router_test.exs +++ b/farmbot_os/test/farmbot_os/configurator/router_test.exs @@ -141,7 +141,10 @@ defmodule FarmbotOS.Configurator.RouterTest do assert redirected_to(conn) == "/config_wireless" conn = - conn(:post, "/config_wireless_step_1", %{"ssid" => "Test Network", "security" => "NONE"}) + conn(:post, "/config_wireless_step_1", %{ + "ssid" => "Test Network", + "security" => "NONE" + }) |> init_test_session(%{"ifname" => "wlan0"}) |> Router.call(@opts) @@ -149,7 +152,10 @@ defmodule FarmbotOS.Configurator.RouterTest do assert conn.resp_body =~ "Advanced settings" conn = - conn(:post, "/config_wireless_step_1", %{"ssid" => "Test Network", "security" => "WPA-PSK"}) + conn(:post, "/config_wireless_step_1", %{ + "ssid" => "Test Network", + "security" => "WPA-PSK" + }) |> init_test_session(%{"ifname" => "wlan0"}) |> Router.call(@opts) @@ -157,7 +163,10 @@ defmodule FarmbotOS.Configurator.RouterTest do assert conn.resp_body =~ "Advanced settings" conn = - conn(:post, "/config_wireless_step_1", %{"ssid" => "Test Network", "security" => "WPA2-PSK"}) + conn(:post, "/config_wireless_step_1", %{ + "ssid" => "Test Network", + "security" => "WPA2-PSK" + }) |> init_test_session(%{"ifname" => "wlan0"}) |> Router.call(@opts) @@ -165,7 +174,10 @@ defmodule FarmbotOS.Configurator.RouterTest do assert conn.resp_body =~ "Advanced settings" conn = - conn(:post, "/config_wireless_step_1", %{"ssid" => "Test Network", "security" => "WPA-EAP"}) + conn(:post, "/config_wireless_step_1", %{ + "ssid" => "Test Network", + "security" => "WPA-EAP" + }) |> init_test_session(%{"ifname" => "wlan0"}) |> Router.call(@opts) @@ -227,10 +239,18 @@ defmodule FarmbotOS.Configurator.RouterTest do assert get_session(conn, "net_config_ssid") == "Test Network" assert get_session(conn, "net_config_security") == "WPA-PSK" assert get_session(conn, "net_config_psk") == "ABCDEF" - assert get_session(conn, "net_config_identity") == "NOT TECHNICALLY POSSIBLE" - assert get_session(conn, "net_config_password") == "NOT TECHNICALLY POSSIBLE" + + assert get_session(conn, "net_config_identity") == + "NOT TECHNICALLY POSSIBLE" + + assert get_session(conn, "net_config_password") == + "NOT TECHNICALLY POSSIBLE" + assert get_session(conn, "net_config_domain") == "farmbot.org" - assert get_session(conn, "net_config_name_servers") == "192.168.1.1, 192.168.1.2" + + assert get_session(conn, "net_config_name_servers") == + "192.168.1.1, 192.168.1.2" + assert get_session(conn, "net_config_ipv4_method") == "static" assert get_session(conn, "net_config_ipv4_address") == "192.168.1.100" assert get_session(conn, "net_config_ipv4_gateway") == "192.168.1.1" @@ -268,7 +288,10 @@ defmodule FarmbotOS.Configurator.RouterTest do assert get_session(conn, "auth_config_server") == "https://my.farm.bot" conn = - conn(:post, "/configure_credentials", %{params | "server" => "whoops/i/made/a/type"}) + conn(:post, "/configure_credentials", %{ + params + | "server" => "whoops/i/made/a/type" + }) |> Router.call(@opts) assert redirected_to(conn) == "/credentials" diff --git a/farmbot_os/test/support/mox.ex b/farmbot_os/test/support/mox.ex index 929bcefd..055a9f50 100644 --- a/farmbot_os/test/support/mox.ex +++ b/farmbot_os/test/support/mox.ex @@ -1,2 +1,7 @@ -Mox.defmock(FarmbotTest.Configurator.MockDataLayer, for: FarmbotOS.Configurator.DataLayer) -Mox.defmock(FarmbotTest.Configurator.MockNetworkLayer, for: FarmbotOS.Configurator.NetworkLayer) +Mox.defmock(FarmbotTest.Configurator.MockDataLayer, + for: FarmbotOS.Configurator.DataLayer +) + +Mox.defmock(FarmbotTest.Configurator.MockNetworkLayer, + for: FarmbotOS.Configurator.NetworkLayer +) diff --git a/farmbot_telemetry/lib/farmbot_telemetry.ex b/farmbot_telemetry/lib/farmbot_telemetry.ex index 1ab539b1..5a3a587b 100644 --- a/farmbot_telemetry/lib/farmbot_telemetry.ex +++ b/farmbot_telemetry/lib/farmbot_telemetry.ex @@ -58,7 +58,9 @@ defmodule FarmbotTelemetry do defmacro event(subsystem, measurement, value, meta) do Mix.raise(""" Unknown args for telemetry event: - #{inspect(subsystem)}, #{inspect(measurement)}, #{inspect(value)}, #{inspect(meta)} + #{inspect(subsystem)}, #{inspect(measurement)}, #{inspect(value)}, #{ + inspect(meta) + } """) end @@ -92,15 +94,37 @@ defmodule FarmbotTelemetry do Dispatching is done by calling the `consume_telemetry/1` function. """ - @spec bare_telemetry(uuid, kind(), subsystem(), measurement(), value(), DateTime.t(), meta()) :: + @spec bare_telemetry( + uuid, + kind(), + subsystem(), + measurement(), + value(), + DateTime.t(), + meta() + ) :: :ok - def bare_telemetry(uuid, kind, subsystem, measurement, value, captured_at, meta) - when is_binary(uuid) and is_atom(kind) and is_atom(subsystem) and is_atom(measurement) and + def bare_telemetry( + uuid, + kind, + subsystem, + measurement, + value, + captured_at, + meta + ) + when is_binary(uuid) and is_atom(kind) and is_atom(subsystem) and + is_atom(measurement) and is_list(meta) do _ = :telemetry.execute( [:farmbot_telemetry, kind, subsystem], - %{measurement: measurement, value: value, captured_at: captured_at, uuid: uuid}, + %{ + measurement: measurement, + value: value, + captured_at: captured_at, + uuid: uuid + }, Map.new(meta) ) @@ -142,7 +166,8 @@ defmodule FarmbotTelemetry do @typedoc "Function passed to `consume_telemetry/1`" @type consumer_fun() :: - ({uuid(), DateTime.t(), kind(), subsystem(), measurement(), value(), meta()} -> + ({uuid(), DateTime.t(), kind(), subsystem(), measurement(), value(), + meta()} -> :ok | any()) @doc """ diff --git a/farmbot_telemetry/mix.exs b/farmbot_telemetry/mix.exs index 2c38e1e6..7bd2f567 100644 --- a/farmbot_telemetry/mix.exs +++ b/farmbot_telemetry/mix.exs @@ -1,7 +1,12 @@ defmodule FarmbotTelemetry.MixProject do use Mix.Project - @version Path.join([__DIR__, "..", "VERSION"]) |> File.read!() |> String.trim() - @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) |> File.read!() |> String.trim() + + @version Path.join([__DIR__, "..", "VERSION"]) + |> File.read!() + |> String.trim() + @elixir_version Path.join([__DIR__, "..", "ELIXIR_VERSION"]) + |> File.read!() + |> String.trim() def project do [ @@ -44,7 +49,8 @@ defmodule FarmbotTelemetry.MixProject do {:telemetry, "~> 0.4.1"}, {:uuid, "~> 1.1"}, {:excoveralls, "~> 0.10", only: [:test], targets: [:host]}, - {:dialyxir, "~> 1.0.0-rc.3", only: [:dev], targets: [:host], runtime: false}, + {:dialyxir, "~> 1.0.0-rc.3", + only: [:dev], targets: [:host], runtime: false}, {:ex_doc, "~> 0.19", only: [:dev], targets: [:host], runtime: false} ] end diff --git a/farmbot_telemetry/test/farmbot_telemetry_test.exs b/farmbot_telemetry/test/farmbot_telemetry_test.exs index c668c83c..966f9f70 100644 --- a/farmbot_telemetry/test/farmbot_telemetry_test.exs +++ b/farmbot_telemetry/test/farmbot_telemetry_test.exs @@ -14,7 +14,9 @@ defmodule FarmbotTelemetryTest do test "assigns meta" do :ok = FarmbotTelemetry.attach_recv(:event, :test_subsystem, self()) - :ok = FarmbotTelemetry.event(:test_subsystem, :measurement, 1.0, hello: "world") + + :ok = + FarmbotTelemetry.event(:test_subsystem, :measurement, 1.0, hello: "world") assert_receive {[:farmbot_telemetry, :event, :test_subsystem], %{measurement: :measurement, value: 1.0}, meta, _config}