added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.solarlog-${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-solarlog" description="SolarLog Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.solarlog/${project.version}</bundle>
</feature>
</features>

View File

@@ -0,0 +1,90 @@
/**
* Copyright (c) 2010-2020 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.solarlog.internal;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link SolarLogBinding} class defines common constants, which are
* used across the whole binding.
*
* @author Johann Richard - Initial contribution
*/
public class SolarLogBindingConstants {
public static final String BINDING_ID = "solarlog";
// List of all Thing Type UIDs
public static final ThingTypeUID THING_SOLARLOG = new ThingTypeUID(BINDING_ID, "meter");
// List of all Channel ids
public static final String CHANNEL_ID_LASTUPDATETIME = "lastupdate";
public static final String CHANNEL_ID_PAC = "pac";
public static final String CHANNEL_ID_PDC = "pdc";
public static final String CHANNEL_ID_UAC = "uac";
public static final String CHANNEL_ID_UDC = "udc";
public static final String CHANNEL_ID_YIELDDAY = "yieldday";
public static final String CHANNEL_ID_YIELDYESTERDAY = "yieldyesterday";
public static final String CHANNEL_ID_YIELDMONTH = "yieldmonth";
public static final String CHANNEL_ID_YIELDYEAR = "yieldyear";
public static final String CHANNEL_ID_YIELDTOTAL = "yieldtotal";
public static final String CHANNEL_ID_CONSPAC = "conspac";
public static final String CHANNEL_ID_CONSYIELDDAY = "consyieldday";
public static final String CHANNEL_ID_CONSYIELDYESTERDAY = "consyieldyesterday";
public static final String CHANNEL_ID_CONSYIELDMONTH = "consyieldmonth";
public static final String CHANNEL_ID_CONSYIELDYEAR = "consyieldyear";
public static final String CHANNEL_ID_CONSYIELDTOTAL = "consyieldtotal";
public static final String CHANNEL_ID_TOTALPOWER = "totalpower";
// List of all JSON Id's for channels
public static final String CHANNEL_LASTUPDATETIME = "100";
public static final String CHANNEL_PAC = "101";
public static final String CHANNEL_PDC = "102";
public static final String CHANNEL_UAC = "103";
public static final String CHANNEL_UDC = "104";
public static final String CHANNEL_YIELDDAY = "105";
public static final String CHANNEL_YIELDYESTERDAY = "106";
public static final String CHANNEL_YIELDMONTH = "107";
public static final String CHANNEL_YIELDYEAR = "108";
public static final String CHANNEL_YIELDTOTAL = "109";
public static final String CHANNEL_CONSPAC = "110";
public static final String CHANNEL_CONSYIELDDAY = "111";
public static final String CHANNEL_CONSYIELDYESTERDAY = "112";
public static final String CHANNEL_CONSYIELDMONTH = "113";
public static final String CHANNEL_CONSYIELDYEAR = "114";
public static final String CHANNEL_CONSYIELDTOTAL = "115";
public static final String CHANNEL_TOTALPOWER = "116";
// CHannel Type (DateTime or Number
public static final String CHANNEL_TYPE_LASTUPDATETIME = "DateTime";
public static final String CHANNEL_TYPE_PAC = "Number";
public static final String CHANNEL_TYPE_PDC = "Number";
public static final String CHANNEL_TYPE_UAC = "Number";
public static final String CHANNEL_TYPE_UDC = "Number";
public static final String CHANNEL_TYPE_YIELDDAY = "Number";
public static final String CHANNEL_TYPE_YIELDYESTERDAY = "Number";
public static final String CHANNEL_TYPE_YIELDMONTH = "Number";
public static final String CHANNEL_TYPE_YIELDYEAR = "Number";
public static final String CHANNEL_TYPE_YIELDTOTAL = "Number";
public static final String CHANNEL_TYPE_CONSPAC = "Number";
public static final String CHANNEL_TYPE_CONSYIELDDAY = "Number";
public static final String CHANNEL_TYPE_CONSYIELDYESTERDAY = "Number";
public static final String CHANNEL_TYPE_CONSYIELDMONTH = "Number";
public static final String CHANNEL_TYPE_CONSYIELDYEAR = "Number";
public static final String CHANNEL_TYPE_CONSYIELDTOTAL = "Number";
public static final String CHANNEL_TYPE_TOTALPOWER = "Number";
// Some basic constants (JSON ID)
public static final String SOLARLOG_JSON_ROOT = "801";
public static final String SOLARLOG_JSON_PROPERTIES = "170";
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright (c) 2010-2020 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.solarlog.internal;
/**
* The {@link SolarLogChannel} Enum defines common constants, which are
* used across the whole binding.
*
* @author Johann Richard - Initial contribution
*/
public enum SolarLogChannel {
CHANNEL_LASTUPDATETIME("lastupdate", "100"),
CHANNEL_PAC("pac", "101"),
CHANNEL_PDC("pdc", "102"),
CHANNEL_UAC("uac", "103"),
CHANNEL_UDC("udc", "104"),
CHANNEL_YIELDDAY("yieldday", "105"),
CHANNEL_YIELDYESTERDAY("yieldyesterday", "106"),
CHANNEL_YIELDMONTH("yieldmonth", "107"),
CHANNEL_YIELDYEAR("yieldyear", "108"),
CHANNEL_YIELDTOTAL("yieldtotal", "109"),
CHANNEL_CONSPAC("conspac", "110"),
CHANNEL_CONSYIELDDAY("consyieldday", "111"),
CHANNEL_CONSYIELDYESTERDAY("consyieldyesterday", "112"),
CHANNEL_CONSYIELDMONTH("consyieldmonth", "113"),
CHANNEL_CONSYIELDYEAR("consyieldyear", "114"),
CHANNEL_CONSYIELDTOTAL("consyieldtotal", "115"),
CHANNEL_TOTALPOWER("totalpower", "116");
private final String id;
private final String index;
SolarLogChannel(String id, String index) {
this.id = id;
this.index = index;
}
public String getId() {
return id;
}
public String getIndex() {
return index;
}
}

View File

@@ -0,0 +1,24 @@
/**
* Copyright (c) 2010-2020 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.solarlog.internal;
/**
* The class {@link SolarLogConfig} represents the configuration
* values available for the Solar-Log Binding.
*
* @author Johann Richard - Initial contribution
*/
public class SolarLogConfig {
public String url;
public int refreshInterval;
}

View File

@@ -0,0 +1,57 @@
/**
* Copyright (c) 2010-2020 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.solarlog.internal;
import static org.openhab.binding.solarlog.internal.SolarLogBindingConstants.THING_SOLARLOG;
import java.util.Collections;
import java.util.Set;
import org.openhab.binding.solarlog.internal.handler.SolarLogHandler;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link SolarLogHandlerFactory} is responsible for creating things and thing
* handlers. It is completely boiler-plate and nothing special at all.
*
* @author Johann Richard - Initial contribution
*/
@Component(configurationPid = "binding.solarlog", service = ThingHandlerFactory.class)
public class SolarLogHandlerFactory extends BaseThingHandlerFactory {
private final Logger logger = LoggerFactory.getLogger(SolarLogHandlerFactory.class);
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_SOLARLOG);
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}
@Override
protected ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
logger.debug("Create Thing Handler {}", THING_SOLARLOG);
if (THING_SOLARLOG.equals(thingTypeUID)) {
return new SolarLogHandler(thing);
}
return null;
}
}

View File

@@ -0,0 +1,166 @@
/**
* Copyright (c) 2010-2020 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.solarlog.internal.handler;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.openhab.binding.solarlog.internal.SolarLogBindingConstants;
import org.openhab.binding.solarlog.internal.SolarLogChannel;
import org.openhab.binding.solarlog.internal.SolarLogConfig;
import org.openhab.core.io.net.http.HttpUtil;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
/**
* The {@link SolarLogHandler} is responsible for handling commands, which are
* sent to one of the channels. It does the "heavy lifting" of connecting to the
* Solar-Log, getting the data, parsing it and updating the channels.
*
* @author Johann Richard - Initial contribution
*/
public class SolarLogHandler extends BaseThingHandler {
private Logger logger = LoggerFactory.getLogger(SolarLogHandler.class);
private SolarLogConfig config;
private final int timeout = 5000;
public SolarLogHandler(Thing thing) {
super(thing);
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
// Read only
}
@Override
public void initialize() {
logger.debug("Initializing Solar-Log");
config = getConfigAs(SolarLogConfig.class);
scheduler.scheduleWithFixedDelay(() -> {
logger.debug("Running refresh cycle");
try {
refresh();
updateStatus(ThingStatus.ONLINE);
// Very rudimentary Exception differentiation
} catch (IOException e) {
logger.debug("Error reading response from Solar-Log", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Communication error with the device. Please retry later.");
} catch (JsonSyntaxException je) {
logger.warn("Invalid JSON when refreshing source {}: {}", getThing().getUID(), je.getMessage());
} catch (Exception e) {
logger.warn("Error refreshing source {}: {}", getThing().getUID(), e.getMessage(), e);
}
}, 0, config.refreshInterval < 15 ? 15 : config.refreshInterval, TimeUnit.SECONDS); // Minimum interval is 15 s
}
private void refresh() throws Exception {
// Get the JSON - somehow
logger.trace("Starting refresh handler");
String httpMethod = "POST";
String url = config.url + "/getjp";
String content = "{\"801\":{\"170\":null}}";
InputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
logger.debug("Attempting to load data from {} with parameter {}", url, content);
String response = HttpUtil.executeUrl(httpMethod, url, stream, null, timeout);
JsonElement solarLogDataElement = new JsonParser().parse(response);
JsonObject solarLogData = solarLogDataElement.getAsJsonObject();
// Check whether the data is well-formed
if (solarLogData.has(SolarLogBindingConstants.SOLARLOG_JSON_ROOT)) {
solarLogData = solarLogData.getAsJsonObject(SolarLogBindingConstants.SOLARLOG_JSON_ROOT);
logger.trace("Found root node in Solar-Log data. Attempting to read data");
if (solarLogData.has(SolarLogBindingConstants.SOLARLOG_JSON_PROPERTIES)) {
solarLogData = solarLogData.getAsJsonObject(SolarLogBindingConstants.SOLARLOG_JSON_PROPERTIES);
for (SolarLogChannel channelConfig : SolarLogChannel.values()) {
if (solarLogData.has(channelConfig.getIndex())) {
String value = solarLogData.get(channelConfig.getIndex()).getAsString();
Channel channel = getThing().getChannel(channelConfig.getId());
State state = getState(value, channelConfig);
if (channel != null) {
logger.trace("Update channel state: {}", state);
updateState(channel.getUID(), state);
}
} else {
logger.debug("Error refreshing source {}: {}", getThing().getUID(), channelConfig.getId());
}
}
}
} else {
logger.warn("Data retrieval failed, no data returned {}", response);
}
}
private State getState(String value, SolarLogChannel type) {
switch (type) {
// Only DateTime channel
case CHANNEL_LASTUPDATETIME:
try {
logger.trace("Parsing date {}", value);
try {
Date date = new SimpleDateFormat("dd.MM.yy HH:mm:ss").parse(value);
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");// dd/MM/yyyy
String strDate = sdfDate.format(date);
logger.trace("Parsing date successful. Returning date. {}", new DateTimeType(strDate));
return new DateTimeType(strDate);
} catch (ParseException fpe) {
logger.trace("Parsing date failed. Returning string.", fpe);
return new StringType(value);
}
} catch (IllegalArgumentException e) {
logger.warn("Parsing date failed. Returning nothing", e);
return UnDefType.UNDEF;
}
// All other channels should be numbers
default:
try {
logger.trace("Parsing number {}", value);
return new DecimalType(new BigDecimal(value));
} catch (NumberFormatException e) {
// Log a warning and return UNDEF
logger.warn("Parsing number failed. Returning nothing", e);
return UnDefType.UNDEF;
}
}
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="solarlog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
<name>Solar-Log Binding</name>
<description>This is the binding for the Solar-Log product range developed and sold by Solare Datensysteme GmbH. The
Solar-Log devices allow monitoring of Photovoltaic (PV) installations and provide a JSON API to extract data. This
includes information about current energy production and use, and other vital parameters of a PV installation. This
binding makes this data accessible to openHAB from where it can be persistently stored, used to trigger actions or be
displayed for information.</description>
<author>Johann Richard</author>
</binding:binding>

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="solarlog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<thing-type id="meter">
<label>Solar-Log Meter</label>
<description>Basic thing for the Solar-Log Binding</description>
<channels>
<channel id="lastupdate" typeId="lastupdate"></channel>
<channel id="pac" typeId="pac"></channel>
<channel id="pdc" typeId="pdc"></channel>
<channel id="uac" typeId="uac"></channel>
<channel id="udc" typeId="udc"></channel>
<channel id="yieldday" typeId="yieldday"></channel>
<channel id="yieldyesterday" typeId="yieldyesterday"></channel>
<channel id="yieldmonth" typeId="yieldmonth"></channel>
<channel id="yieldyear" typeId="yieldyear"></channel>
<channel id="yieldtotal" typeId="yieldtotal"></channel>
<channel id="conspac" typeId="conspac"></channel>
<channel id="consyieldday" typeId="consyieldday"></channel>
<channel id="consyieldyesterday" typeId="consyieldyesterday"></channel>
<channel id="consyieldmonth" typeId="consyieldmonth"></channel>
<channel id="consyieldyear" typeId="consyieldyear"></channel>
<channel id="consyieldtotal" typeId="consyieldtotal"></channel>
<channel id="totalpower" typeId="totalpower"></channel>
</channels>
<config-description>
<parameter name="url" type="text" required="true">
<label>URL</label>
<description>URL of the Solar-Log web interface (e.g. http://solar-log)</description>
<default>http://solar-log</default>
</parameter>
<parameter name="refreshInterval" type="integer" min="15">
<label>Refresh Interval</label>
<description>States how often a refresh shall occur (in s).</description>
<default>15</default>
</parameter>
</config-description>
</thing-type>
<channel-type id="lastupdate">
<item-type>DateTime</item-type>
<label>Last Update</label>
<description>Last Update Time</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="pac">
<item-type>Number</item-type>
<label>PAC</label>
<description>Total output PAC from all of the inverters</description>
<state readOnly="true" pattern="%d W"></state>
</channel-type>
<channel-type id="pdc">
<item-type>Number</item-type>
<label>PDC</label>
<description>Total output PDC from all of the inverters</description>
<state readOnly="true" pattern="%d W"></state>
</channel-type>
<channel-type id="uac">
<item-type>Number</item-type>
<label>UAC</label>
<description>Average voltage UAC from the inverter</description>
<state readOnly="true" pattern="%d V"></state>
</channel-type>
<channel-type id="udc">
<item-type>Number</item-type>
<label>UDC</label>
<description>Average voltage UDC from the inverter</description>
<state readOnly="true" pattern="%d V"></state>
</channel-type>
<channel-type id="yieldday">
<item-type>Number</item-type>
<label>Yield Day</label>
<description>Total yield for the day from all of the inverters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="yieldyesterday">
<item-type>Number</item-type>
<label>Yield Yesterday</label>
<description>Total yield for the previous day from all of the inverters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="yieldmonth">
<item-type>Number</item-type>
<label>Yield Month</label>
<description>Total yield for the month from all of the inverters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="yieldyear">
<item-type>Number</item-type>
<label>Yield Year</label>
<description>Total yield for the year from all of the inverters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="yieldtotal">
<item-type>Number</item-type>
<label>Yield Total</label>
<description>Total yield from all of the inverters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="conspac">
<item-type>Number</item-type>
<label>Consumption PAC</label>
<description>Current total consumption PAC from all of the consumption meters (W)</description>
<state readOnly="true" pattern="%d W"></state>
</channel-type>
<channel-type id="consyieldday">
<item-type>Number</item-type>
<label>Consumption Today</label>
<description>Total consumption from all of the consumption meters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="consyieldyesterday">
<item-type>Number</item-type>
<label>Consumption Yesterday</label>
<description>Total consumption for the previous day; all of the consumption meters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="consyieldmonth">
<item-type>Number</item-type>
<label>Consumption Month</label>
<description>Total consumption for the month; all of the consumption meters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="consyieldyear">
<item-type>Number</item-type>
<label>Consumption Year</label>
<description>Total consumption for the year; all of the consumption meters</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="consyieldtotal">
<item-type>Number</item-type>
<label>Consumption Total</label>
<description>Accumulated total consumption, all Consumption meter</description>
<state readOnly="true" pattern="%d Wh"></state>
</channel-type>
<channel-type id="totalpower">
<item-type>Number</item-type>
<label>Total Power</label>
<description>Installed generator power (Wp)</description>
<state readOnly="true" pattern="%d Wp"></state>
</channel-type>
</thing:thing-descriptions>