Class: SDN::CLI::Provisioner

Inherits:
Object
  • Object
show all
Defined in:
lib/sdn/cli/provisioner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sdn, addr = nil) ⇒ Provisioner

Returns a new instance of Provisioner.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/sdn/cli/provisioner.rb', line 10

def initialize(sdn, addr = nil)
  @sdn = sdn
  @reversed = false
  @pulse_count = 10

  if addr
    @addr = addr = Message.parse_address(addr)
  else
    puts "Discovering motor..."
    message = sdn.ensure(Message::GetNodeAddr.new)
    puts "Found #{message.node_type}"
    @addr = addr = message.src
  end

  puts "Preparing to provision motor #{Message.print_address(addr)}"

  message = sdn.ensure(Message::GetNodeLabel.new(addr))

  node_type = message.node_type
  @ns = ns = (node_type == :st50ilt2) ? Message::ILT2 : Message

  print "Motor is currently labeled '#{message.label}'; " \
        "what would you like to change it to (blank to leave alone)? "
  new_label = $stdin.gets

  unless new_label == "\n"
    new_label.strip!
    sdn.ensure(ns::SetNodeLabel.new(addr, new_label))
  end

  # make sure some limits exist
  unless ns == Message::ILT2
    limits = sdn.ensure(Message::GetMotorLimits.new(addr))
    if limits.up_limit.nil? || limits.down_limit.nil?
      sdn.ensure(Message::SetMotorLimits.new(addr, :delete, :up))
      sdn.ensure(Message::SetMotorLimits.new(addr, :delete, :down))
      sdn.ensure(Message::SetMotorLimits.new(addr, :current_position, :up))
      sdn.ensure(Message::SetMotorLimits.new(addr, :specified_position, :down, 500))
    end
  end

  Curses.init_screen
  begin
    Curses.noecho
    Curses.crmode
    Curses.nonl
    Curses.curs_set(0)
    @win = Curses.stdscr

    process
  rescue Interrupt
    # exitting
  rescue => e
    win.setpos(0, 0)
    win.addstr(e.inspect)
    win.addstr("\n")
    win.addstr(e.backtrace.join("\n"))
    win.refresh
    sleep 10
  ensure
    Curses.close_screen
  end
end

Instance Attribute Details

#addrObject (readonly)

Returns the value of attribute addr.



8
9
10
# File 'lib/sdn/cli/provisioner.rb', line 8

def addr
  @addr
end

#nsObject (readonly)

Returns the value of attribute ns.



8
9
10
# File 'lib/sdn/cli/provisioner.rb', line 8

def ns
  @ns
end

#sdnObject (readonly)

Returns the value of attribute sdn.



8
9
10
# File 'lib/sdn/cli/provisioner.rb', line 8

def sdn
  @sdn
end

#winObject (readonly)

Returns the value of attribute win.



8
9
10
# File 'lib/sdn/cli/provisioner.rb', line 8

def win
  @win
end

Instance Method Details

#ilt2?Boolean

Returns:

  • (Boolean)


259
260
261
# File 'lib/sdn/cli/provisioner.rb', line 259

def ilt2?
  ns == Message::ILT2
end


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/sdn/cli/provisioner.rb', line 170

def print_help
  win.setpos(0, 0)
  win.addstr(<<~TEXT)
    Move the motor. Keys:
    Esc  stop movement
    \u2191    go to upper limit
    \u2193    go to lower limit
    \u2190    jog up #{@pulse_count} pulses
    \u2192    jog down #{@pulse_count} pulses
    >    increase jog size
    <    decrease jog size
    u    set upper limit at current position
    l    set lower limit at current position
    r    reverse motor
  TEXT

  if ilt2?
    win.addstr("R    reverse motor (but leave position alone)\n")
  else
    win.addstr("!    factory reset\n")
  end
  win.addstr("q    quit\n")
  win.refresh
end

#processObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/sdn/cli/provisioner.rb', line 74

def process
  win.keypad = true
  print_help
  refresh
  wait_for_stop

  loop do
    char = win.getch
    case char
    when 27 # Esc
      stop
      refresh
    when Curses::Key::UP
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorPosition.new(addr, :up_limit))
      else
        sdn.ensure(Message::MoveTo.new(addr, :up_limit))
      end
      wait_for_stop
    when Curses::Key::DOWN
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorPosition.new(addr, :down_limit))
      else
        sdn.ensure(Message::MoveTo.new(addr, :down_limit))
      end
      wait_for_stop
    when Curses::Key::LEFT
      if @pos < @pulse_count
        sdn.ensure(Message::ILT2::SetMotorSettings.new(addr,
                                                       reversed_int,
                                                       @limit + @pulse_count - @pos,
                                                       @pulse_count))
        refresh
      end
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorPosition.new(addr, :jog_up_pulses, @pulse_count))
      else
        sdn.ensure(Message::MoveOf.new(addr, :jog_up_pulses, @pulse_count))
      end
      wait_for_stop
    when Curses::Key::RIGHT
      if @limit - @pos < @pulse_count
        sdn.ensure(Message::ILT2::SetMotorSettings.new(addr, reversed_int, @pos + @pulse_count, @pos))
        refresh
      end
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorPosition.new(addr, :jog_down_pulses, @pulse_count))
      else
        sdn.ensure(Message::MoveOf.new(addr, :jog_down_pulses, @pulse_count))
      end
      wait_for_stop
    when "u"
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorSettings.new(addr, reversed_int, @limit - @pos, 0))
      else
        sdn.ensure(Message::SetMotorLimits.new(addr, :current_position, :up))
      end
      refresh
    when "l"
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorSettings.new(addr, reversed_int, @pos, @pos))
      else
        sdn.ensure(Message::SetMotorLimits.new(addr, :current_position, :down))
      end
      refresh
    when "r"
      @reversed = !@reversed
      if ilt2?
        sdn.ensure(Message::ILT2::SetMotorSettings.new(addr, reversed_int, @limit, @limit - @pos))
      else
        sdn.ensure(Message::SetMotorDirection.new(addr, @reversed ? :reversed : :standard))
      end
      refresh
    when "R"
      next unless ilt2?

      @reversed = !@reversed
      sdn.ensure(Message::ILT2::SetMotorSettings.new(addr, reversed_int, @limit, @pos))
      refresh
    when "!"
      next if ilt2?

      sdn.send(Message::SetFactoryDefault.new(addr))
      break
    when "<"
      @pulse_count /= 2 if @pulse_count > 5
      print_help
    when ">"
      @pulse_count *= 2
      print_help
    when "q"
      break
    end
  end
end

#refreshObject



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/sdn/cli/provisioner.rb', line 231

def refresh
  pos = sdn.ensure(ns::GetMotorPosition.new(addr))
  @pos = pos.position_pulses
  if ilt2?
    settings = sdn.ensure(Message::ILT2::GetMotorSettings.new(addr))
    @limit = settings.limit
  else
    limits = sdn.ensure(Message::GetMotorLimits.new(addr))
    @limit = limits.down_limit
    direction = sdn.ensure(Message::GetMotorDirection.new(addr))
    @reversed = direction.direction == :reversed
  end

  win.setpos(14, 0)
  win.addstr("Position: #{@pos}\n")
  win.addstr("Limit: #{@limit}\n")
  win.addstr("Reversed: #{@reversed}\n")
  win.refresh
end

#reversed_intObject



263
264
265
# File 'lib/sdn/cli/provisioner.rb', line 263

def reversed_int
  @reversed ? 1 : 0
end

#stopObject



251
252
253
254
255
256
257
# File 'lib/sdn/cli/provisioner.rb', line 251

def stop
  if ilt2?
    sdn.ensure(Message::ILT2::SetMotorPosition.new(addr, :stop))
  else
    sdn.ensure(Message::Stop.new(addr))
  end
end

#wait_for_stopObject



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/sdn/cli/provisioner.rb', line 195

def wait_for_stop
  win.setpos(13, 0)
  win.addstr("Moving...\n")

  loop do
    win.nodelay = true
    stop if win.getch == 27 # Esc

    sdn.send(ns::GetMotorPosition.new(addr))
    unless ilt2?
      sleep 0.1
      sdn.send(ns::GetMotorStatus.new(addr))
    end

    sdn.receive(0.1) do |message|
      if message.is_a?(ns::PostMotorPosition)
        last_pos = @pos
        @pos = message.position_pulses
        win.setpos(14, 0)
        win.addstr("Position: #{@pos}\n")
      end

      if (ilt2? && last_pos == @pos) ||
         (message.is_a?(Message::PostMotorStatus) &&
          message.state != :running)
        win.setpos(13, 0)
        win.addstr("\n")
        win.nodelay = false
        refresh
        return # rubocop:disable Lint/NonLocalExitFromIterator
      end
    end
    sleep 0.1
  end
end