diff --git a/app/adapters/energy_record.rb b/app/adapters/energy_record.rb new file mode 100644 index 0000000..6640754 --- /dev/null +++ b/app/adapters/energy_record.rb @@ -0,0 +1,70 @@ +require_relative 'base_record' + +class EnergyRecord < BaseRecord + def self.csv_options + { headers: true, col_sep: ',' } + end + + def self.probe?(first_line) + first_line.include?('Time,PV power') + end + + private + + def time + parse_time(row, 'Time') + end + + def fields + { + inverter_power:, + house_power:, + battery_charging_power:, + battery_discharging_power:, + battery_soc:, + grid_import_power:, + grid_export_power:, + } + end + + def inverter_power + @inverter_power ||= parse_value(row, 'PV power') + end + + def house_power + @house_power ||= parse_value(row, 'Load power') + end + + def battery_soc + @battery_soc ||= parse_value(row, 'Battery SOC') + end + + def battery_discharging_power + @battery_discharging_power ||= bat_power.negative? ? -bat_power : 0 + end + + def battery_charging_power + @battery_charging_power ||= bat_power.positive? ? bat_power : 0 + end + + def bat_power + @bat_power ||= parse_value(row, 'Battery power') + end + + def grid_import_power + @grid_import_power ||= grid_power.positive? ? grid_power : 0 + end + + def grid_export_power + @grid_export_power ||= grid_power.negative? ? -grid_power : 0 + end + + def grid_power + @grid_power ||= parse_value(row, 'Grid power') + end + + # KiloWatt + def parse_value(row, *) + cell(row, *).to_f.round + end +end diff --git a/spec/adapters/energy_record_spec.rb b/spec/adapters/energy_record_spec.rb new file mode 100644 index 0000000..71414e0 --- /dev/null +++ b/spec/adapters/energy_record_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe EnergyRecord do + subject(:record) { described_class.new(row, measurement: 'Energy') } + + let(:row) { CSV::Row.new headers, fields } + + let(:headers) { ['Time', 'PV power', 'Load power', 'Battery power', 'Grid power', 'Battery SOC'] } + + describe '#to_h' do + subject(:hash) { record.to_h } + + let(:fields) { ['2023-06-21 10:50:00', '3000', '400', '-500', '100', '67'] } + + let(:expected_time) { Time.parse('2023-06-21 10:50:00').to_i } + + let(:expected_fields) do + { + inverter_power: 3000, + house_power: 400, + battery_charging_power: 0, + battery_discharging_power: 500, + battery_soc: 67, + grid_import_power: 100, + grid_export_power: 0, + } + end + + it 'converts the CSV row to a hash with the correct structure and values' do + expect(hash).to eq( + { name: 'Energy', time: expected_time, fields: expected_fields }, + ) + end + end +end diff --git a/spec/csv_probe_spec.rb b/spec/csv_probe_spec.rb index 311f463..7ffd457 100644 --- a/spec/csv_probe_spec.rb +++ b/spec/csv_probe_spec.rb @@ -38,6 +38,18 @@ end end + context 'when a Mqtt file is given' do + Dir + .glob('spec/data/mqtt/*.csv') + .each do |file_path| + let(:file_path) { file_path } + + it 'returns the MqttRecord class' do + expect(checker.record_class).to eq(EnergyRecord) + end + end + end + context 'when something different is given' do let(:file_path) { 'README.md' } diff --git a/spec/data/mqtt/backfill.csv b/spec/data/mqtt/backfill.csv new file mode 100644 index 0000000..1fca828 --- /dev/null +++ b/spec/data/mqtt/backfill.csv @@ -0,0 +1,100 @@ +Time,PV power,Grid power,Battery power,Load power,Battery SOC +2024-06-18 16:20:00,822,1413,136,1756,100 +2024-06-18 16:25:00,759,1357,140,1631,100 +2024-06-18 16:30:00,633,1500,147,1661,100 +2024-06-18 16:35:00,587,444,135,551,100 +2024-06-18 16:40:00,565,2059,135,2146,100 +2024-06-18 16:45:00,555,3325,134,3417,100 +2024-06-18 16:50:00,523,3042,124,3110,100 +2024-06-18 16:55:00,444,3101,106,3115,100 +2024-06-18 17:00:00,358,2797,27.6,2808,100 +2024-06-18 17:05:00,310,2717,2.97,2727,100 +2024-06-18 17:10:00,273,1682,0,1690,100 +2024-06-18 17:15:00,230,1458,0,1465,99.5 +2024-06-18 17:20:00,208,386,0,393,99 +2024-06-18 17:25:00,190,230,0,238,98.3 +2024-06-18 17:30:00,185,229,0,239,98 +2024-06-18 17:35:00,174,231,0,239,98.0 +2024-06-18 17:40:00,157,230,0,239,97 +2024-06-18 17:45:00,162,229,0,239,97 +2024-06-18 17:50:00,164,218,0,226,96.7 +2024-06-18 17:55:00,155,377,0,385,96 +2024-06-18 18:00:00,159,249,0,258,96 +2024-06-18 18:05:00,148,183,0,192,95.4 +2024-06-18 18:10:00,135,160,0,168,95 +2024-06-18 18:15:00,126,293,0,301,95 +2024-06-18 18:20:00,108,303,0,312,94.1 +2024-06-18 18:25:00,99.3,2975,0,2982,94 +2024-06-18 18:30:00,8.47,4415,1472,2593,94 +2024-06-18 18:35:00,0,2462,1620,450,94.8 +2024-06-18 18:40:00,0,2306,1629,283,97.7 +2024-06-18 18:45:00,0,749,358,208,99.5 +2024-06-18 18:50:00,0,334,9.19,212,100 +2024-06-18 18:55:00,0,488,114,193,100 +2024-06-18 19:00:00,0,502,147,186,100 +2024-06-18 19:05:00,0,528,147,204,100 +2024-06-18 19:10:00,0,659,145,342,100 +2024-06-18 19:15:00,0,488,132,174,100 +2024-06-18 19:20:00,0,488,135,173,100 +2024-06-18 19:25:00,0,493,127,174,100 +2024-06-18 19:30:00,0,483,136,166,100 +2024-06-18 19:35:00,0,433,128,118,100 +2024-06-18 19:40:00,0,436,129,122,100 +2024-06-18 19:45:00,0,314,53.6,114,100 +2024-06-18 19:50:00,0,214,0,107,100 +2024-06-18 19:55:00,0,240,0,130,100 +2024-06-18 20:00:00,0,329,0,222,99.0 +2024-06-18 20:05:00,0,347,0,234,98.8 +2024-06-18 20:10:00,0,347,0,234,98 +2024-06-18 20:15:00,0,611,0,499,98 +2024-06-18 20:20:00,0,342,0,232,98 +2024-06-18 20:25:00,0,641,0,529,97.4 +2024-06-18 20:30:00,0,327,0,217,97 +2024-06-18 20:35:00,0,344,0,231,97 +2024-06-18 20:40:00,0,354,0,234,97 +2024-06-18 20:45:00,0,349,0,232,96.1 +2024-06-18 20:50:00,0,340,0,220,96 +2024-06-18 20:55:00,0,343,0,223,98.3 +2024-06-18 21:00:00,0,349,0,230,100 +2024-06-18 21:05:00,0,337,0,219,100 +2024-06-18 21:10:00,0,711,0,595,100 +2024-06-18 21:15:00,0,349,0,232,100 +2024-06-18 21:20:00,0,418,0,301,100 +2024-06-18 21:25:00,0,407,0,287,100 +2024-06-18 21:30:00,0,485,0,370,100 +2024-06-18 21:35:00,0,1407,0,1294,100 +2024-06-18 21:40:00,0,1399,0,1284,100 +2024-06-18 21:45:00,0,1393,0,1279,100 +2024-06-18 21:50:00,0,1392,0,1276,100 +2024-06-18 21:55:00,0,698,0,579,100 +2024-06-18 22:00:00,0,418,0,301,100 +2024-06-18 22:05:00,0,419,0,305,100 +2024-06-18 22:10:00,0,305,0,194,100 +2024-06-18 22:15:00,0,297,0,181,100 +2024-06-18 22:20:00,0,290,0,170,100 +2024-06-18 22:25:00,0,299,0,180,100 +2024-06-18 22:30:00,0,316,0,198,100 +2024-06-18 22:35:00,0,349,0,225,100 +2024-06-18 22:40:00,0,346,0,221,100 +2024-06-18 22:45:00,0,361,0,235,100 +2024-06-18 22:50:00,0,316,0,193,100 +2024-06-18 22:55:00,0,335,0,214,100 +2024-06-18 23:00:00,0,308,0,181,100 +2024-06-18 23:05:00,0,407,0,278,100 +2024-06-18 23:10:00,0,1334,0,1210,100 +2024-06-18 23:15:00,0,1335,0,1210,100 +2024-06-18 23:20:00,0,1333,0,1205,100 +2024-06-18 23:25:00,0,1329,0,1206,100 +2024-06-18 23:30:00,0,1337,0,1210,100 +2024-06-18 23:35:00,0,1014,0,890,100 +2024-06-18 23:40:00,0,278,0,153,100 +2024-06-18 23:45:00,0,268,0,149,100 +2024-06-18 23:50:00,0,226,0,104,100 +2024-06-18 23:55:00,0,256,0,130,100 +2024-06-19 00:00:00,0,280,0,152,100 +2024-06-19 00:05:00,0,282,0,154,100 +2024-06-19 00:10:00,0,284,0,153,100 +2024-06-19 00:15:00,0,278,0,152,100 +2024-06-19 00:20:00,0,309,0,180,100 +2024-06-19 00:25:00,0,493,0,369,100 +2024-06-19 00:30:00,0,491,0,368,100 diff --git a/spec/import_spec.rb b/spec/import_spec.rb index d3081db..244d542 100644 --- a/spec/import_spec.rb +++ b/spec/import_spec.rb @@ -4,6 +4,6 @@ describe '#run', vcr: { cassette_name: 'import' } do subject(:run) { described_class.run(config:) } - it { is_expected.to eq(8) } + it { is_expected.to eq(9) } end end