78 lines
1.7 KiB
Ruby
78 lines
1.7 KiB
Ruby
begin
|
|
require "mqtt"
|
|
rescue LoadError
|
|
# Fallback to mosquitto_pub when the mqtt gem is not available.
|
|
end
|
|
|
|
module MqttClient
|
|
class << self
|
|
def publish(topic, payload, retain: false, qos: 0)
|
|
return false if topic.nil? || topic.empty?
|
|
|
|
if defined?(MQTT)
|
|
publish_with_ruby_mqtt(topic, payload, retain, qos)
|
|
else
|
|
publish_with_mosquitto_pub(topic, payload, retain, qos)
|
|
end
|
|
rescue StandardError => e
|
|
warn("[MqttClient] publish failed: #{e.class}: #{e.message}")
|
|
false
|
|
end
|
|
|
|
private
|
|
|
|
def publish_with_ruby_mqtt(topic, payload, retain, qos)
|
|
options = {
|
|
host: mqtt_host,
|
|
port: mqtt_port,
|
|
keep_alive: 30
|
|
}
|
|
|
|
options[:username] = mqtt_username if mqtt_username
|
|
options[:password] = mqtt_password if mqtt_password
|
|
|
|
MQTT::Client.connect(options) do |client|
|
|
client.publish(topic, payload.to_s, retain, qos)
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
def publish_with_mosquitto_pub(topic, payload, retain, qos)
|
|
command = [
|
|
"mosquitto_pub",
|
|
"-h", mqtt_host,
|
|
"-p", mqtt_port.to_s,
|
|
"-q", qos.to_s,
|
|
"-t", topic,
|
|
"-m", payload.to_s
|
|
]
|
|
|
|
command << "-r" if retain
|
|
|
|
ok = system(*command)
|
|
warn("[MqttClient] mosquitto_pub failed") unless ok
|
|
ok
|
|
end
|
|
|
|
def mqtt_host
|
|
ENV.fetch("MQTT_HOST", "localhost")
|
|
end
|
|
|
|
def mqtt_port
|
|
Integer(ENV.fetch("MQTT_PORT", "1883"))
|
|
rescue ArgumentError
|
|
1883
|
|
end
|
|
|
|
def mqtt_username
|
|
v = ENV["MQTT_USERNAME"]
|
|
v.nil? || v.strip.empty? ? nil : v
|
|
end
|
|
|
|
def mqtt_password
|
|
ENV["MQTT_PASSWORD"]
|
|
end
|
|
end
|
|
end
|