meteocat 0.1.23 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yml +33 -33
- package/.pre-commit-config.yaml +37 -37
- package/.releaserc +23 -23
- package/.releaserc.toml +14 -14
- package/AUTHORS.md +12 -12
- package/CHANGELOG.md +401 -381
- package/README.md +40 -40
- package/custom_components/meteocat/__init__.py +107 -107
- package/custom_components/meteocat/condition.py +28 -28
- package/custom_components/meteocat/config_flow.py +192 -192
- package/custom_components/meteocat/const.py +55 -54
- package/custom_components/meteocat/coordinator.py +195 -171
- package/custom_components/meteocat/entity.py +98 -98
- package/custom_components/meteocat/helpers.py +42 -42
- package/custom_components/meteocat/manifest.json +12 -12
- package/custom_components/meteocat/options_flow.py +71 -71
- package/custom_components/meteocat/sensor.py +303 -200
- package/custom_components/meteocat/strings.json +25 -25
- package/custom_components/meteocat/translations/ca.json +25 -25
- package/custom_components/meteocat/translations/en.json +25 -25
- package/custom_components/meteocat/translations/es.json +25 -25
- package/custom_components/meteocat/version.py +2 -2
- package/filetree.py +48 -48
- package/filetree.txt +46 -46
- package/hacs.json +5 -5
- package/package.json +22 -22
- package/poetry.lock +3216 -3216
- package/pyproject.toml +64 -64
- package/releaserc.json +17 -17
- package/requirements.test.txt +3 -3
- package/setup.cfg +64 -64
- package/setup.py +10 -10
- package/tests/bandit.yaml +17 -17
- package/tests/conftest.py +19 -19
- package/tests/test_init.py +9 -9
|
@@ -1,200 +1,303 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from
|
|
5
|
-
from homeassistant.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
from homeassistant.
|
|
13
|
-
from homeassistant.helpers.
|
|
14
|
-
from homeassistant.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from homeassistant.helpers.entity import DeviceInfo
|
|
6
|
+
from homeassistant.components.sensor import (
|
|
7
|
+
SensorDeviceClass,
|
|
8
|
+
SensorEntity,
|
|
9
|
+
SensorEntityDescription,
|
|
10
|
+
SensorStateClass,
|
|
11
|
+
)
|
|
12
|
+
from homeassistant.core import callback
|
|
13
|
+
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
14
|
+
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
15
|
+
from homeassistant.const import (
|
|
16
|
+
DEGREE,
|
|
17
|
+
PERCENTAGE,
|
|
18
|
+
UnitOfPressure,
|
|
19
|
+
UnitOfSpeed,
|
|
20
|
+
UnitOfTemperature,
|
|
21
|
+
UnitOfVolumetricFlux,
|
|
22
|
+
UnitOfIrradiance,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
from .const import (
|
|
26
|
+
DOMAIN,
|
|
27
|
+
TOWN_NAME,
|
|
28
|
+
TOWN_ID,
|
|
29
|
+
STATION_NAME,
|
|
30
|
+
STATION_ID,
|
|
31
|
+
WIND_SPEED,
|
|
32
|
+
WIND_DIRECTION,
|
|
33
|
+
TEMPERATURE,
|
|
34
|
+
HUMIDITY,
|
|
35
|
+
PRESSURE,
|
|
36
|
+
PRECIPITATION,
|
|
37
|
+
SOLAR_GLOBAL_IRRADIANCE,
|
|
38
|
+
UV_INDEX,
|
|
39
|
+
MAX_TEMPERATURE,
|
|
40
|
+
MIN_TEMPERATURE,
|
|
41
|
+
WIND_GUST,
|
|
42
|
+
STATION_TIMESTAMP,
|
|
43
|
+
WIND_SPEED_CODE,
|
|
44
|
+
WIND_DIRECTION_CODE,
|
|
45
|
+
TEMPERATURE_CODE,
|
|
46
|
+
HUMIDITY_CODE,
|
|
47
|
+
PRESSURE_CODE,
|
|
48
|
+
PRECIPITATION_CODE,
|
|
49
|
+
SOLAR_GLOBAL_IRRADIANCE_CODE,
|
|
50
|
+
UV_INDEX_CODE,
|
|
51
|
+
MAX_TEMPERATURE_CODE,
|
|
52
|
+
MIN_TEMPERATURE_CODE,
|
|
53
|
+
WIND_GUST_CODE,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
from .coordinator import MeteocatSensorCoordinator
|
|
57
|
+
|
|
58
|
+
@dataclass
|
|
59
|
+
class MeteocatSensorEntityDescription(SensorEntityDescription):
|
|
60
|
+
"""A class that describes Meteocat sensor entities."""
|
|
61
|
+
|
|
62
|
+
SENSOR_TYPES: tuple[MeteocatSensorEntityDescription, ...] = (
|
|
63
|
+
# Sensores dinámicos
|
|
64
|
+
MeteocatSensorEntityDescription(
|
|
65
|
+
key=WIND_SPEED,
|
|
66
|
+
name="Wind Speed",
|
|
67
|
+
icon="mdi:weather-windy",
|
|
68
|
+
device_class=SensorDeviceClass.WIND_SPEED,
|
|
69
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
70
|
+
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
|
71
|
+
),
|
|
72
|
+
MeteocatSensorEntityDescription(
|
|
73
|
+
key=WIND_DIRECTION,
|
|
74
|
+
name="Wind Direction",
|
|
75
|
+
icon="mdi:compass",
|
|
76
|
+
device_class=None,
|
|
77
|
+
),
|
|
78
|
+
MeteocatSensorEntityDescription(
|
|
79
|
+
key=TEMPERATURE,
|
|
80
|
+
name="Temperature",
|
|
81
|
+
icon="mdi:thermometer",
|
|
82
|
+
device_class=SensorDeviceClass.TEMPERATURE,
|
|
83
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
84
|
+
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
85
|
+
),
|
|
86
|
+
MeteocatSensorEntityDescription(
|
|
87
|
+
key=HUMIDITY,
|
|
88
|
+
name="Humidity",
|
|
89
|
+
icon="mdi:water-percent",
|
|
90
|
+
device_class=SensorDeviceClass.HUMIDITY,
|
|
91
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
92
|
+
native_unit_of_measurement=PERCENTAGE,
|
|
93
|
+
),
|
|
94
|
+
MeteocatSensorEntityDescription(
|
|
95
|
+
key=PRESSURE,
|
|
96
|
+
name="Pressure",
|
|
97
|
+
icon="mdi:gauge",
|
|
98
|
+
device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
|
|
99
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
100
|
+
native_unit_of_measurement=UnitOfPressure.HPA,
|
|
101
|
+
),
|
|
102
|
+
MeteocatSensorEntityDescription(
|
|
103
|
+
key=PRECIPITATION,
|
|
104
|
+
name="Precipitation",
|
|
105
|
+
icon="mdi:weather-rainy",
|
|
106
|
+
device_class=None,
|
|
107
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
108
|
+
native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
|
|
109
|
+
),
|
|
110
|
+
MeteocatSensorEntityDescription(
|
|
111
|
+
key=SOLAR_GLOBAL_IRRADIANCE,
|
|
112
|
+
name="Solar Global Irradiance",
|
|
113
|
+
icon="mdi:weather-sunny",
|
|
114
|
+
device_class=SensorDeviceClass.IRRADIANCE,
|
|
115
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
116
|
+
native_unit_of_measurement = UnitOfIrradiance.WATTS_PER_SQUARE_METER,
|
|
117
|
+
),
|
|
118
|
+
MeteocatSensorEntityDescription(
|
|
119
|
+
key=UV_INDEX,
|
|
120
|
+
name="UV Index",
|
|
121
|
+
icon="mdi:weather-sunny",
|
|
122
|
+
),
|
|
123
|
+
MeteocatSensorEntityDescription(
|
|
124
|
+
key=MAX_TEMPERATURE,
|
|
125
|
+
name="Max Temperature",
|
|
126
|
+
icon="mdi:thermometer-plus",
|
|
127
|
+
device_class=SensorDeviceClass.TEMPERATURE,
|
|
128
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
129
|
+
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
130
|
+
),
|
|
131
|
+
MeteocatSensorEntityDescription(
|
|
132
|
+
key=MIN_TEMPERATURE,
|
|
133
|
+
name="Min Temperature",
|
|
134
|
+
icon="mdi:thermometer-minus",
|
|
135
|
+
device_class=SensorDeviceClass.TEMPERATURE,
|
|
136
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
137
|
+
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
138
|
+
),
|
|
139
|
+
MeteocatSensorEntityDescription(
|
|
140
|
+
key=WIND_GUST,
|
|
141
|
+
name="Wind Gust",
|
|
142
|
+
icon="mdi:weather-windy",
|
|
143
|
+
device_class=SensorDeviceClass.WIND_SPEED,
|
|
144
|
+
state_class=SensorStateClass.MEASUREMENT,
|
|
145
|
+
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
|
146
|
+
),
|
|
147
|
+
# Sensores estáticos
|
|
148
|
+
MeteocatSensorEntityDescription(
|
|
149
|
+
key=TOWN_NAME,
|
|
150
|
+
name="Town Name",
|
|
151
|
+
icon="mdi:home-city",
|
|
152
|
+
),
|
|
153
|
+
MeteocatSensorEntityDescription(
|
|
154
|
+
key=TOWN_ID,
|
|
155
|
+
name="Town ID",
|
|
156
|
+
icon="mdi:identifier",
|
|
157
|
+
),
|
|
158
|
+
MeteocatSensorEntityDescription(
|
|
159
|
+
key=STATION_NAME,
|
|
160
|
+
name="Station Name",
|
|
161
|
+
icon="mdi:broadcast",
|
|
162
|
+
),
|
|
163
|
+
MeteocatSensorEntityDescription(
|
|
164
|
+
key=STATION_ID,
|
|
165
|
+
name="Station ID",
|
|
166
|
+
icon="mdi:identifier",
|
|
167
|
+
),
|
|
168
|
+
MeteocatSensorEntityDescription(
|
|
169
|
+
key=STATION_TIMESTAMP,
|
|
170
|
+
name="Station Timestamp",
|
|
171
|
+
icon="mdi:calendar-clock",
|
|
172
|
+
device_class=SensorDeviceClass.TIMESTAMP,
|
|
173
|
+
)
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@callback
|
|
178
|
+
async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback) -> None:
|
|
179
|
+
"""Set up Meteocat sensors from a config entry."""
|
|
180
|
+
entry_data = hass.data[DOMAIN][entry.entry_id]
|
|
181
|
+
coordinator = entry_data["sensor_coordinator"]
|
|
182
|
+
|
|
183
|
+
async_add_entities(
|
|
184
|
+
MeteocatSensor(coordinator, description, entry_data)
|
|
185
|
+
for description in SENSOR_TYPES
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
class MeteocatSensor(CoordinatorEntity[MeteocatSensorCoordinator], SensorEntity):
|
|
189
|
+
"""Representation of a Meteocat sensor."""
|
|
190
|
+
STATIC_KEYS = {TOWN_NAME, TOWN_ID, STATION_NAME, STATION_ID}
|
|
191
|
+
|
|
192
|
+
CODE_MAPPING = {
|
|
193
|
+
WIND_SPEED: WIND_SPEED_CODE,
|
|
194
|
+
WIND_DIRECTION: WIND_DIRECTION_CODE,
|
|
195
|
+
TEMPERATURE: TEMPERATURE_CODE,
|
|
196
|
+
HUMIDITY: HUMIDITY_CODE,
|
|
197
|
+
PRESSURE: PRESSURE_CODE,
|
|
198
|
+
PRECIPITATION: PRECIPITATION_CODE,
|
|
199
|
+
SOLAR_GLOBAL_IRRADIANCE: SOLAR_GLOBAL_IRRADIANCE_CODE,
|
|
200
|
+
UV_INDEX: UV_INDEX_CODE,
|
|
201
|
+
MAX_TEMPERATURE: MAX_TEMPERATURE_CODE,
|
|
202
|
+
MIN_TEMPERATURE: MIN_TEMPERATURE_CODE,
|
|
203
|
+
WIND_GUST: WIND_GUST_CODE,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
def __init__(self, coordinator, description, entry_data):
|
|
207
|
+
"""Initialize the sensor."""
|
|
208
|
+
super().__init__(coordinator)
|
|
209
|
+
self.entity_description = description
|
|
210
|
+
self.api_key = entry_data["api_key"]
|
|
211
|
+
self._town_name = entry_data["town_name"]
|
|
212
|
+
self._town_id = entry_data["town_id"]
|
|
213
|
+
self._station_name = entry_data["station_name"]
|
|
214
|
+
self._station_id = entry_data["station_id"]
|
|
215
|
+
|
|
216
|
+
# Unique ID for the entity
|
|
217
|
+
self._attr_unique_id = f"{self._town_id}_{self.entity_description.key}"
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def native_value(self):
|
|
221
|
+
"""Return the state of the sensor."""
|
|
222
|
+
# Información estática
|
|
223
|
+
if self.entity_description.key in self.STATIC_KEYS:
|
|
224
|
+
# Información estática del `entry_data`
|
|
225
|
+
if self.entity_description.key == TOWN_NAME:
|
|
226
|
+
return self._town_name
|
|
227
|
+
if self.entity_description.key == TOWN_ID:
|
|
228
|
+
return self._town_id
|
|
229
|
+
if self.entity_description.key == STATION_NAME:
|
|
230
|
+
return self._station_name
|
|
231
|
+
if self.entity_description.key == STATION_ID:
|
|
232
|
+
return self._station_id
|
|
233
|
+
# Información dinámica
|
|
234
|
+
sensor_code = self.CODE_MAPPING.get(self.entity_description.key)
|
|
235
|
+
|
|
236
|
+
if sensor_code is not None:
|
|
237
|
+
# Accedemos a las estaciones en el JSON recibido
|
|
238
|
+
stations = self.coordinator.data or []
|
|
239
|
+
for station in stations:
|
|
240
|
+
variables = station.get("variables", [])
|
|
241
|
+
|
|
242
|
+
# Filtramos por código
|
|
243
|
+
variable_data = next(
|
|
244
|
+
(var for var in variables if var.get("codi") == sensor_code),
|
|
245
|
+
None,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
if variable_data:
|
|
249
|
+
# Obtenemos la última lectura
|
|
250
|
+
lectures = variable_data.get("lectures", [])
|
|
251
|
+
if lectures:
|
|
252
|
+
latest_reading = lectures[-1]
|
|
253
|
+
value = latest_reading.get("valor")
|
|
254
|
+
|
|
255
|
+
# Convertimos grados a dirección cardinal para WIND_DIRECTION
|
|
256
|
+
if self.entity_description.key == WIND_DIRECTION and isinstance(value, (int, float)):
|
|
257
|
+
return self._convert_degrees_to_cardinal(value)
|
|
258
|
+
|
|
259
|
+
return value
|
|
260
|
+
# Lógica específica para el sensor de timestamp
|
|
261
|
+
if self.entity_description.key == "station_timestamp":
|
|
262
|
+
stations = self.coordinator.data or []
|
|
263
|
+
for station in stations:
|
|
264
|
+
variables = station.get("variables", [])
|
|
265
|
+
for variable in variables:
|
|
266
|
+
lectures = variable.get("lectures", [])
|
|
267
|
+
if lectures:
|
|
268
|
+
# Obtenemos el campo `data` de la última lectura
|
|
269
|
+
latest_reading = lectures[-1]
|
|
270
|
+
raw_timestamp = latest_reading.get("data")
|
|
271
|
+
|
|
272
|
+
if raw_timestamp:
|
|
273
|
+
# Convertir el timestamp a un objeto datetime
|
|
274
|
+
try:
|
|
275
|
+
return datetime.fromisoformat(raw_timestamp.replace("Z", "+00:00"))
|
|
276
|
+
except ValueError:
|
|
277
|
+
# Manejo de errores si el formato no es válido
|
|
278
|
+
return None
|
|
279
|
+
|
|
280
|
+
return None
|
|
281
|
+
|
|
282
|
+
@staticmethod
|
|
283
|
+
def _convert_degrees_to_cardinal(degree: float) -> str:
|
|
284
|
+
"""Convert degrees to cardinal direction."""
|
|
285
|
+
if not isinstance(degree, (int, float)):
|
|
286
|
+
return "Unknown" # Retorna "Unknown" si el valor no es un número válido
|
|
287
|
+
|
|
288
|
+
directions = [
|
|
289
|
+
"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
|
|
290
|
+
"S", "SSO", "SO", "OSO", "O", "ONO", "NO", "NNO", "N",
|
|
291
|
+
]
|
|
292
|
+
index = round(degree / 22.5) % 16
|
|
293
|
+
return directions[index]
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
def device_info(self) -> DeviceInfo:
|
|
297
|
+
"""Return the device info."""
|
|
298
|
+
return DeviceInfo(
|
|
299
|
+
identifiers={(DOMAIN, self._town_id)},
|
|
300
|
+
name=self._town_name,
|
|
301
|
+
manufacturer="Meteocat",
|
|
302
|
+
model="Meteocat API",
|
|
303
|
+
)
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
{
|
|
2
|
-
"config": {
|
|
3
|
-
"step": {
|
|
4
|
-
"user": {
|
|
5
|
-
"description": "Enter your Meteocat API Key to validate it.",
|
|
6
|
-
"title": "API Key"
|
|
7
|
-
},
|
|
8
|
-
"select_municipi": {
|
|
9
|
-
"description": "Select a municipality from the list.",
|
|
10
|
-
"title": "Municipality Selection"
|
|
11
|
-
},
|
|
12
|
-
"select_station": {
|
|
13
|
-
"description": "Select a station.",
|
|
14
|
-
"title": "Station Selection"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"error": {
|
|
18
|
-
"bad_request": "Invalid request. Please check your API Key.",
|
|
19
|
-
"forbidden": "Access denied. Check your API Key permissions.",
|
|
20
|
-
"rate_limit_exceeded": "Rate limit exceeded. Please try again later.",
|
|
21
|
-
"server_error": "Server error. Please try again later.",
|
|
22
|
-
"connection_error": "Connection error. Please check your network.",
|
|
23
|
-
"unknown_error": "An unknown error occurred."
|
|
24
|
-
}
|
|
25
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"config": {
|
|
3
|
+
"step": {
|
|
4
|
+
"user": {
|
|
5
|
+
"description": "Enter your Meteocat API Key to validate it.",
|
|
6
|
+
"title": "API Key"
|
|
7
|
+
},
|
|
8
|
+
"select_municipi": {
|
|
9
|
+
"description": "Select a municipality from the list.",
|
|
10
|
+
"title": "Municipality Selection"
|
|
11
|
+
},
|
|
12
|
+
"select_station": {
|
|
13
|
+
"description": "Select a station.",
|
|
14
|
+
"title": "Station Selection"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"error": {
|
|
18
|
+
"bad_request": "Invalid request. Please check your API Key.",
|
|
19
|
+
"forbidden": "Access denied. Check your API Key permissions.",
|
|
20
|
+
"rate_limit_exceeded": "Rate limit exceeded. Please try again later.",
|
|
21
|
+
"server_error": "Server error. Please try again later.",
|
|
22
|
+
"connection_error": "Connection error. Please check your network.",
|
|
23
|
+
"unknown_error": "An unknown error occurred."
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
26
|
}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
{
|
|
2
|
-
"config": {
|
|
3
|
-
"step": {
|
|
4
|
-
"user": {
|
|
5
|
-
"description": "Introduïu la API Key subministrada per Meteocat per poder iniciar el procés de validació.",
|
|
6
|
-
"title": "API Key"
|
|
7
|
-
},
|
|
8
|
-
"select_municipi": {
|
|
9
|
-
"description": "Seleccioneu el municipi de la llista.",
|
|
10
|
-
"title": "Selecció de municipi"
|
|
11
|
-
},
|
|
12
|
-
"select_station": {
|
|
13
|
-
"description": "Seleccioneu l'estació de la llista.",
|
|
14
|
-
"title": "Selecció d'estació"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"error": {
|
|
18
|
-
"bad_request": "Petició no vàlida. Reviseu la vostra API Key.",
|
|
19
|
-
"forbidden": "Accés denegat. Reviseu els permisos de la vostra API Key.",
|
|
20
|
-
"rate_limit_exceeded": "Excés del límit de peticions. Si us plau, torneu-ho a provar més tard.",
|
|
21
|
-
"server_error": "Error del servidor. Torneu-ho a provar més tard.",
|
|
22
|
-
"connection_error": "Error de connexió. Reviseu la vostra connexió de xarxa.",
|
|
23
|
-
"unknown_error": "Error desconegut."
|
|
24
|
-
}
|
|
25
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"config": {
|
|
3
|
+
"step": {
|
|
4
|
+
"user": {
|
|
5
|
+
"description": "Introduïu la API Key subministrada per Meteocat per poder iniciar el procés de validació.",
|
|
6
|
+
"title": "API Key"
|
|
7
|
+
},
|
|
8
|
+
"select_municipi": {
|
|
9
|
+
"description": "Seleccioneu el municipi de la llista.",
|
|
10
|
+
"title": "Selecció de municipi"
|
|
11
|
+
},
|
|
12
|
+
"select_station": {
|
|
13
|
+
"description": "Seleccioneu l'estació de la llista.",
|
|
14
|
+
"title": "Selecció d'estació"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"error": {
|
|
18
|
+
"bad_request": "Petició no vàlida. Reviseu la vostra API Key.",
|
|
19
|
+
"forbidden": "Accés denegat. Reviseu els permisos de la vostra API Key.",
|
|
20
|
+
"rate_limit_exceeded": "Excés del límit de peticions. Si us plau, torneu-ho a provar més tard.",
|
|
21
|
+
"server_error": "Error del servidor. Torneu-ho a provar més tard.",
|
|
22
|
+
"connection_error": "Error de connexió. Reviseu la vostra connexió de xarxa.",
|
|
23
|
+
"unknown_error": "Error desconegut."
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
26
|
}
|