2 * Copyright (c) 2010-2022 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.synopanalyzer.internal.synop;
15 import java.util.List;
17 import javax.measure.Unit;
18 import javax.measure.quantity.Speed;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.core.library.unit.Units;
25 * The {@link Synop} is the ancestor common class for analyzing
28 * @author Jonarzz - Initial contribution
31 public abstract class Synop {
32 protected static final int INITIAL_VALUE = -1000;
33 protected static final char PLUS_SIGN_TEMPERATURE = '0';
34 protected static final char MINUS_SIGN_TEMPERATURE = '1';
39 protected static final int WS_WILDTYPE_IN_MPS = 0;
40 protected static final int WS_ANEMOMETER_IN_MPS = 1;
43 * HV - HORIZONTAL VISIBILITY [IN KILOMETERS]
44 * VALUES FROM "00" TO "50" AND FROM "56" TO "99"
45 * 00 MEANS HV = BELOW 0,1
46 * DECIMAL SCOPE MEANS HV = XX / 10
47 * UNIT SCOPE MEANS HV = XX - 50
48 * 89 MEANS HV = OVER 70
49 * 90-99 ROUGHLY NUMBERING :
57 * 97 >= 10,0 < 20,0 km
58 * 98 >= 20,0 < 50,0 km
62 protected static final int HV_LESS_THAN_1_LIMIT = 10;
63 protected static final int HV_LESS_THAN_10_LIMIT = 60;
64 protected static final int HV_LESS_THAN_50_LIMIT = 84;
65 protected static final int HV_LESS_THAN_1_HP_LIMIT = 93;
66 protected static final int HV_LESS_THAN_10_HP_LIMIT = 96;
67 protected static final int HV_LESS_THAN_50_HP_LIMIT = 98;
69 public static enum HorizontalVisibility {
77 private final int VALID_STRING_LENGTH = 5;
79 protected final List<String> stringArray;
85 private int windIndicator;
87 private HorizontalVisibility horizontalVisibility = HorizontalVisibility.UNDEFINED;
88 private float temperature;
91 private int windDirection;
92 private int windSpeed;
93 private float pressure;
95 protected int horizontalVisibilityInt = INITIAL_VALUE;
96 protected @Nullable String temperatureString;
97 protected @Nullable String windString;
98 protected @Nullable String pressureString;
100 public Synop(List<String> stringArray) {
101 this.stringArray = stringArray;
103 setDateHourAndWindIndicator();
104 setHorizontalVisibility();
106 setWindAndOvercast();
110 private void setDateHourAndWindIndicator() {
111 String dayHourAndWindIndicator = "";
113 if (this instanceof SynopLand && stringArray.size() > 1) {
114 dayHourAndWindIndicator = stringArray.get(1);
115 } else if (stringArray.size() > 2) {
116 dayHourAndWindIndicator = stringArray.get(2);
119 if (!isValidString(dayHourAndWindIndicator)) {
123 setHourOfObservation(dayHourAndWindIndicator);
124 setWindIndicator(dayHourAndWindIndicator);
127 private void setHourOfObservation(String str) {
129 hour = Integer.parseInt(str.substring(2, 4));
130 } catch (NumberFormatException e) {
131 hour = INITIAL_VALUE;
134 day = Integer.parseInt(str.substring(0, 2));
135 } catch (NumberFormatException e) {
140 private void setWindIndicator(String str) {
142 windIndicator = Character.getNumericValue(str.charAt(4));
143 } catch (NumberFormatException e) {
144 windIndicator = INITIAL_VALUE;
148 private void setHorizontalVisibility() {
149 setHorizontalVisibilityInt();
151 if (horizontalVisibilityInt != INITIAL_VALUE) {
153 if (horizontalVisibilityInt < HV_LESS_THAN_1_LIMIT || horizontalVisibilityInt < HV_LESS_THAN_1_HP_LIMIT) {
154 horizontalVisibility = HorizontalVisibility.LESS_THAN_1;
155 } else if (horizontalVisibilityInt < HV_LESS_THAN_10_LIMIT
156 || horizontalVisibilityInt < HV_LESS_THAN_10_HP_LIMIT) {
157 horizontalVisibility = HorizontalVisibility.LESS_THAN_10;
158 } else if (horizontalVisibilityInt < HV_LESS_THAN_50_LIMIT
159 || horizontalVisibilityInt < HV_LESS_THAN_50_HP_LIMIT) {
160 horizontalVisibility = HorizontalVisibility.LESS_THAN_50;
162 horizontalVisibility = HorizontalVisibility.MORE_THAN_50;
165 horizontalVisibility = HorizontalVisibility.UNDEFINED;
169 protected abstract void setHorizontalVisibilityInt();
171 private void setTemperature() {
172 setTemperatureString();
173 temperature = INITIAL_VALUE;
174 String temperatureString = this.temperatureString;
175 if (temperatureString != null) {
176 char firstChar = temperatureString.charAt(0);
178 float temp = Float.parseFloat(temperatureString.substring(1, 4)) / 10;
179 temperature = firstChar == PLUS_SIGN_TEMPERATURE ? temp
180 : firstChar == MINUS_SIGN_TEMPERATURE ? -temp : INITIAL_VALUE;
181 } catch (NumberFormatException ignore) {
186 protected abstract void setTemperatureString();
188 private void setWindAndOvercast() {
190 if (windString != null) {
191 String gustyFlag = windString.substring(0, 2);
192 if ("00".equals(gustyFlag)) {
200 windDirection = INITIAL_VALUE;
201 windSpeed = INITIAL_VALUE;
205 private void setOcta() {
206 if (windString != null) {
207 octa = Character.getNumericValue(windString.charAt(0));
213 private void setWindDirection() {
214 if (windString != null) {
215 String windDirectionString = windString.substring(1, 3);
217 if (windDirectionString.equals("99") || windDirectionString.equals("||")) {
218 windDirection = INITIAL_VALUE;
221 windDirection = Integer.parseInt(windDirectionString) * 10;
222 } catch (NumberFormatException e) {
223 windDirection = INITIAL_VALUE;
229 private void setWindSpeed(boolean gustyWind) {
230 String speedString = null;
231 if (windString != null) {
232 speedString = windString.substring(gustyWind ? 2 : 3, 5);
234 windSpeed = Integer.parseInt(speedString);
235 } catch (NumberFormatException e) {
236 windSpeed = INITIAL_VALUE;
241 protected abstract void setWindString();
243 private void setPressure() {
246 if (pressureString != null) {
248 String pressureTemp = pressureString.substring(1, 5);
250 if (pressureTemp.charAt(0) == '0') {
251 pressureTemp = '1' + pressureTemp;
255 pressure = (float) Integer.parseInt(pressureTemp) / 10;
256 } catch (NumberFormatException e) {
257 pressure = INITIAL_VALUE;
262 protected abstract void setPressureString();
264 protected boolean isValidString(String str) {
265 return (str.length() == VALID_STRING_LENGTH);
268 public int getYear() {
272 public int getMonth() {
276 public int getDay() {
280 public int getHour() {
284 public int getWindIndicator() {
285 return windIndicator;
288 public HorizontalVisibility getHorizontalVisibility() {
289 return horizontalVisibility;
292 public float getTemperature() {
296 public int getWindDirection() {
297 return windDirection;
300 public int getWindSpeed() {
304 public float getPressure() {
308 public int getOcta() {
312 public Unit<Speed> getWindUnit() {
313 return (getWindIndicator() == WS_WILDTYPE_IN_MPS || getWindIndicator() == WS_ANEMOMETER_IN_MPS)
314 ? Units.METRE_PER_SECOND