Skip to content

Commit

Permalink
Initial contribution
Browse files Browse the repository at this point in the history
Signed-off-by: Jacob Laursen <[email protected]>
  • Loading branch information
jlaur committed Mar 21, 2023
1 parent d8f6260 commit 942e20c
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 125 deletions.
34 changes: 11 additions & 23 deletions bundles/org.openhab.binding.energidataservice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,10 @@ This has the following advantages:

#### Value-Added Tax

The channels `currentSpotPrice`, `currentNetTariff`, `currentSystemTariff`, `currentElectricityTax` and `currentTransmissionNetTariff` can be configured to include VAT with this configuration parameter:

| Name | Type | Description | Default | Required | Advanced |
|-----------------|---------|----------------------------------------------|---------|----------|----------|
| includeVAT | boolean | Add VAT to amount based on regional settings | no | no | no |

Please be aware that this channel configuration will affect all linked items.
VAT is not included in any of the prices.
To include VAT for items linked to the `Number` channels, the [VAT profile](https://www.openhab.org/addons/transformations/vat/) can be used.
This must be installed separately.
Once installed, simply select "Value-Added Tax" as Profile when linking an item.

#### Current Net Tariff

Expand Down Expand Up @@ -132,7 +129,6 @@ The format of the `hourlyPrices` JSON array is as follows:

Future spot prices for the next day are usually available around 13:00 CET and are fetched around that time.
Historic prices older than 12 hours are removed from the JSON array each hour.
Channel configuration for "Include VAT" is ignored, i.e. VAT is excluded.

## Thing Actions

Expand Down Expand Up @@ -322,26 +318,19 @@ var priceMap = actions.getPrices("SpotPrice,NetTariff");
### Thing Configuration

```java
Thing energidataservice:service:energidataservice "Energi Data Service" [ priceArea="DK1", currencyCode="DKK", gridCompanyGLN="5790001089030" ] {
Channels:
Number : electricity#currentSpotPrice [ includeVAT="true" ]
Number : electricity#currentNetTariff [ includeVAT="true" ]
Number : electricity#currentSystemTariff [ includeVAT="true" ]
Number : electricity#currentElectricityTax [ includeVAT="true" ]
Number : electricity#currentTransmissionNetTariff [ includeVAT="true" ]
}
Thing energidataservice:service:energidataservice "Energi Data Service" [ priceArea="DK1", currencyCode="DKK", gridCompanyGLN="5790001089030" ]
```

### Item Configuration

```java
Group:Number:SUM CurrentTotalPrice "Current Total Price" <price>
Number CurrentSpotPrice "Current Spot Price" <price> (CurrentTotalPrice) {channel="energidataservice:service:energidataservice:electricity#currentSpotPrice"}
Number CurrentNetTariff "Current Net Tariff" <price> (CurrentTotalPrice) {channel="energidataservice:service:energidataservice:electricity#currentNetTariff"}
Number CurrentSystemTariff "Current System Tariff" <price> (CurrentTotalPrice) {channel="energidataservice:service:energidataservice:electricity#currentSystemTariff"}
Number CurrentElectricityTax "Current Electricity Tax" <price> (CurrentTotalPrice) {channel="energidataservice:service:energidataservice:electricity#currentElectricityTax"}
Number CurrentTransmissionNetTariff "Current Transmission Tariff" <price> (CurrentTotalPrice) {channel="energidataservice:service:energidataservice:electricity#currentTransmissionNetTariff"}
String HourlyPrices "Hourly Prices" <price> {channel="energidataservice:service:energidataservice:electricity#hourlyPrices"}
Number CurrentSpotPrice "Current Spot Price" <price> (CurrentTotalPrice) { channel="energidataservice:service:energidataservice:electricity#currentSpotPrice" [profile="transform:VAT"] }
Number CurrentNetTariff "Current Net Tariff" <price> (CurrentTotalPrice) { channel="energidataservice:service:energidataservice:electricity#currentNetTariff" [profile="transform:VAT"] }
Number CurrentSystemTariff "Current System Tariff" <price> (CurrentTotalPrice) { channel="energidataservice:service:energidataservice:electricity#currentSystemTariff" [profile="transform:VAT"] }
Number CurrentElectricityTax "Current Electricity Tax" <price> (CurrentTotalPrice) { channel="energidataservice:service:energidataservice:electricity#currentElectricityTax" [profile="transform:VAT"] }
Number CurrentTransmissionNetTariff "Current Transmission Tariff" <price> (CurrentTotalPrice) { channel="energidataservice:service:energidataservice:electricity#currentTransmissionNetTariff" [profile="transform:VAT"] }
String HourlyPrices "Hourly Prices" <price> { channel="energidataservice:service:energidataservice:electricity#hourlyPrices" }
```

### Thing Actions Example
Expand Down Expand Up @@ -404,5 +393,4 @@ durationPhases.add(Duration.ofMinutes(41))
durationPhases.add(Duration.ofMinutes(104))

var Map<String, Object> result = actions.calculateCheapestPeriod(now.toInstant(), now.plusHours(24).toInstant(), Duration.ofMinutes(236), phases, 0.1 | kWh)

```
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
@NonNullByDefault
public class CacheManager {

public final static int NUMBER_OF_HISTORIC_HOURS = 12;
public final static int SPOT_PRICE_MAX_CACHE_SIZE = 24 + 11 + NUMBER_OF_HISTORIC_HOURS;
public final static int TARIFF_MAX_CACHE_SIZE = 24 * 2 + NUMBER_OF_HISTORIC_HOURS;
public static final int NUMBER_OF_HISTORIC_HOURS = 12;
public static final int SPOT_PRICE_MAX_CACHE_SIZE = 24 + 11 + NUMBER_OF_HISTORIC_HOURS;
public static final int TARIFF_MAX_CACHE_SIZE = 24 * 2 + NUMBER_OF_HISTORIC_HOURS;

private final Clock clock;
private final PriceListParser priceListParser = new PriceListParser();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
public class DatahubPriceConfiguration extends PriceConfiguration {
public class DatahubPriceConfiguration {

/**
* Comma-separated list of charge type codes, e.g. "CD,CD R".
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.energidataservice.internal.handler.EnergiDataServiceHandler;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Thing;
Expand All @@ -46,16 +45,13 @@ public class EnergiDataServiceHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_SERVICE);

private final HttpClient httpClient;
private final LocaleProvider localeProvider;
private final TimeZoneProvider timeZoneProvider;

@Activate
public EnergiDataServiceHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
final @Reference LocaleProvider localeProvider, final @Reference TimeZoneProvider timeZoneProvider,
ComponentContext componentContext) {
final @Reference TimeZoneProvider timeZoneProvider, ComponentContext componentContext) {
super.activate(componentContext);
this.httpClient = httpClientFactory.getCommonHttpClient();
this.localeProvider = localeProvider;
this.timeZoneProvider = timeZoneProvider;
}

Expand All @@ -69,7 +65,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (THING_TYPE_SERVICE.equals(thingTypeUID)) {
return new EnergiDataServiceHandler(thing, httpClient, localeProvider, timeZoneProvider);
return new EnergiDataServiceHandler(thing, httpClient, timeZoneProvider);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@
import org.openhab.binding.energidataservice.internal.api.dto.ElspotpriceRecord;
import org.openhab.binding.energidataservice.internal.config.DatahubPriceConfiguration;
import org.openhab.binding.energidataservice.internal.config.EnergiDataServiceConfiguration;
import org.openhab.binding.energidataservice.internal.config.PriceConfiguration;
import org.openhab.binding.energidataservice.internal.exception.DataServiceException;
import org.openhab.binding.energidataservice.internal.retry.RetryPolicyFactory;
import org.openhab.binding.energidataservice.internal.retry.RetryStrategy;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
Expand Down Expand Up @@ -81,7 +79,6 @@
public class EnergiDataServiceHandler extends BaseThingHandler {

private final Logger logger = LoggerFactory.getLogger(EnergiDataServiceHandler.class);
private final LocaleProvider localeProvider;
private final TimeZoneProvider timeZoneProvider;
private final ApiController apiController;
private final CacheManager cacheManager;
Expand All @@ -97,10 +94,8 @@ private record Price(String hourStart, BigDecimal spotPrice, String spotPriceCur
@Nullable BigDecimal transmissionNetTariff) {
}

public EnergiDataServiceHandler(Thing thing, HttpClient httpClient, LocaleProvider localeProvider,
TimeZoneProvider timeZoneProvider) {
public EnergiDataServiceHandler(Thing thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) {
super(thing);
this.localeProvider = localeProvider;
this.timeZoneProvider = timeZoneProvider;
this.apiController = new ApiController(httpClient, timeZoneProvider);
this.cacheManager = new CacheManager();
Expand Down Expand Up @@ -354,50 +349,15 @@ private void updateCurrentSpotPrice() {
if (!isLinked(CHANNEL_CURRENT_SPOT_PRICE)) {
return;
}
BigDecimal price = getVATAdjustedPrice(cacheManager.getSpotPrice(), CHANNEL_CURRENT_SPOT_PRICE);
updateState(CHANNEL_CURRENT_SPOT_PRICE, price != null ? new DecimalType(price) : UnDefType.UNDEF);
BigDecimal spotPrice = cacheManager.getSpotPrice();
updateState(CHANNEL_CURRENT_SPOT_PRICE, spotPrice != null ? new DecimalType(spotPrice) : UnDefType.UNDEF);
}

private void updateCurrentTariff(String channelId, @Nullable BigDecimal tariff) {
if (!isLinked(channelId)) {
return;
}
BigDecimal price = getVATAdjustedPrice(tariff, channelId);
updateState(channelId, price != null ? new DecimalType(price) : UnDefType.UNDEF);
}

private @Nullable BigDecimal getVATAdjustedPrice(@Nullable BigDecimal price, String channelId) {
if (price == null) {
return price;
}
Channel channel = getThing().getChannel(channelId);
if (channel == null) {
return price;
}
Object obj = channel.getConfiguration().get(PriceConfiguration.INCLUDE_VAT);
if (obj == null) {
return price;
}
Boolean includeVAT = (Boolean) obj;
if (includeVAT) {
return price.multiply(getVATPercentageFactor());
}
return price;
}

private BigDecimal getVATPercentageFactor() {
String country = localeProvider.getLocale().getCountry();
switch (country) {
case "DK":
case "NO":
case "SE":
return new BigDecimal("1.25");
case "DE":
return new BigDecimal("1.19");
default:
logger.debug("No VAT rate for country {}", country);
return BigDecimal.ONE;
}
updateState(channelId, tariff != null ? new DecimalType(tariff) : UnDefType.UNDEF);
}

private void updateHourlyPrices() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,7 @@
</parameter>
</config-description>

<config-description uri="channel-type:energidataservice:spot-price">
<parameter name="includeVAT" type="boolean">
<label>Include VAT</label>
<description>Add VAT to amount based on regional settings.</description>
</parameter>
</config-description>

<config-description uri="channel-type:energidataservice:datahub-price">
<parameter name="includeVAT" type="boolean">
<label>Include VAT</label>
<description>Add VAT to amount based on regional settings.</description>
</parameter>
<parameter name="chargeTypeCodes" type="text">
<label>Charge Type Code Filters</label>
<description>Comma-separated list of charge type codes.</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,13 @@ channel-type.energidataservice.spotPrice.description = Spot price.

channel-type.config.energidataservice.datahub-price.chargeTypeCodes.label = Charge Type Code Filters
channel-type.config.energidataservice.datahub-price.chargeTypeCodes.description = Comma-separated list of charge type codes.
channel-type.config.energidataservice.datahub-price.includeVAT.label = Include VAT
channel-type.config.energidataservice.datahub-price.includeVAT.description = Add VAT to amount based on regional settings.
channel-type.config.energidataservice.datahub-price.notes.label = Note Filters
channel-type.config.energidataservice.datahub-price.notes.description = Comma-separated list of notes.
channel-type.config.energidataservice.datahub-price.start.label = Query Start Date
channel-type.config.energidataservice.datahub-price.start.description = Query start date parameter expressed as either YYYY-MM-DD or dynamically as one of StartOfDay, StartOfMonth or StartOfYear.
channel-type.config.energidataservice.datahub-price.start.option.StartOfDay = Start of day
channel-type.config.energidataservice.datahub-price.start.option.StartOfMonth = Start of month
channel-type.config.energidataservice.datahub-price.start.option.StartOfYear = Start of year
channel-type.config.energidataservice.spot-price.includeVAT.label = Include VAT
channel-type.config.energidataservice.spot-price.includeVAT.description = Add VAT to amount based on regional settings.

# thing status descriptions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<description>Spot price.</description>
<category>Price</category>
<state readOnly="true" pattern="%.9f"></state>
<config-description-ref uri="channel-type:energidataservice:spot-price"/>
</channel-type>

<channel-type id="datahubPrice">
Expand Down

0 comments on commit 942e20c

Please sign in to comment.