]> git.basschouten.com Git - openhab-addons.git/blob
3e3ef5c2ee7da177e7d6e659daaf6ed58d515af8
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.solaredge.internal.model;
14
15 import static org.openhab.binding.solaredge.internal.SolarEdgeBindingConstants.*;
16
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20
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;
32
33 /**
34  * transforms the http response into the openhab datamodel (instances of State)
35  *
36  * @author Alexander Friese - initial contribution
37  */
38 @NonNullByDefault
39 public class LiveDataResponseTransformer extends AbstractDataResponseTransformer {
40     private static final Double ZERO_POWER = 0.0;
41
42     private final ChannelProvider channelProvider;
43
44     public LiveDataResponseTransformer(ChannelProvider channelProvider) {
45         this.channelProvider = channelProvider;
46     }
47
48     public Map<Channel, State> transform(LiveDataResponseMeterless response) {
49         Map<Channel, State> result = new HashMap<>(20);
50         Overview overview = response.getOverview();
51
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);
57             } else {
58                 putPowerType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_PRODUCTION), null,
59                         UNIT_W);
60             }
61
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);
66             } else {
67                 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_DAY, CHANNEL_ID_PRODUCTION),
68                         null, UNIT_WH);
69             }
70
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);
75             } else {
76                 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_MONTH, CHANNEL_ID_PRODUCTION),
77                         null, UNIT_WH);
78             }
79
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);
84             } else {
85                 putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_YEAR, CHANNEL_ID_PRODUCTION),
86                         null, UNIT_WH);
87             }
88
89             // week production is not available
90             putEnergyType(result, channelProvider.getChannel(CHANNEL_GROUP_AGGREGATE_WEEK, CHANNEL_ID_PRODUCTION), null,
91                     UNIT_WH);
92         }
93         return result;
94     }
95
96     public Map<Channel, State> transform(LiveDataResponse response) {
97         Map<Channel, State> result = new HashMap<>(20);
98         SiteCurrentPowerFlow siteCurrentPowerFlow = response.getSiteCurrentPowerFlow();
99
100         if (siteCurrentPowerFlow != null) {
101             Value pv = siteCurrentPowerFlow.pv;
102             Value load = siteCurrentPowerFlow.load;
103             BatteryValue storage = siteCurrentPowerFlow.storage;
104             Value grid = siteCurrentPowerFlow.grid;
105
106             if (pv != null) {
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);
110             }
111
112             if (load != null) {
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),
116                         load.status);
117             }
118
119             if (storage != null) {
120                 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_STATUS),
121                         storage.status);
122                 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CRITICAL),
123                         storage.critical);
124                 putPercentType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_LEVEL),
125                         storage.chargeLevel);
126             }
127
128             if (grid != null) {
129                 putStringType(result, channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_GRID_STATUS),
130                         grid.status);
131             }
132
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);
144
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;
151                     if (grid != null) {
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);
158                         }
159                     }
160
161                     if (storage != null) {
162                         Double currentPower = storage.currentPower;
163                         currentPower = currentPower != null ? currentPower : 0;
164                         if (conFrom != null && conFrom.equalsIgnoreCase(LiveDataResponse.STORAGE)) {
165                             putPowerType(result,
166                                     channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_DISCHARGE),
167                                     currentPower, siteCurrentPowerFlow.unit);
168                             putPowerType(result,
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)) {
172                             putPowerType(result,
173                                     channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE),
174                                     currentPower, siteCurrentPowerFlow.unit);
175                             putPowerType(result,
176                                     channelProvider.getChannel(CHANNEL_GROUP_LIVE, CHANNEL_ID_BATTERY_CHARGE_DISCHARGE),
177                                     currentPower, siteCurrentPowerFlow.unit);
178                         }
179                     }
180                 }
181             }
182         }
183         return result;
184     }
185 }