class Adafruit::IO::MQTT

Attributes

client[R]

provide access to the raw MQTT library client

Public Class Methods

new(username, key, opts={}) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 40
def initialize(username, key, opts={})
  @options = {
    uri: 'io.adafruit.com',
    protocol: 'mqtts',
    port: 8883,
    username: username,
    key: key
  }.merge(opts)

  @connect_uri = "%{protocol}://%{username}:%{key}@%{uri}" % @options

  connect
end

Public Instance Methods

connect() click to toggle source
# File lib/adafruit/io/mqtt.rb, line 54
def connect
  if @client.nil? || !@client.connected?
    @client = ::MQTT::Client.connect @connect_uri, @options[:port], ack_timeout: 10
  end
end
disconnect() click to toggle source
# File lib/adafruit/io/mqtt.rb, line 60
def disconnect
  if @client && @client.connected?
    @client.disconnect
  end
end
get(&block) click to toggle source

Retrieve the last value received from the MQTT connection for any subscribed feeds or groups. This is a blocking method, which means it won't return until a message is retrieved.

Returns [topic, message] or yields it into the given block.

With no block:

mqtt_client.subscribe('feed-key')
loop do
  topic, message = mqtt_client.get
  # do something
end

With a block:

mqtt_client.subscribe('feed-key')
mqtt_client.get do |topic, message|
  # do something
end
# File lib/adafruit/io/mqtt.rb, line 153
def get(&block)
  @client.get(&block)
end
publish(key, value, location={}) click to toggle source

Publish value to feed with given key

# File lib/adafruit/io/mqtt.rb, line 67
def publish(key, value, location={})
  raise 'client is not connected' unless @client.connected?

  topic = key_to_feed_topic(key)
  location = indifferent_keys(location)
  payload = payload_from_value_with_location(value, location)

  @client.publish(topic, payload)
end
publish_group(key, values, location={}) click to toggle source

Publish to multiple feeds within a group.

  • `key` is a group key

  • `values` is a hash where keys are feed keys and values are the published value.

  • `location` is the optional { :lat, :lon, :ele } hash specifying the location data for this publish event.

# File lib/adafruit/io/mqtt.rb, line 85
def publish_group(key, values, location={})
  raise 'client is not connected' unless @client.connected?
  raise 'values must be a hash' unless values.is_a?(Hash)

  topic = key_to_group_topic(key, false)
  location = indifferent_keys(location)
  payload = payload_from_values_with_location(values, location)

  @client.publish(topic, payload)
end
subscribe(key, options={}) click to toggle source

Subscribe to the feed with the given key. Use .get to retrieve messages from subscribed feeds.

Include the { last_value: true } option if you'd like the feed to receive the last value immediately. (like MQTT retain)

# File lib/adafruit/io/mqtt.rb, line 101
def subscribe(key, options={})
  raise 'client is not connected' unless @client.connected?

  topic = key_to_feed_topic(key)
  @client.subscribe(topic)

  if options[:last_value]
    @client.publish(topic + '/get', '')
  end
end
subscribe_group(key) click to toggle source

Subscribe to a group with the given key.

NOTE: Unlike feed subscriptions, group subscriptions return a JSON representation of the group record with a 'feeds' property containing a JSON object whose keys are feed keys and whose values are the last value received for that feed.

# File lib/adafruit/io/mqtt.rb, line 125
def subscribe_group(key)
  raise 'client is not connected' unless @client.connected?

  topic = key_to_group_topic(key)
  @client.subscribe(topic)
end
unsubscribe(key) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 112
def unsubscribe(key)
  raise 'client is not connected' unless @client.connected?

  topic = key_to_feed_topic(key)
  @client.unsubscribe(topic)
end

Private Instance Methods

encode_json(record) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 159
def encode_json(record)
  begin
    JSON.generate record
  rescue JSON::GeneratorError => ex
    puts "failed to generate JSON from record: #{record.inspect}"
    raise ex
  end
end
indifferent_keys(hash) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 202
def indifferent_keys(hash)
  hash.keys.inject({}) {|new_hash, key|
    new_hash[key.to_s]   = hash[key]
    new_hash[key.to_sym] = hash[key]

    new_hash
  }
end
key_to_feed_topic(key) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 168
def key_to_feed_topic(key)
  "%s/f/%s" % [@options[:username], key]
end
key_to_group_topic(key, json=true) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 172
def key_to_group_topic(key, json=true)
  "%s/g/%s%s" % [@options[:username], key, (json ? '/json' : '')]
end
payload_from_value_with_location(value, location) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 176
def payload_from_value_with_location(value, location)
  payload = { value: value.to_s }

  if location.has_key?('lat') && location.has_key?['lon']
    %w(lat lon ele).each do |f|
      payload[f] = location[f]
    end
  end

  encode_json payload
end
payload_from_values_with_location(values, location) click to toggle source
# File lib/adafruit/io/mqtt.rb, line 188
def payload_from_values_with_location(values, location)
  payload = { feeds: values }

  if location.has_key?('lat') && location.has_key?['lon']
    payload[:location] = {}

    %w(lat lon ele).each do |f|
      payload[:location][f] = location[f]
    end
  end

  encode_json payload
end