Skip to content

Commit

Permalink
Merge branch 'release/0.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ledermann committed Nov 7, 2024
2 parents 401ed98 + bddcc76 commit e07f7ef
Show file tree
Hide file tree
Showing 18 changed files with 6,145 additions and 6,085 deletions.
1 change: 0 additions & 1 deletion .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ INFLUX_PORT=8086
INFLUX_TOKEN_WRITE=my-token
INFLUX_ORG=my-org
INFLUX_BUCKET=my-bucket
INFLUX_MEASUREMENT_PV=my-measurement

# Folder with CSV test data
IMPORT_FOLDER=./spec/data
Expand Down
5 changes: 4 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ Metrics/MethodLength:
Max: 20

Metrics/AbcSize:
Max: 20
Max: 25

RSpec/MultipleMemoizedHelpers:
Enabled: false

RSpec/ExampleLength:
Max: 20
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.4
3.3.6
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:3.3.4-alpine AS builder
FROM ruby:3.3.6-alpine AS builder
RUN apk add --no-cache build-base

WORKDIR /csv-importer
Expand All @@ -8,7 +8,7 @@ RUN bundle config --local frozen 1 && \
bundle install -j4 --retry 3 && \
bundle clean --force

FROM ruby:3.3.4-alpine
FROM ruby:3.3.6-alpine
LABEL maintainer="[email protected]"

# Decrease memory usage
Expand Down
43 changes: 21 additions & 22 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.2.1)
activesupport (7.2.2)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
Expand All @@ -16,6 +17,7 @@ GEM
public_suffix (>= 2.0.2, < 7.0)
ast (2.4.2)
base64 (0.2.0)
benchmark (0.3.0)
bigdecimal (3.1.8)
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
Expand All @@ -25,74 +27,71 @@ GEM
csv (3.3.0)
diff-lcs (1.5.1)
docile (1.4.1)
dotenv (3.1.2)
dotenv (3.1.4)
drb (2.2.1)
hashdiff (1.1.1)
i18n (1.14.5)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
influxdb-client (3.1.0)
json (2.7.2)
json (2.8.1)
language_server-protocol (3.17.0.3)
logger (1.6.0)
logger (1.6.1)
minitest (5.25.1)
parallel (1.26.3)
parser (3.3.4.2)
parser (3.3.6.0)
ast (~> 2.4.1)
racc
public_suffix (6.0.1)
racc (1.8.1)
rainbow (3.1.1)
rake (13.2.1)
regexp_parser (2.9.2)
rexml (3.3.6)
strscan
rexml (3.3.9)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.0)
rspec-core (3.13.2)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.2)
rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.1)
rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-support (3.13.1)
rubocop (1.65.1)
rubocop (1.68.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.4, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.32.1)
rubocop-ast (1.34.0)
parser (>= 3.3.1.0)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
rubocop-rspec (3.0.4)
rubocop-rspec (3.2.0)
rubocop (~> 1.61)
ruby-progressbar (1.13.0)
securerandom (0.3.1)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4)
strscan (3.1.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2024.1)
tzinfo-data (1.2024.2)
tzinfo (>= 1.0.0)
unicode-display_width (2.5.0)
unicode-display_width (2.6.0)
vcr (6.3.1)
base64
webmock (3.23.1)
webmock (3.24.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
Expand All @@ -116,4 +115,4 @@ DEPENDENCIES
webmock

BUNDLED WITH
2.5.18
2.5.23
36 changes: 21 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,27 @@ The [senec-collector](https://github.com/solectrus/senec-collector) does not hav

The following environment variables can be used to configure the importer:

| Variable | Description | Default |
| -------------------------------------- | ----------------------------------------------- | --------------- |
| `INFLUX_HOST` | Hostname of InfluxDB | |
| `INFLUX_SCHEMA` | Schema (http/https) of InfluxDB | `http` |
| `INFLUX_PORT` | Port of InfluxDB | `8086` |
| `INFLUX_TOKEN_WRITE` or `INFLUX_TOKEN` | Token for InfluxDB (requires write permissions) | |
| `INFLUX_ORG` | Organization for InfluxDB | |
| `INFLUX_BUCKET` | Bucket for InfluxDB | |
| `INFLUX_MEASUREMENT_PV` | Measurement for InfluxDB | `SENEC` |
| `INFLUX_OPEN_TIMEOUT` | Timeout for InfluxDB connection (in seconds) | `30` |
| `INFLUX_READ_TIMEOUT` | Timeout for InfluxDB read (in seconds) | `30` |
| `INFLUX_WRITE_TIMEOUT` | Timeout for InfluxDB write (in seconds) | `30` |
| `IMPORT_FOLDER` | Folder where CSV files are located | `/data` |
| `IMPORT_PAUSE` | Pause after each imported file (in seconds) | `0` |
| `TZ` | Time zone to use when parsing times | `Europe/Berlin` |
| Variable | Description | Default |
| --------------------------------------- | ----------------------------------------------- | ---------------------------- |
| `INFLUX_HOST` | Hostname of InfluxDB | |
| `INFLUX_SCHEMA` | Schema (http/https) of InfluxDB | `http` |
| `INFLUX_PORT` | Port of InfluxDB | `8086` |
| `INFLUX_TOKEN_WRITE` or `INFLUX_TOKEN` | Token for InfluxDB (requires write permissions) | |
| `INFLUX_ORG` | Organization for InfluxDB | |
| `INFLUX_BUCKET` | Bucket for InfluxDB | |
| `INFLUX_OPEN_TIMEOUT` | Timeout for InfluxDB connection (in seconds) | `30` |
| `INFLUX_READ_TIMEOUT` | Timeout for InfluxDB read (in seconds) | `30` |
| `INFLUX_WRITE_TIMEOUT` | Timeout for InfluxDB write (in seconds) | `30` |
| `INFLUX_SENSOR_INVERTER_POWER` | Measurement/field for inverter power | `SENEC:inverter_power` |
| `INFLUX_SENSOR_HOUSE_POWER` | Measurement/field for house power | `SENEC:house_power` |
| `INFLUX_SENSOR_GRID_IMPORT_POWER` | Measurement/field for grid import power | `SENEC:grid_power_plus` |
| `INFLUX_SENSOR_GRID_EXPORT_POWER` | Measurement/field for grid export power | `SENEC:grid_power_minus` |
| `INFLUX_SENSOR_BATTERY_CHARGE_POWER` | Measurement/field for battery charge power | `SENEC:bat_power_plus` |
| `INFLUX_SENSOR_BATTERY_DISCHARGE_POWER` | Measurement/field for battery discharge power | `SENEC:bat_power_minus` |
| `INFLUX_SENSOR_WALLBOX_POWER` | Measurement/field for wallbox power | `SENEC:wallbox_charge_power` |
| `IMPORT_FOLDER` | Folder where CSV files are located | `/data` |
| `IMPORT_PAUSE` | Pause after each imported file (in seconds) | `0` |
| `TZ` | Time zone to use when parsing times | `Europe/Berlin` |

## License

Expand Down
18 changes: 10 additions & 8 deletions app/adapters/base_record.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
require_relative 'time_zone'

class BaseRecord
def initialize(row, measurement:)
def initialize(row, config:)
@row = row
@measurement = measurement
@config = config
end

attr_reader :row, :measurement

def to_h
{ name: measurement, time:, fields: }
end
attr_reader :row, :config

def to_a
[to_h]
data.group_by { |d| d[:measurement] }.map do |measurement, items|
{
time:,
name: measurement,
fields: items.to_h { |item| [item[:field], item[:value]] },
}
end
end

private
Expand Down
74 changes: 29 additions & 45 deletions app/adapters/senec_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,29 @@ def self.probe?(first_line)
first_line.include?('Uhrzeit;Netzbezug [kWh]')
end

private
def data
%i[
inverter_power
house_power
battery_charging_power
battery_discharging_power
grid_import_power
grid_export_power
wallbox_power
].map do |sensor_name|
{
measurement: config.measurement(sensor_name),
field: config.field(sensor_name),
value: __send__(sensor_name),
}
end
end

def time
parse_time(row, 'Uhrzeit')
end

def fields
{
inverter_power:,
house_power:,
bat_power_plus:,
bat_power_minus:,
bat_fuel_charge: nil,
bat_charge_current:,
bat_voltage:,
grid_power_plus:,
grid_power_minus:,
# There is no data for the wallbox, but we can estimate it
wallbox_charge_power: estimated_wallbox_charge_power,
}
end
private

def inverter_power
@inverter_power ||=
Expand All @@ -42,8 +44,8 @@ def house_power
parse_kw(row, 'Stromverbrauch [kW]', 'Stromverbrauch [kWh]')
end

def bat_power_plus
@bat_power_plus ||=
def battery_charging_power
@battery_charging_power ||=
parse_kw(
row,
'Akkubeladung [kW]',
Expand All @@ -52,9 +54,9 @@ def bat_power_plus
)
end

def bat_power_minus
def battery_discharging_power
# The CSV file format has changed over time, so two different column names are possible
@bat_power_minus ||=
@battery_discharging_power ||=
parse_kw(
row,
'Akkuentnahme [kW]',
Expand All @@ -63,26 +65,18 @@ def bat_power_minus
)
end

def bat_charge_current
@bat_charge_current ||= parse_a(row, 'Akku Stromstärke [A]')
end

def bat_voltage
@bat_voltage ||= parse_v(row, 'Akku Spannung [V]')
def grid_import_power
@grid_import_power ||= parse_kw(row, 'Netzbezug [kW]', 'Netzbezug [kWh]')
end

def grid_power_plus
@grid_power_plus ||= parse_kw(row, 'Netzbezug [kW]', 'Netzbezug [kWh]')
end

def grid_power_minus
@grid_power_minus ||=
def grid_export_power
@grid_export_power ||=
parse_kw(row, 'Netzeinspeisung [kW]', 'Netzeinspeisung [kWh]')
end

def estimated_wallbox_charge_power
incoming = inverter_power + grid_power_plus + bat_power_minus
outgoing = grid_power_minus + house_power + bat_power_plus
def wallbox_power
incoming = inverter_power + grid_import_power + battery_discharging_power
outgoing = grid_export_power + house_power + battery_charging_power
diff = incoming - outgoing

diff < 50 ? 0 : diff
Expand All @@ -92,14 +86,4 @@ def estimated_wallbox_charge_power
def parse_kw(row, *)
(cell(row, *).sub(',', '.').to_f * 1_000).round
end

# Ampere
def parse_a(row, *)
cell(row, *).sub(',', '.').to_f
end

# Volt
def parse_v(row, *)
cell(row, *).sub(',', '.').to_f
end
end
Loading

0 comments on commit e07f7ef

Please sign in to comment.