lex-mqtt 0.1.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 +7 -0
- data/.github/workflows/ci.yml +16 -0
- data/.gitignore +4 -0
- data/.rspec +3 -0
- data/.rubocop.yml +19 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +10 -0
- data/README.md +46 -0
- data/lex-mqtt.gemspec +32 -0
- data/lib/legion/extensions/mqtt/client.rb +26 -0
- data/lib/legion/extensions/mqtt/helpers/client.rb +23 -0
- data/lib/legion/extensions/mqtt/runners/publish.rb +20 -0
- data/lib/legion/extensions/mqtt/runners/subscribe.rb +46 -0
- data/lib/legion/extensions/mqtt/version.rb +9 -0
- data/lib/legion/extensions/mqtt.rb +19 -0
- metadata +74 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7bada2aeb4e0d02eb1325b234c0c861eeabc48e014a861f3478c9f6cfa4e6c56
|
|
4
|
+
data.tar.gz: c9aaf17ca95f9c1949c53f4c3480c81674a5a2e866f047ce33c35c2427ec473a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f432eed99b6b02868cff3f6ee36fc2a516f5e0da79a5f2c473f1a06de4b516219e9f7810095ea7c7da1f6904ceb82ed7a9c7a6343f9d1e84de91b835f3a0669b
|
|
7
|
+
data.tar.gz: a8a4a1b693a75f9ac6c7456b40c5c35474bc37506336ca715fab7dfb1cf74fe66de2da03ed4a00162a5672256e51c14341d059f801e88cda2ae83b0f55ef3c46
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [origin]
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
ci:
|
|
9
|
+
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
10
|
+
|
|
11
|
+
release:
|
|
12
|
+
needs: ci
|
|
13
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/origin'
|
|
14
|
+
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
15
|
+
secrets:
|
|
16
|
+
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-rspec
|
|
3
|
+
AllCops:
|
|
4
|
+
NewCops: enable
|
|
5
|
+
TargetRubyVersion: 3.4
|
|
6
|
+
SuggestExtensions: false
|
|
7
|
+
RSpec/ExampleLength:
|
|
8
|
+
Enabled: false
|
|
9
|
+
RSpec/MultipleExpectations:
|
|
10
|
+
Enabled: false
|
|
11
|
+
RSpec/NestedGroups:
|
|
12
|
+
Enabled: false
|
|
13
|
+
Metrics/BlockLength:
|
|
14
|
+
Exclude:
|
|
15
|
+
- spec/**/*
|
|
16
|
+
Naming/PredicateMethod:
|
|
17
|
+
Enabled: false
|
|
18
|
+
Style/Documentation:
|
|
19
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0] - 2026-03-21
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `Helpers::Client` module with `.connection` factory method wrapping `MQTT::Client`
|
|
7
|
+
- `Runners::Publish` with `publish` (topic, payload, retain, qos)
|
|
8
|
+
- `Runners::Subscribe` with `subscribe` (topic, timeout, max_messages) and `get` (single message)
|
|
9
|
+
- Standalone `Client` class including all runner modules
|
|
10
|
+
- Framework `lex_settings` declaring default host, port, and ssl settings
|
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# lex-mqtt
|
|
2
|
+
|
|
3
|
+
LegionIO extension for MQTT broker integration. Publish and subscribe to MQTT topics via the `mqtt` gem.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### Standalone Client
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require 'lex-mqtt'
|
|
11
|
+
|
|
12
|
+
client = Legion::Extensions::Mqtt::Client.new(
|
|
13
|
+
host: 'broker.example.com',
|
|
14
|
+
port: 1883,
|
|
15
|
+
username: 'user',
|
|
16
|
+
password: 'secret',
|
|
17
|
+
ssl: false
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Publish a message
|
|
21
|
+
client.publish(topic: 'sensors/temperature', payload: '22.5')
|
|
22
|
+
client.publish(topic: 'sensors/temperature', payload: '22.5', retain: true, qos: 1)
|
|
23
|
+
|
|
24
|
+
# Get a single message
|
|
25
|
+
result = client.get(topic: 'sensors/temperature')
|
|
26
|
+
# => { topic: 'sensors/temperature', payload: '22.5' }
|
|
27
|
+
|
|
28
|
+
# Subscribe and collect messages
|
|
29
|
+
result = client.subscribe(topic: 'sensors/#', timeout: 5, max_messages: 10)
|
|
30
|
+
# => { messages: [...], count: 3, topic: 'sensors/#' }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
Default `lex_settings`:
|
|
36
|
+
|
|
37
|
+
| Key | Default |
|
|
38
|
+
|-----|---------|
|
|
39
|
+
| `mqtt.host` | `'localhost'` |
|
|
40
|
+
| `mqtt.port` | `1883` |
|
|
41
|
+
| `mqtt.ssl` | `false` |
|
|
42
|
+
|
|
43
|
+
## Dependencies
|
|
44
|
+
|
|
45
|
+
- `mqtt` (~> 0.6)
|
|
46
|
+
- Ruby >= 3.4
|
data/lex-mqtt.gemspec
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/legion/extensions/mqtt/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'lex-mqtt'
|
|
7
|
+
spec.version = Legion::Extensions::Mqtt::VERSION
|
|
8
|
+
spec.authors = ['Esity']
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'LEX::Mqtt'
|
|
12
|
+
spec.description = 'Connects Legion to MQTT brokers'
|
|
13
|
+
spec.homepage = 'https://github.com/LegionIO/lex-mqtt'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = '>= 3.4'
|
|
16
|
+
|
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-mqtt'
|
|
19
|
+
spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-mqtt'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-mqtt'
|
|
21
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-mqtt/issues'
|
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
23
|
+
|
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
26
|
+
end
|
|
27
|
+
spec.bindir = 'exe'
|
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
29
|
+
spec.require_paths = ['lib']
|
|
30
|
+
|
|
31
|
+
spec.add_dependency 'mqtt', '~> 0.6'
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helpers/client'
|
|
4
|
+
require_relative 'runners/publish'
|
|
5
|
+
require_relative 'runners/subscribe'
|
|
6
|
+
|
|
7
|
+
module Legion
|
|
8
|
+
module Extensions
|
|
9
|
+
module Mqtt
|
|
10
|
+
class Client
|
|
11
|
+
include Runners::Publish
|
|
12
|
+
include Runners::Subscribe
|
|
13
|
+
|
|
14
|
+
attr_reader :opts
|
|
15
|
+
|
|
16
|
+
def initialize(host: 'localhost', port: 1883, username: nil, password: nil, ssl: false)
|
|
17
|
+
@opts = { host: host, port: port, username: username, password: password, ssl: ssl }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def settings
|
|
21
|
+
{ options: @opts }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mqtt'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Mqtt
|
|
8
|
+
module Helpers
|
|
9
|
+
module Client
|
|
10
|
+
def self.connection(**opts)
|
|
11
|
+
MQTT::Client.new(
|
|
12
|
+
host: opts[:host] || 'localhost',
|
|
13
|
+
port: opts[:port] || 1883,
|
|
14
|
+
username: opts[:username],
|
|
15
|
+
password: opts[:password],
|
|
16
|
+
ssl: opts[:ssl] || false
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Mqtt
|
|
6
|
+
module Runners
|
|
7
|
+
module Publish
|
|
8
|
+
def publish(topic:, payload:, retain: false, qos: 0, **)
|
|
9
|
+
client = Helpers::Client.connection(**@opts)
|
|
10
|
+
client.connect
|
|
11
|
+
client.publish(topic, payload, retain, qos)
|
|
12
|
+
{ published: true, topic: topic, retain: retain, qos: qos }
|
|
13
|
+
ensure
|
|
14
|
+
client&.disconnect
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Mqtt
|
|
6
|
+
module Runners
|
|
7
|
+
module Subscribe
|
|
8
|
+
def subscribe(topic:, timeout: 5, max_messages: 10, **)
|
|
9
|
+
messages = with_client(topic) { |c| collect_messages(c, timeout, max_messages) }
|
|
10
|
+
{ messages: messages, count: messages.size, topic: topic }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(topic:, **)
|
|
14
|
+
topic_name, payload = with_client(topic, &:get)
|
|
15
|
+
{ topic: topic_name, payload: payload }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def with_client(topic)
|
|
21
|
+
client = Helpers::Client.connection(**@opts)
|
|
22
|
+
client.connect
|
|
23
|
+
client.subscribe(topic)
|
|
24
|
+
yield(client)
|
|
25
|
+
ensure
|
|
26
|
+
client&.disconnect
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def collect_messages(client, timeout, max_messages)
|
|
30
|
+
messages = []
|
|
31
|
+
deadline = Time.now + timeout
|
|
32
|
+
loop do
|
|
33
|
+
break if messages.size >= max_messages || Time.now > deadline
|
|
34
|
+
|
|
35
|
+
topic_name, msg = client.get_packet&.then { |pkt| [pkt.topic, pkt.payload] }
|
|
36
|
+
messages << { topic: topic_name, payload: msg } if topic_name
|
|
37
|
+
rescue MQTT::Exception
|
|
38
|
+
break
|
|
39
|
+
end
|
|
40
|
+
messages
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/mqtt/version'
|
|
4
|
+
require 'legion/extensions/mqtt/helpers/client'
|
|
5
|
+
require 'legion/extensions/mqtt/runners/publish'
|
|
6
|
+
require 'legion/extensions/mqtt/runners/subscribe'
|
|
7
|
+
require 'legion/extensions/mqtt/client'
|
|
8
|
+
|
|
9
|
+
module Legion
|
|
10
|
+
module Extensions
|
|
11
|
+
module Mqtt
|
|
12
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
13
|
+
|
|
14
|
+
def self.lex_settings
|
|
15
|
+
{ mqtt: { host: 'localhost', port: 1883, ssl: false } }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-mqtt
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Esity
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: mqtt
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.6'
|
|
26
|
+
description: Connects Legion to MQTT brokers
|
|
27
|
+
email:
|
|
28
|
+
- matthewdiverson@gmail.com
|
|
29
|
+
executables: []
|
|
30
|
+
extensions: []
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- ".github/workflows/ci.yml"
|
|
34
|
+
- ".gitignore"
|
|
35
|
+
- ".rspec"
|
|
36
|
+
- ".rubocop.yml"
|
|
37
|
+
- CHANGELOG.md
|
|
38
|
+
- Gemfile
|
|
39
|
+
- README.md
|
|
40
|
+
- lex-mqtt.gemspec
|
|
41
|
+
- lib/legion/extensions/mqtt.rb
|
|
42
|
+
- lib/legion/extensions/mqtt/client.rb
|
|
43
|
+
- lib/legion/extensions/mqtt/helpers/client.rb
|
|
44
|
+
- lib/legion/extensions/mqtt/runners/publish.rb
|
|
45
|
+
- lib/legion/extensions/mqtt/runners/subscribe.rb
|
|
46
|
+
- lib/legion/extensions/mqtt/version.rb
|
|
47
|
+
homepage: https://github.com/LegionIO/lex-mqtt
|
|
48
|
+
licenses:
|
|
49
|
+
- MIT
|
|
50
|
+
metadata:
|
|
51
|
+
homepage_uri: https://github.com/LegionIO/lex-mqtt
|
|
52
|
+
source_code_uri: https://github.com/LegionIO/lex-mqtt
|
|
53
|
+
documentation_uri: https://github.com/LegionIO/lex-mqtt
|
|
54
|
+
changelog_uri: https://github.com/LegionIO/lex-mqtt
|
|
55
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-mqtt/issues
|
|
56
|
+
rubygems_mfa_required: 'true'
|
|
57
|
+
rdoc_options: []
|
|
58
|
+
require_paths:
|
|
59
|
+
- lib
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: '3.4'
|
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
requirements: []
|
|
71
|
+
rubygems_version: 3.6.9
|
|
72
|
+
specification_version: 4
|
|
73
|
+
summary: LEX::Mqtt
|
|
74
|
+
test_files: []
|