generated from rmcguire/go-server-with-otel
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dcdf5e4230 | |||
| 1b42d26ffc | |||
| a8e0a6ef1e | |||
| 059b89b5cd | |||
| 87e53bd620 | |||
| c481d3f032 |
@@ -30,6 +30,13 @@ that's all it takes — no extra wiring.
|
|||||||
|
|
||||||
- `costPerKWH` is **US dollars per kWh** (0.18 = 18¢), feeding
|
- `costPerKWH` is **US dollars per kWh** (0.18 = 18¢), feeding
|
||||||
`econet_energy_cost_dollars`.
|
`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
|
## Metrics conventions
|
||||||
|
|
||||||
|
|||||||
+50
-15
@@ -1,18 +1,53 @@
|
|||||||
# v0.7.0
|
# Changelog
|
||||||
* feat: Add HTTP log exclusion regex paths to configuration schema.
|
|
||||||
* chore: Update Go version to 1.25.
|
|
||||||
* chore: Update module dependencies.
|
|
||||||
|
|
||||||
# v0.6.0
|
All notable changes to econet-exporter are documented here. The format is
|
||||||
* feat: Introduce Model Context Protocol (MCP) server with a demo random fact tool.
|
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
||||||
* feat: Add MCP server configuration file (`contrib/mcpinspector.json`).
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
* 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`.
|
|
||||||
|
|
||||||
# v0.5.0
|
## [v0.2.0] - 2026-07-05
|
||||||
|
|
||||||
* Added OpenTelemetry tracing for application startup.
|
### Added
|
||||||
* 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`.
|
* `econetTLSInsecure` config option (env `ECONET_TLS_INSECURE`) to skip TLS
|
||||||
* Configured `air` live-reloading to exclude the `proto` directory.
|
certificate verification when
|
||||||
* Refactored application initialization logic for improved modularity and OpenTelemetry integration.
|
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.
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ FROM alpine:latest
|
|||||||
|
|
||||||
ARG APP_NAME=econet-exporter
|
ARG APP_NAME=econet-exporter
|
||||||
|
|
||||||
|
RUN apk add --no-cache ca-certificates
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
USER 100:101
|
USER 100:101
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -15,13 +15,13 @@ type: application
|
|||||||
# This is the chart version. This version number should be incremented each time you make changes
|
# 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.
|
# to the chart and its templates, including the app version.
|
||||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||||
version: 0.1.3
|
version: 0.1.5
|
||||||
|
|
||||||
# This is the version number of the application being deployed. This version number should be
|
# 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
|
# 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.
|
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||||
# It is recommended to use it with quotes.
|
# It is recommended to use it with quotes.
|
||||||
appVersion: "v0.1.0"
|
appVersion: "v0.2.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: hull
|
- name: hull
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ type ServiceConfig struct {
|
|||||||
EconetEmail string `yaml:"econetEmail" json:"econetEmail,omitempty" env:"ECONET_EMAIL"`
|
EconetEmail string `yaml:"econetEmail" json:"econetEmail,omitempty" env:"ECONET_EMAIL"`
|
||||||
EconetPassword string `yaml:"econetPassword" json:"econetPassword,omitempty" env:"ECONET_PASSWORD"`
|
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
|
// 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
|
// means 18 cents/kWh, NOT 18). It derives the econet_energy_cost_dollars
|
||||||
// metric from kWh energy usage.
|
// metric from kWh energy usage.
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ package econet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
rheemcloud "github.com/kevinburke/rheemcloud-go"
|
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{
|
client, err := rheemcloud.Connect(ctx, cfg.EconetEmail, cfg.EconetPassword, &rheemcloud.Config{
|
||||||
Logger: slog.Default(),
|
Logger: slog.Default(),
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: cfg.EconetTLSInsecure,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("econet: connect failed: %w", err)
|
return nil, fmt.Errorf("econet: connect failed: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user