dji_mqtt_connect 0.1.8 → 0.1.10

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.
@@ -46,6 +46,11 @@ module DjiMqttConnect
46
46
  Thing::Product::EventsTopicRepository.new(self)
47
47
  end
48
48
 
49
+ # Handles topic thing/product/#{pid}/events_reply
50
+ def thing_product_events_reply_topic
51
+ Thing::Product::EventsReplyTopicRepository.new(self)
52
+ end
53
+
49
54
  # Handles topic thing/product/#{pid}/osd
50
55
  def thing_product_osd_topic
51
56
  Thing::Product::OsdTopicRepository.new(self)
@@ -4,6 +4,65 @@ module DjiMqttConnect
4
4
  # Factories for building example messages
5
5
  # Do not include this in your production code
6
6
  module Factories
7
+ # Events
8
+
9
+ def build_file_upload_callback_events_message
10
+ message_data = {
11
+ file: {
12
+ object_key: "object_key",
13
+ path: "xxx",
14
+ name: "dog.jpeg",
15
+ ext: {
16
+ flight_id: "xxx",
17
+ drone_model_key: "0-67-0",
18
+ payload_model_key: "0-67-0",
19
+ is_original: true
20
+ },
21
+ metadata: {
22
+ shoot_position: {
23
+ lat: 22.1,
24
+ lng: 122.5
25
+ },
26
+ gimbal_yaw_degree: -91.4,
27
+ absolute_altitude: 56.311,
28
+ relative_altitude: 41.124,
29
+ created_time: "2021-05-10 16:04:20"
30
+ }
31
+ },
32
+ result: 0
33
+ }
34
+
35
+ Thing::Product::FileUploadCallbackEventsMessage.new(
36
+ _method: "file_upload_callback",
37
+ bid: "12345678-1234-1234-1234-12345678901B",
38
+ tid: "12345678-1234-1234-1234-12345678901A",
39
+ need_reply: 1,
40
+ gateway: "xxx",
41
+ timestamp: 1654070968655,
42
+ data: message_data,
43
+ _data: message_data
44
+ )
45
+ end
46
+
47
+ def build_highest_priority_upload_flighttask_media_events_message
48
+ message_data = {
49
+ flight_id: SecureRandom.uuid
50
+ }
51
+
52
+ Thing::Product::HighestPriorityUploadFlighttaskMediaEventsMessage.new(
53
+ bid: "fe0e2218-038f-46fe-b27d-74cd257c386a",
54
+ _data: message_data,
55
+ data: message_data,
56
+ _method: "highest_priority_upload_flighttask_media",
57
+ need_reply: 1,
58
+ tid: "c6aa22c0-e9dd-4895-a25c-6c12411513df",
59
+ timestamp: 1684986146586,
60
+ gateway: "DOCK01"
61
+ )
62
+ end
63
+
64
+ # Status
65
+
7
66
  def build_device_online_update_topo_message
8
67
  message_data = {
9
68
  type: 98,
@@ -46,6 +105,8 @@ module DjiMqttConnect
46
105
  )
47
106
  end
48
107
 
108
+ # Requests
109
+
49
110
  def build_thing_product_config_requests_message
50
111
  message_data = {
51
112
  config_type: "json",
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-transformer"
4
+ require "json"
5
+
6
+ module DjiMqttConnect
7
+ module Thing::Product
8
+ class EventsReplyMarshal < MessageMarshal
9
+ # Renames the method attribute
10
+ class HashTransformer < Dry::Transformer::Pipe
11
+ import Dry::Transformer::HashTransformations
12
+
13
+ define! do
14
+ rename_keys _method: :method
15
+ end
16
+ end
17
+
18
+ # Converts a message for transmission via MQTT
19
+ def dump(message)
20
+ # Fix up the hash representation
21
+ transformed_message = hash_transformer.call(message)
22
+
23
+ # Convert the transformed message into JSON
24
+ JSON.generate(transformed_message)
25
+ end
26
+
27
+ private
28
+
29
+ def hash_transformer
30
+ @hash_transformer ||= HashTransformer.new
31
+ end
32
+ end
33
+ end
34
+ end
@@ -15,12 +15,15 @@ module DjiMqttConnect
15
15
 
16
16
  attribute :sub_devices, Types::Array do
17
17
  attribute :sn, Types::String
18
+ attribute? :domain, Types::DeviceDomain
18
19
  attribute :type, Types::DeviceType
19
20
  attribute :sub_type, Types::DeviceSubType
20
21
  attribute :index, Types::String
21
22
  attribute :device_secret, Types::String
22
23
  attribute :nonce, Types::String
23
24
  attribute? :version, Types::Integer
25
+
26
+ alias_method :serial_number, :sn
24
27
  end
25
28
  end
26
29
  end
@@ -11,6 +11,9 @@ module DjiMqttConnect
11
11
  job_number
12
12
  ]
13
13
 
14
+ # {"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"}
15
+ AirConditionerState = Types::Integer.enum(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
16
+
14
17
  attribute :data do
15
18
  include Mixins::LatitudeConditional
16
19
  include Mixins::LongitudeConditional
@@ -152,9 +155,12 @@ module DjiMqttConnect
152
155
  attribute? :mode_code, Types::Integer.enum(0, 1, 2, 3, 4)
153
156
 
154
157
  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)
158
+ attribute :air_conditioner_state, AirConditionerState | Types::Integer
157
159
  attribute :switch_time, Types::Integer
160
+
161
+ def air_conditioner_state?
162
+ AirConditionerState.valid?(air_conditioner_state)
163
+ end
158
164
  end
159
165
 
160
166
  # {"0":"Closed","1":"Opened"}
@@ -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/topic-definition.html#events-reply-struct-example
6
+ class EventsReplyMessage < Message
7
+ # a result of 0 means we approve of this action
8
+ def self.build_for(events_message, result: 0)
9
+ new(
10
+ _method: events_message._method,
11
+ tid: events_message.tid,
12
+ bid: events_message.bid,
13
+ timestamp: Time.now.strftime("%s%L").to_i,
14
+ data: {
15
+ result: result
16
+ }
17
+ )
18
+ end
19
+
20
+ attribute :bid, Types::UUID
21
+ attribute :tid, Types::UUID
22
+ attribute :timestamp, Types::Timestamp
23
+
24
+ attribute :_method, Types::String.enum(
25
+ "file_upload_callback",
26
+ "highest_priority_upload_flighttask_media"
27
+ )
28
+
29
+ attribute :data do
30
+ attribute :result, Types::Integer
31
+ end
32
+ end
33
+ end
34
+ end
@@ -51,6 +51,10 @@ module DjiMqttConnect
51
51
 
52
52
  attribute :result, Types::Integer
53
53
  end
54
+
55
+ def need_reply?
56
+ need_reply == 1
57
+ end
54
58
  end
55
59
  end
56
60
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ class HighestPriorityUploadFlighttaskMediaEventsMessage < EventsMessage
6
+ attribute :_method, Types::String.enum("highest_priority_upload_flighttask_media")
7
+
8
+ # NOTE: Not documented, but appears in examples
9
+ attribute? :need_reply, Types::Integer.enum(0, 1)
10
+
11
+ attribute :data do
12
+ attribute :flight_id, Types::String
13
+ end
14
+
15
+ def need_reply?
16
+ need_reply == 1
17
+ end
18
+ end
19
+ end
20
+ end
@@ -26,6 +26,33 @@ module DjiMqttConnect
26
26
 
27
27
  attribute :sensor_index, Types::Integer
28
28
  end
29
+
30
+ def in_the_sky?
31
+ in_the_sky == 1
32
+ end
33
+
34
+ def aircraft_message
35
+ if in_the_sky?
36
+ Translations.aircraft_in_the_sky_hms_event_code_message(
37
+ code: code,
38
+ sensor_index: args.sensor_index,
39
+ component_index: args.component_index
40
+ )
41
+ else
42
+ Translations.aircraft_hms_event_code_message(
43
+ code: code,
44
+ sensor_index: args.sensor_index,
45
+ component_index: args.component_index
46
+ )
47
+ end
48
+ end
49
+
50
+ def dock_message
51
+ Translations.dock_hms_event_code_message(
52
+ code: code,
53
+ sensor_index: args.sensor_index
54
+ )
55
+ end
29
56
  end
30
57
  end
31
58
  end
@@ -2,6 +2,9 @@
2
2
 
3
3
  module DjiMqttConnect
4
4
  class Railtie < Rails::Railtie
5
+ # Add all error code translations to I18n
6
+ DjiMqttConnect::Translations.load_translations!
7
+
5
8
  # Allow ActiveJob to serialize DjiMqttConnect::Message objects
6
9
  config.active_job.custom_serializers << Railties::MessageSerializer
7
10
 
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ module Thing::Product
5
+ class EventsReplyTopicRepository < TopicRepository
6
+ # Publishes a message to gateway_sn on the "thing/product/+/events_reply" topic.
7
+ def publish_to_device(gateway_sn, events_reply_message)
8
+ publish_to_topic(
9
+ "thing/product/#{gateway_sn}/events_reply",
10
+ events_reply_message,
11
+ marshal: EventsReplyMarshal
12
+ )
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DjiMqttConnect
4
+ # https://developer.dji.com/doc/cloud-api-tutorial/en/feature-set/dock-feature-set/hms.html
5
+ module Translations
6
+ module_function
7
+
8
+ def load_translations!
9
+ I18n.load_path += Dir[File.expand_path(File.join(__dir__, "../../config/locales/*.yml"))]
10
+ end
11
+
12
+ def aircraft_in_the_sky_hms_event_code_message(code:, sensor_index:, component_index:)
13
+ I18n.translate(
14
+ "fpv_tip_#{code}_in_the_sky",
15
+ alarmid: code,
16
+ index: sensor_index + 1,
17
+ component_index: component_index + 1,
18
+ battery_index: battery_position(sensor_index),
19
+ scope: "dji_mqtt_connect.hms_event_codes",
20
+ default: code
21
+ )
22
+ end
23
+
24
+ def aircraft_hms_event_code_message(code:, sensor_index:, component_index:)
25
+ I18n.translate(
26
+ "fpv_tip_#{code}",
27
+ alarmid: code,
28
+ index: sensor_index + 1,
29
+ component_index: component_index + 1,
30
+ battery_index: battery_position(sensor_index),
31
+ scope: "dji_mqtt_connect.hms_event_codes",
32
+ default: code
33
+ )
34
+ end
35
+
36
+ def dock_hms_event_code_message(code:, sensor_index:)
37
+ I18n.translate(
38
+ "dock_tip_#{code}",
39
+ alarmid: code,
40
+ dock_cover_index: dock_cover_position(sensor_index),
41
+ charging_rod_index: dock_charging_rod_position(sensor_index),
42
+ scope: "dji_mqtt_connect.hms_event_codes",
43
+ default: code
44
+ )
45
+ end
46
+
47
+ def position_name(position)
48
+ I18n.translate(position, scope: "dji_mqtt_connect.position", default: position)
49
+ end
50
+
51
+ # If the text contains "%battery_index" and sensor_index is 0, use "left" to replace "%battery_index", otherwise, use "right" to replace.
52
+ def battery_position(sensor_index)
53
+ case sensor_index
54
+ when 0
55
+ position_name("left")
56
+ when 1
57
+ position_name("right")
58
+ else
59
+ position_name("unknown")
60
+ end
61
+ end
62
+
63
+ # If the text contains "%dock_cover_index" and sensor_index is 0, use "left" to replace "%dock_cover_index", otherwise, use "right" to replace.
64
+ def dock_cover_position(sensor_index)
65
+ case sensor_index
66
+ when 0
67
+ position_name("left")
68
+ when 1
69
+ position_name("right")
70
+ else
71
+ position_name("unknown")
72
+ end
73
+ end
74
+
75
+ # If the text contains "%charging_rod_index", when sensor_index is 0, replace "%charging_rod_index" with "front". When sensor_index is 1, use "back" instead. When sensor_index is 2, use "left" instead. When sensor_index is 3, use "right" instead.
76
+ def dock_charging_rod_position(sensor_index)
77
+ case sensor_index
78
+ when 0
79
+ position_name("front")
80
+ when 1
81
+ position_name("back")
82
+ when 2
83
+ position_name("left")
84
+ when 3
85
+ position_name("right")
86
+ else
87
+ position_name("unknown")
88
+ end
89
+ end
90
+ end
91
+ end
@@ -21,7 +21,12 @@ module DjiMqttConnect
21
21
  Longitude = NullInteger | Types::JSON::Decimal.constrained(gteq: -180, lteq: 180)
22
22
 
23
23
  # Device Details
24
- DeviceDomain = Types::Coercible::Integer # dock returns this value as string
24
+ AIRCRAFT_DOMAIN = 0
25
+ PAYLOAD_DOMAIN = 1
26
+ REMOTE_CONTROLLER_DOMAIN = 2
27
+ DOCK_DOMAIN = 3
28
+
29
+ DeviceDomain = Types::Coercible::Integer.enum(AIRCRAFT_DOMAIN, PAYLOAD_DOMAIN, REMOTE_CONTROLLER_DOMAIN, DOCK_DOMAIN) # dock returns this value as string
25
30
  DeviceType = Types::Integer
26
31
  DeviceSubType = Types::Integer
27
32
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DjiMqttConnect
4
- VERSION = "0.1.8"
4
+ VERSION = "0.1.10"
5
5
  end
@@ -11,6 +11,7 @@ module DjiMqttConnect
11
11
  autoload :Message, "dji_mqtt_connect/message"
12
12
  autoload :MessageMarshal, "dji_mqtt_connect/message_marshal"
13
13
  autoload :TopicRepository, "dji_mqtt_connect/topic_repository"
14
+ autoload :Translations, "dji_mqtt_connect/translations"
14
15
  autoload :Types, "dji_mqtt_connect/types"
15
16
 
16
17
  module Sys
@@ -34,10 +35,13 @@ module DjiMqttConnect
34
35
  module Product
35
36
  # Messages
36
37
  autoload :FileUploadCallbackEventsMessage, "dji_mqtt_connect/messages/thing/product/file_upload_callback_events_message"
38
+ autoload :HighestPriorityUploadFlighttaskMediaEventsMessage, "dji_mqtt_connect/messages/thing/product/highest_priority_upload_flighttask_media_events_message"
37
39
  autoload :HmsEventsMessage, "dji_mqtt_connect/messages/thing/product/hms_events_message"
38
40
  autoload :StatusCodeEventsMessage, "dji_mqtt_connect/messages/thing/product/status_code_events_message"
39
41
  autoload :EventsMessage, "dji_mqtt_connect/messages/thing/product/events_message"
40
42
 
43
+ autoload :EventsReplyMessage, "dji_mqtt_connect/messages/thing/product/events_reply_message"
44
+
41
45
  autoload :OsdMessage, "dji_mqtt_connect/messages/thing/product/osd_message"
42
46
  autoload :DockOsdMessage, "dji_mqtt_connect/messages/thing/product/dock_osd_message"
43
47
  autoload :DroneOsdMessage, "dji_mqtt_connect/messages/thing/product/drone_osd_message"
@@ -58,12 +62,14 @@ module DjiMqttConnect
58
62
 
59
63
  # Topics
60
64
  autoload :EventsTopicRepository, "dji_mqtt_connect/topics/thing/product/events"
65
+ autoload :EventsReplyTopicRepository, "dji_mqtt_connect/topics/thing/product/events_reply"
61
66
  autoload :OsdTopicRepository, "dji_mqtt_connect/topics/thing/product/osd"
62
67
  autoload :RequestsTopicRepository, "dji_mqtt_connect/topics/thing/product/requests"
63
68
  autoload :RequestsReplyTopicRepository, "dji_mqtt_connect/topics/thing/product/requests_reply"
64
69
 
65
70
  # Marshals
66
71
  autoload :EventsMarshal, "dji_mqtt_connect/marshals/thing/product/events_marshal"
72
+ autoload :EventsReplyMarshal, "dji_mqtt_connect/marshals/thing/product/events_reply_marshal"
67
73
 
68
74
  autoload :OsdMarshal, "dji_mqtt_connect/marshals/thing/product/osd_marshal"
69
75
 
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.8
4
+ version: 0.1.10
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-19 00:00:00.000000000 Z
11
+ date: 2023-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -103,6 +103,8 @@ files:
103
103
  - Gemfile.lock
104
104
  - README.md
105
105
  - Rakefile
106
+ - config/locales/dji_mqtt_connect.en.yml
107
+ - config/locales/dji_mqtt_connect.zh.yml
106
108
  - dji_mqtt_connect.gemspec
107
109
  - lib/dji_mqtt_connect.rb
108
110
  - lib/dji_mqtt_connect/client.rb
@@ -111,6 +113,7 @@ files:
111
113
  - lib/dji_mqtt_connect/marshals/sys/product/status_marshal.rb
112
114
  - lib/dji_mqtt_connect/marshals/sys/product/status_reply_marshal.rb
113
115
  - lib/dji_mqtt_connect/marshals/thing/product/events_marshal.rb
116
+ - lib/dji_mqtt_connect/marshals/thing/product/events_reply_marshal.rb
114
117
  - lib/dji_mqtt_connect/marshals/thing/product/osd_marshal.rb
115
118
  - lib/dji_mqtt_connect/marshals/thing/product/requests_marshal.rb
116
119
  - lib/dji_mqtt_connect/marshals/thing/product/requests_reply_marshal.rb
@@ -130,7 +133,9 @@ files:
130
133
  - lib/dji_mqtt_connect/messages/thing/product/dock_osd_message.rb
131
134
  - lib/dji_mqtt_connect/messages/thing/product/drone_osd_message.rb
132
135
  - lib/dji_mqtt_connect/messages/thing/product/events_message.rb
136
+ - lib/dji_mqtt_connect/messages/thing/product/events_reply_message.rb
133
137
  - lib/dji_mqtt_connect/messages/thing/product/file_upload_callback_events_message.rb
138
+ - lib/dji_mqtt_connect/messages/thing/product/highest_priority_upload_flighttask_media_events_message.rb
134
139
  - lib/dji_mqtt_connect/messages/thing/product/hms_events_message.rb
135
140
  - lib/dji_mqtt_connect/messages/thing/product/osd_message.rb
136
141
  - lib/dji_mqtt_connect/messages/thing/product/remote_osd_message.rb
@@ -147,9 +152,11 @@ files:
147
152
  - lib/dji_mqtt_connect/topics/sys/product/status.rb
148
153
  - lib/dji_mqtt_connect/topics/sys/product/status_reply.rb
149
154
  - lib/dji_mqtt_connect/topics/thing/product/events.rb
155
+ - lib/dji_mqtt_connect/topics/thing/product/events_reply.rb
150
156
  - lib/dji_mqtt_connect/topics/thing/product/osd.rb
151
157
  - lib/dji_mqtt_connect/topics/thing/product/requests.rb
152
158
  - lib/dji_mqtt_connect/topics/thing/product/requests_reply.rb
159
+ - lib/dji_mqtt_connect/translations.rb
153
160
  - lib/dji_mqtt_connect/types.rb
154
161
  - lib/dji_mqtt_connect/utils/message_parsing.rb
155
162
  - lib/dji_mqtt_connect/utils/message_sanitizer.rb