Skip to content

Commit

Permalink
[awattar] Initial contribution (openhab#11976)
Browse files Browse the repository at this point in the history
* First alpha version of the awattar binding

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Corrected typos

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* More typos

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Improved time handling to consider time zone.

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Corrected logical time problem, start adding nextprice thing

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Added support for Austria

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Use List instead of Set

Signed-off-by: wolfii <wolfgang.klimt@consol.de>
Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Minor corrections

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Removed unneeded handler, corrected fetching of prices

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Added i18n, updated documentation

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Corrected pom.xml after rebase

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Updated version to 3.3.0-SNAPSHOT

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Corrected findings of Code analysis tool

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Updated copyright notice

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Updates to get rid of compiler warnings

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Worked on review comments from @fwolter

Obeyed most of the review comments. Exceptions:

* binding is already added to bom/openhab-addons/pom.xml (at least I found it there and there was a commit notice in git log)
* mvn license:format brought back 2021, so I manually set everything to 2022. Should I try to rebase my whole branch?
* In two places the binding needs to adjust to minute boundaries, hence scheduleWithFixedDelay will not work.
* I removed empty trailing lines, but mvn spotless:apply brought them back
* The OhInfXmlUsageCheck seems to be wrong.
* The ConstantNameCheck in AwattarUtil seems to be mislead by the fact that all members of the class are static, including the logger. From my point of view it is not a real "constant".

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Updated Readme to match code changes

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Further work on review comments from @fwolter

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Corrected config definition

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Changed Copyright to 2022

Signed-off-by: Wolfgang Klimt <github@klimt.de>

* Review comments from @fwolter. Improved timezone handling

Signed-off-by: Wolfgang Klimt <github@klimt.de>

Co-authored-by: wolfii <wolfgang.klimt@consol.de>
  • Loading branch information
2 people authored and psmedley committed Feb 23, 2023
1 parent a2f27b1 commit 46ce574
Show file tree
Hide file tree
Showing 27 changed files with 2,420 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
/bundles/org.openhab.binding.autelis/ @digitaldan
/bundles/org.openhab.binding.automower/ @maxpg
/bundles/org.openhab.binding.avmfritz/ @cweitkamp
/bundles/org.openhab.binding.awattar/ @Wolfgang1966
/bundles/org.openhab.binding.benqprojector/ @mlobstein
/bundles/org.openhab.binding.bigassfan/ @mhilbush
/bundles/org.openhab.binding.bluetooth/ @cdjackson @cpmeister
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@
<artifactId>org.openhab.binding.avmfritz</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.awattar</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.benqprojector</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.awattar/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
263 changes: 263 additions & 0 deletions bundles/org.openhab.binding.awattar/README.md

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions bundles/org.openhab.binding.awattar/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>3.3.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.awattar</artifactId>

<name>openHAB Add-ons :: Bundles :: aWATTar Binding</name>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.awattar-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-binding-awattar" description="aWATTar Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.awattar/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.awattar.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Base class for results
*
* @author Wolfgang Klimt - initial contribution
*/
@NonNullByDefault
public abstract class AwattarBestPriceResult {

private long start;
private long end;

public AwattarBestPriceResult() {
}

public long getStart() {
return start;
}

public void updateStart(long start) {
if (this.start == 0 || this.start > start) {
this.start = start;
}
}

public long getEnd() {
return end;
}

public void updateEnd(long end) {
if (this.end == 0 || this.end < end) {
this.end = end;
}
}

public abstract boolean isActive();

public abstract String getHours();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.awattar.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Stores the bestprice config
*
* @author Wolfgang Klimt - initial contribution
*/
@NonNullByDefault
public class AwattarBestpriceConfiguration {

public int rangeStart;
public int rangeDuration;
public int length;
public boolean consecutive;

public String toString() {
return String.format("{ s: %d, d: %d, l: %d, c: %b )", rangeStart, rangeDuration, length, consecutive);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.awattar.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.type.ChannelGroupTypeUID;

/**
* The {@link AwattarBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Wolfgang Klimt - Initial contribution
*/
@NonNullByDefault
public class AwattarBindingConstants {

public static final String BINDING_ID = "awattar";
public static final String API = "api";

// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge");
public static final ThingTypeUID THING_TYPE_PRICE = new ThingTypeUID(BINDING_ID, "prices");
public static final ThingTypeUID THING_TYPE_BESTPRICE = new ThingTypeUID(BINDING_ID, "bestprice");
public static final ThingTypeUID THING_TYPE_BESTNEXT = new ThingTypeUID(BINDING_ID, "bestnext");

public static final ChannelGroupTypeUID CHANNEL_GROUP_TYPE_HOURLY_PRICES = new ChannelGroupTypeUID(BINDING_ID,
"hourly-prices");

public static final String CHANNEL_GROUP_CURRENT = "current";

// List of all Channel ids
public static final String CHANNEL_TOTAL_NET = "total-net";
public static final String CHANNEL_TOTAL_GROSS = "total-gross";
public static final String CHANNEL_MARKET_NET = "market-net";
public static final String CHANNEL_MARKET_GROSS = "market-gross";

public static final String CHANNEL_ACTIVE = "active";
public static final String CHANNEL_START = "start";
public static final String CHANNEL_END = "end";
public static final String CHANNEL_COUNTDOWN = "countdown";
public static final String CHANNEL_REMAINING = "remaining";
public static final String CHANNEL_HOURS = "hours";
public static final String CHANNEL_DURATION = "rangeDuration";
public static final String CHANNEL_LOOKUP_HOURS = "lookupHours";
public static final String CHANNEL_CONSECUTIVE = "consecutive";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.awattar.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Stores the bridge configuration
*
* @author Wolfgang Klimt - initial contribution
*/
@NonNullByDefault
public class AwattarBridgeConfiguration {

public double basePrice;
public double vatPercent;
public String country = "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.awattar.internal;

import static org.openhab.binding.awattar.internal.AwattarUtil.formatDate;
import static org.openhab.binding.awattar.internal.AwattarUtil.getHourFrom;

import java.time.Instant;
import java.time.ZoneId;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Stores a consecutive bestprice result
*
* @author Wolfgang Klimt - initial contribution
*/
@NonNullByDefault
public class AwattarConsecutiveBestPriceResult extends AwattarBestPriceResult {

private double priceSum = 0;
private int length = 0;
private String hours;
private ZoneId zoneId;

public AwattarConsecutiveBestPriceResult(List<AwattarPrice> prices, ZoneId zoneId) {
super();
this.zoneId = zoneId;
StringBuilder hours = new StringBuilder();
boolean second = false;
for (AwattarPrice price : prices) {
priceSum += price.getPrice();
length++;
updateStart(price.getStartTimestamp());
updateEnd(price.getEndTimestamp());
if (second) {
hours.append(',');
}
hours.append(getHourFrom(price.getStartTimestamp(), zoneId));
second = true;
}
this.hours = hours.toString();
}

@Override
public boolean isActive() {
return contains(Instant.now().toEpochMilli());
}

public boolean contains(long timestamp) {
return timestamp >= getStart() && timestamp < getEnd();
}

public double getPriceSum() {
return priceSum;
}

public String toString() {
return String.format("{%s, %s, %.2f}", formatDate(getStart(), zoneId), formatDate(getEnd(), zoneId),
priceSum / length);
}

public String getHours() {
return hours;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.awattar.internal;

import static org.openhab.binding.awattar.internal.AwattarUtil.*;

import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Stores a non consecutive bestprice result
*
* @author Wolfgang Klimt - initial contribution
*/
@NonNullByDefault
public class AwattarNonConsecutiveBestPriceResult extends AwattarBestPriceResult {

private List<AwattarPrice> members;
private ZoneId zoneId;
private boolean sorted = true;

public AwattarNonConsecutiveBestPriceResult(int size, ZoneId zoneId) {
super();
this.zoneId = zoneId;
members = new ArrayList<AwattarPrice>();
}

public void addMember(AwattarPrice member) {
sorted = false;
members.add(member);
updateStart(member.getStartTimestamp());
updateEnd(member.getEndTimestamp());
}

@Override
public boolean isActive() {
return members.stream().anyMatch(x -> x.contains(Instant.now().toEpochMilli()));
}

public String toString() {
return String.format("NonConsecutiveBestpriceResult with %s", members.toString());
}

private void sort() {
if (!sorted) {
members.sort(new Comparator<AwattarPrice>() {
@Override
public int compare(AwattarPrice o1, AwattarPrice o2) {
return Long.compare(o1.getStartTimestamp(), o2.getStartTimestamp());
}
});
}
}

public String getHours() {
boolean second = false;
sort();
StringBuilder res = new StringBuilder();
for (AwattarPrice price : members) {
if (second) {
res.append(',');
}
res.append(getHourFrom(price.getStartTimestamp(), zoneId));
second = true;
}
return res.toString();
}
}
Loading

0 comments on commit 46ce574

Please sign in to comment.