-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Prometheus support #195
Conversation
If you open this project in GoLand, it will create a .idea/ directory which could have been tracked by Git.
Some metrics are implemented in handler.go and scan.go. Each metrics is accessible via global variable. Helper method UpdateMeasurementMetric adds flexibility to updating specific measurement without hardcoding Prometheus Metric in certain places.
87a593c
to
9564705
Compare
When using newGaugeOpts/newCounterOpts, all objects will share the same namespace "mbmd"
…auges of measurements Instead of creating a new counter/gauges for a measurement by hand, we simply just add a newly added measurement to the appropriate counterVeh/gaugesVeh map. This also means that everytime a new measurement in meters.Measurement is introduced, the maps in prometheus.go need to be updated as well.
07d34b2
to
47ef881
Compare
47ef881
to
5bb9fdc
Compare
Instead of actively managing and storing each measurement in gauges and counters map respectively, in measurements.go, each entry in `iec` is assigned a PrometheusMetricType. When prometheus_metrics.Init is called, the appropriate prometheus.Metric will be initialized and will still be stored in gauges/counters map, but its content now dynamically changes based on meters.Measurements actually enum entries, making meters.Measurements the single instance of responsibility for handling metric types.
Instead of creating only one instance of each Prometheus metric measurement, each metric will now differ in each device's manufacturer
12da79d
to
5cfafbb
Compare
Each static metrics is now categorized by interface `collectable`. `collectable.Collect()` will be called when all static metrics are registered to the default Prometheus registry.
When using `prometheus.MustRegister(...)`, the app will panic if a slice entry is nil. Meanwhile fail fast isn't bad, the stack trace doesn't provide enough/precise information about the panic. `prometheus.Register(prometheus.Collector)` however returns an error object which makes it much easier to troubleshoot metric registrations.
If no device description is available, we cannot distinguish between all device structs which it makes also difficult to distinguish between metrics. Therefore I add the device name that the config specifies in order to make them "comparable"
As these metrics are SunSpec specific, we integrate them into Prometheus metrics name
Full names now use the plural form.
Add conversion funcs in order to display measurement values in units specifically set for Prometheus. Starting with this commit, Kilowatt-hours are converted to Joules.
This is purely a change of expressions
This can be quite useful in case the serial number of the smart meter is missing
…eus names This also renames measurementOptions functions: - withPrometheusDescription -> withPrometheusHelpText - withGenericPrometheusDescription -> withGenericPrometheusHelpText - generatePrometheusDescription -> generatePrometheusHelpText
Prometheus metrics are now automatically converted to a measurement's elementary unit.
…riptions Unit stuff is now in a separate package called `units`. units.go has been completely refactored to use the functional options pattern as well.
763ef94
to
381f906
Compare
…measurement Prometheus (partial) names: string_n_energy_generated
Sum: newInternalMeasurement(withDescription("Total Energy Sum"), withPrometheusName("energy_sum"), withUnit(units.KiloWattHour), withMetricType(Counter)), | ||
SumT1: newInternalMeasurement(withDescription("Tariff 1 Energy Sum"), withUnit(units.KiloWattHour), withMetricType(Counter)), | ||
SumT2: newInternalMeasurement(withDescription("Tariff 2 Energy Sum"), withUnit(units.KiloWattHour), withMetricType(Counter)), | ||
SumL1: newInternalMeasurement(withDescription("L1 Energy Sum"), withUnit(units.KiloWattHour), withMetricType(Counter)), | ||
SumL2: newInternalMeasurement(withDescription("L2 Energy Sum"), withUnit(units.KiloWattHour), withMetricType(Counter)), | ||
SumL3: newInternalMeasurement(withDescription("L3 Energy Sum"), withUnit(units.KiloWattHour), withMetricType(Counter)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andig What does Total [Energy] Sum
exactly mean? Does it represent a kind of balance between imported/exported energy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is just the Sum
value that mbmd
is reading from the meters. Whether this is actually a sum of import and export (probably import - export) is up to the meter manufacturer.
Bus scan metrics are pointless as they're used for diagnosis purposes. As they're not registered and no REST is available, we can remove these metrics.
…metheus Also removes debug message of printing all measurement names.
This allows us to pass a measurement's timestamp and using setters on gauges.
any update on this? |
While not the same as a native Prometheus exporter, I am now using a python script to get the mbmd data via mqtt into Prometheus: https://github.com/RichieB2B/simple-mqtt-exporter/blob/main/examples/config-mbmd.py |
Hey, I'm sorry, but I'm afraid I cannot provide real support or updates on this one. This implementation has been part of a research project some years before, and I can't guarantee its functionality anymore as e.g. I have no way to test this in a local environment properly. Feel free to pick up on this MR if you think that the current code base suits your needs. |
@kereis Thanks for the update! Once my SolarEdge inverters are running will continue with your PR/MR. https://github.com/SchumacherFM/mbmd already started with some refactorings of your code. |
See #193