mqttopia 0.2.1 → 0.2.6
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/.rubocop.yml +3 -1
- data/lib/mqttopia/client.rb +16 -26
- data/lib/mqttopia/serializers/live_location.rb +43 -0
- data/lib/mqttopia/subscriptions/redirect.rb +6 -3
- data/lib/mqttopia/subscriptions/services/base.rb +1 -0
- data/lib/mqttopia/subscriptions/services/live_locations.rb +44 -0
- data/lib/mqttopia/subscriptions/services/test_debug.rb +0 -1
- data/lib/mqttopia/subscriptions/services/trip_metrics.rb +0 -1
- data/lib/mqttopia/subscriptions/services/trip_points.rb +0 -1
- data/lib/mqttopia/topics/services.rb +6 -0
- data/lib/mqttopia/version.rb +1 -1
- data/lib/mqttopia.rb +8 -2
- data/mqttopia.gemspec +1 -1
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edee59e5d3689309f81800724fae4cf97af41c023bc0e74033af9dfc90986888
|
4
|
+
data.tar.gz: 114e468743d3aa4224143b3693c9ec5ec80e951610842ff5eb16aac47c3e12ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20156c35a36cf6a90272b57c2dcf6911465a6a7889256d1d9adcf9ca9ced463113a1040babf15ae377101be636e44b8cda441a643f43a8aea5e55d4164fd08fa
|
7
|
+
data.tar.gz: 7f74f05a5c489c0da9b4e5ad58d2f902d96b6208ffe697045bdb8f945c4c4fb39fad7e5fbb4909cc85d7e8d70949a1a7bfbb525a73c382ef5899712cf1b4398c
|
data/.rubocop.yml
CHANGED
data/lib/mqttopia/client.rb
CHANGED
@@ -9,7 +9,7 @@ module Mqttopia
|
|
9
9
|
class Client
|
10
10
|
@instance_mutex = Mutex.new
|
11
11
|
|
12
|
-
attr_reader :mqtt_client, :debugging, :debugging_topic
|
12
|
+
attr_reader :mqtt_client, :debugging, :debugging_topic, :client_id
|
13
13
|
|
14
14
|
def self.instance
|
15
15
|
@instance_mutex.synchronize do
|
@@ -25,19 +25,24 @@ module Mqttopia
|
|
25
25
|
port: Mqttopia.port,
|
26
26
|
ssl: Mqttopia.ssl
|
27
27
|
)
|
28
|
+
@client_id = SecureRandom.hex(3) + "-#{Mqttopia.client_id}"
|
28
29
|
@mqtt_client = MQTT::Client.new(
|
29
30
|
version: Mqttopia.version,
|
30
31
|
port: port,
|
31
32
|
username: username,
|
32
33
|
password: password,
|
33
34
|
ssl: ssl,
|
34
|
-
client_id:
|
35
|
+
client_id: @client_id,
|
35
36
|
keep_alive: Mqttopia.keep_alive,
|
36
37
|
will_topic: Mqttopia.will_topic,
|
37
38
|
will_retain: Mqttopia.will_retain,
|
38
39
|
will_payload: Mqttopia.will_payload,
|
39
40
|
will_qos: Mqttopia.will_qos,
|
40
|
-
ack_timeout: Mqttopia.ack_timeout
|
41
|
+
ack_timeout: Mqttopia.ack_timeout,
|
42
|
+
connect_timeout: Mqttopia.connect_timeout,
|
43
|
+
max_retries: Mqttopia.max_retries,
|
44
|
+
retry_interval: Mqttopia.retry_interval,
|
45
|
+
logger: Mqttopia.logger
|
41
46
|
)
|
42
47
|
@subscriptions = {}
|
43
48
|
@subscription_thread_mutex ||= Mutex.new
|
@@ -56,7 +61,7 @@ module Mqttopia
|
|
56
61
|
raise ArgumentError, "No hosts available" if host.nil?
|
57
62
|
|
58
63
|
mqtt_client.host = host
|
59
|
-
mqtt_client.connect
|
64
|
+
mqtt_client.connect(client_id)
|
60
65
|
|
61
66
|
retry_count = 0 # Reset retry count on successful connection
|
62
67
|
break # Exit the loop once connected
|
@@ -143,30 +148,13 @@ module Mqttopia
|
|
143
148
|
@subscription_thread_mutex.synchronize do
|
144
149
|
return if @subscription_thread
|
145
150
|
|
146
|
-
@subscription_thread
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
loop do
|
151
|
-
mqtt_client.get do |topic, message|
|
152
|
-
handle_subscription_message(topic, message)
|
153
|
-
end
|
154
|
-
|
155
|
-
retry_count = 0 # Reset retry count i
|
156
|
-
f successful
|
157
|
-
rescue StandardError => e
|
158
|
-
retry_count += 1
|
159
|
-
log_error("subscription_thread", e)
|
160
|
-
|
161
|
-
if retry_count >= max_retries
|
162
|
-
log_error("subscription_thread", "Terminating after #{max_retries} failed attempts")
|
163
|
-
break # Exit the loop and terminate the thread
|
164
|
-
end
|
165
|
-
|
166
|
-
sleep(2 * retry_count) # Delay before retrying
|
167
|
-
retry # Restart loop if under max retries
|
151
|
+
@subscription_thread = Thread.new do
|
152
|
+
mqtt_client.get do |topic, message|
|
153
|
+
handle_subscription_message(topic, message)
|
168
154
|
end
|
169
155
|
end
|
156
|
+
rescue StandardError => e
|
157
|
+
log_error("start_subscription_thread", e)
|
170
158
|
end
|
171
159
|
end
|
172
160
|
|
@@ -181,6 +169,8 @@ module Mqttopia
|
|
181
169
|
|
182
170
|
@subscriptions.each do |subscribed_topic, callback|
|
183
171
|
callback.call(response[:data]) if subscribed_topic.to_s == response[:event]
|
172
|
+
rescue StandardError => e
|
173
|
+
log_error("handle_subscription_message", e)
|
184
174
|
end
|
185
175
|
end
|
186
176
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mqttopia
|
4
|
+
module Serializers
|
5
|
+
module LiveLocation
|
6
|
+
module_function
|
7
|
+
|
8
|
+
KEYS = %i[tid batt loc].freeze
|
9
|
+
|
10
|
+
def serialize(body)
|
11
|
+
return unless valid_live_location?(body[:live_location])
|
12
|
+
|
13
|
+
{
|
14
|
+
trip_id: body[:trip_id],
|
15
|
+
live_location: serialize_live_location(
|
16
|
+
body.dig(:live_location, :loc)&.merge!(batt: body.dig(:live_location, :batt))
|
17
|
+
),
|
18
|
+
logged_at: body.dig(:live_location, :loc, :ts)&.to_s,
|
19
|
+
received_at: current_timestamp
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def serialize_live_location(live_location)
|
24
|
+
{
|
25
|
+
latitude: live_location[:lat],
|
26
|
+
longitude: live_location[:lon],
|
27
|
+
accuracy: live_location[:acc],
|
28
|
+
altitude: live_location[:alt],
|
29
|
+
speed: live_location[:spd],
|
30
|
+
battery: live_location[:batt]
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def valid_live_location?(live_location)
|
35
|
+
live_location.is_a?(Hash) && KEYS.all? { |key| live_location.key?(key) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def current_timestamp
|
39
|
+
DateTime.now.strftime("%Q")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "services/trip_metrics"
|
4
|
-
require_relative "services/test_debug"
|
5
|
-
require_relative "services/trip_points"
|
3
|
+
# require_relative "services/trip_metrics"
|
4
|
+
# require_relative "services/test_debug"
|
5
|
+
# require_relative "services/trip_points"
|
6
|
+
# require_relative "services/live_locations"
|
7
|
+
Dir[File.join(__dir__, "services", "*.rb")].sort.each { |file| require_relative file }
|
8
|
+
|
6
9
|
require_relative "../topics/services"
|
7
10
|
|
8
11
|
module Mqttopia
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../serializers/live_location"
|
4
|
+
require_relative "./base"
|
5
|
+
|
6
|
+
module Mqttopia
|
7
|
+
module Subscriptions
|
8
|
+
module Services
|
9
|
+
class LiveLocations < Mqttopia::Subscriptions::Services::Base
|
10
|
+
class LiveLocationsInvalidError < ArgumentError
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :trip_id, :live_location, :options, :user_id
|
14
|
+
|
15
|
+
validates :trip_id, presence: true, numericality: { only_integer: true, greater_than: 0 }
|
16
|
+
validates :live_location, presence: true
|
17
|
+
# validate :live_location_json_format
|
18
|
+
|
19
|
+
def initialize(trip_id:, live_location:, options: {})
|
20
|
+
@trip_id = trip_id
|
21
|
+
@live_location = live_location
|
22
|
+
@options = options
|
23
|
+
@user_id = options[:user_id]
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.call(topic, payload, options = {})
|
27
|
+
trip_id = payload[:tid]
|
28
|
+
options[:user_id] = topic.include?("user/") && topic.match(%r{user/[^/]+}) && extract_user_id(topic)
|
29
|
+
|
30
|
+
new(trip_id: trip_id, live_location: payload, options: options).process
|
31
|
+
end
|
32
|
+
|
33
|
+
def process
|
34
|
+
raise LiveLocationsInvalidError, errors.full_messages.to_sentence unless valid?
|
35
|
+
|
36
|
+
Mqttopia::Serializers::LiveLocation.serialize({
|
37
|
+
trip_id: trip_id,
|
38
|
+
live_location: live_location
|
39
|
+
})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -16,6 +16,12 @@ module Mqttopia
|
|
16
16
|
serializer: "Mqttopia::Serializers::TripPoint",
|
17
17
|
regex: %r{\Ailla/trips/(?<trip_id>\d+)/driver_trip_point/send(?:/user/(?<user_id>\d+))?\z}
|
18
18
|
},
|
19
|
+
live_location: {
|
20
|
+
topic_name: "illa/fleet/location/vehicle/:trip_id/user/:user_id",
|
21
|
+
service: "Mqttopia::Subscriptions::Services::LiveLocations",
|
22
|
+
serializer: "Mqttopia::Serializers::LiveLocation",
|
23
|
+
regex: %r{\Ailla/fleet/location/vehicle/(?<trip_id>\d+)(?:/user/(?<user_id>\d+))?\z}
|
24
|
+
},
|
19
25
|
test_debug: {
|
20
26
|
topic_name: "test",
|
21
27
|
service: "Mqttopia::Subscriptions::Services::TestDebug",
|
data/lib/mqttopia/version.rb
CHANGED
data/lib/mqttopia.rb
CHANGED
@@ -27,6 +27,9 @@ module Mqttopia
|
|
27
27
|
:will_payload,
|
28
28
|
:will_qos,
|
29
29
|
:ack_timeout,
|
30
|
+
:connect_timeout,
|
31
|
+
:max_retries,
|
32
|
+
:retry_interval,
|
30
33
|
:client_id,
|
31
34
|
:debugging,
|
32
35
|
:debugging_topic
|
@@ -38,8 +41,11 @@ module Mqttopia
|
|
38
41
|
@@will_retain = false
|
39
42
|
@@will_payload = nil
|
40
43
|
@@will_qos = 0
|
41
|
-
@@keep_alive =
|
42
|
-
@@ack_timeout =
|
44
|
+
@@keep_alive = 30
|
45
|
+
@@ack_timeout = 5
|
46
|
+
@@connect_timeout = 30
|
47
|
+
@@max_retries = 30
|
48
|
+
@@retry_interval = 20
|
43
49
|
@@logger = ::Logger.new($stdout)
|
44
50
|
@@logger_level = :info
|
45
51
|
@@debugging = false
|
data/mqttopia.gemspec
CHANGED
@@ -32,9 +32,9 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
# Uncomment to register a new dependency of your gem
|
34
34
|
spec.add_dependency "activemodel", ">= 4.1"
|
35
|
+
spec.add_dependency "go-mqtt", ">= 0.0.2"
|
35
36
|
spec.add_dependency "json", ">= 1.6"
|
36
37
|
spec.add_dependency "logger", ">= 1.4"
|
37
|
-
spec.add_dependency "mqtt", ">= 0.6"
|
38
38
|
spec.add_dependency "railties", ">= 4.2"
|
39
39
|
spec.add_dependency "rake", ">= 11.0"
|
40
40
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mqttopia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Illa Tech
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -25,47 +25,47 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: go-mqtt
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.0.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.0.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: json
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '1.
|
47
|
+
version: '1.6'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '1.
|
54
|
+
version: '1.6'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: logger
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '1.4'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '1.4'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: railties
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,11 +184,13 @@ files:
|
|
184
184
|
- lib/mqttopia/client.rb
|
185
185
|
- lib/mqttopia/helpers/data_extractor.rb
|
186
186
|
- lib/mqttopia/logger.rb
|
187
|
+
- lib/mqttopia/serializers/live_location.rb
|
187
188
|
- lib/mqttopia/serializers/test_debug.rb
|
188
189
|
- lib/mqttopia/serializers/trip_metric.rb
|
189
190
|
- lib/mqttopia/serializers/trip_point.rb
|
190
191
|
- lib/mqttopia/subscriptions/redirect.rb
|
191
192
|
- lib/mqttopia/subscriptions/services/base.rb
|
193
|
+
- lib/mqttopia/subscriptions/services/live_locations.rb
|
192
194
|
- lib/mqttopia/subscriptions/services/test_debug.rb
|
193
195
|
- lib/mqttopia/subscriptions/services/trip_metrics.rb
|
194
196
|
- lib/mqttopia/subscriptions/services/trip_points.rb
|