Skip to content

Commit 425e491

Browse files
committed
Merge branch 'develop' into feat/intelligent-device-change-repair-notice
2 parents 95c9ddb + 8b9c13d commit 425e491

File tree

11 files changed

+92
-48
lines changed

11 files changed

+92
-48
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Setup python environment
2+
description: Sets up required python environment, and caches dependencies
3+
inputs:
4+
python-version:
5+
description: 'Python version to use'
6+
required: true
7+
runs:
8+
using: composite
9+
steps:
10+
- name: Set up Python
11+
uses: actions/setup-python@v5
12+
with:
13+
python-version: ${{ inputs.python-version }}
14+
- name: Display Python version
15+
run: python3 -c "import sys; print(sys.version)"
16+
shell: bash
17+
- name: Cache pip
18+
uses: actions/cache@v4
19+
with:
20+
path: |
21+
~/.cache/pip
22+
key: ${{ runner.os }}-${{ inputs.python-version }}-pip-${{ hashFiles('**/requirements*.txt') }}
23+
restore-keys: |
24+
${{ runner.os }}-${{ inputs.python-version }}-pip-
25+
- name: Install Python modules
26+
run: |
27+
pip install -r requirements.test.txt
28+
shell: bash

.github/actions/setup/action.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@ runs:
44
using: composite
55
steps:
66
- name: Install dependencies
7-
run: sudo apt install libffi-dev libncurses5-dev zlib1g zlib1g-dev libssl-dev libreadline-dev libbz2-dev libsqlite3-dev
7+
run: sudo apt install libffi-dev libncurses5-dev zlib1g zlib1g-dev libssl-dev libreadline-dev libbz2-dev libsqlite3-dev liblzma-dev
88
shell: bash
99
- name: asdf_install
10-
uses: asdf-vm/actions/install@v3
11-
- name: Install Python modules
12-
run: |
13-
pip install -r requirements.test.txt
14-
shell: bash
10+
uses: asdf-vm/actions/install@v4

.github/workflows/docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
mkdocs-material-
3737
- run: pip install -r requirements.txt
3838
- run: mkdocs build
39-
39+
4040
deploy_docs:
4141
if: ${{ github.repository_owner == 'BottlecapDave' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main') }}
4242
name: Deploy docs
@@ -50,7 +50,7 @@ jobs:
5050
sparse-checkout: |
5151
_docs
5252
- name: asdf_install
53-
uses: asdf-vm/actions/install@v3
53+
uses: asdf-vm/actions/install@v4
5454
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
5555
- uses: actions/cache@v4
5656
with:

.github/workflows/main.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,31 +41,47 @@ jobs:
4141
if: ${{ github.event_name != 'schedule' || github.repository_owner == 'BottlecapDave' }}
4242
name: Unit Tests
4343
runs-on: ubuntu-latest
44+
timeout-minutes: 15
45+
strategy:
46+
matrix:
47+
python-version: ["3.12", "3.13"]
4448
steps:
4549
- name: Checkout
4650
uses: actions/checkout@v4
4751
with:
4852
fetch-depth: 0
4953
- name: Setup
5054
uses: ./.github/actions/setup
55+
- name: Setup Python environment
56+
uses: ./.github/actions/setup-python
57+
with:
58+
python-version: ${{ matrix.python-version }}
5159
- name: Run unit tests
5260
run: |
53-
python -m pytest tests/unit
61+
python3 -m pytest tests/unit
5462
integration_tests:
5563
# Tests are geared towards my account, so ignore for others
5664
if: ${{ github.repository_owner == 'BottlecapDave' && github.repository_owner == github.actor }}
5765
name: Integration Tests
5866
runs-on: ubuntu-latest
67+
timeout-minutes: 15
68+
strategy:
69+
matrix:
70+
python-version: ["3.12", "3.13"]
5971
steps:
6072
- name: Checkout
6173
uses: actions/checkout@v4
6274
with:
6375
fetch-depth: 0
6476
- name: Setup
6577
uses: ./.github/actions/setup
78+
- name: Setup Python environment
79+
uses: ./.github/actions/setup-python
80+
with:
81+
python-version: ${{ matrix.python-version }}
6682
- name: Run integration tests
6783
run: |
68-
python -m pytest tests/integration
84+
python3 -m pytest tests/integration
6985
env:
7086
API_KEY: ${{ secrets.OCTOPUS_ENERGY_API_TOKEN }}
7187
GAS_MPRN: ${{ secrets.OCTOPUS_ENERGY_GAS_MPRN }}
@@ -76,7 +92,7 @@ jobs:
7692
release:
7793
name: Release
7894
if: ${{ github.repository_owner == 'BottlecapDave' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') }}
79-
needs:
95+
needs:
8096
- validate
8197
- unit_tests
8298
- integration_tests
@@ -87,7 +103,7 @@ jobs:
87103
with:
88104
fetch-depth: 0
89105
- name: asdf_install
90-
uses: asdf-vm/actions/install@v3
106+
uses: asdf-vm/actions/install@v4
91107
- name: Install dependencies
92108
run: npm ci
93109
- name: Release

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ We use `asdf` to manage plugins.
88
asdf plugin-add nodejs
99
asdf plugin-add python
1010
sudo apt update & sudo apt upgrade
11-
sudo apt install libffi-dev libncurses5-dev zlib1g zlib1g-dev libssl-dev libreadline-dev libbz2-dev libsqlite3-dev
11+
sudo apt install libffi-dev libncurses5-dev zlib1g zlib1g-dev libssl-dev libreadline-dev libbz2-dev libsqlite3-dev liblzma-dev
1212
```
1313

1414
## Python
@@ -35,4 +35,4 @@ Integration tests are written utilising `pytest`. To run them
3535

3636
```bash
3737
API_KEY=<<OCTOPUS_API_KEY>> python -m pytest tests/integration
38-
```
38+
```

_docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Please follow the [setup guide](./setup/account.md) to setup your initial accoun
5151

5252
### Home Mini
5353

54-
If you are lucky enough to own an [Octopus Home Mini](https://octopus.energy/blog/octopus-home-mini/), you can now receive this data within Home Assistant. When setting up (or editing) your account within Home Assistant, you will need to check the box next to `I have a Home Mini`. This will gain [electricity entities](./entities/electricity.md#home-minipro-entities) and [gas entities](./entities/gas.md#home-minipro-entities) which can be added to the [energy dashboard](https://www.home-assistant.io/blog/2021/08/04/home-energy-management/).
54+
If you are lucky enough to own an [Octopus Home Mini](https://octopus.energy/blog/octopus-home-mini/) (you can request one via this link), you can now receive this data within Home Assistant. When setting up (or editing) your account within Home Assistant, you will need to check the box next to `I have a Home Mini`. This will gain [electricity entities](./entities/electricity.md#home-minipro-entities) and [gas entities](./entities/gas.md#home-minipro-entities) which can be added to the [energy dashboard](https://www.home-assistant.io/blog/2021/08/04/home-energy-management/).
5555

5656
!!! info
5757

@@ -63,7 +63,7 @@ If you are lucky enough to own an [Octopus Home Mini](https://octopus.energy/blo
6363

6464
### Home Pro
6565

66-
If you are lucky enough to own an Octopus Home Pro, you can now receive this data within Home Assistant. When setting up (or editing) your account within Home Assistant, you will need to configure your [Home Pro](./setup/account.md#home-pro). This will gain [electricity entities](./entities/electricity.md#home-minipro-entities) and [gas entities](./entities/gas.md#home-minipro-entities) which can be added to the [energy dashboard](https://www.home-assistant.io/blog/2021/08/04/home-energy-management/).
66+
If you are lucky enough to own an [Octopus Home Pro](https://forum.octopus.energy/t/for-the-pro-user/8453/2352/) (note that is is no longer possible to obtain one), you can now receive this data within Home Assistant. When setting up (or editing) your account within Home Assistant, you will need to configure your [Home Pro](./setup/account.md#home-pro). This will gain [electricity entities](./entities/electricity.md#home-minipro-entities) and [gas entities](./entities/gas.md#home-minipro-entities) which can be added to the [energy dashboard](https://www.home-assistant.io/blog/2021/08/04/home-energy-management/).
6767

6868
!!! info
6969

_docs/setup/account.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Setup is done entirely via the [integration UI](https://my.home-assistant.io/red
44

55
## Home Mini
66

7-
If you are lucky enough to own an [Octopus Home Mini](https://octopus.energy/blog/octopus-home-mini/), you can now receive this data within Home Assistant. When setting up (or editing) your account within Home Assistant, you will need to check the box next to `I have a Home Mini`. This will gain the following entities which can be added to the [energy dashboard](https://www.home-assistant.io/blog/2021/08/04/home-energy-management/):
7+
If you are lucky enough to own an [Octopus Home Mini](https://octopus.energy/blog/octopus-home-mini/) (you can request one via this link), you can now receive this data within Home Assistant. When setting up (or editing) your account within Home Assistant, you will need to check the box next to `I have a Home Mini`. This will gain the following entities which can be added to the [energy dashboard](https://www.home-assistant.io/blog/2021/08/04/home-energy-management/):
88

99
!!! info
1010

@@ -73,7 +73,7 @@ In this scenario only started dispatches will be taken into account for adjustme
7373

7474
## Home Pro
7575

76-
If you are lucky enough to own an [Octopus Home Pro](https://forum.octopus.energy/t/for-the-pro-user/8453/2352/), you can now receive this data locally from within Home Assistant.
76+
If you are lucky enough to own an [Octopus Home Pro](https://forum.octopus.energy/t/for-the-pro-user/8453/2352/) (note that is is no longer possible to obtain one), you can now receive this data locally from within Home Assistant.
7777

7878
!!! warning
7979

@@ -128,4 +128,4 @@ Once the API has been configured, you will need to set the address to the IP add
128128

129129
### Entities
130130

131-
See [entities](../entities/home_pro.md) for more information.
131+
See [entities](../entities/home_pro.md) for more information.

custom_components/octopus_energy/coordinators/electricity_rates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ async def async_refresh_electricity_rates_data(
190190
dispatches_result.dispatches.started,
191191
intelligent_rate_mode)
192192

193-
_LOGGER.debug(f"Rates adjusted: {new_rates}; dispatches: {dispatches_result.dispatches.to_dict()}")
193+
_LOGGER.debug(f"Dispatches refreshed - Rates adjusted: {new_rates}; dispatches: {dispatches_result.dispatches.to_dict()}")
194194

195195
# Sort our rates again _just in case_
196196
new_rates.sort(key=lambda rate: (rate["start"].timestamp(), rate["start"].fold))

custom_components/octopus_energy/coordinators/intelligent_dispatches.py

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,42 +79,35 @@ def __init__(self, last_evaluated: datetime, request_attempts: int, dispatches:
7979
self.requests_current_hour = requests_current_hour
8080
self.requests_current_hour_last_reset = requests_current_hour_last_reset
8181

82+
def has_dispatch_items_changed(existing_dispatches: list[SimpleIntelligentDispatchItem], new_dispatches: list[SimpleIntelligentDispatchItem]):
83+
if len(existing_dispatches) != len(new_dispatches):
84+
return True
85+
86+
if len(existing_dispatches) > 0:
87+
for i in range(0, len(existing_dispatches)):
88+
if (existing_dispatches[i].start != new_dispatches[i].start or
89+
existing_dispatches[i].end != new_dispatches[i].end):
90+
return True
91+
92+
return False
93+
8294
def has_dispatches_changed(existing_dispatches: IntelligentDispatches, new_dispatches: IntelligentDispatches):
8395
return (
8496
existing_dispatches.current_state != new_dispatches.current_state or
8597
len(existing_dispatches.completed) != len(new_dispatches.completed) or
86-
(
87-
len(existing_dispatches.completed) > 0 and
88-
(
89-
existing_dispatches.completed[0].start != new_dispatches.completed[0].start or
90-
existing_dispatches.completed[-1].start != new_dispatches.completed[-1].start
91-
)
92-
)
93-
or
98+
has_dispatch_items_changed(existing_dispatches.completed, new_dispatches.completed) or
9499
len(existing_dispatches.planned) != len(new_dispatches.planned) or
95-
(
96-
len(existing_dispatches.planned) > 0 and
97-
(
98-
existing_dispatches.planned[0].start != new_dispatches.planned[0].start or
99-
existing_dispatches.planned[-1].start != new_dispatches.planned[-1].start
100-
)
101-
)
102-
or
100+
has_dispatch_items_changed(existing_dispatches.planned, new_dispatches.planned) or
103101
len(existing_dispatches.started) != len(new_dispatches.started) or
104-
(
105-
len(existing_dispatches.started) > 0 and
106-
(
107-
existing_dispatches.started[0].start != new_dispatches.started[0].start or
108-
existing_dispatches.started[-1].start != new_dispatches.started[-1].start
109-
)
110-
)
102+
has_dispatch_items_changed(existing_dispatches.started, new_dispatches.started)
111103
)
112104

113105
def merge_started_dispatches(current: datetime,
114106
current_state: str,
115107
started_dispatches: list[SimpleIntelligentDispatchItem],
116108
planned_dispatches: list[IntelligentDispatchItem]):
117109
new_started_dispatches = clean_previous_dispatches(current, started_dispatches)
110+
new_started_dispatches = list(map(lambda item: SimpleIntelligentDispatchItem(item.start, item.end), new_started_dispatches))
118111

119112
if current_state == "SMART_CONTROL_IN_PROGRESS":
120113
for planned_dispatch in planned_dispatches:

custom_components/octopus_energy/intelligent/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
_LOGGER = logging.getLogger(__name__)
1818

19-
def mock_intelligent_dispatches() -> IntelligentDispatches:
19+
def mock_intelligent_dispatches(current_state = "SMART_CONTROL_CAPABLE") -> IntelligentDispatches:
2020
planned: list[IntelligentDispatchItem] = []
2121
completed: list[IntelligentDispatchItem] = []
22-
current_state = "SMART_CONTROL_CAPABLE"
2322

2423
dispatches = [
2524
IntelligentDispatchItem(

0 commit comments

Comments
 (0)