procon_bypass_man 0.3.5 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +4 -0
- data/CHANGELOG.md +10 -3
- data/Gemfile +1 -0
- data/Gemfile.lock +3 -1
- data/Steepfile +0 -1
- data/bin/console +3 -0
- data/bin/generate_output_report +18 -0
- data/bin/validate_external_input +19 -0
- data/docs/getting_started.md +5 -0
- data/docs/setting/integration_external_input_serial_port.md +56 -0
- data/docs/setting/integration_external_input_serial_port_format.md +36 -0
- data/lib/procon_bypass_man/background/jobs/post_completed_remote_action_job.rb +20 -0
- data/lib/procon_bypass_man/background/jobs/report_info_log_job.rb +11 -0
- data/lib/procon_bypass_man/background/jobs/report_procon_performance_measurements_job.rb +1 -0
- data/lib/procon_bypass_man/background.rb +1 -0
- data/lib/procon_bypass_man/bypass/procon_to_switch.rb +19 -1
- data/lib/procon_bypass_man/commands/print_boot_message_command.rb +2 -0
- data/lib/procon_bypass_man/commands/send_info_log_command.rb +11 -0
- data/lib/procon_bypass_man/commands.rb +1 -0
- data/lib/procon_bypass_man/configuration.rb +7 -1
- data/lib/procon_bypass_man/external_input/channels/base.rb +12 -0
- data/lib/procon_bypass_man/external_input/channels/serial_port_channel.rb +48 -0
- data/lib/procon_bypass_man/external_input/channels/tcpip.rb +16 -0
- data/lib/procon_bypass_man/external_input/channels.rb +12 -0
- data/lib/procon_bypass_man/external_input/external_data.rb +79 -0
- data/lib/procon_bypass_man/external_input.rb +35 -0
- data/lib/procon_bypass_man/processor.rb +3 -2
- data/lib/procon_bypass_man/procon/button_collection.rb +5 -0
- data/lib/procon_bypass_man/procon/performance_measurement/measurements_summarizer.rb +4 -0
- data/lib/procon_bypass_man/procon/performance_measurement.rb +7 -1
- data/lib/procon_bypass_man/procon.rb +38 -12
- data/lib/procon_bypass_man/procon_display/status.rb +1 -2
- data/lib/procon_bypass_man/procon_display.rb +0 -1
- data/lib/procon_bypass_man/{remote_macro → remote_action}/queue_over_process.rb +2 -2
- data/lib/procon_bypass_man/{remote_macro/remote_macro_object.rb → remote_action/remote_action_object.rb} +1 -1
- data/lib/procon_bypass_man/{remote_macro/remote_macro_receiver.rb → remote_action/remote_action_receiver.rb} +8 -7
- data/lib/procon_bypass_man/remote_action/remote_action_sender.rb +9 -0
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/base_action.rb +55 -0
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/change_pbm_version_action.rb +31 -0
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/commands/run_remote_pbm_job_dispatch_command.rb +29 -0
- data/lib/procon_bypass_man/{remote_pbm_action/commands/update_remote_pbm_action_status_command.rb → remote_action/remote_pbm_job/commands/update_remote_pbm_job_status_command.rb} +2 -2
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/reboot_os_action.rb +24 -0
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/report_procon_status.rb +25 -0
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/restore_pbm_setting.rb +42 -0
- data/lib/procon_bypass_man/remote_action/remote_pbm_job/stop_pbm_action.rb +23 -0
- data/lib/procon_bypass_man/{remote_pbm_action/value_objects/remote_pbm_action_object.rb → remote_action/remote_pbm_job/value_objects/remote_pbm_job_object.rb} +2 -2
- data/lib/procon_bypass_man/remote_action/remote_pbm_job.rb +45 -0
- data/lib/procon_bypass_man/remote_action/task.rb +14 -0
- data/lib/procon_bypass_man/{remote_macro → remote_action}/task_queue.rb +1 -1
- data/lib/procon_bypass_man/remote_action.rb +19 -0
- data/lib/procon_bypass_man/support/callbacks.rb +1 -0
- data/lib/procon_bypass_man/support/retryable.rb +4 -2
- data/lib/procon_bypass_man/support/{update_remote_pbm_action_status_http_client.rb → update_remote_pbm_job_status_http_client.rb} +1 -1
- data/lib/procon_bypass_man/support/web_connectivity_checker.rb +39 -0
- data/lib/procon_bypass_man/version.rb +1 -1
- data/lib/procon_bypass_man/websocket/client.rb +42 -26
- data/lib/procon_bypass_man.rb +12 -8
- data/project_template/app.rb +10 -1
- data/project_template/app.rb.erb +11 -1
- data/sig/main.rbs +0 -6
- metadata +34 -20
- data/lib/procon_bypass_man/procon_display/bypass_hook.rb +0 -12
- data/lib/procon_bypass_man/remote_macro/remote_macro_sender.rb +0 -8
- data/lib/procon_bypass_man/remote_macro/task.rb +0 -2
- data/lib/procon_bypass_man/remote_macro.rb +0 -16
- data/lib/procon_bypass_man/remote_pbm_action/base_action.rb +0 -53
- data/lib/procon_bypass_man/remote_pbm_action/change_pbm_version_action.rb +0 -29
- data/lib/procon_bypass_man/remote_pbm_action/commands/run_remote_pbm_action_dispatch_command.rb +0 -21
- data/lib/procon_bypass_man/remote_pbm_action/reboot_os_action.rb +0 -22
- data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +0 -41
- data/lib/procon_bypass_man/remote_pbm_action/stop_pbm_action.rb +0 -21
- data/lib/procon_bypass_man/remote_pbm_action.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86e705d2907d51077191585d2cd16fb198a8a55226613d25f44b15b5e58f8806
|
4
|
+
data.tar.gz: a13290f301295913bbc30a06a1e06689dc5aae328cadd39ed1e91982ff7586d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30618560c54d7c7a730bf97d74b601fce287d6900ed3eaf3c54b1071349b8a7d8b9e346c9099f6dbfad25a568710c5aaa4ce09ad4b12805a2f6d2d3a8134b27f
|
7
|
+
data.tar.gz: 96c796ecbbfa544a0427537a50ea17a0b7f10eee360bc6b072872c7621627dccf5403e78bdc2b580e5957fc5758f9b58979ef1f7f341da1a58b849a693ae79f8
|
data/.circleci/config.yml
CHANGED
@@ -119,6 +119,7 @@ build_jobs: &build_jobs
|
|
119
119
|
- "3.0.1"
|
120
120
|
- "3.0.2"
|
121
121
|
- "3.1.2"
|
122
|
+
- "3.2.2"
|
122
123
|
- bundle_install:
|
123
124
|
matrix:
|
124
125
|
parameters:
|
@@ -127,6 +128,7 @@ build_jobs: &build_jobs
|
|
127
128
|
- "3.0.1"
|
128
129
|
- "3.0.2"
|
129
130
|
- "3.1.2"
|
131
|
+
- "3.2.2"
|
130
132
|
- lint:
|
131
133
|
matrix:
|
132
134
|
parameters:
|
@@ -135,6 +137,7 @@ build_jobs: &build_jobs
|
|
135
137
|
- "3.0.1"
|
136
138
|
- "3.0.2"
|
137
139
|
- "3.1.2"
|
140
|
+
- "3.2.2"
|
138
141
|
requires:
|
139
142
|
- bundle_install
|
140
143
|
- type_check:
|
@@ -154,6 +157,7 @@ build_jobs: &build_jobs
|
|
154
157
|
- "3.0.1"
|
155
158
|
- "3.0.2"
|
156
159
|
- "3.1.2"
|
160
|
+
- "3.2.2"
|
157
161
|
requires:
|
158
162
|
- bundle_install
|
159
163
|
workflows:
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
## [0.3.
|
2
|
-
*
|
1
|
+
## [0.3.7] 2023-04-06
|
2
|
+
* PBM-Cloudと連携しているかをbootメッセージに表示ようになりました
|
3
|
+
* シリアルポート経由でPBMに入力ができるようになりました
|
4
|
+
|
5
|
+
## [0.3.6] 2023-03-12
|
6
|
+
- プロコンの入力状態をpbm-cloudサーバに送信できるようになりました
|
7
|
+
|
8
|
+
## [0.3.5] - 2023-2-9
|
9
|
+
* 設定ファイルに起動に必要なPBMのバージョンを表記できるようになりました
|
3
10
|
* https://github.com/splaplapla/procon_bypass_man/pull/238
|
4
|
-
* レイヤー変更ボタン(prefix_keys_for_changing_layer)
|
11
|
+
* レイヤー変更ボタン(prefix_keys_for_changing_layer)が空欄の時に設定ファイルをエラーが起きないようにしました
|
5
12
|
* PBM-CloudからPBMをアップグレードするときに、古いバージョンを削除するようにしました
|
6
13
|
|
7
14
|
## [0.3.4] - 2022-12-26
|
data/Gemfile
CHANGED
@@ -13,6 +13,7 @@ gem "rubocop", require: false
|
|
13
13
|
gem "sinatra", require: false
|
14
14
|
gem "webrick", require: false
|
15
15
|
gem "stackprof", require: false
|
16
|
+
gem "serialport" # シリアル通信をする時に必要。通常はいらない
|
16
17
|
|
17
18
|
if Gem::Version.new(RUBY_VERSION) > Gem::Version.new("2.6.0")
|
18
19
|
gem 'typeprof', require: false
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
procon_bypass_man (0.3.
|
4
|
+
procon_bypass_man (0.3.7)
|
5
5
|
action_cable_client
|
6
6
|
blue_green_process (= 0.1.4.2)
|
7
7
|
pbmenv (>= 0.1.11)
|
@@ -80,6 +80,7 @@ GEM
|
|
80
80
|
parser (>= 3.0.1.1)
|
81
81
|
ruby-progressbar (1.11.0)
|
82
82
|
ruby2_keywords (0.0.5)
|
83
|
+
serialport (1.3.2)
|
83
84
|
set (1.0.3)
|
84
85
|
sinatra (2.2.0)
|
85
86
|
mustermann (~> 1.0)
|
@@ -134,6 +135,7 @@ DEPENDENCIES
|
|
134
135
|
rbs
|
135
136
|
rspec
|
136
137
|
rubocop
|
138
|
+
serialport
|
137
139
|
sinatra
|
138
140
|
stackprof
|
139
141
|
steep
|
data/Steepfile
CHANGED
@@ -40,7 +40,6 @@ target :lib do
|
|
40
40
|
check 'lib/procon_bypass_man/support/on_memory_cache'
|
41
41
|
check 'lib/procon_bypass_man/support/uptime.rb'
|
42
42
|
check 'lib/procon_bypass_man/support/safe_timeout'
|
43
|
-
check 'lib/procon_bypass_man/support/update_remote_pbm_action_status_http_client'
|
44
43
|
check 'lib/procon_bypass_man/support/compress_array'
|
45
44
|
|
46
45
|
signature 'sig'
|
data/bin/console
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "procon_bypass_man"
|
5
|
+
require "pry"
|
6
|
+
|
7
|
+
# \x30のみ生成する
|
8
|
+
# Usage:
|
9
|
+
# $ `generate_output_report x zl y` のように、引数にボタン名を渡す
|
10
|
+
|
11
|
+
no_action_binary = ["30f28100800078c77448287509550274ff131029001b0022005a0271ff191028001e00210064027cff1410280020002100000000000000000000000000000000"].pack("H*")
|
12
|
+
user_operation = ProconBypassMan::Procon::UserOperation.new(no_action_binary)
|
13
|
+
|
14
|
+
ARGV.map { |x| x.to_sym }.each do |button|
|
15
|
+
user_operation.press_button(button)
|
16
|
+
end
|
17
|
+
|
18
|
+
puts user_operation.binary.unpack.first
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Usage:
|
4
|
+
# NOTE: JSON形式の文字列がどういう形で読み込まれるかを確認できます
|
5
|
+
# $ echo '{"hex":"hogehoge", "buttons": ["a","b", "zr"]}' | bin/validate_external_input
|
6
|
+
# => 読み取った値: {:hex=>"hogehoge", :buttons=>["a", "b", "zr"]}
|
7
|
+
|
8
|
+
require "bundler/setup"
|
9
|
+
require "json"
|
10
|
+
require "procon_bypass_man"
|
11
|
+
require "procon_bypass_man/external_input"
|
12
|
+
|
13
|
+
begin
|
14
|
+
json_str = ARGF.read
|
15
|
+
external_data = ProconBypassMan::ExternalInput::ExternalData.parse!(json_str)
|
16
|
+
puts("読み取った値: #{{ hex: external_data.hex, buttons: external_data.buttons }}")
|
17
|
+
rescue JSON::ParserError => e
|
18
|
+
puts "failed to parse JSON: #{e.message}"
|
19
|
+
end
|
data/docs/getting_started.md
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
* [設定ファイルの書き方がわからない、エラーが起きるとき](#設定ファイルの書き方がわからない、エラーが起きるとき)
|
19
19
|
* [procon_bypass_manのアップグレード方法](#procon_bypass_manのアップグレード方法)
|
20
20
|
* [procon_bypass_man_cloudについて](#procon_bypass_man_cloudについて)
|
21
|
+
* [シリアルポート・GPIOから読み取る](#シリアルポートから読み取る)
|
21
22
|
* [最適化について](#最適化について)
|
22
23
|
|
23
24
|
## はじめに
|
@@ -251,6 +252,10 @@ procon_bypass_man_cloudとの接続が完了後、Raspberry Piを起動時にpro
|
|
251
252
|
|
252
253
|
セットアップ方法は https://pbm-cloud.jiikko.com/faq に書いています。
|
253
254
|
|
255
|
+
## シリアルポートから読み取る
|
256
|
+
* [ラズベリーパイのシリアルポート(GPIO)へ書き込んでPBM経由してSwitchへ入力をする方法](/docs/setting/integration_external_input_serial_port.md)
|
257
|
+
* [ラズベリーパイのシリアルポート(GPIO)に書き込むフォーマットについて](/docs/setting/integration_external_input_serial_port_format.md)
|
258
|
+
|
254
259
|
## 最適化について
|
255
260
|
本稿では、Rubyの最適化について書きます。上級者向けです。適用しなくても普通に動きますが、逆に適用したことで何らかのケースで遅くなる場合があるかもしれません。
|
256
261
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# ラズベリーパイのシリアルポート(GPIO)へ書き込んでPBM経由してSwitchへ入力をする方法
|
2
|
+
* procon_bypass_man: 0.3.7以上が必要です
|
3
|
+
* GPIOからSwitchへ入力できます。本テキストでは設定方法を記載します
|
4
|
+
|
5
|
+
## 1. シリアルポートへ書き込みができるようにラズベリーパイのセットアップする
|
6
|
+
https://toki-blog.com/pi-serial/ の「汎用シリアルとして使う」 を実施してください
|
7
|
+
|
8
|
+
## 2. GPIOへケーブルを挿す
|
9
|
+
対応しているケーブルをGPIOとPCに接続してください。
|
10
|
+
|
11
|
+
## 3. PBMのapp.rbを編集し、シリアルポートから読み出せるようにPBMのapp.rbを編集する
|
12
|
+
`gemの追加`と`デバイスファイルを指す修正` の2つ必要です。
|
13
|
+
|
14
|
+
* 1) シリアルポートから読み出すために追加でgemが必要です。 `app.rb` に `gem "serialport"` を追加してください。
|
15
|
+
|
16
|
+
```diff
|
17
|
+
gemfile do
|
18
|
+
source 'https://rubygems.org'
|
19
|
+
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
20
|
+
gem 'procon_bypass_man', '0.3.7'
|
21
|
+
+ gem "serialport"
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
* 2) 以下を参考にして`config.external_input_channels`の行を追加してください。
|
26
|
+
|
27
|
+
```diff
|
28
|
+
ProconBypassMan.configure do |config|
|
29
|
+
config.root = File.expand_path(__dir__)
|
30
|
+
config.logger = Logger.new("#{ProconBypassMan.root}/app.log", 1, 1024 * 1024 * 1)
|
31
|
+
config.logger.level = :debug
|
32
|
+
|
33
|
+
# バイパスするログを全部app.logに流すか
|
34
|
+
config.verbose_bypass_log = false
|
35
|
+
|
36
|
+
# webからProconBypassManを操作できるwebサービスと連携します
|
37
|
+
# 連携中はエラーログ、パフォーマンスに関するメトリクスを送信します
|
38
|
+
# config.api_servers = 'https://pbm-cloud.jiikko.com'
|
39
|
+
|
40
|
+
# エラーが起きたらerror.logに書き込みます
|
41
|
+
config.enable_critical_error_logging = true
|
42
|
+
|
43
|
+
# pbm-cloudで使う場合はnever_exitにtrueをセットしてください. trueがセットされている場合、不慮の事故が発生してもプロセスが終了しなくなります
|
44
|
+
config.never_exit_accidentally = true
|
45
|
+
|
46
|
+
# 接続に成功したらコントローラーのHOME LEDを光らせるか
|
47
|
+
config.enable_home_led_on_connect = true
|
48
|
+
|
49
|
+
+ config.external_input_channels = [
|
50
|
+
+ ProconBypassMan::ExternalInput::Channels::SerialPortChannel.new(device_path: '/dev/serial0', baud_rate: 9600),
|
51
|
+
+ ]
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
以上で設定は完了です。PBMを起動し、連携ツールからGPIOへ書き込んでください。
|
56
|
+
書き込みフォーマットについては [ラズベリーパイのシリアルポート(GPIO)に書き込むフォーマットについて](/docs/setting/integration_external_input_serial_port_format.md) を参照してください。
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# ラズベリーパイのシリアルポート(GPIO)に書き込むフォーマットについて
|
2
|
+
* procon_bypass_man: 0.3.7からGPIOを経由してSwitchへ入力できるようになりました。本テキストではPBMが読み取れるフォーマットについて記載します
|
3
|
+
|
4
|
+
## フォーマット
|
5
|
+
JSON形式, plain textに対応しています
|
6
|
+
|
7
|
+
* JSON形式
|
8
|
+
* 受付可能なカラム
|
9
|
+
* hex
|
10
|
+
* 16進数でエンコードした`INPUT 0x30` を書いてください。スティック操作を除くボタン部分のみが読み込まれます
|
11
|
+
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/ac8093c84194b3232acb675ac1accce9bcb456a3/bluetooth_hid_notes.md#input-0x30
|
12
|
+
* ex: '30f28100800078c77448287509550274ff131029001b0022005a0271ff191028001e00210064027cff1410280020002100000000000000000000000000000000'
|
13
|
+
* buttons
|
14
|
+
* 「入力したいボタン」「入力したくないボタン」を配列で渡してください
|
15
|
+
* 「入力したいボタン」
|
16
|
+
* `"y", "x", "b", "a", "sl", "sr", "r", "zr", "minus", "plus", "thumbr", "thumbl", "home", "cap", "down", "up", "right", "left", "l", "zl"`
|
17
|
+
* 「入力したくないボタン」
|
18
|
+
* `"uny", "unx", "unb", "una", "unsl", "unsr", "unr", "unzr", "unminus", "unplus", "unthumbr", "unthumbl", "unhome", "uncap", "undown", "unup", "unright", "unleft", "unl", "unzl"`
|
19
|
+
* ex: `['a', 'b']`
|
20
|
+
* 仕様
|
21
|
+
* JSONにhex, buttonsの両方が含まれている場合、hexを優先し、buttonsは無視します
|
22
|
+
* JSONの例
|
23
|
+
* `'{"hex":"30f28100800078c77448287509550274ff131029001b0022005a0271ff191028001e00210064027cff1410280020002100000000000000000000000000000000", "buttons": ["a"] }'`
|
24
|
+
* plain text
|
25
|
+
* コロンで囲ったボタンを1つの入力として解釈します
|
26
|
+
* `:a::b::uny:` を入力した場合には、a, b, uny を読み込みます
|
27
|
+
|
28
|
+
## 正しいJSONかを検証する
|
29
|
+
本リポジトリにJSONを検証する `bin/validate_external_input` を同梱しています。実行例を以下に示します。
|
30
|
+
|
31
|
+
```shell
|
32
|
+
$ echo '{"hex":"30f28100800078c77448287509550274ff131029001b0022005a0271ff191028001e00210064027cff1410280020002100000000000000000000000000000000", "buttons": ["a"] }' | bin/validate_external_input
|
33
|
+
読み取った値: {:hex=>"30f28100800078c77448287509550274ff131029001b0022005a0271ff191028001e00210064027cff1410280020002100000000000000000000000000000000", :buttons=>[:a]}
|
34
|
+
```
|
35
|
+
|
36
|
+
以上。
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class ProconBypassMan::PostCompletedRemoteActionJob < ProconBypassMan::BaseJob
|
2
|
+
extend ProconBypassMan::HasExternalApiSetting
|
3
|
+
|
4
|
+
# @param [Symbol] status
|
5
|
+
def self.perform(job_id)
|
6
|
+
ProconBypassMan::RemoteMacroHttpClient.new(
|
7
|
+
path: path,
|
8
|
+
server: api_server,
|
9
|
+
).post(job_id: job_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.path
|
13
|
+
device_id = ProconBypassMan.device_id
|
14
|
+
"/api/devices/#{ProconBypassMan.device_id}/completed_pbm_remote_macro_jobs"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.re_enqueue_if_failed
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class ProconBypassMan::ReportInfoLogJob < ProconBypassMan::ReportEventBaseJob
|
2
|
+
extend ProconBypassMan::HasExternalApiSetting
|
3
|
+
|
4
|
+
# @param [String] body
|
5
|
+
def self.perform(body)
|
6
|
+
ProconBypassMan::ReportHttpClient.new(
|
7
|
+
path: path,
|
8
|
+
server: api_server,
|
9
|
+
).post(body: body, event_type: :info)
|
10
|
+
end
|
11
|
+
end
|
@@ -21,6 +21,7 @@ class ProconBypassMan::ReportProconPerformanceMeasurementsJob < ProconBypassMan:
|
|
21
21
|
time_taken_p50: metric.time_taken_p50,
|
22
22
|
time_taken_p95: metric.time_taken_p95,
|
23
23
|
time_taken_p99: metric.time_taken_p99,
|
24
|
+
external_input_time_max: metric.external_input_time_max,
|
24
25
|
read_error_count: metric.read_error_count,
|
25
26
|
write_error_count: metric.write_error_count,
|
26
27
|
gc_count: metric.gc_count,
|
@@ -10,6 +10,7 @@ require "procon_bypass_man/background/jobs/report_error_reload_config_job"
|
|
10
10
|
require "procon_bypass_man/background/jobs/report_load_config_job"
|
11
11
|
require "procon_bypass_man/background/jobs/report_error_job"
|
12
12
|
require "procon_bypass_man/background/jobs/report_warning_job"
|
13
|
+
require "procon_bypass_man/background/jobs/report_info_log_job"
|
13
14
|
require "procon_bypass_man/background/jobs/report_completed_upgrade_pbm_job"
|
14
15
|
require "procon_bypass_man/background/jobs/report_procon_performance_measurements_job"
|
15
16
|
require "procon_bypass_man/background/jobs/sync_device_stats_job"
|
@@ -47,14 +47,32 @@ class ProconBypassMan::Bypass::ProconToSwitch
|
|
47
47
|
self.bypass_value.binary = ProconBypassMan::Domains::InboundProconBinary.new(binary: raw_output)
|
48
48
|
end
|
49
49
|
|
50
|
+
# 後続処理で入力値を取得できるように詰めておく
|
51
|
+
ProconBypassMan::ProconDisplay::Status.instance.current = bypass_value.binary.to_procon_reader.to_hash
|
52
|
+
|
53
|
+
# NOTE: 外部からの入力を受け取る
|
54
|
+
external_input_data = nil
|
55
|
+
measurement.record_external_input_time do
|
56
|
+
# TODO: シリアルぽーとから読み取ると252.chrみたいなゴミデータを受け取ってEncoding::UndefinedConversionErrorが発生する可能性がある. 発生したら上限までretryした方がいいかも
|
57
|
+
if(data = ProconBypassMan::ExternalInput.read)
|
58
|
+
begin
|
59
|
+
external_input_data = ProconBypassMan::ExternalInput::ExternalData.parse!(data)
|
60
|
+
ProconBypassMan.logger.debug { "[ExternalInput] 読み取った値: { hex: #{external_input_data.hex}, raw_data: '#{external_input_data.raw_data}', buttons: #{external_input_data.buttons} }" }
|
61
|
+
rescue ProconBypassMan::ExternalInput::ParseError => e
|
62
|
+
ProconBypassMan.logger.error "[ExternalInput][#{e}] #{data.force_encoding('UTF-8').scrub}, #{data.force_encoding('ASCII-8BIT').codepoints} をparseできませんでした"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
50
67
|
result = measurement.record_write_time do
|
51
68
|
begin
|
52
69
|
ProconBypassMan::Retryable.retryable(tries: 5, on_no_retry: [Errno::EIO, Errno::ENODEV, Errno::EPROTO, IOError, Errno::ESHUTDOWN, Errno::ETIMEDOUT]) do
|
53
70
|
begin
|
54
71
|
# 終了処理を希望されているのでブロックを無視してメソッドを抜けてOK
|
55
72
|
return(false) if will_terminate? # rubocop:disable Lint/NoReturnInBeginEndBlocks
|
73
|
+
|
56
74
|
binary = ::ProconBypassMan::Procon::Rumbler.monitor do
|
57
|
-
ProconBypassMan::Processor.new(bypass_value.binary).process
|
75
|
+
ProconBypassMan::Processor.new(bypass_value.binary).process(external_input_data: external_input_data)
|
58
76
|
end
|
59
77
|
self.gadget.write_nonblock(binary)
|
60
78
|
|
@@ -34,6 +34,7 @@ class ProconBypassMan::PrintBootMessageCommand
|
|
34
34
|
ProconBypassMan::VERSION: #{@table[:pbm_version]}
|
35
35
|
RUBY_VERSION: #{@table[:ruby_version]}
|
36
36
|
Pbmenv::VERSION: #{@table[:pbmenv_version]}
|
37
|
+
PBM-Cloud Integration: #{ProconBypassMan::WebConnectivityChecker.new(ProconBypassMan.config.api_server)}
|
37
38
|
pid: #{@table[:pid]}
|
38
39
|
root: #{@table[:root_path]}
|
39
40
|
pid_path: #{@table[:pid_path]}
|
@@ -56,6 +57,7 @@ class ProconBypassMan::PrintBootMessageCommand
|
|
56
57
|
def self.execute
|
57
58
|
message = BootMessage.new
|
58
59
|
ProconBypassMan::ReportBootJob.perform_async(message.to_hash)
|
60
|
+
ProconBypassMan.logger.info message.to_s
|
59
61
|
puts message.to_s
|
60
62
|
end
|
61
63
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class ProconBypassMan::SendInfoLogCommand
|
2
|
+
# @param [String] message
|
3
|
+
# @return [void]
|
4
|
+
def self.execute(message: , stdout: true)
|
5
|
+
body = message
|
6
|
+
ProconBypassMan.logger.info(body)
|
7
|
+
puts body if stdout
|
8
|
+
|
9
|
+
ProconBypassMan::ReportInfoLogJob.perform(body)
|
10
|
+
end
|
11
|
+
end
|
@@ -5,3 +5,4 @@ require "procon_bypass_man/commands/write_device_id_command"
|
|
5
5
|
require "procon_bypass_man/commands/send_reload_config_event_command"
|
6
6
|
require "procon_bypass_man/commands/send_error_command"
|
7
7
|
require "procon_bypass_man/commands/send_warning_command"
|
8
|
+
require "procon_bypass_man/commands/send_info_log_command"
|
@@ -54,6 +54,7 @@ class ProconBypassMan::Configuration
|
|
54
54
|
|
55
55
|
attr_accessor :enable_critical_error_logging
|
56
56
|
attr_writer :verbose_bypass_log, :raw_setting, :never_exit_accidentally, :enable_home_led_on_connect
|
57
|
+
attr_writer :external_input_channels
|
57
58
|
# 削除予定
|
58
59
|
attr_writer :enable_reporting_pressed_buttons
|
59
60
|
|
@@ -149,7 +150,7 @@ class ProconBypassMan::Configuration
|
|
149
150
|
end
|
150
151
|
|
151
152
|
# @return [Boolean]
|
152
|
-
def
|
153
|
+
def enable_remote_action?
|
153
154
|
enable_ws?
|
154
155
|
end
|
155
156
|
|
@@ -193,4 +194,9 @@ class ProconBypassMan::Configuration
|
|
193
194
|
true
|
194
195
|
end
|
195
196
|
end
|
197
|
+
|
198
|
+
# @return [Array<ProconBypassMan::ExternalInput::Channel::TCPIP, ProconBypassMan::ExternalInput::Channel::SerialPort>]
|
199
|
+
def external_input_channels
|
200
|
+
@external_input_channels || []
|
201
|
+
end
|
196
202
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ProconBypassMan
|
2
|
+
module ExternalInput
|
3
|
+
module Channels
|
4
|
+
class SerialPortChannel < Base
|
5
|
+
attr_reader :serial_port
|
6
|
+
|
7
|
+
# @param [String] device_path
|
8
|
+
# @param [Integer] baud_rate
|
9
|
+
def initialize(device_path: , baud_rate: 9600)
|
10
|
+
require 'serialport'
|
11
|
+
|
12
|
+
super()
|
13
|
+
# data_bitsあたりは必要があれば設定ができるようにしたいがよくわからないのでとりあえずnilを入れる
|
14
|
+
data_bits = 8
|
15
|
+
stop_bits = 1
|
16
|
+
parity = SerialPort::NONE
|
17
|
+
@serial_port= SerialPort.new(device_path, baud_rate, data_bits, stop_bits, parity)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String, NilClass]
|
21
|
+
# NOTE: この実装では、::IO::EAGAINWaitReadableを実質的な終端として扱っているので、高速に書き込みがされると取りこぼす可能性がある.
|
22
|
+
# NOTE: read_nonblockでバッファから読み出すとき、バッファが空になるまでは::IO::EAGAINWaitReadableが起きない前提で実装している.
|
23
|
+
# NOTE: 取りこぼししないよう精度を上げるには、終端文字が来るまで1文字ずつ読む必要があるがパフォーマンスが犠牲になってしまう. この対策をするには、bypass処理の開始で非同期に1文字ずつ読み込むことをすると多少マシになるはず
|
24
|
+
def read
|
25
|
+
buffer = ''
|
26
|
+
loop do
|
27
|
+
begin
|
28
|
+
buffer += @serial_port.read_nonblock(1024) || ''
|
29
|
+
rescue ::IO::EAGAINWaitReadable
|
30
|
+
break
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
return nil if buffer.empty?
|
35
|
+
|
36
|
+
# NOTE: 高速に書き込まれた場合、複数のチャンクを含む可能性があるので、最初だけを切り取る
|
37
|
+
chunks = buffer.split("\n")
|
38
|
+
if(chunks.size > 1)
|
39
|
+
ProconBypassMan::SendErrorCommand.execute(
|
40
|
+
error: "[ExternalInput] シリアルポートから読み込んだchunkが複数あります. 高い書き込み頻度に耐えられていないので実装を見直してください。 (chunks.size: #{chunks.size})"
|
41
|
+
)
|
42
|
+
end
|
43
|
+
chunks.first
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# TODO: 実装する
|
2
|
+
# module ProconBypassMan
|
3
|
+
# module ExternalInput
|
4
|
+
# module Channels
|
5
|
+
# class TCPIP < Base
|
6
|
+
# def initialize(port: )
|
7
|
+
# super()
|
8
|
+
# # TODO: ここでTCPサーバを起動する(port)
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def read
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
# end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ProconBypassMan
|
4
|
+
module ExternalInput
|
5
|
+
module Channels
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require "procon_bypass_man/external_input/channels/base"
|
11
|
+
require "procon_bypass_man/external_input/channels/serial_port_channel"
|
12
|
+
require "procon_bypass_man/external_input/channels/tcpip"
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module ProconBypassMan
|
2
|
+
module ExternalInput
|
3
|
+
class ExternalData
|
4
|
+
UNPRESS_BUTTONS = Set.new(ProconBypassMan::Procon::ButtonCollection.available.map { |x| "un#{x}".to_sym })
|
5
|
+
|
6
|
+
# @return [String, NilClass] 16進数表現のデータ
|
7
|
+
attr_reader :hex
|
8
|
+
|
9
|
+
# @return [String, NilClass] ログに表示する用
|
10
|
+
attr_reader :raw_data
|
11
|
+
|
12
|
+
# @raise [ParseError]
|
13
|
+
# @return [ExternalData] JSON か カンマ区切りのbuttons
|
14
|
+
def self.parse!(raw_data)
|
15
|
+
raise ParseError unless raw_data.ascii_only?
|
16
|
+
|
17
|
+
if is_json(raw_data)
|
18
|
+
begin
|
19
|
+
json = JSON.parse(raw_data)
|
20
|
+
return new(hex: json['hex'], buttons: json['buttons'])
|
21
|
+
rescue JSON::ParserError
|
22
|
+
raise ParseError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return new(hex: nil, buttons: raw_data.scan(/:\w+:/).map { |x| x.gsub(':', '') }, raw_data: raw_data)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param [String] raw_data
|
30
|
+
# @return [Boolean]
|
31
|
+
def self.is_json(raw_data)
|
32
|
+
raw_data.start_with?('{')
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param [String, NilClass] hex
|
36
|
+
# @param [Array<String>, NilClass] buttons
|
37
|
+
# @param [String, NilClass] raw_data
|
38
|
+
def initialize(hex: , buttons: , raw_data: nil)
|
39
|
+
@hex = hex
|
40
|
+
@buttons = buttons || []
|
41
|
+
@raw_data = raw_data
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String, NilClass]
|
45
|
+
def to_binary
|
46
|
+
return nil if @hex.nil?
|
47
|
+
[@hex].pack('H*')
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Array<Symbol>]
|
51
|
+
def press_buttons
|
52
|
+
buttons.select do |button|
|
53
|
+
ProconBypassMan::Procon::ButtonCollection::BUTTONS_MAP[button]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Array<Symbol>]
|
58
|
+
def unpress_buttons
|
59
|
+
buttons.select { |button|
|
60
|
+
UNPRESS_BUTTONS.include?(button)
|
61
|
+
}.map { |b| to_button(b.to_s).to_sym }
|
62
|
+
end
|
63
|
+
|
64
|
+
# NOTE: ログに表示する用
|
65
|
+
# @return [Array<Symbol>]
|
66
|
+
def buttons
|
67
|
+
@buttons.map(&:to_sym)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# @return [String]
|
73
|
+
# NOTE: un#{button} って名前をbuttonに変換する
|
74
|
+
def to_button(button)
|
75
|
+
button.sub(/^un/, '')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ProconBypassMan
|
4
|
+
module ExternalInput
|
5
|
+
class ParseError < StandardError; end
|
6
|
+
|
7
|
+
@@channels = nil
|
8
|
+
|
9
|
+
# @return [Array<ProconBypassMan::ExternalInput::Channels::Base>]
|
10
|
+
def self.channels
|
11
|
+
@@channels
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [void]
|
15
|
+
def self.prepare_channels
|
16
|
+
@@channels = ProconBypassMan.config.external_input_channels
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [NilClass, String]
|
20
|
+
# NOTE: 外部入力からのreadがボトルネックになるなら、Concurrent::Futureを使ってプロコンからの読み出しと並列化することを検討する
|
21
|
+
def self.read
|
22
|
+
raise '外部入力が未初期化です' if @@channels.nil?
|
23
|
+
|
24
|
+
value = nil
|
25
|
+
@@channels.each do |channel|
|
26
|
+
value = channel.read
|
27
|
+
break if value
|
28
|
+
end
|
29
|
+
value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require "procon_bypass_man/external_input/external_data"
|
35
|
+
require "procon_bypass_man/external_input/channels.rb"
|
@@ -5,12 +5,13 @@ class ProconBypassMan::Processor
|
|
5
5
|
@binary = binary
|
6
6
|
end
|
7
7
|
|
8
|
+
# @param [ProconBypassMan::ExternalInput::ExternalData, NilClass] external_input_data
|
8
9
|
# @return [String] 加工後の入力データ
|
9
|
-
def process
|
10
|
+
def process(external_input_data: nil)
|
10
11
|
return @binary.raw unless @binary.user_operation_data?
|
11
12
|
|
12
13
|
procon = ProconBypassMan::Procon.new(@binary.raw)
|
13
14
|
procon.apply!
|
14
|
-
procon.to_binary
|
15
|
+
procon.to_binary(external_input_data: external_input_data)
|
15
16
|
end
|
16
17
|
end
|