Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions .github/workflows/build-hub-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,20 @@ jobs:
echo "CONTEXT=./hub-server" >> $GITHUB_ENV
echo "IMAGE_NAME=ghcr.io/devoldschool/powermeter_hub_server/hub-server" >> $GITHUB_ENV

# Step 5: Determine tags
# Step 5: Generate version
- name: Generate version
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
else
VERSION="dev-${GITHUB_SHA::8}"
fi
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Writing version $VERSION to __version__.py"
echo "__version__ = \"$VERSION\"" > hub-server/__version__.py

# Step 6: Determine tags
- name: Determine tags
run: |
TAGS="${{ env.IMAGE_NAME }}:latest,${{ env.IMAGE_NAME }}:${GITHUB_SHA}"
Expand All @@ -48,7 +61,7 @@ jobs:
fi
echo "TAGS=$TAGS" >> $GITHUB_ENV

# Step 6: Build and push Docker image
# Step 7: Build and push Docker image
- name: Build & Push
uses: docker/build-push-action@v5
with:
Expand All @@ -57,4 +70,5 @@ jobs:
push: true
tags: ${{ env.TAGS }}
labels: |
org.opencontainers.image.description=PowerMeter Hub Server.
org.opencontainers.image.description=PowerMeter Hub Server.
org.opencontainers.image.version=${{ env.VERSION }}
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ server:
local-data: "aa.bb.cc.dddddd.keys.sensornet.info 86400 IN A 10.0.0.213"
```

## Data Formats and Units

**MQTT payloads:**
- **Power**: Raw sensor values (h1/h2: milliamps; h3: deciwatts).
- See below for conversion to Watts.
- **Energy**: Kilowatt-hours (kWh)

**For Home Assistant users**: When MQTT discovery is *enabled*, Home Assistant automatically converts Power readings to watts using the `value_template` included in discovery messages.

**For other MQTT consumers**: You must apply the conversion yourself. Formulas are in `config.py`.

## Home Assistant Integration

### Home Assistant Operating System hosted
Expand Down Expand Up @@ -137,16 +148,19 @@ HA_DISCOVERY=true

With `HA_DISCOVERY=true`, the hub-server will automatically publish Home Assistant MQTT discovery payloads. This creates two sensors per Efergy device:

| Sensor | Topic | Unit | Device Class | State Class |
|------------------------------------------|-------------------------------------|------|--------------|------------------|
| `sensor.efergy_hub_live_power_usage_SID` | `home/efergy/<sensor_label>/power` | kW | power | measurement |
| `sensor.efergy_hub__energy_consumption` | `home/efergy/<sensor_label>/energy` | kWh | energy | total_increasing |
| Sensor | Topic | Unit | Device Class | State Class |
|----------------------------------------|-----------------------------------------|------|--------------|------------------|
| `sensor.efergy_hub_power_<sid>` | `home/efergy/efergy_h<X>_<SID>/power` | W | power | measurement |
| `sensor.efergy_hub_energy_consumption` | `home/efergy/energy_consumption/energy` | kWh | energy | total_increasing |

> **Note**:
> MQTT payloads for power are raw values, but Home Assistant applies the necessary conversion to Watts automatically. See the [Data Formats and Units](#data-formats-and-units) section for details.

Home Assistant will pick up these sensors automatically, making them available for dashboards, automations, and the Energy Dashboard.

3. Add Sensors to Energy Dashboard
Once discovered, the `sensor.efergy_energy_consumption` sensor can be added to Home Assistant’s Energy Dashboard under Grid Consumption, allowing you to track daily, weekly, and monthly usage.

Once discovered, the `sensor.efergy_hub_energy_consumption` sensor can be added to Home Assistant’s Energy Dashboard under Grid Consumption, allowing you to track daily, weekly, and monthly usage.


### Container hosted
Expand Down Expand Up @@ -181,7 +195,7 @@ sql: !include sensors.yaml
5. **Restart Home Assistant**.

You will now have two sensors:
* `sensor.efergy_hub_live_power_usage_SID`: The instantaneous power reading in kW.
* `sensor.efergy_hub_power_<sid>`: The instantaneous power reading in W.
* `sensor.efergy_hub_energy_consumption`: A running total of energy consumed in kWh, which can be added directly to your Home Assistant Energy Dashboard.


Expand All @@ -192,4 +206,6 @@ You will now have two sensors:

## Efergy Data Format

Documentation about the known data formats is within the [Wiki](https://github.com/DevOldSchool/powermeter_hub_server/wiki/Hub-v2-v3-Data-Format).
Documentation about the known hub payload formats and data structures:
- [Hub v1 Data Format](https://github.com/DevOldSchool/powermeter_hub_server/wiki/Hub-V1-Data-Format)
- [Hub v2/v3 Data Format](https://github.com/DevOldSchool/powermeter_hub_server/wiki/Hub-v2-v3-Data-Format)
2 changes: 1 addition & 1 deletion hub-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.9-slim
FROM python:3.14-slim

LABEL org.opencontainers.image.description="PowerMeter Hub Server."

Expand Down
5 changes: 5 additions & 0 deletions hub-server/__version__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Auto-generated during build by GitHub Actions
# Do not edit manually - this file is overwritten during CI/CD build
__version__ = "dev-local"


15 changes: 14 additions & 1 deletion hub-server/hub_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
import logging
import socket
import sys
from http.server import HTTPServer, SimpleHTTPRequestHandler
from typing import Type
from urllib.parse import urlparse, parse_qs
Expand All @@ -14,8 +15,9 @@
from mqtt_manager import MQTTManager
from aggregator import Aggregator
from payload_parser import parse_sensor_payload
from __version__ import __version__
from config import (
SERVER_PORT, LOG_LEVEL
SERVER_PORT, LOG_LEVEL, MQTT_ENABLED, HA_DISCOVERY
)

class EfergyHTTPServer(HTTPServer):
Expand Down Expand Up @@ -243,6 +245,17 @@ def run_server(database: Database, host: str = '0.0.0.0', port: int = 5000):
format="%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d - %(message)s",
)

# Startup banner
logging.info("=" * 60)
logging.info(" Efergy Hub Server")
logging.info(f" Version: {__version__}")
logging.info("=" * 60)
logging.info(f" Python: {sys.version.split()[0]}")
logging.info(f" Port: {SERVER_PORT}")
logging.info(f" MQTT: {'enabled' if MQTT_ENABLED else 'disabled'}")
logging.info(f" HA Discovery: {'enabled' if HA_DISCOVERY else 'disabled'}")
logging.info("=" * 60)

# Adjust this path as needed for your project structure
DB_FILE_PATH = Path(__file__).resolve().parent / "data/readings.db"

Expand Down
2 changes: 1 addition & 1 deletion hub-server/mqtt_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def publish_power_discovery(self, label: str, sid: str, topic: str, hub_version:
unit_of_measurement = POWER_UNIT_OF_MEASUREMENT_H3
value_template = POWER_VALUE_TEMPLATE_H3
else:
unit_of_measurement = "kW"
unit_of_measurement = "W"
value_template = "{{ (value_json.value | float) }}"

payload = {
Expand Down