diff --git a/README.md b/README.md index 59b41cf..ad892e5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,58 @@ # solar-toolkit -A side project to collect, transport and store data from a Goodwe solar inverter. +A side project to collect, transport and store data from a Goodwe solar +inverter. + +Based on Marcel Blijleven's [Python +library](https://github.com/marcelblijleven/goodwe), ported to Go and +re-packaged as a client/server application. + +This project is mostly for personal use - it hasn't been polished for wider +usage and isn't yet compatible with the full range of inverters supported by +the above library (it has been tested against a GW5000-EH). + +## Git + +The main git repo is: https://git.netflux.io/rob/solar-toolkit + +It is also mirrored on GitHub: https://github.com/rfwatson/solar-toolkit + +## Components + +### solar-toolkit-daemon + +A binary which can be triggered using using a cronjob. It queries the inverter +for metrics, parses and encodes them and sends the result over HTTPS to the +server process. + +### solar-toolkit-gateway + +A binary which accepts incoming HTTP requests containing inverter metrics, and +writes them to a PostgreSQL database. + +## Visualisation + +Once collected, the metrics can be visualised using any graphing software, e.g. +[Grafana](https://grafana.com/). + +![Solar metrics](picture.png "Solar metrics") + +## TODO + +* (client) improve error handling, e.g. during network outage +* (client) support more Goodwe models +* (client) allow fine-tuning of the collected metrics (e.g. ignore selected + metrics) +* (database) migrate from fixed schema to a single JSONB column ## Build +``` +go build ./... +``` + +To build the client for linux-arm64 (e.g. Raspberry Pi): + ``` GOOS=linux GOARCH=arm go build -o solar-toolkit-daemon ./cmd/daemon ``` diff --git a/command/command.go b/command/command.go index 95c99f5..7e431f5 100644 --- a/command/command.go +++ b/command/command.go @@ -1,3 +1,5 @@ +// Package command provides communication patterns for Goodwe inverters using +// the Modbus protocol. package command import ( diff --git a/inverter/et.go b/inverter/et.go index 8e6bcd4..53c5bf3 100644 --- a/inverter/et.go +++ b/inverter/et.go @@ -1,3 +1,4 @@ +// Package inverter contains inverter model-specific functionality. package inverter import ( @@ -15,6 +16,9 @@ import ( // The timezone used to parse timestamps. const locationName = "Europe/Madrid" +// ET represents an inverter from Goodwe's ET/EH/BT/SH series. +// +// See: https://github.com/marcelblijleven/goodwe/blob/29de1c4303fffd3e984eb3314db4b5085fbaf334/goodwe/et.py#L16 type ET struct { SerialNumber string ModelName string @@ -24,7 +28,7 @@ func (inv ET) isSinglePhase() bool { return strings.Contains(inv.SerialNumber, "EHU") } -// Unexported struct used for parsing binary data only. +// etDeviceInfo is an unexported struct used for parsing binary data only. type etDeviceInfo struct { ModbusVersion uint16 RatedPower uint16 @@ -59,7 +63,7 @@ func (info *etDeviceInfo) toDeviceInfo() *DeviceInfo { } } -// Unexported struct used for parsing binary data only. +// etMeterData is an unexported struct used for parsing binary data only. type etMeterData struct { ComMode int16 RSSI int16 @@ -130,7 +134,7 @@ func (data *etMeterData) toMeterData(singlePhase bool) *ETMeterData { } } -// Unexported struct used for parsing binary data only. +// etRuntimeData is an unexported struct used for parsing binary data only. // // Raw types are based partly on the the PyPI library, and partly on the // third-party online documentation: diff --git a/inverter/types.go b/inverter/types.go index 125522f..787de88 100644 --- a/inverter/types.go +++ b/inverter/types.go @@ -57,6 +57,7 @@ type DeviceInfo struct { SinglePhase bool `json:"single_phase"` } +// ETRuntimeData holds parsed runtime data for the ET series of inverters. type ETRuntimeData struct { Timestamp time.Time `json:"timestamp" db:"timestamp"` PV1Voltage Voltage `json:"pv1_voltage" db:"pv1_voltage"` @@ -137,6 +138,7 @@ type ETRuntimeData struct { HouseConsumption Power `json:"house_consumption" db:"house_consumption"` } +// ETMeterData holds parsed meter data for the ET series of inverters. type ETMeterData struct { ComMode int `json:"com_mode" db:"-"` RSSI int `json:"-" db:"-"` diff --git a/picture.png b/picture.png new file mode 100644 index 0000000..a4b881f Binary files /dev/null and b/picture.png differ