1
1
defmodule BotState do
2
+ @ moduledoc """
3
+ Farmbots Hardware State tracker
4
+ """
2
5
use GenServer
3
6
require Logger
4
7
5
8
@ save_interval 15000
6
9
@ twelve_hours 3600000
7
10
8
- def init ( _ ) do
11
+ defmodule State do
12
+ @ moduledoc """
13
+ Farmbots Hardware State tracker State module
14
+ """
15
+ defstruct [
16
+ locks: [ ] ,
17
+ mcu_params: % { } ,
18
+ location: [ 0 , 0 , 0 ] ,
19
+ pins: % { } ,
20
+ configuration: % { } ,
21
+ informational_settings: % { } ,
22
+ authorization: % {
23
+ token: nil ,
24
+ email: nil ,
25
+ pass: nil ,
26
+ server: nil ,
27
+ network: nil
28
+ }
29
+ ]
30
+ @ type t :: % __MODULE__ {
31
+ locks: list ( % { reason: String . t } ) ,
32
+ mcu_params: map ,
33
+ location: [ number , ... ] , # i should change this to a tuple
34
+ pins: % { } ,
35
+ configuration: % { } ,
36
+ informational_settings: % { } ,
37
+ authorization: % {
38
+ token: map | nil ,
39
+ email: String . t | nil ,
40
+ pass: String . t | nil ,
41
+ server: String . t | nil ,
42
+ network: String . t | nil
43
+ }
44
+ }
45
+ end
46
+
47
+ def init ( args ) do
9
48
NetMan . put_pid ( BotState )
10
49
save_interval
11
50
check_updates
12
- { :ok , load }
51
+ { :ok , load ( args ) }
13
52
end
14
53
15
54
def start_link ( args ) do
@@ -30,24 +69,24 @@ defmodule BotState do
30
69
throttled
31
70
end
32
71
33
- def load do
72
+ def load ( % { target: target , compat_version: compat_version } ) do
34
73
token = case FarmbotAuth . get_token ( ) do
35
74
{ :ok , token } -> token
36
75
_ -> nil
37
76
end
38
- default_state = % {
39
- mcu_params: % { } ,
40
- location: [ 0 , 0 , 0 ] ,
41
- pins: % { } ,
42
- configuration: % { os_auto_update: false ,
43
- fw_auto_update: false ,
44
- timezone: nil ,
45
- steps_per_mm: 500 } ,
77
+ default_state = % State {
78
+ configuration: % {
79
+ os_auto_update: false ,
80
+ fw_auto_update: false ,
81
+ timezone: nil ,
82
+ steps_per_mm: 500
83
+ } ,
46
84
informational_settings: % {
47
85
controller_version: Fw . version ,
48
86
private_ip: nil ,
49
87
throttled: get_throttled ,
50
- locked: false
88
+ target: target ,
89
+ compat_version: compat_version
51
90
} ,
52
91
authorization: % {
53
92
token: token ,
@@ -63,7 +102,7 @@ defmodule BotState do
63
102
r = Map . keys ( rcontents )
64
103
Logger . debug ( "default: #{ inspect l } saved: #{ inspect r } " )
65
104
if ( l != r ) do # SORRY ABOUT THIS
66
- Logger . debug "UPDATING TO NEW STATE TREE FORMAT OR SOMETHING"
105
+ Logger . warn ( "UPDATING TO NEW STATE TREE FORMAT OR SOMETHING" )
67
106
spawn fn -> apply_auth ( default_state . authorization ) end
68
107
spawn fn -> apply_status ( default_state ) end
69
108
default_state
@@ -137,6 +176,36 @@ defmodule BotState do
137
176
{ :reply , state . authorization . token , state }
138
177
end
139
178
179
+ # Allow the frontend to do stuff again.
180
+ def handle_call ( { :remove_lock , string } , _from , state ) do
181
+ maybe_index = Enum . find_index ( state . locks , fn ( % { reason: str } ) -> str == string end )
182
+ cond do
183
+ is_integer ( maybe_index ) ->
184
+ { :reply , :ok , Map . put ( state , :locks ,
185
+ List . delete_at ( state . locks , maybe_index ) ) }
186
+ true ->
187
+ { :reply , { :error , :no_index } , state }
188
+ end
189
+ end
190
+
191
+ def handle_call ( { :get_lock , string } , _from , state ) do
192
+ maybe_index = Enum . find_index ( state . locks , fn ( % { reason: str } ) -> str == string end )
193
+ { :reply , maybe_index , state }
194
+ end
195
+
196
+ # Lock the frontend from doing stuff
197
+ def handle_cast ( { :add_lock , string } , state ) do
198
+ maybe_index = Enum . find_index ( state . locks , fn ( % { reason: str } ) -> str == string end )
199
+ cond do
200
+ is_integer ( maybe_index ) ->
201
+ { :noreply , Map . put ( state , :locks ,
202
+ List . replace_at ( state . locks , maybe_index , % { reason: string } ) ) }
203
+ is_nil ( maybe_index ) ->
204
+ { :noreply , Map . put ( state , :locks ,
205
+ state . locks ++ [ % { reason: string } ] ) }
206
+ end
207
+ end
208
+
140
209
def handle_cast ( { :update_info , key , value } , state ) do
141
210
new_info = Map . put ( state . informational_settings , key , value )
142
211
{ :noreply , Map . put ( state , :informational_settings , new_info ) }
@@ -178,13 +247,6 @@ defmodule BotState do
178
247
end
179
248
180
249
def handle_cast ( { :creds , { email , pass , server } } , state ) do
181
- # authorization: %{
182
- # token: nil
183
- # email: nil,
184
- # pass: nil,
185
- # server: nil
186
- # network: nil
187
- # }
188
250
auth = Map . merge ( state . authorization ,
189
251
% { email: email , pass: pass , server: server , token: nil , network: nil } )
190
252
{ :noreply , Map . put ( state , :authorization , auth ) }
@@ -260,6 +322,11 @@ defmodule BotState do
260
322
GenServer . call ( __MODULE__ , :get_token )
261
323
end
262
324
325
+ @ spec get_lock ( String . t ) :: integer | nil
326
+ def get_lock ( string ) when is_bitstring ( string ) do
327
+ GenServer . call ( __MODULE__ , { :get_lock , string } )
328
+ end
329
+
263
330
def set_pos ( x , y , z )
264
331
when is_integer ( x ) and is_integer ( y ) and is_integer ( z ) do
265
332
GenServer . cast ( __MODULE__ , { :set_pos , { x , y , z } } )
@@ -282,6 +349,16 @@ defmodule BotState do
282
349
GenServer . call ( __MODULE__ , { :get_pin , pin_number } )
283
350
end
284
351
352
+ @ spec add_lock ( String . t ) :: :ok
353
+ def add_lock ( string ) when is_bitstring ( string ) do
354
+ GenServer . cast ( __MODULE__ , { :add_lock , string } )
355
+ end
356
+
357
+ @ spec remove_lock ( String . t ) :: :ok | { :error , atom }
358
+ def remove_lock ( string ) when is_bitstring ( string ) do
359
+ GenServer . call ( __MODULE__ , { :remove_lock , string } )
360
+ end
361
+
285
362
def set_end_stop ( _something ) do
286
363
#TODO
287
364
nil
0 commit comments