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.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 private static final char PLUS_SIGN_TEMPERATURE = '0';
34 private static final char MINUS_SIGN_TEMPERATURE = '1';
39 private static final int WS_WILDTYPE_IN_MPS = 0;
40 private 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 private static final int HV_LESS_THAN_1_LIMIT = 10;
63 private static final int HV_LESS_THAN_10_LIMIT = 60;
64 private static final int HV_LESS_THAN_50_LIMIT = 84;
65 private static final int HV_LESS_THAN_1_HP_LIMIT = 93;
66 private static final int HV_LESS_THAN_10_HP_LIMIT = 96;
67 private static final int HV_LESS_THAN_50_HP_LIMIT = 98;
69 public enum HorizontalVisibility {
77 private static 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 protected abstract void setTemperatureString();
112 protected abstract void setHorizontalVisibilityInt();
114 protected abstract void setPressureString();
116 protected abstract void setWindString();
118 private void setDateHourAndWindIndicator() {
119 String dayHourAndWindIndicator = "";
121 if (this instanceof SynopLand && stringArray.size() > 1) {
122 dayHourAndWindIndicator = stringArray.get(1);
123 } else if (stringArray.size() > 2) {
124 dayHourAndWindIndicator = stringArray.get(2);
127 if (!isValidString(dayHourAndWindIndicator)) {
131 setHourOfObservation(dayHourAndWindIndicator);
132 setWindIndicator(dayHourAndWindIndicator);
135 private void setHourOfObservation(String str) {
137 hour = Integer.parseInt(str.substring(2, 4));
138 } catch (NumberFormatException e) {
139 hour = INITIAL_VALUE;
142 day = Integer.parseInt(str.substring(0, 2));
143 } catch (NumberFormatException e) {
148 private void setWindIndicator(String str) {
150 windIndicator = Character.getNumericValue(str.charAt(4));
151 } catch (NumberFormatException e) {
152 windIndicator = INITIAL_VALUE;
156 private void setHorizontalVisibility() {
157 setHorizontalVisibilityInt();
158 if (horizontalVisibilityInt != INITIAL_VALUE) {
159 if (horizontalVisibilityInt < HV_LESS_THAN_1_LIMIT || horizontalVisibilityInt < HV_LESS_THAN_1_HP_LIMIT) {
160 horizontalVisibility = HorizontalVisibility.LESS_THAN_1;
161 } else if (horizontalVisibilityInt < HV_LESS_THAN_10_LIMIT
162 || horizontalVisibilityInt < HV_LESS_THAN_10_HP_LIMIT) {
163 horizontalVisibility = HorizontalVisibility.LESS_THAN_10;
164 } else if (horizontalVisibilityInt < HV_LESS_THAN_50_LIMIT
165 || horizontalVisibilityInt < HV_LESS_THAN_50_HP_LIMIT) {
166 horizontalVisibility = HorizontalVisibility.LESS_THAN_50;
168 horizontalVisibility = HorizontalVisibility.MORE_THAN_50;
171 horizontalVisibility = HorizontalVisibility.UNDEFINED;
175 private void setTemperature() {
176 setTemperatureString();
177 temperature = INITIAL_VALUE;
178 String temperatureString = this.temperatureString;
179 if (temperatureString != null) {
180 char firstChar = temperatureString.charAt(0);
182 float temp = Float.parseFloat(temperatureString.substring(1, 4)) / 10;
183 temperature = firstChar == PLUS_SIGN_TEMPERATURE ? temp
184 : firstChar == MINUS_SIGN_TEMPERATURE ? -temp : INITIAL_VALUE;
185 } catch (NumberFormatException ignore) {
190 private void setWindAndOvercast() {
192 String localWind = windString;
193 if (localWind != null) {
194 String gustyFlag = localWind.substring(0, 2);
195 if ("00".equals(gustyFlag)) {
203 windDirection = INITIAL_VALUE;
204 windSpeed = INITIAL_VALUE;
208 private void setOcta() {
209 String localWind = windString;
210 if (localWind != null) {
211 octa = Character.getNumericValue(localWind.charAt(0));
217 private void setWindDirection() {
218 String localWind = windString;
219 if (localWind != null) {
220 String windDirectionString = localWind.substring(1, 3);
222 if ("99".equals(windDirectionString) || "||".equals(windDirectionString)) {
223 windDirection = INITIAL_VALUE;
226 windDirection = Integer.parseInt(windDirectionString) * 10;
227 } catch (NumberFormatException e) {
228 windDirection = INITIAL_VALUE;
234 private void setWindSpeed(boolean gustyWind) {
235 String speedString = null;
236 String localWind = windString;
237 if (localWind != null) {
238 speedString = localWind.substring(gustyWind ? 2 : 3, 5);
240 windSpeed = Integer.parseInt(speedString);
241 } catch (NumberFormatException e) {
242 windSpeed = INITIAL_VALUE;
247 private void setPressure() {
249 String localPressure = pressureString;
250 if (localPressure != null) {
251 String pressureTemp = localPressure.substring(1, 5);
252 if (pressureTemp.charAt(0) == '0') {
253 pressureTemp = '1' + pressureTemp;
256 pressure = (float) Integer.parseInt(pressureTemp) / 10;
257 } catch (NumberFormatException e) {
258 pressure = INITIAL_VALUE;
263 protected boolean isValidString(String str) {
264 return (str.length() == VALID_STRING_LENGTH);
267 public int getYear() {
271 public int getMonth() {
275 public int getDay() {
279 public int getHour() {
283 public int getWindIndicator() {
284 return windIndicator;
287 public HorizontalVisibility getHorizontalVisibility() {
288 return horizontalVisibility;
291 public float getTemperature() {
295 public @Nullable Integer getWindDirection() {
296 return windDirection != INITIAL_VALUE ? windDirection : null;
299 public int getWindSpeed() {
303 public float getPressure() {
307 public int getOcta() {
311 public Unit<Speed> getWindUnit() {
312 return (getWindIndicator() == WS_WILDTYPE_IN_MPS || getWindIndicator() == WS_ANEMOMETER_IN_MPS)
313 ? Units.METRE_PER_SECOND