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.
Files changed (35) hide show
  1. package/.github/workflows/release.yml +33 -33
  2. package/.pre-commit-config.yaml +37 -37
  3. package/.releaserc +23 -23
  4. package/.releaserc.toml +14 -14
  5. package/AUTHORS.md +12 -12
  6. package/CHANGELOG.md +401 -381
  7. package/README.md +40 -40
  8. package/custom_components/meteocat/__init__.py +107 -107
  9. package/custom_components/meteocat/condition.py +28 -28
  10. package/custom_components/meteocat/config_flow.py +192 -192
  11. package/custom_components/meteocat/const.py +55 -54
  12. package/custom_components/meteocat/coordinator.py +195 -171
  13. package/custom_components/meteocat/entity.py +98 -98
  14. package/custom_components/meteocat/helpers.py +42 -42
  15. package/custom_components/meteocat/manifest.json +12 -12
  16. package/custom_components/meteocat/options_flow.py +71 -71
  17. package/custom_components/meteocat/sensor.py +303 -200
  18. package/custom_components/meteocat/strings.json +25 -25
  19. package/custom_components/meteocat/translations/ca.json +25 -25
  20. package/custom_components/meteocat/translations/en.json +25 -25
  21. package/custom_components/meteocat/translations/es.json +25 -25
  22. package/custom_components/meteocat/version.py +2 -2
  23. package/filetree.py +48 -48
  24. package/filetree.txt +46 -46
  25. package/hacs.json +5 -5
  26. package/package.json +22 -22
  27. package/poetry.lock +3216 -3216
  28. package/pyproject.toml +64 -64
  29. package/releaserc.json +17 -17
  30. package/requirements.test.txt +3 -3
  31. package/setup.cfg +64 -64
  32. package/setup.py +10 -10
  33. package/tests/bandit.yaml +17 -17
  34. package/tests/conftest.py +19 -19
  35. package/tests/test_init.py +9 -9
@@ -1,200 +1,303 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from homeassistant.helpers.entity import DeviceInfo
5
- from homeassistant.components.sensor import (
6
- SensorDeviceClass,
7
- SensorEntity,
8
- SensorEntityDescription,
9
- SensorStateClass,
10
- )
11
- from homeassistant.core import callback
12
- from homeassistant.helpers.entity_platform import AddEntitiesCallback
13
- from homeassistant.helpers.update_coordinator import CoordinatorEntity
14
- from homeassistant.const import (
15
- DEGREE,
16
- PERCENTAGE,
17
- UnitOfPressure,
18
- UnitOfSpeed,
19
- UnitOfTemperature,
20
- UnitOfVolumetricFlux,
21
- )
22
-
23
- from .const import (
24
- DOMAIN,
25
- WIND_SPEED,
26
- WIND_DIRECTION,
27
- TEMPERATURE,
28
- HUMIDITY,
29
- PRESSURE,
30
- PRECIPITATION,
31
- UV_INDEX,
32
- MAX_TEMPERATURE,
33
- MIN_TEMPERATURE,
34
- WIND_GUST,
35
- VARIABLE_CODE_MAPPING,
36
- )
37
-
38
- from .coordinator import MeteocatSensorCoordinator
39
-
40
-
41
- @dataclass
42
- class MeteocatSensorEntityDescription(SensorEntityDescription):
43
- """A class that describes Meteocat sensor entities."""
44
-
45
-
46
- SENSOR_TYPES: tuple[MeteocatSensorEntityDescription, ...] = (
47
- MeteocatSensorEntityDescription(
48
- key=WIND_SPEED,
49
- name="Wind Speed",
50
- icon="mdi:weather-windy",
51
- device_class=SensorDeviceClass.WIND_SPEED,
52
- state_class=SensorStateClass.MEASUREMENT,
53
- native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
54
- ),
55
- MeteocatSensorEntityDescription(
56
- key=WIND_DIRECTION,
57
- name="Wind Direction",
58
- icon="mdi:compass",
59
- device_class=None,
60
- ),
61
- MeteocatSensorEntityDescription(
62
- key=TEMPERATURE,
63
- name="Temperature",
64
- icon="mdi:thermometer",
65
- device_class=SensorDeviceClass.TEMPERATURE,
66
- state_class=SensorStateClass.MEASUREMENT,
67
- native_unit_of_measurement=UnitOfTemperature.CELSIUS,
68
- ),
69
- MeteocatSensorEntityDescription(
70
- key=HUMIDITY,
71
- name="Humidity",
72
- icon="mdi:water-percent",
73
- device_class=SensorDeviceClass.HUMIDITY,
74
- state_class=SensorStateClass.MEASUREMENT,
75
- native_unit_of_measurement=PERCENTAGE,
76
- ),
77
- MeteocatSensorEntityDescription(
78
- key=PRESSURE,
79
- name="Pressure",
80
- icon="mdi:gauge",
81
- device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
82
- state_class=SensorStateClass.MEASUREMENT,
83
- native_unit_of_measurement=UnitOfPressure.HPA,
84
- ),
85
- MeteocatSensorEntityDescription(
86
- key=PRECIPITATION,
87
- name="Precipitation",
88
- icon="mdi:weather-rainy",
89
- device_class=None,
90
- state_class=SensorStateClass.MEASUREMENT,
91
- native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
92
- ),
93
- MeteocatSensorEntityDescription(
94
- key=UV_INDEX,
95
- name="UV Index",
96
- icon="mdi:weather-sunny",
97
- ),
98
- MeteocatSensorEntityDescription(
99
- key=MAX_TEMPERATURE,
100
- name="Max Temperature",
101
- icon="mdi:thermometer-plus",
102
- device_class=SensorDeviceClass.TEMPERATURE,
103
- state_class=SensorStateClass.MEASUREMENT,
104
- native_unit_of_measurement=UnitOfTemperature.CELSIUS,
105
- ),
106
- MeteocatSensorEntityDescription(
107
- key=MIN_TEMPERATURE,
108
- name="Min Temperature",
109
- icon="mdi:thermometer-minus",
110
- device_class=SensorDeviceClass.TEMPERATURE,
111
- state_class=SensorStateClass.MEASUREMENT,
112
- native_unit_of_measurement=UnitOfTemperature.CELSIUS,
113
- ),
114
- MeteocatSensorEntityDescription(
115
- key=WIND_GUST,
116
- name="Wind Gust",
117
- icon="mdi:weather-windy",
118
- device_class=SensorDeviceClass.WIND_SPEED,
119
- state_class=SensorStateClass.MEASUREMENT,
120
- native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
121
- ),
122
- )
123
-
124
-
125
- @callback
126
- async def async_setup_entry(hass, entry, async_add_entities: AddEntitiesCallback) -> None:
127
- """Set up Meteocat sensors from a config entry."""
128
- entry_data = hass.data[DOMAIN][entry.entry_id]
129
- coordinator = entry_data["sensor_coordinator"]
130
-
131
- async_add_entities(
132
- MeteocatSensor(coordinator, description, entry_data)
133
- for description in SENSOR_TYPES
134
- )
135
-
136
-
137
- class MeteocatSensor(CoordinatorEntity[MeteocatSensorCoordinator], SensorEntity):
138
- """Representation of a Meteocat sensor."""
139
-
140
- def __init__(self, coordinator, description, entry_data):
141
- """Initialize the sensor."""
142
- super().__init__(coordinator)
143
- self.entity_description = description
144
- self.api_key = entry_data["api_key"] # Usamos la API key de la configuración
145
- self._town_name = entry_data["town_name"] # Usamos el nombre del municipio
146
- self._town_id = entry_data["town_id"] # Usamos el ID del municipio
147
- self._variable_name = entry_data["variable_name"] # Usamos el nombre de la variable
148
- self._variable_id = entry_data["variable_id"] # Usamos el ID de la variable
149
- self._station_name = entry_data["station_name"] # Usamos el nombre de la estación
150
- self._station_id = entry_data["station_id"] # Usamos el ID de la estación
151
-
152
- # Unique ID for the entity
153
- self._attr_unique_id = f"{self._town_id}_{self.entity_description.key}"
154
-
155
- @property
156
- def native_value(self):
157
- """Return the state of the sensor."""
158
- sensor_code = next(
159
- (code for code, key in VARIABLE_CODE_MAPPING.items() if key == self.entity_description.key),
160
- None,
161
- )
162
-
163
- if sensor_code is not None:
164
- variable_data = next(
165
- (var for var in self.coordinator.data.get("variables", []) if var["codi"] == sensor_code),
166
- None,
167
- )
168
- if variable_data:
169
- # Asume que quieres el último valor registrado
170
- latest_reading = variable_data["lectures"][-1]
171
- value = latest_reading.get("valor")
172
-
173
- # Convertir grados a direcciones cardinales para WIND_DIRECTION
174
- if self.entity_description.key == WIND_DIRECTION and isinstance(value, (int, float)):
175
- return self._convert_degrees_to_cardinal(value)
176
-
177
- return value
178
-
179
- return None
180
-
181
- @staticmethod
182
- def _convert_degrees_to_cardinal(degree: float) -> str:
183
- """Convert degrees to cardinal direction."""
184
- directions = [
185
- "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
186
- "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N",
187
- ]
188
- index = round(degree / 22.5) % 16
189
- return directions[index]
190
-
191
-
192
- @property
193
- def device_info(self) -> DeviceInfo:
194
- """Return the device info."""
195
- return DeviceInfo(
196
- identifiers={(DOMAIN, self._town_id)},
197
- name=self._town_name,
198
- manufacturer="Meteocat",
199
- model="Meteocat API"
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
  }