dji_mqtt_connect 0.1.1.4 → 0.1.2

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop/rspec.yml +2 -2
  3. data/Gemfile.lock +20 -9
  4. data/dji_mqtt_connect.gemspec +48 -0
  5. data/lib/dji_mqtt_connect/factories.rb +65 -0
  6. data/lib/dji_mqtt_connect/marshals/thing/product/osd_marshal.rb +17 -3
  7. data/lib/dji_mqtt_connect/messages/thing/product/airport_organization_get_requests_message.rb +15 -0
  8. data/lib/dji_mqtt_connect/messages/thing/product/airport_organization_get_requests_reply_message.rb +34 -0
  9. data/lib/dji_mqtt_connect/messages/thing/product/dock_osd_message.rb +199 -0
  10. data/lib/dji_mqtt_connect/messages/thing/product/drone_osd_message.rb +114 -10
  11. data/lib/dji_mqtt_connect/messages/thing/product/remote_osd_message.rb +4 -9
  12. data/lib/dji_mqtt_connect/messages/thing/product/storage_config_get_requests_message.rb +14 -0
  13. data/lib/dji_mqtt_connect/messages/thing/product/storage_config_get_requests_reply_message.rb +44 -0
  14. data/lib/dji_mqtt_connect/mixins/latitude_conditional.rb +12 -0
  15. data/lib/dji_mqtt_connect/mixins/longitude_conditional.rb +12 -0
  16. data/lib/dji_mqtt_connect/mixins/temperature_conditional.rb +12 -0
  17. data/lib/dji_mqtt_connect/topics/sys/product/status.rb +8 -1
  18. data/lib/dji_mqtt_connect/topics/thing/product/osd.rb +8 -3
  19. data/lib/dji_mqtt_connect/topics/thing/product/requests.rb +8 -1
  20. data/lib/dji_mqtt_connect/types.rb +3 -0
  21. data/lib/dji_mqtt_connect/utils/message_sanitizer.rb +90 -0
  22. data/lib/dji_mqtt_connect/utils/message_schema_generator.rb +39 -0
  23. data/lib/dji_mqtt_connect/utils/mqttx_fixture_data_generator.rb +68 -0
  24. data/lib/dji_mqtt_connect/version.rb +1 -1
  25. data/lib/dji_mqtt_connect.rb +15 -0
  26. metadata +14 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7418cbbd6b891b0d72ea6d8e47f9b7f813b9de2dffd97f7bae249292a73f510
4
- data.tar.gz: 6f2047ad8fcb7db0eff553c8c4dde862d2dbaa8b0820cd240a400d276470e51f
3
+ metadata.gz: 824a4b8942fc65705e25588a32df620e49602573b1eb14ed6f1b2c34c98023cd
4
+ data.tar.gz: 7f9dc5c06e40c04862baed3c41b8342da77a9fbedb083ab7432b9173180ebce1
5
5
  SHA512:
6
- metadata.gz: d1d174f8a9475a59f1e5ed31835903a49dbc1100464fbf9da910b47f7219ed348ab710aee3baef7c1da75d17ef4e5340203e033650a50257018fa7499fae67b1
7
- data.tar.gz: 9c9795cea856dd583733174aa9fd0871c50772b23d438bfb3d1608dd913187df62e4e7cb9468c6ad4beba336c60d163f9887a8c635714cf1dd0853ab25789f69
6
+ metadata.gz: 58ccec055d15866882fd93521c5d312719012c10e8778e18b99191c2bb48a7173ac0283f7f18daf21fb950d0472c02b3cb861cd1d07b0da0584e62278d62554c
7
+ data.tar.gz: ac4f30aa186b37fa04dbadbc49d813648c08ca031809a7c3b73d97fb0d6f7489cc680d74e0a3a83015ebcf77d26d25386c7f8dbecdb4e04e337308bc3a1f7a6c
data/.rubocop/rspec.yml CHANGED
@@ -48,8 +48,8 @@ RSpec/ReceiveCounts:
48
48
  Capybara/CurrentPathExpectation:
49
49
  Enabled: true
50
50
 
51
- RSpec/FactoryBot/AttributeDefinedStatically:
51
+ FactoryBot/AttributeDefinedStatically:
52
52
  Enabled: true
53
53
 
54
- RSpec/FactoryBot/CreateList:
54
+ FactoryBot/CreateList:
55
55
  Enabled: true
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dji_mqtt_connect (0.1.1.4)
4
+ dji_mqtt_connect (0.1.2)
5
5
  activesupport (>= 6.0, <= 8)
6
6
  dry-struct (~> 1.6)
7
7
  dry-transformer (~> 1.0)
@@ -46,15 +46,16 @@ GEM
46
46
  zeitwerk (~> 2.6)
47
47
  globalid (1.1.0)
48
48
  activesupport (>= 5.0)
49
- i18n (1.12.0)
49
+ i18n (1.13.0)
50
50
  concurrent-ruby (~> 1.0)
51
51
  ice_nine (0.11.2)
52
52
  json (2.6.3)
53
53
  language_server-protocol (3.17.0.3)
54
+ lint_roller (1.0.0)
54
55
  minitest (5.18.0)
55
56
  mqtt (0.6.0)
56
57
  parallel (1.23.0)
57
- parser (3.2.2.0)
58
+ parser (3.2.2.1)
58
59
  ast (~> 2.4.1)
59
60
  rainbow (3.1.1)
60
61
  rake (13.0.6)
@@ -66,7 +67,7 @@ GEM
66
67
  rspec-mocks (~> 3.12.0)
67
68
  rspec-core (3.12.2)
68
69
  rspec-support (~> 3.12.0)
69
- rspec-expectations (3.12.2)
70
+ rspec-expectations (3.12.3)
70
71
  diff-lcs (>= 1.2.0, < 2.0)
71
72
  rspec-support (~> 3.12.0)
72
73
  rspec-mocks (3.12.5)
@@ -83,18 +84,21 @@ GEM
83
84
  rubocop-ast (>= 1.28.0, < 2.0)
84
85
  ruby-progressbar (~> 1.7)
85
86
  unicode-display_width (>= 2.4.0, < 3.0)
86
- rubocop-ast (1.28.0)
87
+ rubocop-ast (1.28.1)
87
88
  parser (>= 3.2.1.0)
88
- rubocop-capybara (2.17.1)
89
+ rubocop-capybara (2.18.0)
89
90
  rubocop (~> 1.41)
91
+ rubocop-factory_bot (2.22.0)
92
+ rubocop (~> 1.33)
90
93
  rubocop-performance (1.16.0)
91
94
  rubocop (>= 1.7.0, < 2.0)
92
95
  rubocop-ast (>= 0.4.0)
93
96
  rubocop-rake (0.6.0)
94
97
  rubocop (~> 1.0)
95
- rubocop-rspec (2.20.0)
98
+ rubocop-rspec (2.22.0)
96
99
  rubocop (~> 1.33)
97
100
  rubocop-capybara (~> 2.17)
101
+ rubocop-factory_bot (~> 2.22)
98
102
  ruby-progressbar (1.13.0)
99
103
  simplecov (0.22.0)
100
104
  docile (~> 1.1)
@@ -102,16 +106,23 @@ GEM
102
106
  simplecov_json_formatter (~> 0.1)
103
107
  simplecov-html (0.12.3)
104
108
  simplecov_json_formatter (0.1.4)
105
- standard (1.27.0)
109
+ standard (1.28.2)
106
110
  language_server-protocol (~> 3.17.0.2)
111
+ lint_roller (~> 1.0)
107
112
  rubocop (~> 1.50.2)
113
+ standard-custom (~> 1.0.0)
114
+ standard-performance (~> 1.0.1)
115
+ standard-custom (1.0.0)
116
+ lint_roller (~> 1.0)
117
+ standard-performance (1.0.1)
118
+ lint_roller (~> 1.0)
108
119
  rubocop-performance (~> 1.16.0)
109
120
  tzinfo (2.0.6)
110
121
  concurrent-ruby (~> 1.0)
111
122
  unicode-display_width (2.4.2)
112
123
  wisper (2.0.1)
113
124
  wisper-rspec (1.1.0)
114
- zeitwerk (2.6.7)
125
+ zeitwerk (2.6.8)
115
126
 
116
127
  PLATFORMS
117
128
  x86_64-darwin-21
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/dji_mqtt_connect/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "dji_mqtt_connect"
7
+ spec.version = DjiMqttConnect::VERSION
8
+ spec.authors = ["Sphere Drones"]
9
+ spec.email = ["projects@spheregroup.com.au"]
10
+
11
+ spec.summary = "Manages MQTT Connections with DJI Drones"
12
+ # spec.description = "TODO: Write a longer description or delete this line."
13
+ spec.homepage = "https://github.com/sphere-drones/dji_mqtt_connect"
14
+ spec.required_ruby_version = ">= 3.1.0"
15
+
16
+ # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/sphere-drones/dji_mqtt_connect"
20
+ spec.metadata["changelog_uri"] = "https://github.com/sphere-drones/dji_mqtt_connect/main/CHANGELOG.md"
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(__dir__) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
27
+ end
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ # Use Active Support for inflection and logging
34
+ spec.add_dependency "activesupport", ">= 6.0", "<= 8"
35
+
36
+ # Use Dry-rb for valid POROs
37
+ spec.add_dependency "dry-struct", "~> 1.6"
38
+ spec.add_dependency "dry-transformer", "~> 1.0"
39
+
40
+ # Use MQTT as a client for receiving/sending messages
41
+ spec.add_dependency "mqtt", "~> 0.6.0"
42
+
43
+ # Use Whisper for events
44
+ spec.add_dependency "wisper", "~> 2.0"
45
+
46
+ # For more information and examples about making a new gem, check out our
47
+ # guide at: https://bundler.io/guides/creating_gem.html
48
+ end
@@ -114,5 +114,70 @@ module DjiMqttConnect
114
114
  end
115
115
  )
116
116
  end
117
+
118
+ def build_thing_product_airport_organization_get_requests_message
119
+ message_data = {
120
+ device_binding_code: "device_binding_code",
121
+ organization_id: "organization_id"
122
+ }
123
+
124
+ Thing::Product::AirportOrganizationGetRequestsMessage.new(
125
+ _method: "airport_organization_get",
126
+ _data: message_data,
127
+ tid: "3093aad5-bb98-5026-685a-cea540eb9267",
128
+ bid: "479533e0-cb01-933c-3758-22f2a82abeb8",
129
+ timestamp: 1679380233000,
130
+ data: message_data
131
+ )
132
+ end
133
+
134
+ def build_thing_product_airport_organization_get_requests_reply_message
135
+ airport_organization_get_request = build_thing_product_airport_organization_get_requests_message
136
+
137
+ Thing::Product::AirportOrganizationGetRequestsReplyMessage.build_for(
138
+ airport_organization_get_request,
139
+ result: 0,
140
+ output: {
141
+ organization_name: "12345"
142
+ }
143
+ )
144
+ end
145
+
146
+ def build_thing_product_storage_config_get_requests_message
147
+ message_data = {
148
+ module: 0
149
+ }
150
+
151
+ Thing::Product::StorageConfigGetRequestsMessage.new(
152
+ _method: "storage_config_get",
153
+ _data: message_data,
154
+ tid: "3093aad5-bb98-5026-685a-cea540eb9267",
155
+ bid: "479533e0-cb01-933c-3758-22f2a82abeb8",
156
+ timestamp: 1679380233000,
157
+ data: message_data
158
+ )
159
+ end
160
+
161
+ def build_thing_product_storage_config_get_requests_reply_message
162
+ storage_config_get_request = build_thing_product_storage_config_get_requests_message
163
+
164
+ Thing::Product::StorageConfigGetRequestsReplyMessage.build_for(
165
+ storage_config_get_request,
166
+ result: 0,
167
+ output: {
168
+ bucket: "bucket_name",
169
+ credentials: {
170
+ access_key_id: "access_key_id",
171
+ access_key_secret: "access_key_secret",
172
+ expire: 3600,
173
+ security_token: "security_token"
174
+ },
175
+ endpoint: "https://oss-cn-hangzhou.aliyuncs.com",
176
+ object_key_prefix: "b4cfaae6-bd9d-4cd0-8472-63b608c3c581",
177
+ provider: "ali",
178
+ region: "hz"
179
+ }
180
+ )
181
+ end
117
182
  end
118
183
  end
@@ -12,10 +12,15 @@ module DjiMqttConnect
12
12
  import Dry::Transformer::HashTransformations
13
13
 
14
14
  define! do
15
+ # Ensure there is a data element
16
+ map_value "data", ->(data) { data || {} }
17
+
18
+ # Create a backup for unsupported attributes
15
19
  copy_keys "data" => "_data"
16
20
 
17
21
  map_value "data" do
18
- guard ->(data) { data&.key?("wireless_link") } do
22
+ # Rename the invalid (for Ruby) wireless link attributes
23
+ guard ->(data) { data.key?("wireless_link") } do
19
24
  # Translate wireless_link 4g keys (from remote payload)
20
25
  map_value "wireless_link" do
21
26
  rename_keys "4g_freq_band" => "_4g_freq_band",
@@ -38,6 +43,8 @@ module DjiMqttConnect
38
43
  DroneOsdMessage
39
44
  elsif remote_osd_data_attributes.all? { |attribute| message_data.key?(attribute.to_s) }
40
45
  RemoteOsdMessage
46
+ elsif dock_osd_data_attributes.any? { |attribute| message_data.key?(attribute.to_s) }
47
+ DockOsdMessage
41
48
  else
42
49
  OsdMessage
43
50
  end
@@ -57,12 +64,19 @@ module DjiMqttConnect
57
64
  @attribute_transformer ||= AttributeTransformer.new
58
65
  end
59
66
 
67
+ def dock_osd_data_attributes
68
+ @dock_osd_data_attributes ||= DockOsdMessage::STABLE_DATA_ATTRIBUTES.map(&:to_s)
69
+ end
70
+
60
71
  def drone_osd_data_attributes
61
- @drone_osd_data_attributes ||= DjiMqttConnect::Thing::Product::DroneOsdMessage::Data.schema.keys.map(&:name)
72
+ @drone_osd_data_attributes ||= DroneOsdMessage::STABLE_DATA_ATTRIBUTES.map(&:to_s)
62
73
  end
63
74
 
64
75
  def remote_osd_data_attributes
65
- @remote_osd_data_attributes ||= DjiMqttConnect::Thing::Product::RemoteOsdMessage::Data.schema.keys.map(&:name)
76
+ @remote_osd_data_attributes ||= begin
77
+ data_keys = DjiMqttConnect::Thing::Product::RemoteOsdMessage::Data.schema.keys
78
+ data_keys.select(&:required?).map(&:name)
79
+ end
66
80
  end
67
81
  end
68
82
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ # https://developer.dji.com/doc/cloud-api-tutorial/en/server-api-reference/mqtt/thing-model/gateway/dock/organization.html#search-for-the-organization-information-that-device-bound-to
6
+ class AirportOrganizationGetRequestsMessage < RequestsMessage
7
+ attribute :_method, Types::String.enum("airport_organization_get")
8
+
9
+ attribute :data do
10
+ attribute :device_binding_code, Types::String
11
+ attribute :organization_id, Types::String
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ # https://developer.dji.com/doc/cloud-api-tutorial/en/server-api-reference/mqtt/thing-model/gateway/dock/organization.html#search-for-the-organization-information-that-device-bound-to
6
+ class AirportOrganizationGetRequestsReplyMessage < Message
7
+ def self.build_for(airport_organization_get_message, output:, result: 0)
8
+ new(
9
+ _method: airport_organization_get_message._method,
10
+ tid: airport_organization_get_message.tid,
11
+ bid: airport_organization_get_message.bid,
12
+ timestamp: Time.now.strftime("%s%L").to_i,
13
+ data: {
14
+ result: result,
15
+ output: output
16
+ }
17
+ )
18
+ end
19
+
20
+ attribute :tid, Types::UUID
21
+ attribute :bid, Types::UUID
22
+ attribute :timestamp, Types::Timestamp
23
+
24
+ attribute :_method, Types::String.enum("airport_organization_get")
25
+
26
+ attribute :data do
27
+ attribute :result, Types::Integer
28
+ attribute :output do
29
+ attribute :organization_name, Types::String
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ class DockOsdMessage < OsdMessage
6
+ schema schema.strict
7
+
8
+ STABLE_DATA_ATTRIBUTES = %i[
9
+ drc_state
10
+ drone_in_dock
11
+ job_number
12
+ ]
13
+
14
+ attribute :data do
15
+ include Mixins::LatitudeConditional
16
+ include Mixins::LongitudeConditional
17
+ include Mixins::TemperatureConditional
18
+
19
+ attribute? :acc_time, Types::Integer
20
+ attribute? :activation_time, Types::Integer
21
+
22
+ attribute? :backup_battery do
23
+ include Mixins::TemperatureConditional
24
+
25
+ attribute :switch, Types::Integer.enum(0, 1)
26
+ attribute :voltage, Types::Integer
27
+ attribute :temperature, Types::Temperature
28
+ end
29
+
30
+ # {"0":"Disconnected","1":"Connecting","2":"Connected"}
31
+ attribute? :drc_state, Types::Integer.enum(0, 1, 2)
32
+
33
+ attribute? :drone_battery_maintenance_info do
34
+ attribute :batteries, Types::Array do
35
+ include Mixins::TemperatureConditional
36
+
37
+ attribute :index, Types::Integer
38
+ attribute :capacity_percent, Types::Integer
39
+ attribute :voltage, Types::Integer
40
+ attribute :temperature, Types::Temperature
41
+ end
42
+
43
+ # {"0":"Battery is not in heating or insulation","1":"Battery is in heating","2":"Battery is in insulation"}
44
+ attribute? :heat_state, Types::Integer.enum(0, 1, 2)
45
+
46
+ # {"0":"No need to maintenance","1":"Need maintenance","2":"Under maintenance"}
47
+ attribute? :maintenance_state, Types::Integer
48
+ attribute? :maintenance_time_left, Types::Integer
49
+ end
50
+
51
+ attribute? :drone_charge_state do
52
+ # {"0":"not charging","1":"charging"}
53
+ attribute :state, Types::Integer.enum(0, 1)
54
+
55
+ # {"min":"0","max":"100"}
56
+ attribute :capacity_percent, Types::Integer.constrained(gteq: 0, lteq: 100)
57
+ end
58
+ attribute? :drone_in_dock, Types::Integer.enum(0, 1)
59
+
60
+ attribute? :electric_supply_voltage, Types::Integer
61
+
62
+ attribute? :flighttask_prepare_capacity, Types::Integer
63
+ attribute? :flighttask_step_code, Types::Integer
64
+
65
+ attribute? :job_number, Types::Integer
66
+
67
+ attribute? :latitude, Types::Latitude
68
+ attribute? :longitude, Types::Longitude
69
+
70
+ attribute? :maintain_status do
71
+ attribute :maintain_status_array, Types::Array do
72
+ # {"0":"No maintenance","1":"Under maintenance"}
73
+ attribute :state, Types::Integer
74
+
75
+ # {"0":"No maintenance","1":"Drone basic maintenance","2":"Drone routine maintenance","3":"Drone deep maintenance","17":"Dock maintenance"}
76
+ attribute :last_maintain_type, Types::Integer
77
+
78
+ attribute :last_maintain_time, Types::Integer
79
+ attribute :last_maintain_work_sorties, Types::Integer
80
+ end
81
+ end
82
+
83
+ attribute? :media_file_detail do
84
+ attribute :remain_upload, Types::Integer
85
+ end
86
+
87
+ attribute? :network_state do
88
+ attribute :type, Types::Integer
89
+ attribute :quality, Types::Integer
90
+ attribute :rate, Types::JSON::Decimal
91
+ end
92
+
93
+ attribute? :sdr do
94
+ attribute :down_quality, Types::Integer
95
+ attribute :frequency_band, Types::JSON::Decimal
96
+ attribute :up_quality, Types::Integer
97
+ end
98
+
99
+ attribute? :wireless_link do
100
+ attribute :_4g_freq_band, Types::JSON::Decimal
101
+ attribute :_4g_gnd_quality, Types::Integer
102
+ attribute :_4g_link_state, Types::Integer
103
+ attribute :_4g_quality, Types::Integer
104
+ attribute :_4g_uav_quality, Types::Integer
105
+ attribute :dongle_number, Types::Integer
106
+ attribute :link_workmode, Types::Integer
107
+ attribute :sdr_freq_band, Types::JSON::Decimal
108
+ attribute :sdr_link_state, Types::Integer
109
+ attribute :sdr_quality, Types::Integer
110
+ end
111
+
112
+ attribute? :working_current, Types::Integer
113
+ attribute? :working_voltage, Types::Integer
114
+
115
+ # Weather
116
+
117
+ attribute? :height, Types::JSON::Decimal
118
+ attribute? :humidity, Types::Integer
119
+ attribute? :rainfall, Types::JSON::Decimal
120
+ attribute? :temperature, Types::Temperature
121
+ attribute? :wind_speed, Types::JSON::Decimal
122
+ attribute? :environment_temperature, Types::Temperature
123
+
124
+ attribute? :alternate_land_point do
125
+ attribute :latitude, Types::Latitude
126
+ attribute :longitude, Types::Longitude
127
+ attribute :height, Types::JSON::Decimal
128
+ attribute :safe_land_height, Types::JSON::Decimal
129
+ attribute :is_configured, Types::Integer.enum(0, 1)
130
+ end
131
+
132
+ attribute? :first_power_on, Types::Integer
133
+
134
+ attribute? :position_state do
135
+ # {"0":"Not calibrated","1":"Calibrated"}
136
+ attribute :is_calibration, Types::Integer.enum(0, 1)
137
+
138
+ # {"0":"Not start","1":"fixing","2":"fix successfully","3":"fix failed"}
139
+ attribute :is_fixed, Types::Integer.enum(0, 1, 2, 3)
140
+
141
+ attribute :quality, Types::Integer.constrained(gteq: 0, lteq: 5)
142
+ attribute :gps_number, Types::Integer
143
+ attribute :rtk_number, Types::Integer
144
+ end
145
+
146
+ attribute? :storage do
147
+ attribute :total, Types::Integer
148
+ attribute :used, Types::Integer
149
+ end
150
+
151
+ # {"0":"Idle","1":"On-site debugging","2":"Remote debugging","3":"Firmware upgrading","4":"Working"}
152
+ attribute? :mode_code, Types::Integer.enum(0, 1, 2, 3, 4)
153
+
154
+ attribute? :air_conditioner do
155
+ # {"0":"Idle mode (No cooling, heating, and dehumidification)","1":"Cooling mode","2":"Heating mode","3":"Dehumidification mode","4":"Cooling exit mode","5":"Heating exit mode","6":"Dehumidification exit mode","7":"Cooling preparation mode","8":"Heating preparation mode","9":"Dehumidification preparation mode"}
156
+ attribute :air_conditioner_state, Types::Integer.enum(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
157
+ attribute :switch_time, Types::Integer
158
+ end
159
+
160
+ # {"0":"Closed","1":"Opened"}
161
+ attribute? :alarm_state, Types::Integer.enum(0, 1)
162
+
163
+ # {"1":"Planned storage strategy of battery","2":"Emergency storage strategy of battery"}
164
+ attribute? :battery_store_mode, Types::Integer.enum(1, 2)
165
+
166
+ # {"0":"Closed","1":"Opened","2":"Half-open","3":"Cover state is abnormal"}
167
+ attribute? :cover_state, Types::Integer.enum(0, 1, 2, 3)
168
+
169
+ # {"0":"Closed","1":"Opened"}
170
+ attribute? :emergency_stop_state, Types::Integer.enum(0, 1)
171
+
172
+ # {"0":"Closed","1":"Opened","2":"Half-open","3":"Putter state is abnormal"}
173
+ attribute? :putter_state, Types::Integer.enum(0, 1, 2, 3)
174
+
175
+ # {"0":"Closed","1":"Opened"}
176
+ attribute? :supplement_light_state, Types::Integer.enum(0, 1)
177
+
178
+ attribute? :sub_device do
179
+ attribute? :device_sn, Types::String
180
+ attribute? :device_model_key, Types::String
181
+
182
+ # {"0":"Offline","1":"Online"}
183
+ attribute :device_online_status, Types::Integer.enum(0, 1)
184
+
185
+ # {"0":"Not paired","1":"Paired"}
186
+ attribute :device_paired, Types::Integer.enum(0, 1)
187
+ end
188
+
189
+ def drone_in_dock?
190
+ drone_in_dock == 1
191
+ end
192
+
193
+ def environment_temperature?
194
+ environment_temperature && !Types::InvalidTemperature.valid?(environment_temperature)
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -3,19 +3,42 @@
3
3
  module DjiMqttConnect
4
4
  module Thing::Product
5
5
  class DroneOsdMessage < OsdMessage
6
+ STABLE_DATA_ATTRIBUTES = %i[
7
+ mode_code
8
+ gear
9
+ horizontal_speed
10
+ vertical_speed
11
+ latitude
12
+ longitude
13
+ height
14
+ elevation
15
+ attitude_head
16
+ attitude_pitch
17
+ attitude_roll
18
+ home_distance
19
+ wind_direction
20
+ wind_speed
21
+ ]
22
+
6
23
  attribute :data do
24
+ include Mixins::LatitudeConditional
25
+ include Mixins::LongitudeConditional
26
+
7
27
  attribute :attitude_head, Types::JSON::Decimal
8
28
  attribute :attitude_pitch, Types::JSON::Decimal
9
29
  attribute :attitude_roll, Types::JSON::Decimal
10
30
  attribute :battery do
11
31
  attribute :batteries, Types::Array do
32
+ include Mixins::TemperatureConditional
33
+
12
34
  attribute :capacity_percent, Types::Integer
13
35
  attribute :firmware_version, Types::String
36
+ attribute? :high_voltage_storage_days, Types::Integer
14
37
  attribute :index, Types::Integer
15
38
  attribute :loop_times, Types::Integer
16
39
  attribute :sn, Types::String
17
40
  attribute :sub_type, Types::DeviceSubType
18
- attribute :temperature, Types::JSON::Decimal
41
+ attribute :temperature, Types::Temperature
19
42
  attribute :type, Types::DeviceType
20
43
  attribute :voltage, Types::Integer
21
44
  end
@@ -24,15 +47,21 @@ module DjiMqttConnect
24
47
  attribute :remain_flight_time, Types::Integer
25
48
  attribute :return_home_power, Types::Integer
26
49
  end
27
- attribute :distance_limit_status do
50
+ attribute? :distance_limit_status do
28
51
  attribute :distance_limit, Types::Integer
29
- attribute :state, Types::Integer
52
+
53
+ # {"0":"Not reached","1":"Reached"}
54
+ attribute? :is_near_distance_limit, Types::Integer.enum(0, 1)
55
+
56
+ # {"0":"Not set","1":"Have been set"}
57
+ attribute :state, Types::Integer.enum(0, 1)
30
58
  end
31
59
  attribute :elevation, Types::JSON::Decimal
60
+
32
61
  attribute :firmware_version, Types::String
33
62
  attribute :gear, Types::Integer
34
63
  attribute :height, Types::JSON::Decimal
35
- attribute :height_limit, Types::JSON::Decimal
64
+ attribute? :height_limit, Types::JSON::Decimal
36
65
  attribute :home_distance, Types::JSON::Decimal
37
66
  attribute :horizontal_speed, Types::JSON::Decimal
38
67
  attribute :latitude, Types::Latitude
@@ -44,24 +73,99 @@ module DjiMqttConnect
44
73
  attribute :quality, Types::Integer
45
74
  attribute :rtk_number, Types::Integer
46
75
  end
47
- attribute :storage do
76
+ attribute? :storage do
48
77
  attribute :total, Types::Integer
49
78
  attribute :used, Types::Integer
50
79
  end
51
80
  attribute :total_flight_distance, Types::JSON::Decimal
52
81
  attribute :total_flight_time, Types::JSON::Decimal
53
- attribute :track_id, Types::String
82
+ attribute? :track_id, Types::String
54
83
  attribute :vertical_speed, Types::JSON::Decimal
55
84
  attribute :wind_direction, Types::JSON::Decimal
56
85
  attribute :wind_speed, Types::JSON::Decimal
57
86
 
58
- def latitude?
59
- !Types::NullInteger.valid?(latitude)
87
+ # M30 Fields
88
+
89
+ attribute? :cameras, Types::Array do
90
+ # {"0":"Photo taking","1":"Recording"}
91
+ attribute :camera_mode, Types::Integer.enum(0, 1)
92
+
93
+ # {"min":2,"max":20}
94
+ attribute :ir_zoom_factor, Types::JSON::Decimal
95
+
96
+ attribute :liveview_world_region do
97
+ attribute :bottom, Types::JSON::Decimal.constrained(gteq: 0, lteq: 1)
98
+ attribute :left, Types::JSON::Decimal.constrained(gteq: 0, lteq: 1)
99
+ attribute :right, Types::JSON::Decimal.constrained(gteq: 0, lteq: 1)
100
+ attribute :top, Types::JSON::Decimal.constrained(gteq: 0, lteq: 1)
101
+ end
102
+
103
+ attribute :payload_index, Types::String
104
+
105
+ # {"0":"Idle","1":"Taking photo"}
106
+ attribute :photo_state, Types::Integer.enum(0, 1)
107
+
108
+ # {"0":"Idle","1":"Recording"}
109
+ attribute :recording_state, Types::Integer.enum(0, 1)
110
+
111
+ # {"unit":"s"}
112
+ attribute :record_time, Types::Integer
113
+
114
+ attribute :remain_photo_num, Types::Integer
115
+
116
+ # {"unit":"s"}
117
+ attribute :remain_record_duration, Types::Integer
118
+
119
+ # {"min":2,"max":200}
120
+ attribute :zoom_factor, Types::JSON::Decimal
60
121
  end
61
122
 
62
- def longitude?
63
- !Types::NullInteger.valid?(longitude)
123
+ # {"0":"Continue to execute the wayline task","1":"Exit the wayline task, and execute the remote controller out of control action."}
124
+ attribute? :exit_wayline_when_rc_lost, Types::Integer.enum(0, 1)
125
+
126
+ attribute? :is_near_area_limit, Types::Integer.enum(0, 1)
127
+
128
+ # {"0":"Not reached","1":"Reached"}
129
+ attribute? :is_near_height_limit, Types::Integer.enum(0, 1)
130
+
131
+ attribute? :maintain_status do
132
+ attribute :maintain_status_array, Types::Array do
133
+ attribute :last_maintain_flight_sorties, Types::Integer
134
+
135
+ # {"unit":"hour"}
136
+ attribute :last_maintain_flight_time, Types::Integer
137
+
138
+ attribute :last_maintain_time, Types::Integer
139
+
140
+ # {"0":"No maintenance","1":"Drone basic maintenance","2":"Drone routine maintenance","3":"Drone deep maintenance","17":"Dock maintenance"}
141
+ attribute :last_maintain_type, Types::Integer.enum(0, 1, 2, 3, 17)
142
+
143
+ # {"0":"No maintenance","1":"Under maintenance"}
144
+ attribute :state, Types::Integer.enum(0, 1)
145
+ end
64
146
  end
147
+
148
+ # {"0":"Off","1":"On"}
149
+ attribute? :night_lights_state, Types::Integer.enum(0, 1)
150
+
151
+ attribute? :obstacle_avoidance do
152
+ # {"0":"Close","1":"Open"}
153
+ attribute :horizon, Types::Integer.enum(0, 1)
154
+
155
+ # {"0":"Close","1":"Open"}
156
+ attribute :upside, Types::Integer.enum(0, 1)
157
+
158
+ # {"0":"Close","1":"Open"}
159
+ attribute :downside, Types::Integer.enum(0, 1)
160
+ end
161
+
162
+ # {"0":"Hovering","1":"Landing","2":"Returning to home"}
163
+ attribute? :rc_lost_action, Types::Integer.enum(0, 1, 2)
164
+
165
+ # {"unit":"m","min":20,"max":500}
166
+ attribute? :rth_altitude, Types::Integer
167
+
168
+ attribute? :total_flight_sorties, Types::Integer
65
169
  end
66
170
  end
67
171
  end
@@ -4,6 +4,9 @@ module DjiMqttConnect
4
4
  module Thing::Product
5
5
  class RemoteOsdMessage < OsdMessage
6
6
  attribute :data do
7
+ include Mixins::LatitudeConditional
8
+ include Mixins::LongitudeConditional
9
+
7
10
  attribute :capacity_percent, Types::Integer
8
11
  attribute :latitude, Types::Latitude
9
12
  attribute :live_status do
@@ -14,7 +17,7 @@ module DjiMqttConnect
14
17
  end
15
18
  attribute :longitude, Types::Longitude
16
19
  attribute :transmission_signal_quality, Types::Integer
17
- attribute :wireless_link do
20
+ attribute? :wireless_link do
18
21
  attribute :_4g_freq_band, Types::JSON::Decimal
19
22
  attribute :_4g_gnd_quality, Types::Integer
20
23
  attribute :_4g_link_state, Types::Integer
@@ -31,14 +34,6 @@ module DjiMqttConnect
31
34
  attribute :frequency_band, Types::Integer
32
35
  attribute :upward_quality, Types::Integer
33
36
  end
34
-
35
- def latitude?
36
- !Types::NullInteger.valid?(latitude)
37
- end
38
-
39
- def longitude?
40
- !Types::NullInteger.valid?(longitude)
41
- end
42
37
  end
43
38
  end
44
39
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ # https://developer.dji.com/doc/cloud-api-tutorial/en/server-api-reference/mqtt/thing-model/gateway/dock/file.html#obtain-upload-temporary-credentials
6
+ class StorageConfigGetRequestsMessage < RequestsMessage
7
+ attribute :_method, Types::String.enum("storage_config_get")
8
+
9
+ attribute :data do
10
+ attribute :module, Types::Integer.enum(0)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ # https://developer.dji.com/doc/cloud-api-tutorial/en/server-api-reference/mqtt/thing-model/gateway/dock/file.html#obtain-upload-temporary-credentials
6
+ class StorageConfigGetRequestsReplyMessage < Message
7
+ def self.build_for(storage_config_get_message, output:, result: 0)
8
+ new(
9
+ _method: storage_config_get_message._method,
10
+ tid: storage_config_get_message.tid,
11
+ bid: storage_config_get_message.bid,
12
+ timestamp: Time.now.strftime("%s%L").to_i,
13
+ data: {
14
+ result: result,
15
+ output: output
16
+ }
17
+ )
18
+ end
19
+
20
+ attribute :tid, Types::UUID
21
+ attribute :bid, Types::UUID
22
+ attribute :timestamp, Types::Timestamp
23
+
24
+ attribute :_method, Types::String.enum("storage_config_get")
25
+
26
+ attribute :data do
27
+ attribute :result, Types::Integer
28
+ attribute :output do
29
+ attribute :bucket, Types::String
30
+ attribute :credentials do
31
+ attribute :access_key_id, Types::String
32
+ attribute :access_key_secret, Types::String
33
+ attribute :expire, Types::Integer
34
+ attribute :security_token, Types::String
35
+ end
36
+ attribute :endpoint, Types::String
37
+ attribute :provider, Types::String
38
+ attribute :region, Types::String
39
+ attribute :object_key_prefix, Types::String
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Mixins
5
+ # Provides a conditional that returns false for nil for invalid latitude values
6
+ module LatitudeConditional
7
+ def latitude?
8
+ latitude && !Types::NullInteger.valid?(latitude)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Mixins
5
+ # Provides a conditional that returns false for nil for invalid longitude values
6
+ module LongitudeConditional
7
+ def longitude?
8
+ longitude && !Types::NullInteger.valid?(longitude)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Mixins
5
+ # Provides a conditional that returns false for nil or excessive values (invalid data)
6
+ module TemperatureConditional
7
+ def temperature?
8
+ temperature && !Types::InvalidTemperature.valid?(temperature)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -16,7 +16,14 @@ module DjiMqttConnect
16
16
  message = status_marshal.load(raw_message)
17
17
 
18
18
  logger.info("Received #{message} from #{device_identifier}")
19
- broadcast(message._method.to_sym, device_identifier, message)
19
+
20
+ if message.instance_of?(StatusMessage)
21
+ # Broadcast an unsupported message event
22
+ broadcast(:unsupported_message, topic, raw_message)
23
+ else
24
+ # Build event name and broadcast (i.e. ::UpdateTopoStatusMessage => update_topo)
25
+ broadcast(message._method.to_sym, device_identifier, message)
26
+ end
20
27
  rescue ParseError => error
21
28
  broadcast(:parse_error, error, topic, raw_message)
22
29
  end
@@ -17,9 +17,14 @@ module DjiMqttConnect
17
17
 
18
18
  logger.info("Received #{message} from #{device_identifier}")
19
19
 
20
- # Build event name and broadcast (i.e. ::RemoteOsdMessage => remote_osd_update)
21
- event_name = message.class.name.demodulize.sub(/Message\z/, "Update").underscore.to_sym
22
- broadcast(event_name, device_identifier, message)
20
+ if message.instance_of?(OsdMessage)
21
+ # Broadcast an unsupported message event
22
+ broadcast(:unsupported_message, topic, raw_message)
23
+ else
24
+ # Build event name and broadcast (i.e. ::RemoteOsdMessage => remote_osd_update)
25
+ event_name = message.class.name.demodulize.sub(/Message\z/, "Update").underscore.to_sym
26
+ broadcast(event_name, device_identifier, message)
27
+ end
23
28
  rescue ParseError => error
24
29
  broadcast(:parse_error, error, topic, raw_message)
25
30
  end
@@ -16,7 +16,14 @@ module DjiMqttConnect
16
16
  message = requests_marshal.load(raw_message)
17
17
 
18
18
  logger.info("Received #{message} from #{gateway_sn}")
19
- broadcast(message._method.to_sym, gateway_sn, message)
19
+
20
+ if message.instance_of?(RequestsMessage)
21
+ # Broadcast an unsupported message event
22
+ broadcast(:unsupported_message, topic, raw_message)
23
+ else
24
+ # Build event name and broadcast (i.e. ::ConfigRequestsMessage => config)
25
+ broadcast(message._method.to_sym, gateway_sn, message)
26
+ end
20
27
  rescue ParseError => error
21
28
  broadcast(:parse_error, error, topic, raw_message)
22
29
  end
@@ -24,5 +24,8 @@ module DjiMqttConnect
24
24
  DeviceDomain = Types::Coercible::Integer # dock returns this value as string
25
25
  DeviceType = Types::Integer
26
26
  DeviceSubType = Types::Integer
27
+
28
+ InvalidTemperature = Types::Integer.constrained(gteq: 1300) # maximum temp of k-type thermocouple, errors are usually 30K+
29
+ Temperature = InvalidTemperature | Types::JSON::Decimal
27
30
  end
28
31
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+
5
+ module DjiMqttConnect
6
+ module Utils
7
+ # Sanitizes MQTT messages to remove any personally-identifiable information
8
+ class MessageSanitizer
9
+ DEFAULT_LATITUDE = "-33.865143"
10
+ DEFAULT_LONGITUDE = "151.209900"
11
+
12
+ SECRET_KEYS = %w[app_id app_key app_license callsign device_secret nonce]
13
+
14
+ SERIAL_NUMBER_KEYS = %w[device_sn gateway sn]
15
+
16
+ TOPIC_REGEX = /\A.+\/.+\/(.+)\/.+/
17
+
18
+ def initialize(latitude: DEFAULT_LATITUDE, longitude: DEFAULT_LONGITUDE, secret_keys: SECRET_KEYS, serial_number_keys: SERIAL_NUMBER_KEYS, serial_number_aliases: {})
19
+ @latitude = latitude
20
+ @longitude = longitude
21
+
22
+ @secret_keys = secret_keys
23
+ @serial_number_keys = serial_number_keys
24
+
25
+ serial_aliases = serial_number_aliases.stringify_keys
26
+ @serial_number_generator = Hash.new do |h, k|
27
+ return "" if k.length == 0
28
+ h[k] = serial_aliases.fetch(k) { sprintf("%s%02d", "SERIAL", h.length + 1) }
29
+ end
30
+ serial_aliases.keys.each { |k| serial_number_generator[k] }
31
+ end
32
+
33
+ def sanitize_topic(topic)
34
+ topic.sub(TOPIC_REGEX) { |topic_match| topic_match.sub($1, serial_number_generator[$1]) }
35
+ end
36
+
37
+ def sanitize_message(message)
38
+ sanitized_message = sanitize_object(message)
39
+ strip_serial_numbers(sanitized_message)
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :latitude, :longitude
45
+ attr_reader :secret_keys, :serial_number_keys, :serial_number_generator
46
+
47
+ def sanitize_object(object)
48
+ case object
49
+ when Hash
50
+ serial_number_keys.each do |key|
51
+ if object.key?(key) && object[key].length > 0
52
+ object[key] = serial_number_generator[object[key]]
53
+ end
54
+ end
55
+ secret_keys.each do |key|
56
+ object[key] = key.upcase if object.key?(key)
57
+ end
58
+ if object.key?("latitude")
59
+ obj_latitude = object["latitude"]
60
+ object["latitude"] = (obj_latitude.is_a?(Integer) && obj_latitude.zero?) ? 0 : latitude
61
+ end
62
+ if object.key?("longitude")
63
+ obj_longitude = object["longitude"]
64
+ object["longitude"] = (obj_longitude.is_a?(Integer) && obj_longitude.zero?) ? 0 : longitude
65
+ end
66
+
67
+ object.transform_values { |v| sanitize_object(v) }
68
+ when Array
69
+ object.map { |v| sanitize_object(v) }
70
+ else
71
+ object
72
+ end
73
+ end
74
+
75
+ # Strips known serial numbers from an object
76
+ def strip_serial_numbers(object)
77
+ case object
78
+ when Hash
79
+ object.transform_values { |v| strip_serial_numbers(v) }
80
+ when Array
81
+ object.map { |v| strip_serial_numbers(v) }
82
+ when String
83
+ object.split("-").map { |s| serial_number_generator.fetch(s, s) }.join("-")
84
+ else
85
+ object
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
4
+
5
+ module DjiMqttConnect
6
+ module Utils
7
+ # Generates a simple message schema from a mqtt message
8
+ #
9
+ # Schema is simply the class name of any element that is not a Hash or Array
10
+ class MessageSchemaGenerator
11
+ def initialize(retain_attributes: [])
12
+ @retain_attributes = Array.wrap(retain_attributes)
13
+ end
14
+
15
+ def generate(message)
16
+ case message
17
+ when Hash
18
+ retain_values = retain_attributes.each_with_object({}) do |attribute, hash|
19
+ next unless message.key?(attribute)
20
+
21
+ attribute_value = message[attribute]
22
+ next if attribute_value.is_a?(Hash) || attribute_value.is_a?(Array)
23
+
24
+ hash[attribute] = "#{attribute_value.class.name}:#{attribute_value}"
25
+ end
26
+ message.transform_values { |v| generate(v) }.merge(retain_values)
27
+ when Array
28
+ message.map { |v| generate(v) }
29
+ else
30
+ message.class.name
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :retain_attributes
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module DjiMqttConnect
6
+ module Utils
7
+ # Generates anonymised fixture data from MQTTX JSON Export Dumps
8
+ class MqttxFixtureDataGenerator
9
+ def self.from_file(file_path, **sanitizer_args)
10
+ raw_data = File.read(file_path)
11
+ new JSON.parse(raw_data), message_sanitizer: MessageSanitizer.new(**sanitizer_args)
12
+ end
13
+
14
+ def initialize(mqttx_data, message_sanitizer:)
15
+ @mqttx_data = mqttx_data
16
+ @message_sanitizer = message_sanitizer
17
+ end
18
+
19
+ # Generates fixture data using ALL found messages in the MQTTX export
20
+ #
21
+ # # Output is:
22
+ # <topic 1>: <message 1 as json>
23
+ # <topic 1>: <message 2 as json>
24
+ def generate
25
+ extracted_messages.each_with_object(StringIO.new) do |(topic, message), builder|
26
+ builder.puts [topic, message.to_json].join(": ")
27
+ end.string
28
+ end
29
+
30
+ # Generates fixture data using unique found messages in the MQTTX export
31
+ #
32
+ # A message is considered unique if the topic and schema does not match any other messages
33
+ #
34
+ # # Output is:
35
+ # <topic 1>: <message 1 as json>
36
+ def generate_unique(**schema_generator_args)
37
+ message_schema_generator = MessageSchemaGenerator.new(**schema_generator_args)
38
+
39
+ unique_messages = extracted_messages.each_with_object({}) do |(topic, message), found|
40
+ message_schema = message_schema_generator.generate(message)
41
+ found[[topic, message_schema]] ||= [topic, message]
42
+ end.values
43
+
44
+ unique_messages.each_with_object(StringIO.new) do |(topic, message), builder|
45
+ builder.puts [topic, message.to_json].join(": ")
46
+ end.string
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :mqttx_data, :message_sanitizer
52
+
53
+ def extracted_messages
54
+ return enum_for(:extracted_messages) unless block_given?
55
+
56
+ mqttx_data.each do |client_output|
57
+ client_messages = client_output["messages"]
58
+
59
+ client_messages.each do |message|
60
+ message_topic = message_sanitizer.sanitize_topic(message.fetch("topic"))
61
+ message_payload = JSON.parse message.fetch("payload")
62
+ yield(message_topic, message_sanitizer.sanitize_message(message_payload))
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DjiMqttConnect
4
- VERSION = "0.1.1.4"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -34,15 +34,20 @@ module DjiMqttConnect
34
34
  module Product
35
35
  # Messages
36
36
  autoload :OsdMessage, "dji_mqtt_connect/messages/thing/product/osd_message"
37
+ autoload :DockOsdMessage, "dji_mqtt_connect/messages/thing/product/dock_osd_message"
37
38
  autoload :DroneOsdMessage, "dji_mqtt_connect/messages/thing/product/drone_osd_message"
38
39
  autoload :RemoteOsdMessage, "dji_mqtt_connect/messages/thing/product/remote_osd_message"
39
40
 
40
41
  autoload :AirportBindStatusRequestsMessage, "dji_mqtt_connect/messages/thing/product/airport_bind_status_requests_message"
42
+ autoload :AirportOrganizationGetRequestsMessage, "dji_mqtt_connect/messages/thing/product/airport_organization_get_requests_message"
41
43
  autoload :ConfigRequestsMessage, "dji_mqtt_connect/messages/thing/product/config_requests_message"
44
+ autoload :StorageConfigGetRequestsMessage, "dji_mqtt_connect/messages/thing/product/storage_config_get_requests_message"
42
45
  autoload :RequestsMessage, "dji_mqtt_connect/messages/thing/product/requests_message"
43
46
 
44
47
  autoload :AirportBindStatusRequestsReplyMessage, "dji_mqtt_connect/messages/thing/product/airport_bind_status_requests_reply_message"
48
+ autoload :AirportOrganizationGetRequestsReplyMessage, "dji_mqtt_connect/messages/thing/product/airport_organization_get_requests_reply_message"
45
49
  autoload :ConfigRequestsReplyMessage, "dji_mqtt_connect/messages/thing/product/config_requests_reply_message"
50
+ autoload :StorageConfigGetRequestsReplyMessage, "dji_mqtt_connect/messages/thing/product/storage_config_get_requests_reply_message"
46
51
 
47
52
  # Topics
48
53
  autoload :OsdTopicRepository, "dji_mqtt_connect/topics/thing/product/osd"
@@ -57,9 +62,19 @@ module DjiMqttConnect
57
62
  end
58
63
  end
59
64
 
65
+ # Mixinx
66
+ module Mixins
67
+ autoload :LatitudeConditional, "dji_mqtt_connect/mixins/latitude_conditional"
68
+ autoload :LongitudeConditional, "dji_mqtt_connect/mixins/longitude_conditional"
69
+ autoload :TemperatureConditional, "dji_mqtt_connect/mixins/temperature_conditional"
70
+ end
71
+
60
72
  # Utils
61
73
  module Utils
62
74
  autoload :MessageParsing, "dji_mqtt_connect/utils/message_parsing"
75
+ autoload :MessageSanitizer, "dji_mqtt_connect/utils/message_sanitizer"
76
+ autoload :MessageSchemaGenerator, "dji_mqtt_connect/utils/message_schema_generator"
77
+ autoload :MqttxFixtureDataGenerator, "dji_mqtt_connect/utils/mqttx_fixture_data_generator"
63
78
  end
64
79
 
65
80
  # Railties
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dji_mqtt_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.4
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sphere Drones
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-05 00:00:00.000000000 Z
11
+ date: 2023-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -103,6 +103,7 @@ files:
103
103
  - Gemfile.lock
104
104
  - README.md
105
105
  - Rakefile
106
+ - dji_mqtt_connect.gemspec
106
107
  - lib/dji_mqtt_connect.rb
107
108
  - lib/dji_mqtt_connect/client.rb
108
109
  - lib/dji_mqtt_connect/error.rb
@@ -119,12 +120,20 @@ files:
119
120
  - lib/dji_mqtt_connect/messages/sys/product/update_topo_status_reply_message.rb
120
121
  - lib/dji_mqtt_connect/messages/thing/product/airport_bind_status_requests_message.rb
121
122
  - lib/dji_mqtt_connect/messages/thing/product/airport_bind_status_requests_reply_message.rb
123
+ - lib/dji_mqtt_connect/messages/thing/product/airport_organization_get_requests_message.rb
124
+ - lib/dji_mqtt_connect/messages/thing/product/airport_organization_get_requests_reply_message.rb
122
125
  - lib/dji_mqtt_connect/messages/thing/product/config_requests_message.rb
123
126
  - lib/dji_mqtt_connect/messages/thing/product/config_requests_reply_message.rb
127
+ - lib/dji_mqtt_connect/messages/thing/product/dock_osd_message.rb
124
128
  - lib/dji_mqtt_connect/messages/thing/product/drone_osd_message.rb
125
129
  - lib/dji_mqtt_connect/messages/thing/product/osd_message.rb
126
130
  - lib/dji_mqtt_connect/messages/thing/product/remote_osd_message.rb
127
131
  - lib/dji_mqtt_connect/messages/thing/product/requests_message.rb
132
+ - lib/dji_mqtt_connect/messages/thing/product/storage_config_get_requests_message.rb
133
+ - lib/dji_mqtt_connect/messages/thing/product/storage_config_get_requests_reply_message.rb
134
+ - lib/dji_mqtt_connect/mixins/latitude_conditional.rb
135
+ - lib/dji_mqtt_connect/mixins/longitude_conditional.rb
136
+ - lib/dji_mqtt_connect/mixins/temperature_conditional.rb
128
137
  - lib/dji_mqtt_connect/railtie.rb
129
138
  - lib/dji_mqtt_connect/railties/message_serializer.rb
130
139
  - lib/dji_mqtt_connect/topic_repository.rb
@@ -135,6 +144,9 @@ files:
135
144
  - lib/dji_mqtt_connect/topics/thing/product/requests_reply.rb
136
145
  - lib/dji_mqtt_connect/types.rb
137
146
  - lib/dji_mqtt_connect/utils/message_parsing.rb
147
+ - lib/dji_mqtt_connect/utils/message_sanitizer.rb
148
+ - lib/dji_mqtt_connect/utils/message_schema_generator.rb
149
+ - lib/dji_mqtt_connect/utils/mqttx_fixture_data_generator.rb
138
150
  - lib/dji_mqtt_connect/version.rb
139
151
  - sig/dji_mqtt_connect.rbs
140
152
  homepage: https://github.com/sphere-drones/dji_mqtt_connect