Skip to content

Commit

Permalink
Merge pull request #20 from badguy99/next_price
Browse files Browse the repository at this point in the history
Add ability to set hours to next, to get the next import or export price
  • Loading branch information
badguy99 committed Dec 29, 2020
2 parents 846ad9e + a5579ec commit cb34a06
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 35 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ If you think this will be useful to you, please consider signing up to Octopus E

Octoblock is an app which works under [AppDaemon](https://www.home-assistant.io/docs/ecosystem/appdaemon/) within [Home Assistant](https://www.home-assistant.io/) which finds the cheapest “n” hour block for import or the most expensive “n” hour block for export, and works out the price of that block, for the Octopus Energy, Agile Octopus / Agile Outgoing Octopus tariffs.

*Please note:* *Breaking Changes!* New yaml structure in version 2!

It creates and sets sensors for the cost and start time, for example, using the `apps.yaml` file below, the following entities are created and then updated:
```yaml
sensor.octopus_1hour_time
Expand All @@ -26,13 +24,20 @@ sensor.octopus_export_1hour_time
sensor.octopus_export_1hour_price
```

Sensor names can be overridden and your own name specified in the yaml configuration. These will be of the format `sensor.<your_name>_time` and `sensor.<your_name>_price` with any dots in `<your_name>` changed to underscores.

### Special Cases
With `start_period` set to `now` and `hour` set to `0` the current import or export price is returned, and the sensors are named:
```yaml
sensor.octopus_current_price
sensor.octopus_export_current_price
```

Sensor names can be overridden and your own name specified in the yaml configuration. These will be of the format `sensor.<your_name>_time` and `sensor.<your_name>_price` with any dots in `<your_name>` changed to underscores.
With `start_period` set to `now` and `hour` set to `next` the next import or export price is returned, and the sensors are named:
```yaml
sensor.octopus_next_price
sensor.octopus_export_next_price
```

## Installation

Expand Down
67 changes: 35 additions & 32 deletions apps/octoblock/octoblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def get_import_prices(self):
)

tariff = json.loads(r.text)
self.incoming_tariff = tariff[u"results"]
self.incoming_tariff = tariff["results"]
self.incoming_tariff.reverse()

def get_export_prices(self):
Expand All @@ -113,7 +113,7 @@ def get_export_prices(self):
)

tariff = json.loads(r.text)
self.outgoing_tariff = tariff[u"results"]
self.outgoing_tariff = tariff["results"]
self.outgoing_tariff.reverse()

def calculate_limit_points(self):
Expand Down Expand Up @@ -232,50 +232,38 @@ def date_to_idx(cls, tariff, date):
return idx

def get_current_period_and_cost(self, tariffresults):
now_or_next = "Current" if self.hours == 0 else "Next"
direction = "import" if self.incoming else "export"
now_utc_flr = self.floor_dt(datetime.datetime.utcnow())
api_date_now = self.dt_to_api_date(now_utc_flr)
self.log(
"**Now API Date get_period_and_cost: {} **".format(api_date_now),
level="DEBUG",
f"**Now API Date get_period_and_cost: {api_date_now} **", level="DEBUG"
)

i = self.date_to_idx(tariffresults, api_date_now)
if self.incoming:
self.price = tariffresults[i]["value_inc_vat"]
self.log(
"Current import price is: {} p/kWh".format(self.price), level="INFO"
)
self.log(
"**Tariff Date get_period_and_cost: {} **".format(
tariffresults[i]["valid_from"]
),
level="DEBUG",
)

elif self.outgoing:
self.price = tariffresults[i]["value_inc_vat"]
self.log(
"Current export price is: {} p/kWh".format(self.price), level="INFO"
)
self.log(
"**Tariff Date get_period_and_cost: {} **".format(
tariffresults[i]["valid_from"]
),
level="DEBUG",
)
if str(self.hours).lower() == "next":
i += 1
self.price = tariffresults[i]["value_inc_vat"]
self.log(
f"{now_or_next} {direction} price is: {self.price} p/kWh", level="INFO"
)
self.log(
f"**Tariff Date get_period_and_cost: {tariffresults[i]['valid_from']} **",
level="DEBUG",
)

def get_period_and_cost(self):
blocks = float(self.hours) * 2
blocks = int(blocks)
if self.incoming:
tariffresults = self.incoming_tariff
else:
tariffresults = self.outgoing_tariff

if self.hours == 0:
if self.hours == 0 or str(self.hours).lower() == "next":
self.get_current_period_and_cost(tariffresults)

else:
blocks = float(self.hours) * 2
blocks = int(blocks)
start_idx = self.date_to_idx(tariffresults, self.start_date)
end_idx = self.date_to_idx(tariffresults, self.end_date)
if not end_idx:
Expand All @@ -297,7 +285,7 @@ def get_period_and_cost(self):
continue
cost = 0
for block in range(blocks):
cost = cost + (tariffresults[curridx + block][u"value_inc_vat"])
cost = cost + (tariffresults[curridx + block]["value_inc_vat"])
cost = cost / blocks
period[str(self.hours) + "_hour_average"] = cost

Expand Down Expand Up @@ -327,7 +315,7 @@ def get_period_and_cost(self):
for curridx in range(start_idx, end_idx):
period = tariffresults[curridx]
if period[str(self.hours) + "_hour_average"] == self.price:
self.time = period[u"valid_from"]
self.time = period["valid_from"]
self.log("**Time: {}**".format(self.time), level="DEBUG")

if self.use_timezone:
Expand Down Expand Up @@ -357,6 +345,12 @@ def write_block_sensor_data(self):
state=round(self.price, 4),
attributes={"unit_of_measurement": "p/kWh", "icon": "mdi:flash"},
)
elif str(self.hours).lower() == "next":
self.set_state(
"sensor.octopus_next_price",
state=round(self.price, 4),
attributes={"unit_of_measurement": "p/kWh", "icon": "mdi:flash"},
)
else:
if not self.name:
entity_id_t = "sensor.octopus_" + hours + "hour_time"
Expand All @@ -382,6 +376,15 @@ def write_block_sensor_data(self):
"icon": "mdi:flash-outline",
},
)
elif str(self.hours).lower() == "next":
self.set_state(
"sensor.octopus_export_next_price",
state=round(self.price, 4),
attributes={
"unit_of_measurement": "p/kWh",
"icon": "mdi:flash-outline",
},
)
else:
if not self.name:
entity_id_t = "sensor.octopus_export" + hours + "hour_time"
Expand Down

0 comments on commit cb34a06

Please sign in to comment.