From 2651babb13c90be3018d1d3cd8ca0ec1fb3921c8 Mon Sep 17 00:00:00 2001 From: Georg Ledermann Date: Fri, 17 Jan 2025 06:34:39 +0100 Subject: [PATCH] Prepare to store MAC address as tag to InfluxDB --- lib/flux_writer.rb | 2 ++ lib/shelly_response_parser.rb | 9 ++++++++- lib/solectrus_record.rb | 16 ++++++++++------ spec/cassettes/influx-success.yml | 12 ++++++------ spec/cassettes/shelly-pro-3em.yml | 26 +++++++++++++------------- spec/lib/solectrus_record_spec.rb | 9 +++++---- 6 files changed, 44 insertions(+), 30 deletions(-) diff --git a/lib/flux_writer.rb b/lib/flux_writer.rb index 3f6e104..bfd4f83 100644 --- a/lib/flux_writer.rb +++ b/lib/flux_writer.rb @@ -22,6 +22,8 @@ def point(record) name: influx_measurement, time: record.time, fields: record.to_hash, + # TODO: Add tags, so just ONE Measurement would be enough + # tags: { mac: record.mac }.compact, ) end diff --git a/lib/shelly_response_parser.rb b/lib/shelly_response_parser.rb index 0443c73..a1de277 100644 --- a/lib/shelly_response_parser.rb +++ b/lib/shelly_response_parser.rb @@ -7,7 +7,7 @@ def initialize(json) attr_reader :data def solectrus_record(id: 1, response_duration: nil) - SolectrusRecord.new(id:, response_duration:, time:, payload: record_hash) + SolectrusRecord.new(id:, mac:, time:, payload: record_hash.merge(response_duration:)) end private @@ -22,6 +22,13 @@ def record_hash }.compact end + def mac + data.dig('sys', 'mac') || + data['mac'] || + device_status&.dig('mac') || + device_status&.dig('sys', 'mac') + end + def time data['unixtime'] || data.dig('sys', 'unixtime') || diff --git a/lib/solectrus_record.rb b/lib/solectrus_record.rb index 1eb5d1e..9275612 100644 --- a/lib/solectrus_record.rb +++ b/lib/solectrus_record.rb @@ -1,16 +1,13 @@ class SolectrusRecord - def initialize(id:, time:, payload:, response_duration: nil) + def initialize(id:, time:, payload:, mac: nil, response_duration: nil) @id = id @time = time @payload = payload + @mac = mac @response_duration = response_duration end - attr_reader :id, :time, :response_duration - - def to_hash - @payload - end + attr_reader :id, :time, :mac %i[ temp @@ -18,12 +15,19 @@ def to_hash power_a power_b power_c + response_duration ].each do |method| define_method(method) do @payload[method] end end + def to_hash + @payload.merge( + response_duration:, + ).compact + end + def power? !power.round.zero? end diff --git a/spec/cassettes/influx-success.yml b/spec/cassettes/influx-success.yml index 959ff4f..6ec7bd6 100644 --- a/spec/cassettes/influx-success.yml +++ b/spec/cassettes/influx-success.yml @@ -5,15 +5,15 @@ http_interactions: uri: http://:8086/api/v2/write?bucket=&org=&precision=s body: encoding: UTF-8 - string: my-shelly-measurement power=18.471,power_a=13.6,power_b=4.9,power_c=0.0,response_duration=145i,temp=46.2 - 1727340752 + string: my-shelly-measurement power=1343.772,power_a=504.5,power_b=447.7,power_c=391.6,response_duration=0i,temp=47.7 + 1737091338 headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 Accept: - "*/*" User-Agent: - - influxdb-client-ruby/3.1.0 + - influxdb-client-ruby/3.2.0 Authorization: - Token Content-Type: @@ -26,11 +26,11 @@ http_interactions: X-Influxdb-Build: - OSS X-Influxdb-Version: - - v2.7.10 + - v2.7.11 Date: - - Thu, 26 Sep 2024 08:52:32 GMT + - Fri, 17 Jan 2025 05:57:41 GMT body: encoding: UTF-8 string: '' - recorded_at: Thu, 26 Sep 2024 08:52:32 GMT + recorded_at: Fri, 17 Jan 2025 05:57:41 GMT recorded_with: VCR 6.3.1 diff --git a/spec/cassettes/shelly-pro-3em.yml b/spec/cassettes/shelly-pro-3em.yml index b414b3f..b30f46e 100644 --- a/spec/cassettes/shelly-pro-3em.yml +++ b/spec/cassettes/shelly-pro-3em.yml @@ -23,7 +23,7 @@ http_interactions: body: encoding: UTF-8 string: Not Found - recorded_at: Thu, 16 Jan 2025 13:15:01 GMT + recorded_at: Fri, 17 Jan 2025 05:22:18 GMT - request: method: get uri: http://shelly-pro-3em/rpc/Shelly.GetStatus @@ -41,18 +41,18 @@ http_interactions: content-type: - application/json content-length: - - '1298' + - '1299' server: - ShellyHTTP/1.0.0 connection: - close body: encoding: UTF-8 - string: '{"ble":{},"bthome":{"errors":["bluetooth_disabled"]},"cloud":{"connected":true},"em:0":{"id":0,"a_current":1.667,"a_voltage":234.2,"a_act_power":234.8,"a_aprt_power":390.3,"a_pf":0.60,"a_freq":50.0,"b_current":1.555,"b_voltage":234.8,"b_act_power":160.6,"b_aprt_power":365.0,"b_pf":0.44,"b_freq":50.0,"c_current":1.461,"c_voltage":234.5,"c_act_power":130.6,"c_aprt_power":342.3,"c_pf":0.38,"c_freq":50.0,"n_current":null,"total_current":4.683,"total_act_power":526.009,"total_aprt_power":1097.506, - "user_calibrated_phase":[]},"emdata:0":{"id":0,"a_total_act_energy":811415.06,"a_total_act_ret_energy":0.57,"b_total_act_energy":692807.69,"b_total_act_ret_energy":0.01,"c_total_act_energy":578729.08,"c_total_act_ret_energy":3856.74,"total_act":2082951.84, - "total_act_ret":3857.31},"eth":{"ip":"192.168.178.83"},"modbus":{},"mqtt":{"connected":false},"sys":{"mac":"34987A45A6A0","restart_required":false,"time":"14:15","unixtime":1737033302,"uptime":7805113,"ram_size":247508,"ram_free":130068,"fs_size":524288,"fs_free":180224,"cfg_rev":38,"kvs_rev":2,"schedule_rev":0,"webhook_rev":2,"available_updates":{"beta":{"version":"1.5.0-beta1"}},"reset_reason":3},"temperature:0":{"id": - 0,"tC":46.8, "tF":116.2},"wifi":{"sta_ip":null,"status":"disconnected","ssid":null,"rssi":0},"ws":{"connected":false}}' - recorded_at: Thu, 16 Jan 2025 13:15:02 GMT + string: '{"ble":{},"bthome":{"errors":["bluetooth_disabled"]},"cloud":{"connected":true},"em:0":{"id":0,"a_current":2.839,"a_voltage":234.1,"a_act_power":504.5,"a_aprt_power":664.4,"a_pf":0.77,"a_freq":50.0,"b_current":2.687,"b_voltage":234.7,"b_act_power":447.7,"b_aprt_power":630.4,"b_pf":0.71,"b_freq":50.0,"c_current":2.467,"c_voltage":234.8,"c_act_power":391.6,"c_aprt_power":578.7,"c_pf":0.67,"c_freq":50.0,"n_current":null,"total_current":7.993,"total_act_power":1343.772,"total_aprt_power":1873.466, + "user_calibrated_phase":[]},"emdata:0":{"id":0,"a_total_act_energy":816427.80,"a_total_act_ret_energy":0.57,"b_total_act_energy":696574.16,"b_total_act_ret_energy":0.01,"c_total_act_energy":581963.46,"c_total_act_ret_energy":3856.74,"total_act":2094965.42, + "total_act_ret":3857.31},"eth":{"ip":"192.168.178.83"},"modbus":{},"mqtt":{"connected":false},"sys":{"mac":"34987A45A6A0","restart_required":false,"time":"06:22","unixtime":1737091338,"uptime":7863151,"ram_size":247516,"ram_free":130480,"fs_size":524288,"fs_free":180224,"cfg_rev":38,"kvs_rev":2,"schedule_rev":0,"webhook_rev":2,"available_updates":{"beta":{"version":"1.5.0-beta1"}},"reset_reason":3},"temperature:0":{"id": + 0,"tC":47.7, "tF":117.9},"wifi":{"sta_ip":null,"status":"disconnected","ssid":null,"rssi":0},"ws":{"connected":false}}' + recorded_at: Fri, 17 Jan 2025 05:22:18 GMT - request: method: get uri: http://shelly-pro-3em/rpc/Shelly.GetStatus @@ -70,16 +70,16 @@ http_interactions: content-type: - application/json content-length: - - '1298' + - '1299' server: - ShellyHTTP/1.0.0 connection: - close body: encoding: UTF-8 - string: '{"ble":{},"bthome":{"errors":["bluetooth_disabled"]},"cloud":{"connected":true},"em:0":{"id":0,"a_current":1.667,"a_voltage":234.2,"a_act_power":234.8,"a_aprt_power":390.3,"a_pf":0.60,"a_freq":50.0,"b_current":1.555,"b_voltage":234.8,"b_act_power":160.6,"b_aprt_power":365.0,"b_pf":0.44,"b_freq":50.0,"c_current":1.461,"c_voltage":234.5,"c_act_power":130.6,"c_aprt_power":342.3,"c_pf":0.38,"c_freq":50.0,"n_current":null,"total_current":4.683,"total_act_power":526.009,"total_aprt_power":1097.506, - "user_calibrated_phase":[]},"emdata:0":{"id":0,"a_total_act_energy":811415.06,"a_total_act_ret_energy":0.57,"b_total_act_energy":692807.69,"b_total_act_ret_energy":0.01,"c_total_act_energy":578729.08,"c_total_act_ret_energy":3856.74,"total_act":2082951.84, - "total_act_ret":3857.31},"eth":{"ip":"192.168.178.83"},"modbus":{},"mqtt":{"connected":false},"sys":{"mac":"34987A45A6A0","restart_required":false,"time":"14:15","unixtime":1737033302,"uptime":7805113,"ram_size":247508,"ram_free":130068,"fs_size":524288,"fs_free":180224,"cfg_rev":38,"kvs_rev":2,"schedule_rev":0,"webhook_rev":2,"available_updates":{"beta":{"version":"1.5.0-beta1"}},"reset_reason":3},"temperature:0":{"id": - 0,"tC":46.8, "tF":116.2},"wifi":{"sta_ip":null,"status":"disconnected","ssid":null,"rssi":0},"ws":{"connected":false}}' - recorded_at: Thu, 16 Jan 2025 13:15:02 GMT + string: '{"ble":{},"bthome":{"errors":["bluetooth_disabled"]},"cloud":{"connected":true},"em:0":{"id":0,"a_current":2.839,"a_voltage":234.1,"a_act_power":504.5,"a_aprt_power":664.4,"a_pf":0.77,"a_freq":50.0,"b_current":2.687,"b_voltage":234.7,"b_act_power":447.7,"b_aprt_power":630.4,"b_pf":0.71,"b_freq":50.0,"c_current":2.467,"c_voltage":234.8,"c_act_power":391.6,"c_aprt_power":578.7,"c_pf":0.67,"c_freq":50.0,"n_current":null,"total_current":7.993,"total_act_power":1343.772,"total_aprt_power":1873.466, + "user_calibrated_phase":[]},"emdata:0":{"id":0,"a_total_act_energy":816427.80,"a_total_act_ret_energy":0.57,"b_total_act_energy":696574.16,"b_total_act_ret_energy":0.01,"c_total_act_energy":581963.46,"c_total_act_ret_energy":3856.74,"total_act":2094965.42, + "total_act_ret":3857.31},"eth":{"ip":"192.168.178.83"},"modbus":{},"mqtt":{"connected":false},"sys":{"mac":"34987A45A6A0","restart_required":false,"time":"06:22","unixtime":1737091338,"uptime":7863151,"ram_size":247516,"ram_free":130480,"fs_size":524288,"fs_free":180224,"cfg_rev":38,"kvs_rev":2,"schedule_rev":0,"webhook_rev":2,"available_updates":{"beta":{"version":"1.5.0-beta1"}},"reset_reason":3},"temperature:0":{"id": + 0,"tC":47.7, "tF":117.9},"wifi":{"sta_ip":null,"status":"disconnected","ssid":null,"rssi":0},"ws":{"connected":false}}' + recorded_at: Fri, 17 Jan 2025 05:22:18 GMT recorded_with: VCR 6.3.1 diff --git a/spec/lib/solectrus_record_spec.rb b/spec/lib/solectrus_record_spec.rb index 265e2cb..dfd1b14 100644 --- a/spec/lib/solectrus_record_spec.rb +++ b/spec/lib/solectrus_record_spec.rb @@ -1,7 +1,7 @@ require 'solectrus_record' describe SolectrusRecord do - subject(:record) { described_class.new(id: 1, response_duration: 20.5, time: Time.now, payload:) } + subject(:record) { described_class.new(id: 1, mac: 'deadbeef0001', time: Time.now, payload:) } let(:payload) do { @@ -10,6 +10,7 @@ power_a: 10.2, power_b: 20.5, power_c: 30.3, + response_duration: 20.5, } end @@ -42,13 +43,13 @@ end end - describe '#response_duration' do + describe '#mac' do it 'returns the value' do - expect(record.response_duration).to eq(20.5) + expect(record.mac).to eq('deadbeef0001') end end - %i[temp power power_a power_b power_c].each do |method| + %i[temp power power_a power_b power_c response_duration].each do |method| describe "##{method}" do it "returns the value of #{method} from the payload" do expect(record.send(method)).to eq(payload[method])