m2x-mqtt 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7b40f2dd197405129dea92eee3a9524a2ef941f0
4
+ data.tar.gz: 7c0504db6e1027b964e375338a62c77d20b4c5e1
5
+ SHA512:
6
+ metadata.gz: 695edb1116ab19e40677f7b5d93ea1c69196098738013e8959f5faaa56b247aa4c71794edbd0144583968840d450448c2c79b4f6cca7e92ef724bae27d6e1940
7
+ data.tar.gz: a8066d83bd256be686471e6ae476383fb1c1e28417706fcc66e9e895b00dfd797ce3e2609340e6aaac5a7fa93850009c91baa17e88353d285e5d1c619e2fda87
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 AT&T M2X
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,135 @@
1
+ # AT&T's M2X Ruby (MQTT) Client
2
+
3
+ [AT&T’s M2X](https://m2x.att.com/) is a cloud-based fully managed data storage service for network connected machine-to-machine (M2M) devices. From trucks and turbines to vending machines and freight containers, M2X enables the devices that power your business to connect and share valuable data.
4
+
5
+ This library aims to provide a simple wrapper to interact with the [AT&T M2X API](https://m2x.att.com/developer/documentation/overview) for [Ruby](https://www.ruby-lang.org/en/) using the [MQTT protocol](http://mqtt.org/). Refer to the [Glossary of Terms](https://m2x.att.com/developer/documentation/glossary) to understand the nomenclature used throughout this documentation.
6
+
7
+
8
+ Getting Started
9
+ ==========================
10
+ 1. Signup for an [M2X Account](https://m2x.att.com/signup).
11
+ 2. Obtain your _Master Key_ from the Master Keys tab of your [Account Settings](https://m2x.att.com/account) screen.
12
+ 2. Create your first [Device](https://m2x.att.com/devices) and copy its _Device ID_.
13
+ 3. Review the [M2X API Documentation](https://m2x.att.com/developer/documentation/overview).
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ $ gem install m2x-mqtt
19
+ ```
20
+ ## Usage
21
+
22
+ In order to communicate with the M2X API, you need an instance of [M2X::MQTT](lib/m2x/mqtt.rb). You need to pass your API key in the constructor to access your data.
23
+
24
+ ```ruby
25
+ m2x = M2X::MQTT.new(<YOUR-API-KEY>)
26
+ ```
27
+
28
+ This provides an interface to your data in M2X
29
+
30
+ - [Distribution](lib/m2x/mqtt/distribution.rb)
31
+ ```ruby
32
+ distribution = m2x.distribution("<DISTRIBUTION-ID>")
33
+ ```
34
+
35
+ - [Device](lib/m2x/mqtt/device.rb)
36
+ ```ruby
37
+ device = m2x.device("<DEVICE-ID>")
38
+ ```
39
+
40
+ - [Stream](lib/m2x/mqtt/stream.rb)
41
+ ```ruby
42
+ stream = m2x.stream("<DEVICE-ID>", "<STREAM-NAME>")
43
+
44
+ stream = m2x.device("<DEVICE-ID>").stream("<STREAM-NAME>")
45
+ ```
46
+
47
+ Refer to the documentation on each class for further usage instructions.
48
+
49
+ ## Example
50
+
51
+ In order to run this example, you will need a `Device ID` and `API Key`. If you don't have any, access your M2X account, create a new [Device](https://m2x.att.com/devices), and copy the `Device ID` and `API Key` values. The following script will send your CPU load average to three different streams named `load_1m`, `load_5m` and `load_15`. Check that there's no need to create a stream in order to write values into it.
52
+
53
+ In order to execute this script, run:
54
+
55
+ ```bash
56
+ API_KEY=<YOUR-API-KEY> DEVICE=<YOUR-DEVICE-ID> ./m2x-uptime.rb
57
+ ```
58
+
59
+ ```ruby
60
+ #! /usr/bin/env ruby
61
+
62
+ #
63
+ # https://github.com/attm2x/m2x-ruby-mqtt#example
64
+ # for instructions
65
+ #
66
+
67
+ require "time"
68
+ require "m2x/mqtt"
69
+
70
+ API_KEY = ENV.fetch("API_KEY")
71
+ DEVICE = ENV.fetch("DEVICE")
72
+
73
+ puts "M2X::MQTT/#{M2X::MQTT::VERSION} example"
74
+
75
+ @run = true
76
+
77
+ stop = Proc.new { @run = false }
78
+
79
+ trap(:INT, &stop)
80
+ trap(:TERM, &stop)
81
+
82
+ # Match `uptime` load averages output for both Linux and OSX
83
+ UPTIME_RE = /(\d+\.\d+),? (\d+\.\d+),? (\d+\.\d+)$/
84
+
85
+ def load_avg
86
+ `uptime`.match(UPTIME_RE).captures
87
+ end
88
+
89
+ m2x = M2X::MQTT.new(API_KEY)
90
+
91
+ # Get the device
92
+ device = m2x.device(DEVICE)
93
+
94
+ # Create the streams if they don't exist
95
+ device.stream("load_1m").update!
96
+ device.stream("load_5m").update!
97
+ device.stream("load_15m").update!
98
+
99
+ while @run
100
+ load_1m, load_5m, load_15m = load_avg
101
+
102
+ # Write the different values into AT&T M2X
103
+ now = Time.now.iso8601
104
+
105
+ values = {
106
+ load_1m: [ { value: load_1m, timestamp: now } ],
107
+ load_5m: [ { value: load_5m, timestamp: now } ],
108
+ load_15m: [ { value: load_15m, timestamp: now } ]
109
+ }
110
+
111
+ res = device.post_updates(values: values)
112
+
113
+ sleep 1
114
+ end
115
+
116
+ puts
117
+ ```
118
+
119
+ You can find this script in [`examples/m2x-uptime.rb`](examples/m2x-uptime.rb).
120
+
121
+ ## Versioning
122
+
123
+ This gem aims to adhere to [Semantic Versioning 2.0.0](http://semver.org/). As a summary, given a version number `MAJOR.MINOR.PATCH`:
124
+
125
+ 1. `MAJOR` will increment when backwards-incompatible changes are introduced to the client.
126
+ 2. `MINOR` will increment when backwards-compatible functionality is added.
127
+ 3. `PATCH` will increment with backwards-compatible bug fixes.
128
+
129
+ Additional labels for pre-release and build metadata are available as extensions to the `MAJOR.MINOR.PATCH` format.
130
+
131
+ **Note**: the client version does not necessarily reflect the version used in the AT&T M2X API.
132
+
133
+ ## License
134
+
135
+ This gem is provided under the MIT license. See [LICENSE](LICENSE) for applicable terms.
@@ -0,0 +1,47 @@
1
+ module M2X
2
+ class MQTT
3
+ require_relative "mqtt/version"
4
+ require_relative "mqtt/client"
5
+ require_relative "mqtt/resource"
6
+ require_relative "mqtt/device"
7
+ require_relative "mqtt/distribution"
8
+ require_relative "mqtt/stream"
9
+
10
+ attr_accessor :client
11
+
12
+ def initialize(api_key, options={})
13
+ @api_key = api_key
14
+ @options = options
15
+ end
16
+
17
+ def client
18
+ @client ||= M2X::MQTT::Client.new(@api_key, @options)
19
+ end
20
+
21
+ # Returns the status of the M2X system.
22
+ #
23
+ # The response to this endpoint is an object in which each of its attributes
24
+ # represents an M2X subsystem and its current status.
25
+ def status
26
+ client.subscribe
27
+ client.get("/status")
28
+ client.get_response
29
+ end
30
+
31
+ def device(id)
32
+ M2X::MQTT::Device.new(client, "id" => id)
33
+ end
34
+
35
+ def create_device(attributes)
36
+ M2X::MQTT::Device.create!(client, attributes)
37
+ end
38
+
39
+ def distribution(id)
40
+ M2X::MQTT::Distribution.new(client, "id" => id)
41
+ end
42
+
43
+ def stream(device_id, name)
44
+ M2X::MQTT::Stream.new(client, device(device_id), "name" => name)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,117 @@
1
+ require "mqtt"
2
+ require "json"
3
+ require "securerandom"
4
+
5
+ class M2X::MQTT::Client
6
+ DEFAULT_API_URL = "api-m2x.att.com".freeze
7
+ API_VERSION = "v2"
8
+
9
+ USER_AGENT = "M2X-Ruby/#{M2X::MQTT::VERSION} #{RUBY_ENGINE}/#{RUBY_VERSION} (#{RUBY_PLATFORM})".freeze
10
+
11
+ DEFAULTS = {
12
+ api_url: DEFAULT_API_URL,
13
+ use_ssl: false
14
+ }
15
+
16
+ def initialize(api_key, options={})
17
+ @api_key = api_key
18
+ @options = DEFAULTS.merge(options)
19
+ end
20
+
21
+ # Public: Subscribe the client to the responses topic.
22
+ #
23
+ # This is required in order to receive responses from the
24
+ # M2X API server. Note that #get_response already subscribes
25
+ # the client.
26
+ def subscribe
27
+ mqtt_client.subscribe(response_topic)
28
+ end
29
+
30
+ # Public: Send a payload to the M2X API server.
31
+ #
32
+ # payload - a Hash with the following keys:
33
+ # :id
34
+ # :method
35
+ # :resource
36
+ # :body
37
+ # See https://m2x.att.com/developer/documentation/v2/mqtt
38
+ def publish(payload)
39
+ mqtt_client.publish(request_topic, payload.to_json)
40
+ end
41
+
42
+ # Public: Retrieve a response from the M2X Server.
43
+ #
44
+ # Returns a Hash with the response from the MQTT Server in M2X.
45
+ # Optionally receives a block which will iterate through responses
46
+ # and yield each one.
47
+ def get_response
48
+ return JSON.parse(mqtt_client.get_packet(response_topic).payload) unless block_given?
49
+
50
+ mqtt_client.get_packet(response_topic) do |packet|
51
+ yield JSON.parse(packet.payload)
52
+ end
53
+ end
54
+
55
+ [:get, :post, :put, :delete, :head, :options, :patch].each do |verb|
56
+ define_method verb do |path, params=nil|
57
+ request(verb, path, params)
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def request(verb, path, params=nil)
64
+ path = versioned(path)
65
+ body = params || {}
66
+
67
+ payload = {
68
+ id: SecureRandom.hex,
69
+ agent: USER_AGENT,
70
+ method: verb.upcase,
71
+ resource: path,
72
+ body: body
73
+ }
74
+
75
+ publish(payload)
76
+
77
+ { id: payload[:id] }
78
+ end
79
+
80
+ def request_topic
81
+ @request_topic ||= "m2x/#{@api_key}/requests".freeze
82
+ end
83
+
84
+ def response_topic
85
+ @response_topic ||= "m2x/#{@api_key}/responses".freeze
86
+ end
87
+
88
+ def mqtt_client
89
+ @mqtt_client ||= ::MQTT::Client.new.tap do |client|
90
+ client.host = @options[:api_url]
91
+ client.username = @api_key
92
+
93
+ if @options[:use_ssl]
94
+ client.ssl = true
95
+ client.port = 8883
96
+ end
97
+ end
98
+
99
+ unless @mqtt_client.connected?
100
+ @mqtt_client.connect
101
+ end
102
+
103
+ @mqtt_client
104
+ end
105
+
106
+ def versioned(path)
107
+ versioned?(path) ? path : "/#{API_VERSION}#{path}"
108
+ end
109
+
110
+ def versioned?(path)
111
+ path =~ /^\/v\d+\//
112
+ end
113
+
114
+ at_exit do
115
+ @mqtt_client.disconnect if defined?(@mqtt_client)
116
+ end
117
+ end
@@ -0,0 +1,62 @@
1
+ # Wrapper for AT&T M2X Device API
2
+ # https://m2x.att.com/developer/documentation/v2/device
3
+ class M2X::MQTT::Device < M2X::MQTT::Resource
4
+
5
+ PATH = "/devices"
6
+
7
+ class << self
8
+ # Create a new device
9
+ #
10
+ # https://m2x.att.com/developer/documentation/v2/device#Create-Device
11
+ def create!(client, params)
12
+ client.post(PATH, params)
13
+
14
+ new(client, params)
15
+ end
16
+ end
17
+
18
+ def path
19
+ @path ||= "#{ PATH }/#{ URI.encode(@attributes.fetch("id")) }"
20
+ end
21
+
22
+ def stream(name)
23
+ M2X::MQTT::Stream.new(@client, self, "name" => name)
24
+ end
25
+
26
+ # Update the current location of the specified device.
27
+ #
28
+ # https://m2x.att.com/developer/documentation/v2/device#Update-Device-Location
29
+ def update_location(params)
30
+ @client.put("#{path}/location", params)
31
+ end
32
+
33
+ # Post Device Updates (Multiple Values to Multiple Streams)
34
+ #
35
+ # This method allows posting multiple values to multiple streams
36
+ # belonging to a device and optionally, the device location.
37
+ #
38
+ # All the streams should be created before posting values using this method.
39
+ #
40
+ # The `values` parameter contains an object with one attribute per each stream to be updated.
41
+ # The value of each one of these attributes is an array of timestamped values.
42
+ #
43
+ # {
44
+ # temperature: [
45
+ # { "timestamp": <Time in ISO8601>, "value": x },
46
+ # { "timestamp": <Time in ISO8601>, "value": y },
47
+ # ],
48
+ # humidity: [
49
+ # { "timestamp": <Time in ISO8601>, "value": x },
50
+ # { "timestamp": <Time in ISO8601>, "value": y },
51
+ # ]
52
+ #
53
+ # }
54
+ #
55
+ # The optional location attribute can contain location information that will
56
+ # be used to update the current location of the specified device
57
+ #
58
+ # https://staging.m2x.sl.attcompute.com/developer/documentation/v2/device#Post-Device-Updates--Multiple-Values-to-Multiple-Streams-
59
+ def post_updates(params)
60
+ @client.post("#{path}/updates", params)
61
+ end
62
+ end
@@ -0,0 +1,20 @@
1
+ # Wrapper for AT&T M2X Distribution API
2
+ # https://m2x.att.com/developer/documentation/v2/distribution
3
+ class M2X::MQTT::Distribution < M2X::MQTT::Resource
4
+
5
+ PATH = "/distributions"
6
+
7
+ def path
8
+ @path ||= "#{ PATH }/#{ URI.encode(@attributes.fetch("id")) }"
9
+ end
10
+
11
+ # Add a new device to an existing distribution
12
+ #
13
+ # Accepts a `serial` parameter, that must be a unique identifier
14
+ # within this distribution.
15
+ #
16
+ # https://m2x.att.com/developer/documentation/v2/distribution#Add-Device-to-an-existing-Distribution
17
+ def add_device(serial)
18
+ @client.post("#{path}/devices", serial: serial)
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ require "uri"
2
+ require "forwardable"
3
+
4
+ # Wrapper for M2X::Client resources
5
+ class M2X::MQTT::Resource
6
+ extend Forwardable
7
+
8
+ attr_reader :attributes
9
+
10
+ def_delegator :@attributes, :[]
11
+
12
+ def initialize(client, attributes)
13
+ @client = client
14
+ @attributes = attributes
15
+ end
16
+
17
+ def inspect
18
+ "<#{self.class.name}: #{attributes.inspect}>"
19
+ end
20
+
21
+ def path
22
+ raise NotImplementedError
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ # Wrapper for AT&T M2X Data Streams API
2
+ # https://m2x.att.com/developer/documentation/v2/device
3
+ class M2X::MQTT::Stream < M2X::MQTT::Resource
4
+
5
+ def initialize(client, device, attributes)
6
+ @client = client
7
+ @device = device
8
+ @attributes = attributes
9
+ end
10
+
11
+ def path
12
+ @path ||= "#{@device.path}/streams/#{ URI.encode(@attributes.fetch("name")) }"
13
+ end
14
+
15
+ # Update stream properties
16
+ # (if the stream does not exist it gets created).
17
+ #
18
+ # https://m2x.att.com/developer/documentation/v2/device#Create-Update-Data-Stream
19
+ def update!(params={})
20
+ @client.put(path, params)
21
+
22
+ @attributes.merge!(params)
23
+ end
24
+
25
+ # Update the current value of the stream. The timestamp
26
+ # is optional. If ommited, the current server time will be used
27
+ #
28
+ # https://m2x.att.com/developer/documentation/v2/device#Update-Data-Stream-Value
29
+ def update_value(value, timestamp=nil)
30
+ params = { value: value }
31
+
32
+ params[:at] = timestamp if timestamp
33
+
34
+ @client.put("#{path}/value", params)
35
+ end
36
+
37
+ # Post multiple values to the stream
38
+ #
39
+ # The `values` parameter is an array with the following format:
40
+ #
41
+ # [
42
+ # { "timestamp": <Time in ISO8601>, "value": x },
43
+ # { "timestamp": <Time in ISO8601>, "value": y },
44
+ # [ ... ]
45
+ # ]
46
+ #
47
+ # https://m2x.att.com/developer/documentation/v2/device#Post-Data-Stream-Values
48
+ def post_values(values)
49
+ params = { values: values }
50
+
51
+ @client.post("#{path}/values", params)
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ module M2X
2
+ class MQTT
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require "./lib/m2x/mqtt/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "m2x-mqtt"
7
+ s.version = ::M2X::MQTT::VERSION
8
+ s.summary = "Ruby client for AT&T M2X (MQTT)"
9
+ s.description = "AT&T’s M2X is a cloud-based fully managed data storage service for network connected machine-to-machine (M2M) devices. From trucks and turbines to vending machines and freight containers, M2X enables the devices that power your business to connect and share valuable data."
10
+ s.authors = ["Leandro López", "Matías Flores", "Federico Saravia"]
11
+ s.email = ["inkel.ar@gmail.com", "flores.matias@gmail.com", "fedesaravia@gmail.com"]
12
+ s.homepage = "http://github.com/attm2x/m2x-ruby-mqtt"
13
+ s.licenses = ["MIT"]
14
+
15
+ s.files = Dir[
16
+ "LICENSE",
17
+ "README.md",
18
+ "lib/**/*.rb",
19
+ "*.gemspec"
20
+ ]
21
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: m2x-mqtt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Leandro López
8
+ - Matías Flores
9
+ - Federico Saravia
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2015-03-16 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: AT&T’s M2X is a cloud-based fully managed data storage service for network
16
+ connected machine-to-machine (M2M) devices. From trucks and turbines to vending
17
+ machines and freight containers, M2X enables the devices that power your business
18
+ to connect and share valuable data.
19
+ email:
20
+ - inkel.ar@gmail.com
21
+ - flores.matias@gmail.com
22
+ - fedesaravia@gmail.com
23
+ executables: []
24
+ extensions: []
25
+ extra_rdoc_files: []
26
+ files:
27
+ - LICENSE
28
+ - README.md
29
+ - lib/m2x/mqtt.rb
30
+ - lib/m2x/mqtt/client.rb
31
+ - lib/m2x/mqtt/device.rb
32
+ - lib/m2x/mqtt/distribution.rb
33
+ - lib/m2x/mqtt/resource.rb
34
+ - lib/m2x/mqtt/stream.rb
35
+ - lib/m2x/mqtt/version.rb
36
+ - m2x-mqtt.gemspec
37
+ homepage: http://github.com/attm2x/m2x-ruby-mqtt
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.4.5
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: Ruby client for AT&T M2X (MQTT)
61
+ test_files: []
62
+ has_rdoc: