rsmp 0.47.0 → 0.48.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.
- checksums.yaml +4 -4
- data/.github/workflows/copilot-setup-steps.yml +1 -1
- data/.github/workflows/rubocop.yaml +1 -1
- data/.github/workflows/sus.yaml +1 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +5 -5
- data/README.md +3 -1
- data/documentation/cli.md +225 -0
- data/documentation/configuration.md +57 -0
- data/lib/rsmp/cli/configuration.rb +30 -0
- data/lib/rsmp/cli.rb +18 -45
- data/lib/rsmp/collect/command_matcher.rb +13 -4
- data/lib/rsmp/collect/status_matcher.rb +14 -4
- data/lib/rsmp/command_list.rb +1 -1
- data/lib/rsmp/convert/export/json_schema/index.rb +64 -0
- data/lib/rsmp/convert/export/json_schema/items.rb +9 -1
- data/lib/rsmp/convert/export/json_schema/outputs.rb +65 -25
- data/lib/rsmp/convert/export/json_schema/values.rb +40 -11
- data/lib/rsmp/convert/export/json_schema.rb +3 -1
- data/lib/rsmp/message/sxl_codec.rb +194 -0
- data/lib/rsmp/message.rb +2 -0
- data/lib/rsmp/node/site/connections.rb +80 -0
- data/lib/rsmp/node/site/site.rb +21 -35
- data/lib/rsmp/node/supervisor/supervisor.rb +42 -0
- data/lib/rsmp/options/schemas/site.json +3 -0
- data/lib/rsmp/options/schemas/supervisor.json +1 -0
- data/lib/rsmp/options/site_options.rb +30 -21
- data/lib/rsmp/options/supervisor_options.rb +1 -0
- data/lib/rsmp/proxy/modules/receive.rb +3 -1
- data/lib/rsmp/proxy/modules/send.rb +26 -14
- data/lib/rsmp/proxy/proxy.rb +17 -0
- data/lib/rsmp/proxy/site/connection.rb +79 -0
- data/lib/rsmp/proxy/site/modules/commands.rb +24 -1
- data/lib/rsmp/proxy/site/site_proxy.rb +6 -15
- data/lib/rsmp/proxy/supervisor/modules/commands.rb +55 -0
- data/lib/rsmp/proxy/supervisor/modules/status.rb +13 -104
- data/lib/rsmp/proxy/supervisor/modules/status_updates.rb +148 -0
- data/lib/rsmp/proxy/supervisor/supervisor_proxy.rb +19 -0
- data/lib/rsmp/schema.rb +38 -1
- data/lib/rsmp/tlc/detector_logic.rb +2 -2
- data/lib/rsmp/tlc/modules/helpers.rb +0 -22
- data/lib/rsmp/tlc/modules/inputs.rb +4 -3
- data/lib/rsmp/tlc/modules/modes.rb +2 -2
- data/lib/rsmp/tlc/modules/plans.rb +7 -3
- data/lib/rsmp/tlc/modules/system.rb +1 -1
- data/lib/rsmp/tlc/proxy/control.rb +19 -19
- data/lib/rsmp/tlc/proxy/detectors.rb +3 -3
- data/lib/rsmp/tlc/proxy/io.rb +15 -12
- data/lib/rsmp/tlc/proxy/plans.rb +14 -14
- data/lib/rsmp/tlc/proxy/status.rb +9 -5
- data/lib/rsmp/tlc/proxy/system.rb +12 -6
- data/lib/rsmp/tlc/signal_group.rb +2 -2
- data/lib/rsmp/tlc/supervisor_interface.rb +42 -0
- data/lib/rsmp/tlc/traffic_controller_site.rb +1 -18
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +4 -0
- data/schemas/core/3.1.4/command_response.json +11 -0
- data/schemas/core/3.1.5/command_response.json +11 -0
- data/schemas/core/3.2.0/command_response.json +11 -0
- data/schemas/core/3.2.1/command_response.json +11 -0
- data/schemas/core/3.2.2/command_response.json +11 -0
- data/schemas/core/3.3.0/command_response.json +11 -0
- data/schemas/tlc/1.0.10/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.10/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.10/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.10/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.10/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.10/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.10/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.10/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.10/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.10/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.10/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.10/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.10/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.10/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.10/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.10/commands/M0012.json +35 -29
- data/schemas/tlc/1.0.10/commands/M0013.json +35 -29
- data/schemas/tlc/1.0.10/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.10/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.10/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.10/commands/command_requests.json +995 -1
- data/schemas/tlc/1.0.10/defs/guards.json +19 -0
- data/schemas/tlc/1.0.10/sxl.yaml +56 -56
- data/schemas/tlc/1.0.10/sxl_index.json +226 -244
- data/schemas/tlc/1.0.13/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.13/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.13/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.13/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.13/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.13/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.13/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0012.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0013.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0014.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0015.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0016.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0017.json +35 -29
- data/schemas/tlc/1.0.13/commands/M0018.json +48 -42
- data/schemas/tlc/1.0.13/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.13/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.13/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.13/commands/command_requests.json +1293 -1
- data/schemas/tlc/1.0.13/defs/guards.json +19 -0
- data/schemas/tlc/1.0.13/sxl.yaml +63 -63
- data/schemas/tlc/1.0.13/sxl_index.json +280 -298
- data/schemas/tlc/1.0.14/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.14/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.14/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.14/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.14/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.14/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.14/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0012.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0013.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0014.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0015.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0016.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0017.json +35 -29
- data/schemas/tlc/1.0.14/commands/M0018.json +48 -42
- data/schemas/tlc/1.0.14/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.14/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.14/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.14/commands/command_requests.json +1293 -1
- data/schemas/tlc/1.0.14/defs/guards.json +19 -0
- data/schemas/tlc/1.0.14/sxl.yaml +63 -63
- data/schemas/tlc/1.0.14/sxl_index.json +304 -322
- data/schemas/tlc/1.0.15/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.15/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.15/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.15/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.15/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.15/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.15/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0012.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0013.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0014.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0015.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0016.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0017.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0018.json +48 -42
- data/schemas/tlc/1.0.15/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.15/commands/M0020.json +61 -55
- data/schemas/tlc/1.0.15/commands/M0021.json +35 -29
- data/schemas/tlc/1.0.15/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.15/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.15/commands/command_requests.json +1425 -1
- data/schemas/tlc/1.0.15/defs/guards.json +19 -0
- data/schemas/tlc/1.0.15/sxl.yaml +66 -66
- data/schemas/tlc/1.0.15/sxl_index.json +330 -350
- data/schemas/tlc/1.0.7/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.7/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.7/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.7/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.7/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.7/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.7/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.7/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.7/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.7/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.7/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.7/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.7/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.7/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.7/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.7/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.7/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.7/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.7/commands/command_requests.json +895 -1
- data/schemas/tlc/1.0.7/defs/guards.json +19 -0
- data/schemas/tlc/1.0.7/sxl.yaml +58 -58
- data/schemas/tlc/1.0.7/sxl_index.json +228 -246
- data/schemas/tlc/1.0.8/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.8/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.8/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.8/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.8/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.8/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.8/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.8/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.8/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.8/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.8/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.8/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.8/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.8/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.8/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.8/commands/M0012.json +35 -29
- data/schemas/tlc/1.0.8/commands/M0013.json +35 -29
- data/schemas/tlc/1.0.8/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.8/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.8/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.8/commands/command_requests.json +995 -1
- data/schemas/tlc/1.0.8/defs/guards.json +19 -0
- data/schemas/tlc/1.0.8/sxl.yaml +56 -56
- data/schemas/tlc/1.0.8/sxl_index.json +226 -244
- data/schemas/tlc/1.0.9/alarms/A0008.json +21 -15
- data/schemas/tlc/1.0.9/alarms/A0201.json +26 -20
- data/schemas/tlc/1.0.9/alarms/A0202.json +26 -20
- data/schemas/tlc/1.0.9/alarms/A0301.json +69 -63
- data/schemas/tlc/1.0.9/alarms/A0302.json +87 -81
- data/schemas/tlc/1.0.9/commands/M0001.json +66 -60
- data/schemas/tlc/1.0.9/commands/M0002.json +48 -42
- data/schemas/tlc/1.0.9/commands/M0003.json +48 -42
- data/schemas/tlc/1.0.9/commands/M0004.json +35 -29
- data/schemas/tlc/1.0.9/commands/M0005.json +48 -42
- data/schemas/tlc/1.0.9/commands/M0006.json +48 -42
- data/schemas/tlc/1.0.9/commands/M0007.json +35 -29
- data/schemas/tlc/1.0.9/commands/M0008.json +48 -42
- data/schemas/tlc/1.0.9/commands/M0010.json +35 -29
- data/schemas/tlc/1.0.9/commands/M0011.json +35 -29
- data/schemas/tlc/1.0.9/commands/M0012.json +35 -29
- data/schemas/tlc/1.0.9/commands/M0013.json +35 -29
- data/schemas/tlc/1.0.9/commands/M0019.json +61 -55
- data/schemas/tlc/1.0.9/commands/M0103.json +51 -45
- data/schemas/tlc/1.0.9/commands/M0104.json +100 -94
- data/schemas/tlc/1.0.9/commands/command_requests.json +995 -1
- data/schemas/tlc/1.0.9/defs/guards.json +19 -0
- data/schemas/tlc/1.0.9/sxl.yaml +56 -56
- data/schemas/tlc/1.0.9/sxl_index.json +226 -244
- data/schemas/tlc/1.1.0/alarms/A0007.json +25 -19
- data/schemas/tlc/1.1.0/alarms/A0008.json +21 -15
- data/schemas/tlc/1.1.0/alarms/A0201.json +26 -20
- data/schemas/tlc/1.1.0/alarms/A0202.json +26 -20
- data/schemas/tlc/1.1.0/alarms/A0301.json +69 -63
- data/schemas/tlc/1.1.0/alarms/A0302.json +87 -81
- data/schemas/tlc/1.1.0/alarms/A0303.json +69 -63
- data/schemas/tlc/1.1.0/alarms/A0304.json +87 -81
- data/schemas/tlc/1.1.0/commands/M0001.json +66 -60
- data/schemas/tlc/1.1.0/commands/M0002.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0003.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0004.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0005.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0006.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0007.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0008.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0010.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0011.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0012.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0013.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0014.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0015.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0016.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0017.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0018.json +48 -42
- data/schemas/tlc/1.1.0/commands/M0019.json +61 -55
- data/schemas/tlc/1.1.0/commands/M0020.json +61 -55
- data/schemas/tlc/1.1.0/commands/M0021.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0022.json +194 -188
- data/schemas/tlc/1.1.0/commands/M0023.json +35 -29
- data/schemas/tlc/1.1.0/commands/M0103.json +51 -45
- data/schemas/tlc/1.1.0/commands/M0104.json +100 -94
- data/schemas/tlc/1.1.0/commands/command_requests.json +1525 -1
- data/schemas/tlc/1.1.0/defs/guards.json +19 -0
- data/schemas/tlc/1.1.0/statuses/S0033.json +2 -2
- data/schemas/tlc/1.1.0/sxl.yaml +75 -74
- data/schemas/tlc/1.1.0/sxl_index.json +391 -398
- data/schemas/tlc/1.2.0/alarms/A0007.json +25 -19
- data/schemas/tlc/1.2.0/alarms/A0008.json +21 -15
- data/schemas/tlc/1.2.0/alarms/A0201.json +26 -20
- data/schemas/tlc/1.2.0/alarms/A0202.json +26 -20
- data/schemas/tlc/1.2.0/alarms/A0301.json +69 -63
- data/schemas/tlc/1.2.0/alarms/A0302.json +87 -81
- data/schemas/tlc/1.2.0/alarms/A0303.json +69 -63
- data/schemas/tlc/1.2.0/alarms/A0304.json +87 -81
- data/schemas/tlc/1.2.0/commands/M0001.json +66 -60
- data/schemas/tlc/1.2.0/commands/M0002.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0003.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0004.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0005.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0006.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0007.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0008.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0010.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0011.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0012.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0013.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0014.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0015.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0016.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0017.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0018.json +48 -42
- data/schemas/tlc/1.2.0/commands/M0019.json +61 -55
- data/schemas/tlc/1.2.0/commands/M0020.json +61 -55
- data/schemas/tlc/1.2.0/commands/M0021.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0022.json +194 -188
- data/schemas/tlc/1.2.0/commands/M0023.json +35 -29
- data/schemas/tlc/1.2.0/commands/M0103.json +51 -45
- data/schemas/tlc/1.2.0/commands/M0104.json +100 -94
- data/schemas/tlc/1.2.0/commands/command_requests.json +1525 -1
- data/schemas/tlc/1.2.0/defs/guards.json +19 -0
- data/schemas/tlc/1.2.0/statuses/S0033.json +2 -2
- data/schemas/tlc/1.2.0/sxl.yaml +77 -76
- data/schemas/tlc/1.2.0/sxl_index.json +401 -397
- data/schemas/tlc/1.2.1/alarms/A0007.json +25 -19
- data/schemas/tlc/1.2.1/alarms/A0008.json +21 -15
- data/schemas/tlc/1.2.1/alarms/A0201.json +26 -20
- data/schemas/tlc/1.2.1/alarms/A0202.json +26 -20
- data/schemas/tlc/1.2.1/alarms/A0301.json +69 -63
- data/schemas/tlc/1.2.1/alarms/A0302.json +87 -81
- data/schemas/tlc/1.2.1/alarms/A0303.json +69 -63
- data/schemas/tlc/1.2.1/alarms/A0304.json +87 -81
- data/schemas/tlc/1.2.1/commands/M0001.json +66 -60
- data/schemas/tlc/1.2.1/commands/M0002.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0003.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0004.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0005.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0006.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0007.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0008.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0010.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0011.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0012.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0013.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0014.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0015.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0016.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0017.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0018.json +48 -42
- data/schemas/tlc/1.2.1/commands/M0019.json +61 -55
- data/schemas/tlc/1.2.1/commands/M0020.json +61 -55
- data/schemas/tlc/1.2.1/commands/M0021.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0022.json +194 -188
- data/schemas/tlc/1.2.1/commands/M0023.json +35 -29
- data/schemas/tlc/1.2.1/commands/M0103.json +51 -45
- data/schemas/tlc/1.2.1/commands/M0104.json +100 -94
- data/schemas/tlc/1.2.1/commands/command_requests.json +1525 -1
- data/schemas/tlc/1.2.1/defs/guards.json +19 -0
- data/schemas/tlc/1.2.1/statuses/S0033.json +2 -2
- data/schemas/tlc/1.2.1/sxl.yaml +77 -76
- data/schemas/tlc/1.2.1/sxl_index.json +401 -397
- data/schemas/tlc/1.3.0/alarms/A0007.json +25 -19
- data/schemas/tlc/1.3.0/alarms/A0008.json +21 -15
- data/schemas/tlc/1.3.0/alarms/A0201.json +26 -20
- data/schemas/tlc/1.3.0/alarms/A0202.json +26 -20
- data/schemas/tlc/1.3.0/alarms/A0301.json +69 -63
- data/schemas/tlc/1.3.0/alarms/A0302.json +87 -81
- data/schemas/tlc/1.3.0/alarms/A0303.json +70 -64
- data/schemas/tlc/1.3.0/alarms/A0304.json +88 -82
- data/schemas/tlc/1.3.0/commands/M0001.json +66 -60
- data/schemas/tlc/1.3.0/commands/M0002.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0003.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0004.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0005.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0006.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0007.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0008.json +61 -55
- data/schemas/tlc/1.3.0/commands/M0010.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0011.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0012.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0013.json +36 -30
- data/schemas/tlc/1.3.0/commands/M0014.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0015.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0016.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0017.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0018.json +48 -42
- data/schemas/tlc/1.3.0/commands/M0019.json +61 -55
- data/schemas/tlc/1.3.0/commands/M0020.json +61 -55
- data/schemas/tlc/1.3.0/commands/M0021.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0022.json +195 -189
- data/schemas/tlc/1.3.0/commands/M0023.json +35 -29
- data/schemas/tlc/1.3.0/commands/M0024.json +21 -15
- data/schemas/tlc/1.3.0/commands/M0103.json +51 -45
- data/schemas/tlc/1.3.0/commands/M0104.json +100 -94
- data/schemas/tlc/1.3.0/commands/command_requests.json +1559 -1
- data/schemas/tlc/1.3.0/defs/guards.json +19 -0
- data/schemas/tlc/1.3.0/statuses/S0001.json +4 -4
- data/schemas/tlc/1.3.0/statuses/S0005.json +3 -3
- data/schemas/tlc/1.3.0/statuses/S0006.json +2 -2
- data/schemas/tlc/1.3.0/statuses/S0007.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0008.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0009.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0010.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0011.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0012.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0013.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0014.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0015.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0016.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0017.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0019.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0020.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0025.json +2 -2
- data/schemas/tlc/1.3.0/statuses/S0027.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0032.json +2 -2
- data/schemas/tlc/1.3.0/statuses/S0033.json +5 -5
- data/schemas/tlc/1.3.0/statuses/S0034.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0035.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0091.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0092.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0096.json +6 -6
- data/schemas/tlc/1.3.0/statuses/S0201.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0202.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0203.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0204.json +9 -9
- data/schemas/tlc/1.3.0/statuses/S0205.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0206.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0207.json +1 -1
- data/schemas/tlc/1.3.0/statuses/S0208.json +9 -9
- data/schemas/tlc/1.3.0/sxl_index.json +408 -402
- metadata +8 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module RSMP
|
|
2
|
+
module Convert
|
|
3
|
+
module Export
|
|
4
|
+
# Converts SXL definitions to JSON Schema files.
|
|
5
|
+
module JSONSchema
|
|
6
|
+
def self.output_sxl_index(out, sxl)
|
|
7
|
+
out['sxl_index.json'] = output_json({
|
|
8
|
+
'meta' => sxl[:meta],
|
|
9
|
+
'statuses' => index_items(sxl[:statuses]),
|
|
10
|
+
'commands' => index_items(sxl[:commands]),
|
|
11
|
+
'alarms' => index_items(sxl[:alarms])
|
|
12
|
+
})
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.index_items(items)
|
|
16
|
+
items.keys.sort.to_h do |key|
|
|
17
|
+
[key, index_item(items[key])]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.index_item(item)
|
|
22
|
+
arguments = item['arguments'] || {}
|
|
23
|
+
entry = {}
|
|
24
|
+
required = typed_arguments(arguments.reject { |_name, argument| argument['optional'] == true })
|
|
25
|
+
optional = typed_arguments(arguments.select { |_name, argument| argument['optional'] == true })
|
|
26
|
+
entry['required'] = required unless required.empty?
|
|
27
|
+
entry['optional'] = optional unless optional.empty?
|
|
28
|
+
entry
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.typed_arguments(arguments)
|
|
32
|
+
arguments.keys.sort.to_h do |name|
|
|
33
|
+
[name, argument_type_descriptor(arguments[name])]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.argument_type_descriptor(argument)
|
|
38
|
+
type = argument['type']
|
|
39
|
+
case type
|
|
40
|
+
when 'array'
|
|
41
|
+
argument_array_descriptor(argument)
|
|
42
|
+
when 'object'
|
|
43
|
+
argument_object_descriptor(argument)
|
|
44
|
+
else
|
|
45
|
+
type
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.argument_array_descriptor(argument)
|
|
50
|
+
descriptor = { 'type' => argument['type'] }
|
|
51
|
+
descriptor['items'] = typed_arguments(argument['items']) if argument['items'].is_a?(Hash)
|
|
52
|
+
descriptor
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.argument_object_descriptor(argument)
|
|
56
|
+
descriptor = { 'type' => argument['type'] }
|
|
57
|
+
properties = argument['properties'] || argument['items']
|
|
58
|
+
descriptor['properties'] = typed_arguments(properties) if properties.is_a?(Hash)
|
|
59
|
+
descriptor
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -42,12 +42,20 @@ module RSMP
|
|
|
42
42
|
'then' => { 'properties' => { property_key => build_value(argument) } }
|
|
43
43
|
}
|
|
44
44
|
end
|
|
45
|
-
{
|
|
45
|
+
schema = {
|
|
46
46
|
'$schema' => 'https://json-schema.org/draft/2020-12/schema',
|
|
47
47
|
'description' => item['description'],
|
|
48
48
|
'properties' => { 'n' => { 'enum' => arguments.keys.sort } },
|
|
49
49
|
'allOf' => rules
|
|
50
50
|
}
|
|
51
|
+
return schema unless property_key == 'v'
|
|
52
|
+
|
|
53
|
+
schema.delete 'allOf'
|
|
54
|
+
schema.merge(
|
|
55
|
+
'if' => { '$ref' => '../defs/guards.json#/$defs/age_unknown_or_undefined' },
|
|
56
|
+
'then' => {},
|
|
57
|
+
'else' => { 'allOf' => rules }
|
|
58
|
+
)
|
|
51
59
|
end
|
|
52
60
|
end
|
|
53
61
|
end
|
|
@@ -11,6 +11,12 @@ module RSMP
|
|
|
11
11
|
{ 'required' => ['q'] },
|
|
12
12
|
{ 'properties' => { 'q' => { 'enum' => %w[undefined unknown] } } }
|
|
13
13
|
]
|
|
14
|
+
},
|
|
15
|
+
'age_unknown_or_undefined' => {
|
|
16
|
+
'allOf' => [
|
|
17
|
+
{ 'required' => ['age'] },
|
|
18
|
+
{ 'properties' => { 'age' => { 'enum' => %w[undefined unknown] } } }
|
|
19
|
+
]
|
|
14
20
|
}
|
|
15
21
|
}
|
|
16
22
|
}.freeze
|
|
@@ -67,6 +73,15 @@ module RSMP
|
|
|
67
73
|
|
|
68
74
|
# convert commands to json schema
|
|
69
75
|
def self.output_commands(out, items)
|
|
76
|
+
out['defs/guards.json'] ||= output_json(GUARDS_JSON)
|
|
77
|
+
out['commands/commands.json'] = output_json commands_schema(items)
|
|
78
|
+
out['commands/command_requests.json'] = output_json command_requests_schema(items)
|
|
79
|
+
out['commands/command_responses.json'] = output_json command_responses_schema
|
|
80
|
+
|
|
81
|
+
items.each_pair { |key, item| output_command out, key, item }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self.commands_schema(items)
|
|
70
85
|
list = [{ 'properties' => { 'cCI' => { 'enum' => items.keys.sort } } }]
|
|
71
86
|
items.keys.sort.each do |key|
|
|
72
87
|
list << {
|
|
@@ -74,25 +89,67 @@ module RSMP
|
|
|
74
89
|
'then' => { '$ref' => "#{key}.json" }
|
|
75
90
|
}
|
|
76
91
|
end
|
|
77
|
-
|
|
92
|
+
{
|
|
78
93
|
'$schema' => 'https://json-schema.org/draft/2020-12/schema',
|
|
79
94
|
'items' => { 'allOf' => list }
|
|
80
95
|
}
|
|
81
|
-
|
|
96
|
+
end
|
|
82
97
|
|
|
83
|
-
|
|
98
|
+
def self.command_requests_schema(items)
|
|
99
|
+
{
|
|
84
100
|
'$schema' => 'https://json-schema.org/draft/2020-12/schema',
|
|
85
|
-
'properties' => { 'arg' =>
|
|
101
|
+
'properties' => { 'arg' => command_request_arg_schema(items) }
|
|
86
102
|
}
|
|
87
|
-
|
|
103
|
+
end
|
|
88
104
|
|
|
89
|
-
|
|
105
|
+
def self.command_responses_schema
|
|
106
|
+
{
|
|
90
107
|
'$schema' => 'https://json-schema.org/draft/2020-12/schema',
|
|
91
108
|
'properties' => { 'rvs' => { '$ref' => 'commands.json' } }
|
|
92
109
|
}
|
|
93
|
-
|
|
110
|
+
end
|
|
94
111
|
|
|
95
|
-
|
|
112
|
+
def self.command_request_arg_schema(items)
|
|
113
|
+
schema = { '$ref' => 'commands.json' }
|
|
114
|
+
required_rules = command_required_argument_rules(items)
|
|
115
|
+
return schema if required_rules.empty?
|
|
116
|
+
|
|
117
|
+
{ 'allOf' => [schema] + required_rules }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def self.command_required_argument_rules(items)
|
|
121
|
+
items.keys.sort.filter_map do |key|
|
|
122
|
+
required = required_argument_names(items[key])
|
|
123
|
+
next if required.empty?
|
|
124
|
+
|
|
125
|
+
{
|
|
126
|
+
'if' => {
|
|
127
|
+
'contains' => {
|
|
128
|
+
'required' => ['cCI'],
|
|
129
|
+
'properties' => { 'cCI' => { 'const' => key } }
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
'then' => {
|
|
133
|
+
'allOf' => required.map { |name| command_argument_contains_rule(key, name) }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def self.command_argument_contains_rule(command_code, name)
|
|
140
|
+
{
|
|
141
|
+
'contains' => {
|
|
142
|
+
'required' => %w[cCI n],
|
|
143
|
+
'properties' => {
|
|
144
|
+
'cCI' => { 'const' => command_code },
|
|
145
|
+
'n' => { 'const' => name }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def self.required_argument_names(item)
|
|
152
|
+
(item['arguments'] || {}).reject { |_name, argument| argument['optional'] == true }.keys.sort
|
|
96
153
|
end
|
|
97
154
|
|
|
98
155
|
# convert a command to json schema
|
|
@@ -103,23 +160,6 @@ module RSMP
|
|
|
103
160
|
out["commands/#{key}.json"] = output_json json
|
|
104
161
|
end
|
|
105
162
|
|
|
106
|
-
def self.output_sxl_index(out, sxl)
|
|
107
|
-
out['sxl_index.json'] = output_json({
|
|
108
|
-
'meta' => sxl[:meta],
|
|
109
|
-
'statuses' => index_items(sxl[:statuses]),
|
|
110
|
-
'commands' => index_items(sxl[:commands]),
|
|
111
|
-
'alarms' => index_items(sxl[:alarms])
|
|
112
|
-
})
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def self.index_items(items)
|
|
116
|
-
items.keys.sort.to_h do |key|
|
|
117
|
-
[key, {
|
|
118
|
-
'arguments' => (items[key]['arguments'] || {}).keys.sort
|
|
119
|
-
}]
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
163
|
# output the json schema root
|
|
124
164
|
def self.output_root(out, meta)
|
|
125
165
|
json = {
|
|
@@ -3,6 +3,21 @@ module RSMP
|
|
|
3
3
|
module Export
|
|
4
4
|
# Converts SXL definitions to JSON Schema files.
|
|
5
5
|
module JSONSchema
|
|
6
|
+
DIRECT_JSON_TYPES = {
|
|
7
|
+
'boolean' => 'boolean',
|
|
8
|
+
'integer' => 'integer',
|
|
9
|
+
'number' => 'number',
|
|
10
|
+
'object' => 'object',
|
|
11
|
+
'null' => 'null'
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
DEFINITION_REFS = {
|
|
15
|
+
'boolean_as_string' => '../defs/definitions.json#/boolean',
|
|
16
|
+
'timestamp' => '../defs/definitions.json#/timestamp',
|
|
17
|
+
'integer_as_string' => '../defs/definitions.json#/integer',
|
|
18
|
+
'long_as_string' => '../defs/definitions.json#/integer'
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
6
21
|
# convert a yaml item to json schema
|
|
7
22
|
def self.build_value(item)
|
|
8
23
|
out = {}
|
|
@@ -19,20 +34,27 @@ module RSMP
|
|
|
19
34
|
|
|
20
35
|
# convert an item which is not a string-list, to json schema
|
|
21
36
|
def self.handle_types(item, out)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
type = item['type']
|
|
38
|
+
return build_json_array_type(item, out) if type == 'array'
|
|
39
|
+
return build_number_as_string_type(out) if type == 'number_as_string'
|
|
40
|
+
return out['$ref'] = DEFINITION_REFS[type] if DEFINITION_REFS.key?(type)
|
|
41
|
+
|
|
42
|
+
out['type'] = DIRECT_JSON_TYPES.fetch(type, 'string')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.build_json_array_type(item, out)
|
|
46
|
+
if item['items']
|
|
30
47
|
build_json_array item['items'], out
|
|
31
|
-
else
|
|
32
|
-
out['type'] = '
|
|
48
|
+
else
|
|
49
|
+
out['type'] = 'array'
|
|
33
50
|
end
|
|
34
51
|
end
|
|
35
52
|
|
|
53
|
+
def self.build_number_as_string_type(out)
|
|
54
|
+
out['type'] = 'string'
|
|
55
|
+
out['pattern'] = '^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$'
|
|
56
|
+
end
|
|
57
|
+
|
|
36
58
|
# convert an yaml item with type: array to json schema
|
|
37
59
|
def self.build_json_array(item, out)
|
|
38
60
|
required = item.reject { |_k, v| v['optional'] == true }.keys.sort
|
|
@@ -83,7 +105,14 @@ module RSMP
|
|
|
83
105
|
def self.handle_enum(item, out)
|
|
84
106
|
return unless item['values']
|
|
85
107
|
|
|
86
|
-
|
|
108
|
+
values = enum_keys(item)
|
|
109
|
+
values = stringify_values(values) if string_type? item
|
|
110
|
+
out['enum'] = values
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.string_type?(item)
|
|
114
|
+
type = item['type'].to_s
|
|
115
|
+
type == 'string' || type.end_with?('_as_string') || %w[base64 timestamp].include?(type)
|
|
87
116
|
end
|
|
88
117
|
|
|
89
118
|
def self.enum_keys(item)
|
|
@@ -7,6 +7,7 @@ require 'fileutils'
|
|
|
7
7
|
require_relative 'json_schema/values'
|
|
8
8
|
require_relative 'json_schema/items'
|
|
9
9
|
require_relative 'json_schema/outputs'
|
|
10
|
+
require_relative 'json_schema/index'
|
|
10
11
|
|
|
11
12
|
module RSMP
|
|
12
13
|
module Convert
|
|
@@ -19,7 +20,8 @@ module RSMP
|
|
|
19
20
|
object_nl: "\n",
|
|
20
21
|
indent: ' ',
|
|
21
22
|
space_before: ' ',
|
|
22
|
-
space: ' '
|
|
23
|
+
space: ' ',
|
|
24
|
+
ascii_only: true
|
|
23
25
|
}.freeze
|
|
24
26
|
|
|
25
27
|
def self.output_json(item)
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
module RSMP
|
|
2
|
+
# Encodes and decodes SXL argument values for message payloads.
|
|
3
|
+
module MessageSxlCodec
|
|
4
|
+
SXL_ITEM_SHAPES = {
|
|
5
|
+
'StatusResponse' => { kind: :statuses, list: 'sS', code: 'sCI', name: 'n', value: 's' },
|
|
6
|
+
'StatusUpdate' => { kind: :statuses, list: 'sS', code: 'sCI', name: 'n', value: 's' },
|
|
7
|
+
'CommandRequest' => { kind: :commands, list: 'arg', code: 'cCI', name: 'n', value: 'v' },
|
|
8
|
+
'CommandResponse' => { kind: :commands, list: 'rvs', code: 'cCI', name: 'n', value: 'v' },
|
|
9
|
+
'Alarm' => { kind: :alarms, list: 'rvs', code: nil, name: 'n', value: 'v' }
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
def self.included(base)
|
|
13
|
+
base.extend ClassMethods
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def encode_for(schemas)
|
|
17
|
+
transform_sxl_items(schemas, :encode_sxl_value)
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def decode_for(schemas)
|
|
22
|
+
transform_sxl_items(schemas, :decode_sxl_value)
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def transform_sxl_items(schemas, transformer)
|
|
29
|
+
shape = SXL_ITEM_SHAPES[type]
|
|
30
|
+
return unless shape
|
|
31
|
+
|
|
32
|
+
resolved = RSMP::Schema.resolve_sxl(@attributes, schemas: schemas)
|
|
33
|
+
return unless resolved
|
|
34
|
+
|
|
35
|
+
sxl_type, version = resolved
|
|
36
|
+
Array(@attributes[shape[:list]]).each do |item|
|
|
37
|
+
transform_sxl_item(item, shape, sxl_type, version, transformer)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def transform_sxl_item(item, shape, sxl_type, version, transformer)
|
|
42
|
+
item_code = shape[:code] ? item[shape[:code]] : @attributes['aCId']
|
|
43
|
+
name = item[shape[:name]]
|
|
44
|
+
return unless item_code && name && item.key?(shape[:value])
|
|
45
|
+
|
|
46
|
+
descriptor = RSMP::Schema.sxl_argument_descriptor(sxl_type, version, shape[:kind], item_code, name)
|
|
47
|
+
return unless descriptor
|
|
48
|
+
|
|
49
|
+
item[shape[:value]] = self.class.public_send(transformer, item[shape[:value]], descriptor)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Class-level value transforms used by Message and command collectors.
|
|
53
|
+
module ClassMethods
|
|
54
|
+
STRING_TYPES = %w[string base64 timestamp].freeze
|
|
55
|
+
INTEGER_AS_STRING_TYPES = %w[integer_as_string long_as_string].freeze
|
|
56
|
+
|
|
57
|
+
def encode_sxl_value(value, descriptor)
|
|
58
|
+
return nil if value.nil?
|
|
59
|
+
|
|
60
|
+
type = descriptor_type(descriptor)
|
|
61
|
+
return encode_sxl_boolean(value) if type == 'boolean_as_string'
|
|
62
|
+
return encode_sxl_list(value) if list_type?(type)
|
|
63
|
+
return value.is_a?(String) ? value : value.to_s if encode_string_type?(type)
|
|
64
|
+
return encode_sxl_array(value, descriptor) if type == 'array'
|
|
65
|
+
return encode_sxl_object(value, descriptor['properties']) if type == 'object'
|
|
66
|
+
|
|
67
|
+
value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def decode_sxl_value(value, descriptor)
|
|
71
|
+
return nil if value.nil?
|
|
72
|
+
|
|
73
|
+
type = descriptor_type(descriptor)
|
|
74
|
+
return decode_sxl_boolean(value) if type == 'boolean_as_string'
|
|
75
|
+
return decode_sxl_integer(value) if INTEGER_AS_STRING_TYPES.include?(type)
|
|
76
|
+
return decode_sxl_number(value) if type == 'number_as_string'
|
|
77
|
+
return decode_sxl_list(value, type) if list_type?(type)
|
|
78
|
+
return decode_sxl_array(value, descriptor) if type == 'array'
|
|
79
|
+
return decode_sxl_object(value, descriptor['properties']) if type == 'object'
|
|
80
|
+
|
|
81
|
+
value
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def descriptor_type(descriptor)
|
|
85
|
+
descriptor.is_a?(Hash) ? descriptor['type'] : descriptor.to_s
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def list_type?(type)
|
|
89
|
+
type.match?(/_list(_as_string)?\z/)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def encode_string_type?(type)
|
|
93
|
+
STRING_TYPES.include?(type) || INTEGER_AS_STRING_TYPES.include?(type) || type == 'number_as_string'
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def encode_sxl_boolean(value)
|
|
97
|
+
case value
|
|
98
|
+
when true
|
|
99
|
+
'True'
|
|
100
|
+
when false
|
|
101
|
+
'False'
|
|
102
|
+
else
|
|
103
|
+
value
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def encode_sxl_list(value)
|
|
108
|
+
return value if value.is_a?(String)
|
|
109
|
+
return encode_sxl_boolean(value).to_s unless value.is_a?(Array)
|
|
110
|
+
|
|
111
|
+
value.map { |item| encode_sxl_boolean(item) }.join(',')
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def encode_sxl_array(value, descriptor)
|
|
115
|
+
return value unless value.is_a?(Array)
|
|
116
|
+
|
|
117
|
+
items = descriptor['items']
|
|
118
|
+
return value unless items.is_a?(Hash)
|
|
119
|
+
|
|
120
|
+
value.map { |item| encode_sxl_object(item, items) }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def encode_sxl_object(value, properties)
|
|
124
|
+
transform_sxl_object(value, properties, :encode_sxl_value)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def decode_sxl_boolean(value)
|
|
128
|
+
case value
|
|
129
|
+
when 'True'
|
|
130
|
+
true
|
|
131
|
+
when 'False'
|
|
132
|
+
false
|
|
133
|
+
else
|
|
134
|
+
value
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def decode_sxl_integer(value)
|
|
139
|
+
return value unless value.is_a?(String) && value.match?(/\A[+-]?\d+\z/)
|
|
140
|
+
|
|
141
|
+
value.to_i
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def decode_sxl_number(value)
|
|
145
|
+
return value unless value.is_a?(String)
|
|
146
|
+
|
|
147
|
+
Float(value)
|
|
148
|
+
rescue ArgumentError
|
|
149
|
+
value
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def decode_sxl_list(value, type)
|
|
153
|
+
items = value.is_a?(String) ? value.split(',') : Array(value)
|
|
154
|
+
descriptor = list_item_descriptor(type)
|
|
155
|
+
items.map { |item| decode_sxl_value(item, descriptor) }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def list_item_descriptor(type)
|
|
159
|
+
case type
|
|
160
|
+
when /\Aboolean_list/ then 'boolean_as_string'
|
|
161
|
+
when /\Ainteger_list/ then 'integer_as_string'
|
|
162
|
+
when /\Anumber_list/ then 'number_as_string'
|
|
163
|
+
else 'string'
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def decode_sxl_array(value, descriptor)
|
|
168
|
+
return value unless value.is_a?(Array)
|
|
169
|
+
|
|
170
|
+
items = descriptor['items']
|
|
171
|
+
return value unless items.is_a?(Hash)
|
|
172
|
+
|
|
173
|
+
value.map { |item| decode_sxl_array_item(item, items) }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def decode_sxl_array_item(item, descriptor)
|
|
177
|
+
descriptor['type'] ? decode_sxl_value(item, descriptor) : decode_sxl_object(item, descriptor)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def decode_sxl_object(value, properties)
|
|
181
|
+
transform_sxl_object(value, properties, :decode_sxl_value)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def transform_sxl_object(value, properties, transformer)
|
|
185
|
+
return value unless value.is_a?(Hash) && properties.is_a?(Hash)
|
|
186
|
+
|
|
187
|
+
value.each_with_object({}) do |(key, item_value), memo|
|
|
188
|
+
descriptor = properties[key] || properties[key.to_sym]
|
|
189
|
+
memo[key] = descriptor ? public_send(transformer, item_value, descriptor) : item_value
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
data/lib/rsmp/message.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
module RSMP
|
|
3
3
|
# Base RSMP message class used to represent parsed and built messages.
|
|
4
4
|
class Message
|
|
5
|
+
include MessageSxlCodec
|
|
6
|
+
|
|
5
7
|
attr_reader :now, :attributes, :out, :timestamp # this is an internal timestamp recording when we receive/send
|
|
6
8
|
attr_accessor :json, :direction
|
|
7
9
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module RSMP
|
|
2
|
+
# Connection handling for site instances.
|
|
3
|
+
module SiteConnections
|
|
4
|
+
def build_proxies
|
|
5
|
+
return if server_role?
|
|
6
|
+
|
|
7
|
+
@site_settings['supervisors'].each do |supervisor_settings|
|
|
8
|
+
@proxies << SupervisorProxy.new(supervisor_proxy_options(supervisor_settings))
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def listen_for_supervisors
|
|
13
|
+
ip = @site_settings['ip'] || '0.0.0.0'
|
|
14
|
+
port = @site_settings['port']
|
|
15
|
+
log "Starting #{site_type_name} listener on #{ip}:#{port}", level: :info, timestamp: @clock.now
|
|
16
|
+
@endpoint = IO::Endpoint.tcp(ip, port)
|
|
17
|
+
@accept_task = Async::Task.current.async do |task|
|
|
18
|
+
task.annotate 'site accept loop'
|
|
19
|
+
accept_supervisor_connections
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@ready_condition.signal
|
|
23
|
+
@accept_task.wait
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def accept_supervisor_connections
|
|
27
|
+
@endpoint.accept do |socket|
|
|
28
|
+
accept_supervisor_connection socket
|
|
29
|
+
rescue StandardError => e
|
|
30
|
+
distribute_error e, level: :internal
|
|
31
|
+
end
|
|
32
|
+
rescue Async::Stop
|
|
33
|
+
# Expected during shutdown - no action needed
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
distribute_error e, level: :internal
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def accept_supervisor_connection(socket)
|
|
39
|
+
remote_port = socket.remote_address.ip_port
|
|
40
|
+
remote_ip = socket.remote_address.ip_address
|
|
41
|
+
proxy = SupervisorProxy.new(accepted_supervisor_options(socket, remote_ip, remote_port))
|
|
42
|
+
@proxies << proxy
|
|
43
|
+
@proxies_condition.signal
|
|
44
|
+
proxy.start
|
|
45
|
+
proxy.wait
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def connect_to_supervisor(_task, supervisor_settings)
|
|
49
|
+
proxy = build_proxy(supervisor_proxy_options(supervisor_settings))
|
|
50
|
+
@proxies << proxy
|
|
51
|
+
proxy.start
|
|
52
|
+
@proxies_condition.signal
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def supervisor_proxy_options(supervisor_settings)
|
|
58
|
+
{
|
|
59
|
+
site: self,
|
|
60
|
+
task: @task,
|
|
61
|
+
settings: @site_settings,
|
|
62
|
+
ip: supervisor_settings['ip'],
|
|
63
|
+
port: supervisor_settings['port'],
|
|
64
|
+
logger: @logger,
|
|
65
|
+
archive: @archive,
|
|
66
|
+
collect: @collect
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def accepted_supervisor_options(socket, remote_ip, remote_port)
|
|
71
|
+
stream = IO::Stream::Buffered.new(socket)
|
|
72
|
+
supervisor_proxy_options('ip' => remote_ip, 'port' => remote_port).merge(
|
|
73
|
+
socket: socket,
|
|
74
|
+
stream: stream,
|
|
75
|
+
protocol: RSMP::Protocol.new(stream),
|
|
76
|
+
info: { ip: remote_ip, port: remote_port, hostname: remote_ip, now: Clock.now }
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|