Meter Reader is a client library and command-line tool for retrieving near-realtime energy usage data from a smart meter via the Eagle™ Home Energy Gateway. See Rainforest™ Automation for more information about the Eagle™ Home Energy Gateway.
Disclaimer: Meter Reader is not affiliated with the Eagle™ Home Energy Gateway or Rainforest™ Automation.
- Library API - Use as a Python library in your own applications
- CLI Tool - Command-line interface for querying gateway data
- Multiple Commands - Support for device data, instantaneous demand, and historical values
- Multiple Formats - Output in table, JSON, or CSV format
- Type-Safe - Full type hints for better IDE support and type checking
- Modern Packaging - Built with pyproject.toml and PEP 517 compliance
- No Dependencies - Pure Python standard library, no external dependencies
pip install meter-readergit clone https://github.com/eman/meter_reader.git
cd meter_reader
pip install -e .Get help:
mr --helpList devices on gateway:
mr list 192.168.1.10Get current power demand:
mr instantaneous 192.168.1.10Get device data:
mr device-data 192.168.1.10Get summation values for the past day:
mr summation 192.168.1.10 --interval dayfrom meter_reader import Gateway
# Connect to gateway
gateway = Gateway('192.168.1.10')
# Get instantaneous demand
timestamp, demand_kw = gateway.get_instantaneous_demand()
print(f'Current demand: {demand_kw}kW at {timestamp}')
# Get device data
response = gateway.run_command(Name='get_device_data')
print(response['CurrentSummation'])
# Get summation values
data = gateway.run_command(
Name='get_summation_values',
Interval='day'
)
for entry in data:
print(f"{entry['TimeStamp']}: {entry['SummationDelivered']}")All commands support the following options:
-t, --timeout SECONDS- Socket timeout (default: 5)-f, --output-format {table,json,csv}- Output format (default: table)-r, --raw- Display raw XML response--debug- Enable debug logging
List all devices on the gateway:
mr list 192.168.1.10
mr list 192.168.1.10 --output-format json
mr list 192.168.1.10 --rawGet device data from the gateway:
mr device-data 192.168.1.10
mr device-data 192.168.1.10 --output-format jsonGet current instantaneous power demand:
mr instantaneous 192.168.1.10
mr instant 192.168.1.10 # short alias
mr instantaneous 192.168.1.10 --output-format jsonOutput:
2024-02-01 21:58:39+00:00, 0.292kW
Get summation values for a time period:
mr summation 192.168.1.10 --interval day
mr summation 192.168.1.10 --interval hour --frequency 900
mr summation 192.168.1.10 --interval week --output-format csvOptions:
-i, --interval {hour,day,week}- Time interval (default: day)--frequency SECONDS- Seconds between samples-s, --start-time TIME- Start time-e, --end-time TIME- End time-d, --duration SECONDS- Duration in seconds
Get demand values for a time period:
mr demand 192.168.1.10 --interval day
mr demand 192.168.1.10 --interval week --output-format jsonOptions same as summation command.
MessageCluster
DeviceMacId xx:xx:xx:xx:xx:xx:xx:xx
MeterMacId xx:xx:xx:xx:xx:xx:xx
TimeStamp 2024-02-01 21:58:39+00:00
mr device-data 192.168.1.10 --output-format json{
"MessageCluster": {
"DeviceMacId": "xx:xx:xx:xx:xx:xx:xx:xx",
"MeterMacId": "xx:xx:xx:xx:xx:xx:xx",
"TimeStamp": "2024-02-01 21:58:39+00:00"
}
}mr summation 192.168.1.10 --output-format csvMessageCluster.DeviceMacId,xx:xx:xx:xx:xx:xx:xx:xx
MessageCluster.TimeStamp,2024-02-01 21:58:39+00:00
from meter_reader import Gateway
gateway = Gateway(address, port=5002, timeout=5)Parameters:
address(str): Gateway IP address or hostnameport(int): Gateway port (default: 5002)timeout(int): Socket timeout in seconds (default: 5)
Methods:
Send a command to the gateway and return parsed response.
response = gateway.run_command(Name='list_devices')
response = gateway.run_command(
Name='get_summation_values',
Interval='day'
)Parameters:
Name(str): Command nameconvert(bool): Convert data types (default: True)- Other parameters depending on command
Returns: dict or list of dicts
Raises: GatewayError on communication failure
Send a command and return raw XML response.
raw_xml = gateway.run_command_raw(Name='get_device_data')Get current power demand.
timestamp, demand_kw = gateway.get_instantaneous_demand()Returns: Tuple of (datetime, float)
Exception raised when gateway communication fails.
from meter_reader import GatewayError
try:
gateway = Gateway('192.168.1.10')
except GatewayError as e:
print(f'Connection failed: {e}')The following commands are supported by the gateway:
list_devices- List all devicesget_device_data- Get device dataget_instantaneous_demand- Get current demandget_demand_values- Get demand historyget_summation_values- Get summation historyget_fast_poll_status- Get fast poll status
If you get a timeout error, try increasing the timeout value:
mr device-data 192.168.1.10 --timeout 10Or in code:
gateway = Gateway('192.168.1.10', timeout=10)If the gateway doesn't have any devices connected, you may get an error. Check that your gateway is properly configured and devices are paired.
To see the raw response from the gateway for debugging:
mr device-data 192.168.1.10 --rawEnable debug logging to see detailed communication:
mr --debug device-data 192.168.1.10git clone https://github.com/eman/meter_reader.git
cd meter_reader
pip install -e ".[dev]"pytestmypy src/black src/ tests/
isort src/ tests/Version 2.0 includes significant improvements:
- Refactored CLI with subcommands instead of options
- Multiple output formats (table, JSON, CSV)
- Better error handling with logging support
- Modern packaging with pyproject.toml
- Improved documentation with examples
- Bug fix for socket handling with proper timeout support
- Removed OrderedDict usage (Python 3.7+ dict ordering)
- Full type hints throughout codebase
BSD 2-Clause License - See LICENSE.rst for details.
Copyright © 2017-2026 Emmanuel Levijarvi
Contributions are welcome! Please feel free to submit a Pull Request.
For issues, questions, or suggestions, please open an issue on GitHub.