Class: E3DCMqtt::MqttClient
- Inherits:
-
Object
- Object
- E3DCMqtt::MqttClient
- Defined in:
- lib/e3dc_mqtt/mqtt_client.rb
Overview
Thin wrapper around the ‘mqtt` gem with domain-specific publishing: delta-based publishes, JSON payloads, LWT, and typed `publish_status` / `publish_daily_statistics` / `publish_battery_data` helpers.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- ONLINE_TOPIC =
"online".freeze
- DEFAULT_KEEPALIVE =
60
Instance Attribute Summary collapse
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Instance Method Summary collapse
- #disconnect ⇒ Object
-
#initialize(url:, root:, prefix:, client_id: "e3dc-mqtt-ruby", username: "", password: "", tls_verify: true) ⇒ MqttClient
constructor
A new instance of MqttClient.
-
#publish(topic, value, retain: false, qos: 0) ⇒ Object
—– primitive publish helpers —–.
- #publish_battery_data(batteries) ⇒ Object
- #publish_daily_statistics(stats) ⇒ Object
- #publish_if_changed(topic, value) ⇒ Object
- #publish_json(topic, data, retain: false) ⇒ Object
- #publish_json_if_changed(topic, data) ⇒ Object
-
#publish_status(status) ⇒ Object
—– domain publishers —–.
Constructor Details
#initialize(url:, root:, prefix:, client_id: "e3dc-mqtt-ruby", username: "", password: "", tls_verify: true) ⇒ MqttClient
Returns a new instance of MqttClient.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 19 def initialize(url:, root:, prefix:, client_id: "e3dc-mqtt-ruby", username: "", password: "", tls_verify: true) uri = URI.parse(url) ssl = case uri.scheme when "ssl", "mqtts" then true when "tcp", "mqtt" then false when "unix" then raise Error, "unix:// MQTT not yet supported" else raise Error, "unsupported MQTT scheme: #{uri.scheme.inspect}" end @root = "#{root}/#{prefix}" @last_values = {} @client = build_client(uri, ssl, tls_verify, client_id, username, password) connect! end |
Instance Attribute Details
#root ⇒ Object (readonly)
Returns the value of attribute root.
17 18 19 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 17 def root @root end |
Instance Method Details
#disconnect ⇒ Object
35 36 37 38 39 40 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 35 def disconnect publish(ONLINE_TOPIC, "false", retain: true) @client.disconnect rescue StandardError # best-effort on shutdown end |
#publish(topic, value, retain: false, qos: 0) ⇒ Object
—– primitive publish helpers —–
44 45 46 47 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 44 def publish(topic, value, retain: false, qos: 0) full = "#{@root}/#{topic}" @client.publish(full, format_value(value), retain, qos) end |
#publish_battery_data(batteries) ⇒ Object
115 116 117 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 115 def publish_battery_data(batteries) batteries.each { |b| publish_one_battery(b) } end |
#publish_daily_statistics(stats) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 97 def publish_daily_statistics(stats) publish("status_sums/time", stats..utc.iso8601) { "status_sums/autarky_today" => stats.autarky, "status_sums/self_consumption_today" => stats.consumed_production, "status_sums/solar_production_today" => stats.solar_production, "status_sums/house_consumption_today" => stats.consumption, "status_sums/battery_charge_today" => stats.bat_power_in, "status_sums/battery_discharge_today" => stats.bat_power_out, "status_sums/consumption_from_grid_today" => stats.grid_power_out, "status_sums/export_to_grid_today" => stats.grid_power_in, "status_sums/state_of_charge_today" => stats.state_of_charge, "status_sums/start" => stats.start.utc.iso8601, "status_sums/timespan" => iso8601_duration(stats.timespan) }.each { |topic, value| publish_if_changed(topic, value) } end |
#publish_if_changed(topic, value) ⇒ Object
49 50 51 52 53 54 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 49 def publish_if_changed(topic, value) return if @last_values[topic] == value publish(topic, value) @last_values[topic] = value end |
#publish_json(topic, data, retain: false) ⇒ Object
56 57 58 59 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 56 def publish_json(topic, data, retain: false) full = "#{@root}/#{topic}" @client.publish(full, JSON.generate(json_safe(data)), retain, 0) end |
#publish_json_if_changed(topic, data) ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 61 def publish_json_if_changed(topic, data) payload = JSON.generate(json_safe(data)) key = [:json, topic] return if @last_values[key] == payload @client.publish("#{@root}/#{topic}", payload, false, 0) @last_values[key] = payload end |
#publish_status(status) ⇒ Object
—– domain publishers —–
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/e3dc_mqtt/mqtt_client.rb', line 72 def publish_status(status) publish("status/time", status..utc.iso8601) battery_charge, battery_discharge = split_val(status.power_battery) consumption_from_grid, export_to_grid = split_val(status.power_grid) mapping = { "status/additional" => -status.power_add.to_f, "status/autarky" => status.autarky, "status/battery_charge" => battery_charge, "status/battery_discharge" => battery_discharge, "status/battery_consumption" => status.power_battery, "status/consumption_from_grid" => consumption_from_grid, "status/export_to_grid" => export_to_grid, "status/grid_production" => status.power_grid, "status/house_consumption" => status.power_home, "status/self_consumption" => status.self_consumption, "status/solar_production" => status.power_pv, "status/solar_production_excess" => status.power_pv - status.power_home, "status/state_of_charge" => status.battery_soc, "status/wb_consumption" => status.power_wb } mapping.each { |topic, value| publish_if_changed(topic, value) } end |