2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.solaredge.internal.model;
15 import static org.openhab.binding.solaredge.internal.SolarEdgeBindingConstants.*;
17 import java.util.HashMap;
18 import java.util.List;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.solaredge.internal.handler.ChannelProvider;
23 import org.openhab.binding.solaredge.internal.model.LiveDataResponse.BatteryValue;
24 import org.openhab.binding.solaredge.internal.model.LiveDataResponse.Connection;
25 import org.openhab.binding.solaredge.internal.model.LiveDataResponse.SiteCurrentPowerFlow;
26 import org.openhab.binding.solaredge.internal.model.LiveDataResponse.Value;
27 import org.openhab.binding.solaredge.internal.model.LiveDataResponseMeterless.Energy;
28 import org.openhab.binding.solaredge.internal.model.LiveDataResponseMeterless.Overview;
29 import org.openhab.binding.solaredge.internal.model.LiveDataResponseMeterless.Power;
30 import org.openhab.core.thing.Channel;
31 import org.openhab.core.types.State;
34 * transforms the http response into the openhab datamodel (instances of State)
36 * @author Alexander Friese - initial contribution
39 public class LiveDataResponseTransformer extends AbstractDataResponseTransformer {
40 private static final Double ZERO_POWER = 0.0;
42 private final ChannelProvider channelProvider;
44 public LiveDataResponseTransformer(ChannelProvider channelProvider) {
45 this.channelProvider = channelProvider;
48 public Map<Channel, State> transform(LiveDataResponseMeterless response) {
49 Map<Channel, State> result = new HashMap<>(20);
50 Overview overview = response.getOverview();
52 if (overview != null) {
53 Power currentPower = overview.currentPower;
54 if (currentPower != null) {
55 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_PRODUCTION),
56 currentPower.power, UNIT_W);
58 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_PRODUCTION), null,
62 Energy lastDayData = overview.lastDayData;
63 if (lastDayData != null) {
64 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_DAY, CHANNEL_ID_PRODUCTION),
65 lastDayData.energy, UNIT_WH);
67 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_DAY, CHANNEL_ID_PRODUCTION),
71 Energy lastMonthData = overview.lastMonthData;
72 if (lastMonthData != null) {
73 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_MONTH, CHANNEL_ID_PRODUCTION),
74 lastMonthData.energy, UNIT_WH);
76 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_MONTH, CHANNEL_ID_PRODUCTION),
80 Energy lastYearData = overview.lastYearData;
81 if (lastYearData != null) {
82 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_YEAR, CHANNEL_ID_PRODUCTION),
83 lastYearData.energy, UNIT_WH);
85 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_YEAR, CHANNEL_ID_PRODUCTION),
89 // week production is not available
90 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_WEEK, CHANNEL_ID_PRODUCTION), null,
96 public Map<Channel, State> transform(LiveDataResponse response) {
97 Map<Channel, State> result = new HashMap<>(20);
98 SiteCurrentPowerFlow siteCurrentPowerFlow = response.getSiteCurrentPowerFlow();
100 if (siteCurrentPowerFlow != null) {
101 Value pv = siteCurrentPowerFlow.pv;
102 Value load = siteCurrentPowerFlow.load;
103 BatteryValue storage = siteCurrentPowerFlow.storage;
104 Value grid = siteCurrentPowerFlow.grid;
107 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_PRODUCTION),
108 pv.currentPower, siteCurrentPowerFlow.unit);
109 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_PV_STATUS), pv.status);
113 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_CONSUMPTION),
114 load.currentPower, siteCurrentPowerFlow.unit);
115 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_LOAD_STATUS),
119 if (storage != null) {
120 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_STATUS),
122 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CRITICAL),
124 putPercentType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_LEVEL),
125 storage.chargeLevel);
129 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_GRID_STATUS),
133 // init fields with zero
134 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_IMPORT), ZERO_POWER,
135 siteCurrentPowerFlow.unit);
136 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_EXPORT), ZERO_POWER,
137 siteCurrentPowerFlow.unit);
138 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE), ZERO_POWER,
139 siteCurrentPowerFlow.unit);
140 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_DISCHARGE),
141 ZERO_POWER, siteCurrentPowerFlow.unit);
142 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE_DISCHARGE),
143 ZERO_POWER, siteCurrentPowerFlow.unit);
145 // determine power flow from connection list
146 List<Connection> connections = siteCurrentPowerFlow.connections;
147 if (connections != null) {
148 for (Connection con : connections) {
149 String conFrom = con.from;
150 String conTo = con.to;
152 if (conFrom != null && conFrom.equalsIgnoreCase(LiveDataResponse.GRID)) {
153 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_IMPORT),
154 grid.currentPower, siteCurrentPowerFlow.unit);
155 } else if (conTo != null && conTo.equalsIgnoreCase(LiveDataResponse.GRID)) {
156 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_EXPORT),
157 grid.currentPower, siteCurrentPowerFlow.unit);
161 if (storage != null) {
162 Double currentPower = storage.currentPower;
163 currentPower = currentPower != null ? currentPower : 0;
164 if (conFrom != null && conFrom.equalsIgnoreCase(LiveDataResponse.STORAGE)) {
166 channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_DISCHARGE),
167 currentPower, siteCurrentPowerFlow.unit);
169 channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE_DISCHARGE),
170 -1 * currentPower, siteCurrentPowerFlow.unit);
171 } else if (conTo != null && conTo.equalsIgnoreCase(LiveDataResponse.STORAGE)) {
173 channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE),
174 currentPower, siteCurrentPowerFlow.unit);
176 channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE_DISCHARGE),
177 currentPower, siteCurrentPowerFlow.unit);