dji_mqtt_connect 0.1.8 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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