Skip to content

Commit

Permalink
Merge pull request #13 from JoshuaDodds/feature/homeconnect2mqtt
Browse files Browse the repository at this point in the history
Release Candidate: add Feature/homeconnect2mqtt module
  • Loading branch information
JoshuaDodds authored Jan 9, 2025
2 parents b514181 + f19cdb3 commit c2326c3
Show file tree
Hide file tree
Showing 8 changed files with 437 additions and 61 deletions.
79 changes: 25 additions & 54 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,87 +3,58 @@
# Timezone
TIMEZONE='Europe/Amsterdam'

# Docker version and container repo credentials
VERSION="$(TZ=${TIMEZONE} date +%Y.%m.%d.%H)"
CR_PAT=""

# Victron
CERBOGX_IP="0.0.0.0"
VRM_PORTAL_ID='XXXXXXXXXXXXXXXX'

# Domoticz
DZ_URL_PREFIX="http://<IP ADDRESS>:80/json.htm?type=command&param=udevice&idx="
# Your Home consumes roughyl this amount of energy (in kWh) per 24 hours.
DAILY_HOME_ENERGY_CONSUMPTION=16.0

# Module/Feature toggles
# You can select one or more modules to run but make sure that `mqtt_client` is always enabled and is always the
# module defined. This is because the `mqtt_client` module is the one that is responsible for the MQTT connection
# and is a blocking function which will not return while the other modules run in their own threads.
ACTIVE_MODULES='[{
"sync": {
"ev_charge_controller": false,
"energy_broker": false
},
ACTIVE_MODULES='[{"sync": {"ev_charge_controller": false, "energy_broker": false }, "async": {"mqtt_client": true, "tibber_api": false }}]'

"async": {
"mqtt_client": true,
"tibber_api": false
}
}]'
# Enable / disable appliance run scheduling at lowest prices (requires a homeconnect2mqtt bridge in local network)
HOME_CONNECT_APPLIANCE_SCHEDULING=False

# Enable / disable dynamic buy and sell decisions
DYNAMIC_ESS_NET_METERING_ENABLED=False
# Rate in Watts to export energy to the grid from the ESS
ESS_EXPORT_AC_SETPOINT=-8000.0
ESS_EXPORT_AC_SETPOINT=-10000.0

# Percentage of battery capacity to retain for own use (ie. stop energy sale at 65% battery state of charge)
DYNAMIC_ESS_BATT_MIN_SOC=80.0
DYNAMIC_ESS_BATT_MIN_SOC=50.0

VICTRON_OPTIMIZED_CHARGING=0
VICTRON_OPTIMIZED_CHARGING=1
TIBBER_UPDATES_ENABLED=0

# the max amount you want to pay in cents per kWh from Tibber (energy supplier)
MAX_TIBBER_BUY_PRICE=0.30
# the max amount you want to pay in cents per kWh from Tibber (energy supplier) when charging the ESS
MAX_TIBBER_BUY_PRICE=0.40

# !!! Warning !!!
# Unless mitigated in some other way, if the grid is lost when using this mode, the loads will also
# lose power until grid power is restored or manual intervention is done (switch back to inverter mode on).
# Use this carefully.
#
# If energy prices are equal or lower to this, switch to grid consumption (victron inverter pass-through mode)
SWITCH_TO_GRID_PRICE_THRESHOLD=0.22

### ev_charge_controller ESS options
# LOAD_RESERVATION defines the amount of solar energy produced in Watts that you want to reserve for charging your ESS
# and running house (and other) loads. When the MINIMUM_ESS_SOC percentage is reached, this amount will be reduced with
# a division of the LOAD_RESERVATION by the LOAD_REDUCTION_FACTOR to begin favoring the charge of your electric vehicle.
LOAD_RESERVATION=400
LOAD_REDUCTION_FACTOR=2
LOAD_RESERVATION=1
LOAD_REDUCTION_FACTOR=1

# battery will charge at this voltage when under MIMIMUM_ESS_SOC
BATTERY_ABSORPTION_VOLTAGE=55.0
BATTERY_ABSORPTION_VOLTAGE=57.0
# battery charge voltage will be reduced to this voltage WHEN MIMIMUM_ESS_SOC is reached
BATTERY_FLOAT_VOLTAGE=54.8
MINIMUM_ESS_SOC=95
BATTERY_FLOAT_VOLTAGE=57.0
MINIMUM_ESS_SOC=90
# batter max voltage will drop to this when MAXIMUM_ESS_SOC is reached
BATTERY_FULL_VOLTAGE=54.0
MAXIMUM_ESS_SOC=98
BATTERY_FULL_VOLTAGE=55.8
MAXIMUM_ESS_SOC=95

### ABB B2x kWh Meter integration
# if you have integrated an ABB B23/B24 RS-485 meter into your venusOS system you can toggle this option on
# and configure the topic it will read/write to in conf.py. This will allow for bypassing the load reservation
# functionality and result in more precise and accurate surplus power calculations
ABB_METER_INTEGRATION=0

# tesla credentials and home address LAT and LONG
TESLA_EMAIL=[email protected]
HOME_ADDRESS_LAT=54.1345
HOME_ADDRESS_LONG=4.1234

# HomeConnect options
CLIENTID=""
CLIENTSECRET=""
REDIRECTURI=""

# Tibber options
TIBBER_ACCESS_TOKEN="XXXXXXXXXXXXX"


# Pushover API Access
PO_USER_ID=""
PO_API_KEY=""

# AWS Credentials
AWS_ACCESS_KEY=""
AWS_SECRET_KEY=""
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Do you have one or more of the following devices in your home?
- [x] Home Energy Storage System with canbus or serial control and working well with your Victron system
- [x] an ABB B21/23/24 Kilowatt meter (optional)
- [x] a Domoticz based Home Automation system (optional)
- [x] HomeConnect enabled smart appliances (optional and currently requires you to run [https://github.com/hcpy2-0/hcpy](https://github.com/hcpy2-0/hcpy) as an additional service.)

If so, this project might be something you will find interesting. Have a look at what this project offers by
reading more below. Also, many of the cool features the modules in this project offer are visualized and controllable
Expand Down Expand Up @@ -39,7 +40,8 @@ a Domoticz server via its REST API for monitoring and historic tracking
- deep integration with Victron system for monitoring and control via the cerbo Gx MQTT broker
- Creates, exports, and updates a number of custom metrics to the victron MQTT broker for consumption by the [venus-nextgen Energy Dashboard](https://github.com/JoshuaDodds/venus-nextgen)
- dynamic ESS algorithms for automated buy and sell of energy
- solar forecasting data specific to your installation using ML models and AI for quite accurate current day production forecasts (courtesy of new VRM API features developed by Victron Energy). Note: A Victron VRM portal account is needed for this feature.
- solar forecasting data specific to your installation using ML models and AI for quite accurate current day production forecasts (courtesy of new VRM API features developed by Victron Energy). Note: A Victron VRM portal account is needed for this feature.
- HomeConnect supported appliance control. Schedules appliances to run at cheapest time of day without user intervention

Configuration for your CerboGX IP Address, VRM instance ID, and Domoticz IP/Port are configured in
the ```.env``` configuration file.
Expand All @@ -60,7 +62,6 @@ for the things you will need to adjust in your own fork of this repo.
**TODO: handle this issue automatically in a universal container build**



### Running from CLI
```python3 main.py```

Expand All @@ -75,4 +76,4 @@ Finally, use the build.sh script as a template for building an arm64 image and p
---------------
(This package is in its infancy, but contributions and collaborations are welcome.)

Copyright 2022, 2023, 2024 Joshua Dodds - All Rights Reserved.
Copyright 2022, 2023, 2024, 2025 Joshua Dodds - All Rights Reserved.
1 change: 1 addition & 0 deletions lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
'global_state',
'config_retrieval',
'config_change_handler',
'event_handler_appliances',
]
8 changes: 6 additions & 2 deletions lib/clients/mqtt_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ def _on_message(_client, _userdata, msg):
try:
# grab topic and payload from message
topic = msg.topic
value = json.loads(msg.payload.decode("utf-8"))['value']
payload = json.loads(msg.payload.decode("utf-8"))

# Attempt to extract 'value', fall back to entire payload if 'value' is not present
value = payload.get('value', payload)

# format a logging message
logmsg = f"{' '.join(topic.rsplit('/', 3)[1:3])}: {value}"
logging.debug(logmsg)
Expand All @@ -108,4 +112,4 @@ def _on_message(_client, _userdata, msg):
Event(topic, value, logmsg).dispatch()

except Exception as E:
logging.info(E)
logging.info(f"mqtt_client_factory: error processing new message: {E}")
4 changes: 4 additions & 0 deletions lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
"tesla_charge_requested": f"Tesla/vehicle0/control/charge_requested",
"tesla_battery_soc": f"Tesla/vehicle0/battery_soc",
"tesla_battery_soc_setpoint": f"Tesla/vehicle0/battery_soc_setpoint",

# Home Connect Appliance topics
"dryer_state": f"Cerbomoticzgx/homeconnect/dryer/state",
"dishwasher_state": f"Cerbomoticzgx/homeconnect/dishwasher/state",
}
})

Expand Down
11 changes: 10 additions & 1 deletion lib/event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from lib.victron_integration import regulate_battery_max_voltage, ac_power_setpoint
from lib.global_state import GlobalStateClient
from lib.notifications import pushover_notification_critical
from lib.event_handler_appliances import handle_dryer_event, handle_dishwasher_event
from lib.energy_broker import (
manage_sale_of_stored_energy_to_the_grid,
set_charging_schedule,
Expand All @@ -19,7 +20,7 @@
LOAD_RESERVATION = int(retrieve_setting("LOAD_RESERVATION")) or 0
LOAD_RESERVATION_REDUCTION_FACTOR = float(retrieve_setting("LOAD_REDUCTION_FACTOR")) or 1
MINIMUM_ESS_SOC = int(retrieve_setting("MINIMUM_ESS_SOC")) or 100

HOME_CONNECT_APPLIANCE_SCHEDULING = bool(retrieve_setting("HOME_CONNECT_APPLIANCE_SCHEDULING")) or False

class Event:

Expand Down Expand Up @@ -65,6 +66,14 @@ def ac_in_connected(self):
elif event == 1:
logging.info("AC Input: Grid is online.")

def dryer_state(self):
if HOME_CONNECT_APPLIANCE_SCHEDULING:
handle_dryer_event(self.value)

def dishwasher_state(self):
if HOME_CONNECT_APPLIANCE_SCHEDULING:
handle_dishwasher_event(self.value)

def ac_power_setpoint(self):
if float(self.value) > 0 or float(self.value) < 0:
logging.debug(f"AC Power Setpoint changed to {self.value}")
Expand Down
Loading

0 comments on commit c2326c3

Please sign in to comment.