procon_bypass_man 0.1.21 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +9 -0
  3. data/.github/workflows/gitleacks.yml +11 -0
  4. data/.gitignore +1 -0
  5. data/CHANGELOG.md +24 -0
  6. data/Gemfile.lock +4 -4
  7. data/README.md +4 -1
  8. data/docs/getting_started.md +70 -5
  9. data/docs/setting/left-analogstick-cap.md +1 -1
  10. data/docs/setting/splatoon2_macro_dasei_cancel.md +4 -0
  11. data/docs/setting/splatoon2_macro_sokuwari_bubble.md +4 -0
  12. data/docs/setting/splatoon2_shake_tansan.md +47 -0
  13. data/docs/setup_raspi.md +0 -1
  14. data/lib/procon_bypass_man/background/jobs/post_completed_remote_macro_job.rb +17 -0
  15. data/lib/procon_bypass_man/background.rb +1 -0
  16. data/lib/procon_bypass_man/buttons_setting_configuration/layer.rb +142 -80
  17. data/lib/procon_bypass_man/buttons_setting_configuration/loader.rb +3 -1
  18. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/button.rb +28 -0
  19. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/button_list.rb +31 -0
  20. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/disable_macro_if_pressed.rb +28 -0
  21. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/flip_if_pressed.rb +31 -0
  22. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/force_neutral.rb +28 -0
  23. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/if_pressed.rb +26 -0
  24. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/if_pressed_allows_nil.rb +28 -0
  25. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer/open_macro_steps.rb +26 -0
  26. data/lib/procon_bypass_man/buttons_setting_configuration/param_normalizer.rb +17 -0
  27. data/lib/procon_bypass_man/buttons_setting_configuration.rb +5 -4
  28. data/lib/procon_bypass_man/{commands → bypass}/bypass_command.rb +36 -24
  29. data/lib/procon_bypass_man/bypass/usb_hid_logger.rb +4 -0
  30. data/lib/procon_bypass_man/bypass.rb +43 -23
  31. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +2 -3
  32. data/lib/procon_bypass_man/commands/send_error_command.rb +2 -2
  33. data/lib/procon_bypass_man/commands.rb +0 -3
  34. data/lib/procon_bypass_man/configuration.rb +29 -3
  35. data/lib/procon_bypass_man/device_connection/command.rb +28 -0
  36. data/lib/procon_bypass_man/device_connection/executor.rb +190 -0
  37. data/lib/procon_bypass_man/device_connection/output_report_generator.rb +42 -0
  38. data/lib/procon_bypass_man/device_connection/output_report_markerable.rb +28 -0
  39. data/lib/procon_bypass_man/device_connection/output_report_sub_command_table.rb +133 -0
  40. data/lib/procon_bypass_man/device_connection/output_report_watcher.rb +41 -0
  41. data/lib/procon_bypass_man/device_connection/pre_bypass.rb +67 -0
  42. data/lib/procon_bypass_man/device_connection/procon_setting_overrider.rb +78 -0
  43. data/lib/procon_bypass_man/device_connection/spoofing_output_report_watcher.rb +39 -0
  44. data/lib/procon_bypass_man/device_connection.rb +16 -0
  45. data/lib/procon_bypass_man/device_model.rb +17 -0
  46. data/lib/procon_bypass_man/io_monitor.rb +20 -1
  47. data/lib/procon_bypass_man/plugin/splatoon2/macro/charge_tansan_bomb.rb +21 -0
  48. data/lib/procon_bypass_man/plugin/splatoon2/version.rb +1 -1
  49. data/lib/procon_bypass_man/plugins.rb +1 -0
  50. data/lib/procon_bypass_man/procon/analog_stick_cap.rb +4 -23
  51. data/lib/procon_bypass_man/procon/analog_stick_manipulator.rb +36 -0
  52. data/lib/procon_bypass_man/procon/layer_changer.rb +4 -1
  53. data/lib/procon_bypass_man/procon/macro.rb +5 -2
  54. data/lib/procon_bypass_man/procon/macro_builder.rb +20 -20
  55. data/lib/procon_bypass_man/procon/macro_plugin_map.rb +23 -0
  56. data/lib/procon_bypass_man/procon/macro_registry.rb +21 -10
  57. data/lib/procon_bypass_man/procon/suppress_rumble.rb +13 -0
  58. data/lib/procon_bypass_man/procon/user_operation.rb +29 -15
  59. data/lib/procon_bypass_man/procon/value_objects/analog_stick_position.rb +18 -0
  60. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/base.rb +0 -0
  61. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/has_immutable_binary.rb +0 -0
  62. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/has_mutable_binary.rb +0 -0
  63. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/inbound_procon_binary.rb +5 -0
  64. data/lib/procon_bypass_man/{domains → procon/value_objects}/binary/processing_procon_binary.rb +6 -1
  65. data/lib/procon_bypass_man/procon/value_objects/binary.rb +11 -0
  66. data/lib/procon_bypass_man/{domains → procon/value_objects}/bypass_mode.rb +0 -0
  67. data/lib/procon_bypass_man/procon/value_objects/rumble_binary.rb +18 -0
  68. data/lib/procon_bypass_man/procon.rb +27 -5
  69. data/lib/procon_bypass_man/remote_macro/queue_over_process.rb +62 -0
  70. data/lib/procon_bypass_man/remote_macro/remote_macro_object.rb +30 -0
  71. data/lib/procon_bypass_man/remote_macro/remote_macro_receiver.rb +37 -0
  72. data/lib/procon_bypass_man/remote_macro/remote_macro_sender.rb +8 -0
  73. data/lib/procon_bypass_man/remote_macro/task.rb +6 -0
  74. data/lib/procon_bypass_man/remote_macro/task_queue.rb +13 -0
  75. data/lib/procon_bypass_man/remote_macro.rb +14 -0
  76. data/lib/procon_bypass_man/{commands → remote_pbm_action/commands}/run_remote_pbm_action_dispatch_command.rb +0 -0
  77. data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +7 -1
  78. data/lib/procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object.rb +1 -1
  79. data/lib/procon_bypass_man/remote_pbm_action.rb +2 -0
  80. data/lib/procon_bypass_man/runner.rb +13 -13
  81. data/lib/procon_bypass_man/support/cycle_sleep.rb +22 -0
  82. data/lib/procon_bypass_man/support/device_mouse_finder.rb +60 -0
  83. data/lib/procon_bypass_man/{device_procon_finder.rb → support/device_procon_finder.rb} +0 -2
  84. data/lib/procon_bypass_man/support/never_exit_accidentally.rb +3 -3
  85. data/lib/procon_bypass_man/support/remote_macro_http_client.rb +9 -0
  86. data/lib/procon_bypass_man/support/safe_timeout.rb +7 -1
  87. data/lib/procon_bypass_man/{usb_device_controller.rb → support/usb_device_controller.rb} +9 -6
  88. data/lib/procon_bypass_man/support/yaml_loader.rb +12 -0
  89. data/lib/procon_bypass_man/version.rb +1 -1
  90. data/lib/procon_bypass_man/websocket/{pbm_job_client.rb → client.rb} +32 -10
  91. data/lib/procon_bypass_man.rb +69 -46
  92. data/procon_bypass_man.gemspec +1 -1
  93. data/project_template/app.rb +19 -4
  94. data/sig/main.rbs +4 -16
  95. metadata +55 -17
  96. data/lib/procon_bypass_man/commands/connect_device_command.rb +0 -18
  97. data/lib/procon_bypass_man/device_connector.rb +0 -296
  98. data/lib/procon_bypass_man/domains.rb +0 -12
@@ -0,0 +1,30 @@
1
+ module ProconBypassMan
2
+ class RemoteMacroObject
3
+ # valueobjectがvalidatorの責務も持っている. 今度分離する
4
+ class ValidationError < StandardError; end
5
+ class MustBeNotNilError < ValidationError; end
6
+ class NonSupportAction < ValidationError; end
7
+
8
+ attr_accessor :name, :uuid, :steps
9
+
10
+ # @param [String] name
11
+ # @param [String] uuid
12
+ # @param [Array] steps
13
+ def initialize(name: , uuid:, steps: )
14
+ @name = name
15
+ @uuid = uuid
16
+ @steps = steps
17
+ freeze
18
+ end
19
+
20
+ # @raise [MustBeNotNilError]
21
+ # @raise [NonSupportAction]
22
+ # @return [void]
23
+ def validate!
24
+ self.uuid or raise MustBeNotNilError, "uuidは値が必須です"
25
+ unless self.steps.is_a?(Array)
26
+ raise ValidationError, "stepsは配列です"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ class ProconBypassMan::RemoteMacroReceiver
2
+ # forkしたプロセスで動かすクラス。sock経由で命令を受け取ってmacoのキューに積んでいく
3
+ def self.start_with_foreground!
4
+ return unless ProconBypassMan.config.enable_remote_macro?
5
+
6
+ run
7
+ end
8
+
9
+ def self.start!
10
+ return unless ProconBypassMan.config.enable_remote_macro?
11
+
12
+ Thread.start do
13
+ start_with_foreground!
14
+ end
15
+ end
16
+
17
+ def self.run
18
+ while(task = ProconBypassMan::QueueOverProcess.pop)
19
+ receive(task)
20
+ end
21
+ shutdown
22
+ rescue Errno::ENOENT, Errno::ECONNRESET, Errno::ECONNREFUSED => e
23
+ ProconBypassMan.logger.debug(e)
24
+ end
25
+
26
+
27
+ # @param [ProconBypassMan::RemoteMacro::Task] task
28
+ def self.receive(task)
29
+ ProconBypassMan.logger.info "[remote macro][receiver] name: #{task.name}, uuid: #{task.uuid}, steps: #{task.steps}"
30
+ ProconBypassMan::RemoteMacro::TaskQueueInProcess.push(task)
31
+ true
32
+ end
33
+
34
+ def self.shutdown
35
+ ProconBypassMan.logger.info("ProconBypassMan::RemoteMacroReceiverを終了します。")
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ class ProconBypassMan::RemoteMacroSender
2
+ def self.execute(name: , uuid: , steps: )
3
+ ProconBypassMan.logger.info "[remote macro][sender] name: #{name}, uuid: #{uuid}, steps: #{steps}"
4
+ ProconBypassMan::QueueOverProcess.push(
5
+ ProconBypassMan::RemoteMacro::Task.new(name, uuid, steps)
6
+ )
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module ProconBypassMan
2
+ module RemoteMacro
3
+ class Task < Struct.new(:name, :uuid, :steps)
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ module ProconBypassMan
2
+ module RemoteMacro
3
+ class TaskQueue < ::Queue
4
+ def present?
5
+ not empty?
6
+ end
7
+
8
+ def non_blocking_shift
9
+ present? && shift
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module ProconBypassMan
2
+ module RemoteMacro
3
+ require "procon_bypass_man/remote_macro/remote_macro_object"
4
+ require "procon_bypass_man/remote_macro/remote_macro_receiver"
5
+ require "procon_bypass_man/remote_macro/remote_macro_sender"
6
+ require "procon_bypass_man/remote_macro/queue_over_process"
7
+ require "procon_bypass_man/remote_macro/task"
8
+ require "procon_bypass_man/remote_macro/task_queue"
9
+
10
+ ACTION_KEY = "remote_macro"
11
+
12
+ TaskQueueInProcess = ProconBypassMan::RemoteMacro::TaskQueue.new
13
+ end
14
+ end
@@ -17,7 +17,8 @@ module ProconBypassMan
17
17
  path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
18
18
  content: setting,
19
19
  )
20
- ProconBypassMan.hot_reload!
20
+
21
+ hot_reload!
21
22
  end
22
23
 
23
24
  private
@@ -29,6 +30,11 @@ module ProconBypassMan
29
30
  def after_action_callback
30
31
  be_processed
31
32
  end
33
+
34
+ # @return [void]
35
+ def hot_reload!
36
+ Process.kill(:USR2, ProconBypassMan.pid)
37
+ end
32
38
  end
33
39
  end
34
40
  end
@@ -11,7 +11,7 @@ module ProconBypassMan
11
11
  # @param [String] status
12
12
  # @param [String] #uuid
13
13
  # @param [Time] created_at
14
- # @return [Hash] job_args
14
+ # @param [Hash] job_args
15
15
  def initialize(action: , status:, uuid:, created_at:, job_args: )
16
16
  self.action = action
17
17
  self.status = status
@@ -6,6 +6,8 @@ module ProconBypassMan
6
6
  require "procon_bypass_man/remote_pbm_action/stop_pbm_action"
7
7
  require "procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb"
8
8
  require "procon_bypass_man/remote_pbm_action/commands/update_remote_pbm_action_status_command"
9
+ require "procon_bypass_man/remote_pbm_action/commands/run_remote_pbm_action_dispatch_command"
10
+ require "procon_bypass_man/remote_pbm_action/value_objects/remote_pbm_action_object"
9
11
 
10
12
  ACTION_CHANGE_PBM_VERSION = "change_pbm_version"
11
13
  ACTION_REBOOT_OS = "reboot_os"
@@ -8,13 +8,11 @@ class ProconBypassMan::Runner
8
8
  def initialize(gadget: , procon: )
9
9
  @gadget = gadget
10
10
  @procon = procon
11
-
12
- ProconBypassMan::PrintBootMessageCommand.execute
13
11
  end
14
12
 
15
13
  def run
16
14
  self_read, self_write = IO.pipe
17
- %w(TERM INT USR1 USR2).each do |sig|
15
+ %w(TERM INT USR2).each do |sig|
18
16
  begin
19
17
  trap sig do
20
18
  self_write.puts(sig)
@@ -25,21 +23,25 @@ class ProconBypassMan::Runner
25
23
  end
26
24
 
27
25
  loop do
28
- $will_terminate_token = false
29
26
  # NOTE メインプロセスではThreadをいくつか起動しているので念のためパフォーマンスを優先するためにforkしていく
30
- child_pid = Kernel.fork { ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute }
27
+ child_pid = Kernel.fork {
28
+ $will_terminate_token = false
29
+ DRb.start_service if defined?(DRb)
30
+ ProconBypassMan::RemoteMacroReceiver.start!
31
+ ProconBypassMan::BypassCommand.new(gadget: @gadget, procon: @procon).execute # ここでblockingする
32
+ next
33
+ }
31
34
 
32
35
  begin
33
- # TODO 小プロセスが消滅した時に、メインプロセスは生き続けてしまい、何もできなくなる問題がある
36
+ # TODO 子プロセスが消滅した時に、メインプロセスは生き続けてしまい、何もできなくなる問題がある
34
37
  while(readable_io = IO.select([self_read]))
35
38
  signal = readable_io.first[0].gets.strip
36
39
  handle_signal(signal)
37
40
  end
38
41
  rescue InterruptForRestart
39
- $will_terminate_token = true
40
- Process.kill("TERM", child_pid)
42
+ ProconBypassMan::PrintMessageCommand.execute(text: "設定ファイルの再読み込みを開始します")
43
+ Process.kill("USR2", child_pid)
41
44
  Process.wait
42
- ProconBypassMan::PrintMessageCommand.execute(text: "Reloading config file")
43
45
  begin
44
46
  ProconBypassMan::ButtonsSettingConfiguration::Loader.reload_setting
45
47
  ProconBypassMan::SendReloadConfigEventCommand.execute
@@ -49,12 +51,10 @@ class ProconBypassMan::Runner
49
51
  end
50
52
  ProconBypassMan::PrintMessageCommand.execute(text: "バイパス処理を再開します")
51
53
  rescue Interrupt
52
- $will_terminate_token = true
54
+ puts
55
+ ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
53
56
  Process.kill("TERM", child_pid)
54
57
  Process.wait
55
- ProconBypassMan::PrintMessageCommand.execute(text: "処理を終了します")
56
- @gadget&.close
57
- @procon&.close
58
58
  break
59
59
  end
60
60
  end
@@ -0,0 +1,22 @@
1
+ # n秒間sleepしつつ、mainスレッドをm秒間隔で動かしたい時に使う
2
+ class ProconBypassMan::CycleSleep
3
+ attr_accessor :cycle_interval, :execution_cycle
4
+
5
+ def initialize(cycle_interval: , execution_cycle: )
6
+ @cycle_interval = cycle_interval
7
+ @execution_cycle = execution_cycle
8
+ @counter = 0
9
+ end
10
+
11
+ def sleep_or_execute
12
+ result = nil
13
+ if @counter >= @execution_cycle
14
+ @counter = 0
15
+ result = yield
16
+ else
17
+ @counter += 1
18
+ end
19
+ sleep(@cycle_interval)
20
+ return result
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ class ProconBypassMan::DeviceMouseFinder
2
+ class USBDevice < Struct.new(:display_name, :event_no)
3
+ # TODO bInterfaceProtocolの値を見てmouseかを判断したい
4
+ def mouse?
5
+ !!(display_name =~ /mouse/i)
6
+ end
7
+
8
+ def keyboard?
9
+ !!(display_name =~ /keyboard/i)
10
+ end
11
+
12
+ def event_device_path
13
+ "/dev/input/#{event_no}"
14
+ end
15
+ end
16
+
17
+ class Parser
18
+ def self.parse(shell_output)
19
+ instance = new
20
+ instance.set_usb_devices_from(shell_output)
21
+ instance
22
+ end
23
+
24
+ def set_usb_devices_from(shell_output)
25
+ @usb_devices =
26
+ shell_output.split(/\n\n/).map do |text|
27
+ display_name = /N: Name="(.+?)"$/ =~ text && $1
28
+ event_no = /H: Handlers=.*?(event\d).*?$/ =~ text && $1
29
+ USBDevice.new(display_name, event_no)
30
+ end
31
+ end
32
+
33
+ def usb_devices
34
+ @usb_devices ||= []
35
+ end
36
+ end
37
+
38
+ def self.find
39
+ new.find
40
+ end
41
+
42
+ # @return [String, NilClass]
43
+ def find
44
+ find_path
45
+ end
46
+
47
+ private
48
+
49
+ def find_path
50
+ Parser.parse(shell_output).usb_devices.detect(&:mouse?)&.event_device_path
51
+ end
52
+
53
+ def shell_output
54
+ `bash -c '#{shell}'`
55
+ end
56
+
57
+ def shell
58
+ 'cat /proc/bus/input/devices'
59
+ end
60
+ end
@@ -31,8 +31,6 @@ class ProconBypassMan::DeviceProconFinder
31
31
 
32
32
  def get_list_shell
33
33
  <<~SHELL
34
- #!/bin/bash
35
-
36
34
  FILES=/dev/hidraw*
37
35
  for f in $FILES
38
36
  do
@@ -1,11 +1,11 @@
1
1
  module ProconBypassMan
2
2
  module NeverExitAccidentally
3
- def exit_if_allow(status)
3
+ def self.exit_if_allow_at_config
4
4
  if ProconBypassMan.never_exit_accidentally
5
- eternal_sleep
5
+ ProconBypassMan.eternal_sleep
6
6
  else
7
7
  yield if block_given?
8
- exit(status)
8
+ exit 1
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,9 @@
1
+ module ProconBypassMan
2
+ class RemoteMacroHttpClient < HttpClient
3
+ def post(job_id: )
4
+ super(request_body: {
5
+ job_id: job_id,
6
+ })
7
+ end
8
+ end
9
+ end
@@ -7,8 +7,14 @@ module ProconBypassMan
7
7
  @timeout = timeout
8
8
  end
9
9
 
10
+ # @raise [Timeout]
10
11
  def throw_if_timeout!
11
- raise Timeout if @timeout < Time.now
12
+ raise Timeout if timeout?
13
+ end
14
+
15
+ # @return [Boolean]
16
+ def timeout?
17
+ @timeout < Time.now
12
18
  end
13
19
  end
14
20
  end
@@ -1,17 +1,19 @@
1
1
  class ProconBypassMan::UsbDeviceController
2
2
  class << self
3
- def reset
4
- system('echo > /sys/kernel/config/usb_gadget/procon/UDC')
5
- system('ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC')
6
- sleep 0.5
3
+ def reset(cooldown: 0.5)
4
+ [ "echo > /sys/kernel/config/usb_gadget/procon/UDC",
5
+ "ls /sys/class/udc > /sys/kernel/config/usb_gadget/procon/UDC",
6
+ ].each do |shell|
7
+ system shell
8
+ ProconBypassMan.logger.debug { "[SHELL] #{shell}" }
9
+ end
10
+ sleep cooldown
7
11
  end
8
12
 
9
13
  def init
10
14
  return if initialized?
11
15
 
12
16
  shell = <<~EOH
13
- #!/bin/bash
14
-
15
17
  cd /sys/kernel/config/usb_gadget/
16
18
  mkdir -p procon
17
19
  cd procon
@@ -44,6 +46,7 @@ class ProconBypassMan::UsbDeviceController
44
46
  EOH
45
47
 
46
48
  `bash -c '#{shell}'`
49
+ sleep(1)
47
50
  end
48
51
 
49
52
  def initialized?
@@ -0,0 +1,12 @@
1
+ class ProconBypassMan::YamlLoader
2
+ # @param [String] path
3
+ # @return [Hash]
4
+ def self.load(path: )
5
+ YAML.load_file(path).tap do |y|
6
+ # 行末に空白があるとto_yamlしたときに改行コードがエスケープされてしまうのでstrip
7
+ y.transform_values do |v|
8
+ v.strip! if v.is_a?(String)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.1.21"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -1,6 +1,6 @@
1
1
  module ProconBypassMan
2
2
  module Websocket
3
- module PbmJobClient
3
+ module Client
4
4
  CHANNEL = 'PbmJobChannel'
5
5
 
6
6
  def self.start!
@@ -20,11 +20,10 @@ module ProconBypassMan
20
20
  )
21
21
 
22
22
  client.connected {
23
- ProconBypassMan.logger.info('websocket client: successfully connected in ProconBypassMan::Websocket::PbmJobClient')
23
+ ProconBypassMan.logger.info('websocket client: successfully connected in ProconBypassMan::Websocket::Client')
24
24
  }
25
25
  client.subscribed { |msg|
26
- ProconBypassMan.logger.info('websocket client: subscribed')
27
- puts({ event: :subscribed, msg: msg })
26
+ ProconBypassMan.logger.info("websocket client: subscribed(#{msg})")
28
27
  ProconBypassMan::SyncDeviceStatsJob.perform(ProconBypassMan::DeviceStatus.current)
29
28
  }
30
29
 
@@ -39,13 +38,11 @@ module ProconBypassMan
39
38
 
40
39
  client.disconnected {
41
40
  ProconBypassMan.logger.info('websocket client: disconnected!!')
42
- puts :disconnected
43
41
  client.reconnect!
44
42
  sleep 2
45
43
  }
46
44
  client.errored { |msg|
47
45
  ProconBypassMan.logger.error("websocket client: errored!!, #{msg}")
48
- puts :errored
49
46
  client.reconnect!
50
47
  sleep 2
51
48
  }
@@ -63,17 +60,22 @@ module ProconBypassMan
63
60
  # @param [Hash] data
64
61
  def self.dispatch(data: , client: )
65
62
  pbm_job_hash = data.dig("message")
66
- if pbm_job_hash['action'] == "ping"
63
+ case pbm_job_hash['action']
64
+ when "ping"
67
65
  client.perform('pong', { device_id: ProconBypassMan.device_id, message: 'hello from pbm' })
66
+ when ProconBypassMan::RemoteMacro::ACTION_KEY
67
+ validate_and_run_remote_macro(data: data)
68
+ when *ProconBypassMan::RemotePbmAction::ACTIONS
69
+ validate_and_run_remote_pbm_action(data: data)
68
70
  else
69
- validate_and_run(data: data)
71
+ ProconBypassMan.logger.error "unknown action"
70
72
  end
71
73
  end
72
74
 
73
75
  # @raise [ProconBypassMan::RemotePbmActionObject::ValidationError]
74
76
  # @param [Hash] data
75
77
  # @return [Void]
76
- def self.validate_and_run(data: )
78
+ def self.validate_and_run_remote_pbm_action(data: )
77
79
  pbm_job_hash = data.dig("message")
78
80
  begin
79
81
  pbm_job_object = ProconBypassMan::RemotePbmActionObject.new(action: pbm_job_hash["action"],
@@ -83,7 +85,8 @@ module ProconBypassMan
83
85
  job_args: pbm_job_hash["args"])
84
86
  pbm_job_object.validate!
85
87
  rescue ProconBypassMan::RemotePbmActionObject::ValidationError => e
86
- raise
88
+ ProconBypassMan::SendErrorCommand.execute(error: e)
89
+ return
87
90
  end
88
91
 
89
92
  ProconBypassMan::RunRemotePbmActionDispatchCommand.execute(
@@ -92,6 +95,25 @@ module ProconBypassMan
92
95
  job_args: pbm_job_object.job_args
93
96
  )
94
97
  end
98
+
99
+ def self.validate_and_run_remote_macro(data: )
100
+ pbm_job_hash = data.dig("message")
101
+ begin
102
+ remote_macro_object = ProconBypassMan::RemoteMacroObject.new(name: pbm_job_hash["name"],
103
+ uuid: pbm_job_hash["uuid"],
104
+ steps: pbm_job_hash["steps"])
105
+ remote_macro_object.validate!
106
+ rescue ProconBypassMan::RemoteMacroObject::ValidationError => e
107
+ ProconBypassMan::SendErrorCommand.execute(error: e)
108
+ return
109
+ end
110
+
111
+ ProconBypassMan::RemoteMacroSender.execute(
112
+ name: remote_macro_object.name,
113
+ uuid: remote_macro_object.uuid,
114
+ steps: remote_macro_object.steps,
115
+ )
116
+ end
95
117
  end
96
118
  end
97
119
  end