mqtt_api_client 0.1.1 → 0.2.1
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/.env.local.example +8 -0
- data/.rubocop.yml +71 -0
- data/README.md +24 -1
- data/lib/mqtt_api_client/device.rb +89 -0
- data/lib/mqtt_api_client/version.rb +1 -1
- data/lib/mqtt_api_client.rb +1 -3
- metadata +6 -5
- data/.env.example +0 -4
- data/lib/mqtt_api_client/command.rb +0 -95
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a240564b318c55966a38d19bf82e3889f42913e95d6d0b55ca4029ef3e29a38e
|
4
|
+
data.tar.gz: a1882e0fb51e34be57b2cf9ae4daa6c2d80a09eb8a6a198cf3e384442132f043
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 828d9958263be605c6c1ad5f4a10b7aeeac4508e5131ef6bb6399113786e8f8fcf6ed0bb1bda7ecf4f3cffe9757cdc5880d602f10a46b35efec610115c774e2a
|
7
|
+
data.tar.gz: 2ae4cd4206a80f4740b562bb80535584c97dbece54c064da133a5b0660a8f07605a576e62a13e5ada794b5d31a053193616c1b5c3fc7422b828f9eab1d245bd9
|
data/.env.local.example
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
+
|
12
|
+
require:
|
13
|
+
- rubocop-rake
|
14
|
+
- rubocop-rspec
|
15
|
+
|
16
|
+
AllCops:
|
17
|
+
TargetRubyVersion: 3.1
|
18
|
+
NewCops: enable
|
19
|
+
|
20
|
+
Gemspec/RequireMFA:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Layout/CommentIndentation:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Layout/LineLength:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Metrics/MethodLength:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Naming/MemoizedInstanceVariableName:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
RSpec/ExampleLength:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
RSpec/MessageSpies:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
RSpec/MultipleExpectations:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
RSpec/MultipleMemoizedHelpers:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
RSpec/ExpectInHook:
|
48
|
+
Enabled: false
|
49
|
+
|
50
|
+
Style/Documentation:
|
51
|
+
Enabled: false
|
52
|
+
|
53
|
+
Style/EmptyElse:
|
54
|
+
Exclude:
|
55
|
+
- lib/mqtt_api_client/command.rb
|
56
|
+
|
57
|
+
Style/GlobalVars:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
Style/Lambda:
|
61
|
+
Enabled: false
|
62
|
+
|
63
|
+
Style/SingleLineMethods:
|
64
|
+
Enabled: false
|
65
|
+
|
66
|
+
Style/StringLiterals:
|
67
|
+
Enabled: true
|
68
|
+
EnforcedStyle: double_quotes
|
69
|
+
|
70
|
+
Style/YodaCondition:
|
71
|
+
Enabled: false
|
data/README.md
CHANGED
@@ -17,10 +17,33 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
17
17
|
## Usage
|
18
18
|
|
19
19
|
```ruby
|
20
|
-
|
20
|
+
#
|
21
|
+
# connect to your MQTT broker (AWS IoT, Mosquitto, and so on..)
|
22
|
+
# @param [String], crt
|
23
|
+
# @param [String], key
|
24
|
+
# @param [String], host
|
25
|
+
mqtt_client = MQTT::Client.new.tap do |client|
|
26
|
+
# connection info
|
27
|
+
client.host = "my.host"
|
28
|
+
client.port = 8883
|
29
|
+
client.ssl = true
|
30
|
+
|
31
|
+
# certificates
|
32
|
+
client.cert = my_cert
|
33
|
+
client.key = my_private_key
|
34
|
+
|
35
|
+
client.connect
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# @param [MQTT::Client], mqtt_client
|
40
|
+
# @param [String], device_identifier
|
41
|
+
command = MqttApiClient::Command.new(mqtt_client, "D0045F")
|
21
42
|
|
22
43
|
command.health_status
|
23
44
|
command.file_list
|
45
|
+
|
46
|
+
command.disconnect
|
24
47
|
```
|
25
48
|
|
26
49
|
## Development
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
require "fileutils"
|
5
|
+
module MqttApiClient
|
6
|
+
class Device
|
7
|
+
TIMEOUT_SECONDS = 2
|
8
|
+
|
9
|
+
attr_reader :mqtt_client, :device_identifier, :logger
|
10
|
+
|
11
|
+
#
|
12
|
+
# @param mqtt_client [MQTT::Client]
|
13
|
+
# @param device_identifier [String]
|
14
|
+
def initialize(mqtt_client:, device_identifier:, logger: default_logger(device_identifier))
|
15
|
+
@mqtt_client = mqtt_client
|
16
|
+
@device_identifier = device_identifier
|
17
|
+
@logger = logger
|
18
|
+
|
19
|
+
logger&.info "Command logger initialized at #{Time.now}"
|
20
|
+
|
21
|
+
subscribe_to_all(
|
22
|
+
"device/#{device_identifier}/file_list",
|
23
|
+
"device/#{device_identifier}/health_status"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def file_list
|
28
|
+
mqtt_client.publish("device/#{device_identifier}/command", "file_list")
|
29
|
+
|
30
|
+
begin
|
31
|
+
process_get(
|
32
|
+
"device/#{device_identifier}/file_list",
|
33
|
+
"file_list"
|
34
|
+
)
|
35
|
+
rescue Timeout::Error => e
|
36
|
+
logger&.error "file_list timeout: #{e}"
|
37
|
+
|
38
|
+
Timeout::Error.new(e)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def health_status
|
43
|
+
mqtt_client.publish("device/#{device_identifier}/command", "health_status")
|
44
|
+
|
45
|
+
begin
|
46
|
+
process_get(
|
47
|
+
"device/#{device_identifier}/health_status",
|
48
|
+
"health_status"
|
49
|
+
)
|
50
|
+
rescue Timeout::Error => e
|
51
|
+
logger&.error "health_status timeout: #{e}"
|
52
|
+
|
53
|
+
Timeout::Error.new(e)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def disconnect
|
58
|
+
mqtt_client.disconnect
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def process_get(subscribed_topic, logger_key)
|
64
|
+
@_process_get ||= Timeout.timeout(TIMEOUT_SECONDS) do
|
65
|
+
mqtt_client.get do |topic, message|
|
66
|
+
if topic == subscribed_topic
|
67
|
+
logger&.info "#{logger_key}: #{message}"
|
68
|
+
|
69
|
+
# do any logic with a message there, if you need to
|
70
|
+
|
71
|
+
return message
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_logger(device_identifier)
|
78
|
+
FileUtils.mkdir_p("log")
|
79
|
+
|
80
|
+
Logger.new("log/device_#{device_identifier}.log", "daily")
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# @param topics [Array<String]
|
85
|
+
def subscribe_to_all(*topics)
|
86
|
+
topics.each { |topic| mqtt_client.subscribe(topic) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/mqtt_api_client.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mqtt_api_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladyslav Sumskyi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mqtt
|
@@ -31,8 +31,9 @@ executables: []
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
-
- ".env.example"
|
34
|
+
- ".env.local.example"
|
35
35
|
- ".rspec"
|
36
|
+
- ".rubocop.yml"
|
36
37
|
- CHANGELOG.md
|
37
38
|
- CODE_OF_CONDUCT.md
|
38
39
|
- LICENSE.txt
|
@@ -40,7 +41,7 @@ files:
|
|
40
41
|
- Rakefile
|
41
42
|
- bitbucket-pipelines.yml
|
42
43
|
- lib/mqtt_api_client.rb
|
43
|
-
- lib/mqtt_api_client/
|
44
|
+
- lib/mqtt_api_client/device.rb
|
44
45
|
- lib/mqtt_api_client/version.rb
|
45
46
|
homepage: https://bitbucket.org/macklabsinc/mqtt_api_client/src/master/
|
46
47
|
licenses:
|
@@ -66,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
67
|
- !ruby/object:Gem::Version
|
67
68
|
version: '0'
|
68
69
|
requirements: []
|
69
|
-
rubygems_version: 3.4.
|
70
|
+
rubygems_version: 3.4.19
|
70
71
|
signing_key:
|
71
72
|
specification_version: 4
|
72
73
|
summary: MQTT API Client
|
data/.env.example
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "logger"
|
4
|
-
|
5
|
-
module MqttApiClient
|
6
|
-
# commands implemented
|
7
|
-
class Command
|
8
|
-
attr_reader :mqtt_client, :crt, :key, :host, :logger
|
9
|
-
|
10
|
-
#
|
11
|
-
# @param [File|String], crt
|
12
|
-
# @param [File|String], key
|
13
|
-
def initialize(crt, key, host)
|
14
|
-
@crt = if File.file? crt
|
15
|
-
File.read crt
|
16
|
-
else
|
17
|
-
crt
|
18
|
-
end
|
19
|
-
@key = if File.file? key
|
20
|
-
File.read key
|
21
|
-
else
|
22
|
-
key
|
23
|
-
end
|
24
|
-
|
25
|
-
@host = host
|
26
|
-
|
27
|
-
@logger = Logger.new("log/command.log", "daily")
|
28
|
-
@logger.info "Command logger initialized at #{Time.now}"
|
29
|
-
|
30
|
-
connect
|
31
|
-
end
|
32
|
-
|
33
|
-
# rubocop:disable Style/EmptyElse
|
34
|
-
def file_list(device_identifier)
|
35
|
-
subscribed_topic = "device/#{device_identifier}/file_list"
|
36
|
-
|
37
|
-
mqtt_client.subscribe(subscribed_topic)
|
38
|
-
mqtt_client.publish("device/#{device_identifier}/command", "file_list")
|
39
|
-
|
40
|
-
mqtt_client.get do |topic, message|
|
41
|
-
mqtt_client.unsubscribe(subscribed_topic) if topic == subscribed_topic
|
42
|
-
|
43
|
-
if topic == subscribed_topic
|
44
|
-
logger.info "New file_list: #{message}"
|
45
|
-
|
46
|
-
# do some logic with a message, probably update device file_list in the DB ?
|
47
|
-
|
48
|
-
return message
|
49
|
-
else
|
50
|
-
# I don't want to raise exception here because we are
|
51
|
-
# getting messages from the whole mqtt queue, one by one,
|
52
|
-
# and the next message could be that what we need
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def health_status(device_identifier)
|
58
|
-
subscribed_topic = "device/#{device_identifier}/health_status"
|
59
|
-
mqtt_client.subscribe(subscribed_topic)
|
60
|
-
|
61
|
-
mqtt_client.publish("device/#{device_identifier}/command", "health_status")
|
62
|
-
|
63
|
-
mqtt_client.get do |topic, message|
|
64
|
-
mqtt_client.unsubscribe(subscribed_topic) if topic == subscribed_topic
|
65
|
-
|
66
|
-
if topic == subscribed_topic
|
67
|
-
logger.info "New health_status: #{message}"
|
68
|
-
|
69
|
-
# do some logic with a message, probably update device health_status in the DB ?
|
70
|
-
|
71
|
-
return message
|
72
|
-
else
|
73
|
-
# I don't want to raise exception here because we are
|
74
|
-
# getting messages from the whole mqtt queue, one by one,
|
75
|
-
# and the next message could be that what we need
|
76
|
-
end
|
77
|
-
# rubocop:enable Style/EmptyElse
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def connect
|
84
|
-
@mqtt_client = MQTT::Client.new
|
85
|
-
@mqtt_client.host = host
|
86
|
-
@mqtt_client.port = 8883
|
87
|
-
@mqtt_client.ssl = true
|
88
|
-
|
89
|
-
@mqtt_client.cert = crt
|
90
|
-
@mqtt_client.key = key
|
91
|
-
|
92
|
-
@mqtt_client.connect
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|