4 Commits

Author SHA1 Message Date
rmcguire dcdf5e4230 bump chart
Build and Publish / go-binaries (push) Successful in 1m41s
Build and Publish / check-chart (push) Successful in 10s
Build and Publish / helm-release (push) Has been skipped
Build and Publish / container-images (push) Successful in 5m19s
2026-07-05 14:56:30 -04:00
rmcguire 1b42d26ffc add changelog 2026-07-05 14:56:10 -04:00
rmcguire a8e0a6ef1e support tls insecure due to cloudblade old TLS cert 2026-07-05 14:53:10 -04:00
rmcguire 059b89b5cd add TODO
Build and Publish / helm-release (push) Has been skipped
Build and Publish / container-images (push) Has been skipped
Build and Publish / go-binaries (push) Has been skipped
Build and Publish / check-chart (push) Successful in 10s
2026-07-04 17:47:54 -04:00
6 changed files with 77 additions and 26 deletions
+7
View File
@@ -30,6 +30,13 @@ that's all it takes — no extra wiring.
- `costPerKWH` is **US dollars per kWh** (0.18 = 18¢), feeding
`econet_energy_cost_dollars`.
- `econetTLSInsecure` (env `ECONET_TLS_INSECURE`) skips TLS certificate
verification when connecting to the EcoNet cloud API. It exists because the
upstream host (cloudblade) serves a
DigiCert Global Root G1 chain, which is no longer trusted by default in
current root stores. **Evaluate removing this later** — prefer fixing the
trust chain (e.g. bundling the needed intermediate/root CA) over disabling
verification outright.
## Metrics conventions
+50 -15
View File
@@ -1,18 +1,53 @@
# v0.7.0
* feat: Add HTTP log exclusion regex paths to configuration schema.
* chore: Update Go version to 1.25.
* chore: Update module dependencies.
# Changelog
# v0.6.0
* feat: Introduce Model Context Protocol (MCP) server with a demo random fact tool.
* feat: Add MCP server configuration file (`contrib/mcpinspector.json`).
* deps: Update Go module dependencies, including `bufbuild/protovalidate`, `go-app`, `grpc-gateway`, `googleapis/api`, `grpc`, `protobuf`, `golang.org/x/exp`, and `googleapis/rpc`.
* deps: Add new Go module dependencies: `modelcontextprotocol/go-sdk` and `k8s.io/utils`.
All notable changes to econet-exporter are documented here. The format is
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# v0.5.0
## [v0.2.0] - 2026-07-05
* Added OpenTelemetry tracing for application startup.
* Updated Go module dependencies, including `protovalidate`, `go-app`, `grpc`, and OpenTelemetry related packages.
* Enhanced `Makefile` `rename` target to update the application name constant in `main.go`.
* Configured `air` live-reloading to exclude the `proto` directory.
* Refactored application initialization logic for improved modularity and OpenTelemetry integration.
### Added
* `econetTLSInsecure` config option (env `ECONET_TLS_INSECURE`) to skip TLS
certificate verification when
connecting to the Rheem/EcoNet cloud API. The upstream host (cloudblade)
serves an old/untrusted certificate chain; this is a stopgap and should be
removed once the upstream certificate is fixed. See AGENTS.md.
* `TODO.md` tracking outstanding work (CA cert bundle, mutating proto RPCs,
additional tracing spans).
## [v0.1.2] - 2026-07-04
### Added
* CA certificate bundle baked into the container image so the exporter can
establish TLS connections to the EcoNet API.
### Changed
* Bumped Helm chart versions.
## [v0.1.1] - 2026-07-04
### Fixed
* Corrected the Helm chart `appVersion`.
## [v0.1.0] - 2026-07-04
Initial release of the EcoNet exporter for Rheem / Rheemcloud water heaters,
built on the `go-app` framework.
### Added
* `EconetService` owning a single shared `*rheemcloud.Client` across the gRPC,
MCP, and metrics sub-servers (fail-fast on missing credentials).
* gRPC API (`ListDevices`, `GetDevice`) with proto definitions and
grpc-gateway REST bindings.
* MCP server at `/api/mcp` exposing a `list_water_heaters` tool.
* OpenTelemetry observable gauges for device state (temperature, mode, energy
and water usage, cost) with a background usage poller, exported to
Prometheus. Units are encoded in metric names (`_fahrenheit`, `_kwh`,
`_gallons`, `_dollars`).
* `costPerKWH` config (US dollars per kWh) feeding `econet_energy_cost_dollars`.
* Helm chart for Kubernetes deployment.
+6 -9
View File
@@ -1,10 +1,7 @@
# Demo app TODO
# econet-exporter TODO
- [ ] Fix Docerfile for ca cert bundle (TLS error to API host)
- [ ] Add mutating proto RPCs (change mode, etc..)
- [ ] Add spans to things
- [x] Create generic interface for implenting a service
- [x] Create config sample not called demo, so it is more easily reused
- [x] Update README for tagging/versioning/pipeline info
- [x] Update README for detail on installing protoc tools and make
- [x] Rename project
- [x] Finish grpc sample implementation
- [x] Add Dockerfile
- [x] Add gitea CI
+2 -2
View File
@@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.4
version: 0.1.5
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "v0.1.2"
appVersion: "v0.2.0"
dependencies:
- name: hull
+3
View File
@@ -22,6 +22,9 @@ type ServiceConfig struct {
EconetEmail string `yaml:"econetEmail" json:"econetEmail,omitempty" env:"ECONET_EMAIL"`
EconetPassword string `yaml:"econetPassword" json:"econetPassword,omitempty" env:"ECONET_PASSWORD"`
// Necessary due to ancient TLS certificate run by cloudblade that isn't trusted in modern ca-certificate bundles
EconetTLSInsecure bool `yaml:"econetTLSInsecure" json:"econetTLSInsecure,omitempty" env:"ECONET_TLS_INSECURE" default:"false"`
// CostPerKWH is the electricity price in US dollars per kWh (e.g. 0.18
// means 18 cents/kWh, NOT 18). It derives the econet_energy_cost_dollars
// metric from kWh energy usage.
+9
View File
@@ -5,8 +5,10 @@ package econet
import (
"context"
"crypto/tls"
"fmt"
"log/slog"
"net/http"
rheemcloud "github.com/kevinburke/rheemcloud-go"
@@ -55,6 +57,13 @@ func connect(ctx context.Context, cfg *config.ServiceConfig) (*rheemcloud.Client
}
client, err := rheemcloud.Connect(ctx, cfg.EconetEmail, cfg.EconetPassword, &rheemcloud.Config{
Logger: slog.Default(),
HTTPClient: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: cfg.EconetTLSInsecure,
},
},
},
})
if err != nil {
return nil, fmt.Errorf("econet: connect failed: %w", err)