]> git.basschouten.com Git - openhab-addons.git/blob
c36965235e52e3bb8ab90bdb2ada80a665c959b9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.fronius.internal.handler;
14
15 import java.util.Map;
16
17 import org.openhab.binding.fronius.internal.FroniusBaseDeviceConfiguration;
18 import org.openhab.binding.fronius.internal.FroniusBindingConstants;
19 import org.openhab.binding.fronius.internal.FroniusBridgeConfiguration;
20 import org.openhab.binding.fronius.internal.api.InverterRealtimeResponse;
21 import org.openhab.binding.fronius.internal.api.PowerFlowRealtimeInverter;
22 import org.openhab.binding.fronius.internal.api.PowerFlowRealtimeResponse;
23 import org.openhab.binding.fronius.internal.api.ValueUnit;
24 import org.openhab.core.library.types.QuantityType;
25 import org.openhab.core.library.unit.Units;
26 import org.openhab.core.thing.Thing;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * The {@link FroniusSymoInverterHandler} is responsible for updating the data, which are
32  * sent to one of the channels.
33  *
34  * @author Thomas Rokohl - Initial contribution
35  * @author Peter Schraffl - Added device status and error status channels
36  * @author Thomas Kordelle - Added inverter power, battery state of charge and PV solar yield
37  */
38 public class FroniusSymoInverterHandler extends FroniusBaseThingHandler {
39
40     /* power produced/handled by the inverter. */
41     public static final String INVERTER_POWER = "power";
42     /* state of charge of the battery or other storage device */
43     public static final String INVERTER_SOC = "soc";
44
45     private final Logger logger = LoggerFactory.getLogger(FroniusSymoInverterHandler.class);
46     private InverterRealtimeResponse inverterRealtimeResponse;
47     private PowerFlowRealtimeResponse powerFlowResponse;
48     private FroniusBaseDeviceConfiguration config;
49
50     public FroniusSymoInverterHandler(Thing thing) {
51         super(thing);
52     }
53
54     @Override
55     protected String getDescription() {
56         return "Fronius Symo Inverter";
57     }
58
59     @Override
60     public void refresh(FroniusBridgeConfiguration bridgeConfiguration) {
61         updateData(bridgeConfiguration, config);
62         updateChannels();
63     }
64
65     @Override
66     public void initialize() {
67         config = getConfigAs(FroniusBaseDeviceConfiguration.class);
68         super.initialize();
69     }
70
71     /**
72      * Update the channel from the last data retrieved
73      *
74      * @param channelId the id identifying the channel to be updated
75      * @return the last retrieved data
76      */
77     @Override
78     protected Object getValue(String channelId) {
79         final String[] fields = channelId.split("#");
80         if (fields.length < 1) {
81             return null;
82         }
83         final String fieldName = fields[0];
84
85         if (inverterRealtimeResponse != null) {
86             switch (fieldName) {
87                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_DAY_ENERGY:
88                     ValueUnit day = inverterRealtimeResponse.getBody().getData().getDayEnergy();
89                     if (day != null) {
90                         day.setUnit("kWh");
91                     }
92                     return day;
93                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_PAC:
94                     ValueUnit pac = inverterRealtimeResponse.getBody().getData().getPac();
95                     if (pac == null) {
96                         pac = new ValueUnit();
97                         pac.setValue(0);
98                     }
99                     return pac;
100                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_TOTAL:
101                     ValueUnit total = inverterRealtimeResponse.getBody().getData().getTotalEnergy();
102                     if (total != null) {
103                         total.setUnit("MWh");
104                     }
105                     return total;
106                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_YEAR:
107                     ValueUnit year = inverterRealtimeResponse.getBody().getData().getYearEnergy();
108                     if (year != null) {
109                         year.setUnit("MWh");
110                     }
111                     return year;
112                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_FAC:
113                     return inverterRealtimeResponse.getBody().getData().getFac();
114                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_IAC:
115                     return inverterRealtimeResponse.getBody().getData().getIac();
116                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_IDC:
117                     return inverterRealtimeResponse.getBody().getData().getIdc();
118                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_UAC:
119                     return inverterRealtimeResponse.getBody().getData().getUac();
120                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_UDC:
121                     return inverterRealtimeResponse.getBody().getData().getUdc();
122                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_DEVICE_STATUS_ERROR_CODE:
123                     return inverterRealtimeResponse.getBody().getData().getDeviceStatus().getErrorCode();
124                 case FroniusBindingConstants.INVERTER_DATA_CHANNEL_DEVICE_STATUS_STATUS_CODE:
125                     return inverterRealtimeResponse.getBody().getData().getDeviceStatus().getStatusCode();
126                 default:
127                     break;
128             }
129         }
130
131         if (powerFlowResponse != null) {
132             switch (fieldName) {
133                 case FroniusBindingConstants.POWER_FLOW_P_GRID:
134                     return new QuantityType<>(powerFlowResponse.getBody().getData().getSite().getPgrid(), Units.WATT);
135                 case FroniusBindingConstants.POWER_FLOW_P_LOAD:
136                     return new QuantityType<>(powerFlowResponse.getBody().getData().getSite().getPload(), Units.WATT);
137                 case FroniusBindingConstants.POWER_FLOW_P_AKKU:
138                     return new QuantityType<>(powerFlowResponse.getBody().getData().getSite().getPakku(), Units.WATT);
139                 case FroniusBindingConstants.POWER_FLOW_P_PV:
140                     return new QuantityType<>(powerFlowResponse.getBody().getData().getSite().getPpv(), Units.WATT);
141                 case FroniusBindingConstants.POWER_FLOW_INVERTER_1_POWER:
142                     return getInverterFlowValue(INVERTER_POWER, "1");
143                 case FroniusBindingConstants.POWER_FLOW_INVERTER_1_SOC:
144                     return getInverterFlowValue(INVERTER_SOC, "1");
145                 default:
146                     break;
147             }
148         }
149
150         return null;
151     }
152
153     /**
154      * get flow data for a specific inverter.
155      *
156      * @param fieldName
157      * @param number
158      * @return
159      */
160     private Object getInverterFlowValue(final String fieldName, final String number) {
161         final Map<String, PowerFlowRealtimeInverter> inverters = powerFlowResponse.getBody().getData().getInverters();
162         if ((inverters == null) || (inverters.get(number) == null)) {
163             logger.debug("No data for inverter '{}' found.", number);
164             return null;
165         }
166         switch (fieldName) {
167             case INVERTER_POWER:
168                 return new QuantityType<>(inverters.get(number).getP(), Units.WATT);
169             case INVERTER_SOC:
170                 return new QuantityType<>(inverters.get(number).getSoc(), Units.PERCENT);
171             default:
172                 break;
173         }
174         return null;
175     }
176
177     /**
178      * Get new data
179      */
180     private void updateData(FroniusBridgeConfiguration bridgeConfiguration, FroniusBaseDeviceConfiguration config) {
181         inverterRealtimeResponse = getRealtimeData(bridgeConfiguration.hostname, config.deviceId);
182         powerFlowResponse = getPowerFlowRealtime(bridgeConfiguration.hostname);
183     }
184
185     /**
186      * Make the PowerFlowRealtimeDataRequest
187      *
188      * @param ip address of the device
189      * @return {PowerFlowRealtimeResponse} the object representation of the json response
190      */
191     private PowerFlowRealtimeResponse getPowerFlowRealtime(String ip) {
192         String location = FroniusBindingConstants.POWERFLOW_REALTIME_DATA.replace("%IP%",
193                 (ip != null ? ip.trim() : ""));
194         return collectDataFormUrl(PowerFlowRealtimeResponse.class, location);
195     }
196
197     /**
198      * Make the InverterRealtimeDataRequest
199      *
200      * @param ip address of the device
201      * @param deviceId of the device
202      * @return {InverterRealtimeResponse} the object representation of the json response
203      */
204     private InverterRealtimeResponse getRealtimeData(String ip, int deviceId) {
205         String location = FroniusBindingConstants.INVERTER_REALTIME_DATA_URL.replace("%IP%",
206                 (ip != null ? ip.trim() : ""));
207         location = location.replace("%DEVICEID%", Integer.toString(deviceId));
208         return collectDataFormUrl(InverterRealtimeResponse.class, location);
209     }
210 }