Skip to content

Commit 25586ea

Browse files
author
tsunglung
committed
Use seperate API to query the weather of Opendata
1 parent 9a3398f commit 25586ea

File tree

9 files changed

+73
-94
lines changed

9 files changed

+73
-94
lines changed

custom_components/opencwb/config_flow.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
DEFAULT_NAME,
2222
DOMAIN,
2323
FORECAST_MODES,
24-
FORECAST_MODE_ONECALL_HOURLY,
25-
FORECAST_MODE_ONECALL_DAILY
24+
# FORECAST_MODE_ONECALL_HOURLY,
25+
# FORECAST_MODE_ONECALL_DAILY
2626
)
2727
from .core.weatherapi12.uris import ONE_CALL_URI
2828

@@ -60,9 +60,9 @@ async def async_step_user(self, user_input=None):
6060
location_name) + "-" + user_input[CONF_MODE])
6161
self._abort_if_unique_id_configured()
6262

63-
if (location_id != ONE_CALL_URI and
64-
user_input[CONF_MODE] == FORECAST_MODE_ONECALL_DAILY):
65-
user_input[CONF_MODE] = FORECAST_MODE_ONECALL_HOURLY
63+
#if (location_id != ONE_CALL_URI and
64+
# user_input[CONF_MODE] == FORECAST_MODE_ONECALL_DAILY):
65+
# user_input[CONF_MODE] = FORECAST_MODE_ONECALL_HOURLY
6666

6767
try:
6868
api_online = await _is_ocwb_api_online(
@@ -121,9 +121,9 @@ async def async_step_init(self, user_input=None):
121121
location_id = _is_supported_city(
122122
self.config_entry.data.get(CONF_API_KEY),
123123
self.config_entry.data.get(CONF_LOCATION_NAME))
124-
if (location_id != ONE_CALL_URI and
125-
user_input[CONF_MODE] == FORECAST_MODE_ONECALL_DAILY):
126-
user_input[CONF_MODE] = FORECAST_MODE_ONECALL_HOURLY
124+
#if (location_id != ONE_CALL_URI and
125+
# user_input[CONF_MODE] == FORECAST_MODE_ONECALL_DAILY):
126+
# user_input[CONF_MODE] = FORECAST_MODE_ONECALL_HOURLY
127127

128128
return self.async_create_entry(title="", data=user_input)
129129

@@ -153,7 +153,7 @@ def _get_options_schema(self):
153153

154154
async def _is_ocwb_api_online(hass, api_key, lat, lon, loc):
155155
ocwb = OCWB(api_key).weather_manager()
156-
return await hass.async_add_executor_job(ocwb.one_call, lat, lon, loc)
156+
return await hass.async_add_executor_job(ocwb.one_call, lat, lon, loc, "daily")
157157

158158

159159
def _is_supported_city(api_key, loc):

custom_components/opencwb/const.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
2121
# ATTR_FORECAST_PRESSURE,
2222
ATTR_FORECAST_TEMP,
23-
# ATTR_FORECAST_TEMP_LOW,
23+
ATTR_FORECAST_TEMP_LOW,
2424
ATTR_FORECAST_TIME,
2525
ATTR_FORECAST_WIND_BEARING,
2626
ATTR_FORECAST_WIND_SPEED,
@@ -93,7 +93,7 @@
9393
FORECAST_MODE_HOURLY,
9494
FORECAST_MODE_DAILY,
9595
FORECAST_MODE_ONECALL_HOURLY,
96-
# FORECAST_MODE_ONECALL_DAILY,
96+
FORECAST_MODE_ONECALL_DAILY,
9797
]
9898
DEFAULT_FORECAST_MODE = FORECAST_MODE_ONECALL_DAILY
9999

@@ -106,7 +106,7 @@
106106
ATTR_API_WIND_BEARING,
107107
ATTR_API_HUMIDITY,
108108
# ATTR_API_PRESSURE,
109-
ATTR_API_CLOUDS,
109+
# ATTR_API_CLOUDS,
110110
# ATTR_API_RAIN,
111111
# ATTR_API_SNOW,
112112
# ATTR_API_PRECIPITATION_KIND,
@@ -120,7 +120,7 @@
120120
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
121121
# ATTR_FORECAST_PRESSURE,
122122
ATTR_FORECAST_TEMP,
123-
# ATTR_FORECAST_TEMP_LOW,
123+
ATTR_FORECAST_TEMP_LOW,
124124
ATTR_FORECAST_TIME,
125125
ATTR_FORECAST_WIND_BEARING,
126126
ATTR_FORECAST_WIND_SPEED,
@@ -182,7 +182,7 @@
182182
# SENSOR_UNIT: PRESSURE_HPA,
183183
# SENSOR_DEVICE_CLASS: SensorDeviceClass.PRESSURE,
184184
# },
185-
ATTR_API_CLOUDS: {SENSOR_NAME: "Cloud coverage", SENSOR_UNIT: PERCENTAGE},
185+
# ATTR_API_CLOUDS: {SENSOR_NAME: "Cloud coverage", SENSOR_UNIT: PERCENTAGE},
186186
# ATTR_API_RAIN: {SENSOR_NAME: "Rain", SENSOR_UNIT: UnitOfLength.MILLIMETERS},
187187
# ATTR_API_SNOW: {SENSOR_NAME: "Snow", SENSOR_UNIT: UnitOfLength.MILLIMETERS},
188188
# ATTR_API_PRECIPITATION_KIND: {SENSOR_NAME: "Precipitation kind"},
@@ -213,11 +213,11 @@
213213
SENSOR_UNIT: UnitOfTemperature.CELSIUS,
214214
SENSOR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE,
215215
},
216-
# ATTR_FORECAST_TEMP_LOW: {
217-
# SENSOR_NAME: "Temperature Low",
218-
# SENSOR_UNIT: UnitOfTemperature.CELSIUS,
219-
# SENSOR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE,
220-
# },
216+
ATTR_FORECAST_TEMP_LOW: {
217+
SENSOR_NAME: "Temperature Low",
218+
SENSOR_UNIT: UnitOfTemperature.CELSIUS,
219+
SENSOR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE,
220+
},
221221
ATTR_FORECAST_TIME: {
222222
SENSOR_NAME: "Time",
223223
SENSOR_DEVICE_CLASS: SensorDeviceClass.TIMESTAMP,

custom_components/opencwb/core/commons/http_client.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
class HttpRequestBuilder:
1212

13-
URL_TEMPLATE_WITH_SUBDOMAINS = '{}://{}.{}/{}?Authorization={}&format=JSON&locationName={}'
14-
URL_TEMPLATE_WITH_SUBDOMAINS_WITH_LOCATIONID = '{}://{}.{}/{}?Authorization={}&format=JSON&locationId={}&locationName={}'
15-
URL_TEMPLATE_WITHOUT_SUBDOMAINS = '{}://{}/{}?Authorization={}&format=JSON&locationName={}'
16-
URL_TEMPLATE_WITHOUT_SUBDOMAINS_WITH_LOCATIONID = '{}://{}/{}?Authorization={}&format=JSON&locationId={}&locationName={}'
13+
URL_TEMPLATE_WITH_SUBDOMAINS = '{}://{}.{}/{}?Authorization={}&format=JSON&locationName={}&LocationName={}'
14+
URL_TEMPLATE_WITH_SUBDOMAINS_WITH_LOCATIONID = '{}://{}.{}/{}?Authorization={}&format=JSON&locationId={}&locationName={}&LocationName={}'
15+
URL_TEMPLATE_WITHOUT_SUBDOMAINS = '{}://{}/{}?Authorization={}&format=JSON&locationName={}&LocationName={}'
16+
URL_TEMPLATE_WITHOUT_SUBDOMAINS_WITH_LOCATIONID = '{}://{}/{}?Authorization={}&format=JSON&locationId={}&locationName={}&LocationName={}'
1717

1818
"""
1919
A stateful HTTP URL, params and headers builder with a fluent interface
@@ -93,23 +93,23 @@ def build(self):
9393
if locationId:
9494
return self.URL_TEMPLATE_WITH_SUBDOMAINS_WITH_LOCATIONID.format(
9595
self.schema, self.subdomain, self.root, self.path,
96-
self.api_key, locationId, locationName), \
96+
self.api_key, locationId, locationName, locationName), \
9797
self.params, self.headers, self.proxies
9898
else:
9999
return self.URL_TEMPLATE_WITH_SUBDOMAINS.format(
100100
self.schema, self.subdomain, self.root, self.path,
101-
self.api_key, locationName), \
101+
self.api_key, locationName, locationName), \
102102
self.params, self.headers, self.proxies
103103
else:
104104
if locationId:
105105
return self.URL_TEMPLATE_WITHOUT_SUBDOMAINS_WITH_LOCATIONID.format(
106106
self.schema, self.root, self.path,
107-
self.api_key, locationId, locationName), \
107+
self.api_key, locationId, locationName, locationName), \
108108
self.params, self.headers, self.proxies
109109
else:
110110
return self.URL_TEMPLATE_WITHOUT_SUBDOMAINS.format(
111111
self.schema, self.root, self.path,
112-
self.api_key, locationName), \
112+
self.api_key, locationName, locationName), \
113113
self.params, self.headers, self.proxies
114114

115115
def __repr__(self):

custom_components/opencwb/core/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

4-
OCWB_VERSION = (1, 0, 0)
4+
OCWB_VERSION = (1, 2, 0)
55
AGRO_API_VERSION = (1, 0, 0)
66
AIRPOLLUTION_API_VERSION = (1, 0, 0)
77
ALERT_API_VERSION = (1, 0, 0)

custom_components/opencwb/core/utils/opendata_cwb.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ def _get_weather(the_dict, index, wx_index, last_pop, mode):
5050
if element_value is None:
5151
continue
5252

53-
if "WeatherDescription" == i[elementname] or "\u5929\u6c23\u9810\u5831\u7d9c\u5408\u63cf\u8ff0" == i[elementname]:
53+
if i[elementname] in ["WeatherDescription", "\u5929\u6c23\u9810\u5831\u7d9c\u5408\u63cf\u8ff0"]:
5454
if value_str in element_value[0]:
5555
value["weather"][0]["description"] = element_value[0][value_str]
5656
value["weather"][0]["icon"] = ""
5757
else:
5858
value["weather"][0]["description"] = list(element_value[0].values())[0]
5959
value["weather"][0]["icon"] = ""
60-
elif "Wx" == i[elementname] or "\u5929\u6c23\u73fe\u8c61" == i[elementname]:
60+
elif i[elementname] in ["Wx", "\u5929\u6c23\u73fe\u8c61"]:
6161
if value_str in element_value[0]:
6262
value["weather"][0]["main"] = element_value[0][value_str]
6363
value["weather"][0]["id"] = int(element_value[1][value_str])
@@ -75,68 +75,68 @@ def _get_weather(the_dict, index, wx_index, last_pop, mode):
7575
pop = "0"
7676
value["pop"] = float(int(pop)/100)
7777
break
78-
elif "AT" == i[elementname] or "\u9ad4\u611f\u6eab\u5ea6" == i[elementname]:
78+
elif i[elementname]in ["AT", "\u9ad4\u611f\u6eab\u5ea6"]:
7979
if value_str in element_value[0]:
8080
value["main"]["feels_like"] = int(element_value[0][value_str])
8181
else:
8282
value["main"]["feels_like"] = int(list(element_value[0].values())[0])
83-
elif "MaxAT" == i[elementname] or "\u6700\u9ad8\u9ad4\u611f\u6eab\u5ea6" == i[elementname]:
83+
elif i[elementname] in ["MaxAT", "\u6700\u9ad8\u9ad4\u611f\u6eab\u5ea6"]:
8484
if value_str in element_value[0]:
8585
value["main"]["feels_like"] = int(element_value[0][value_str])
8686
value["feels_like"]["max"] = int(element_value[0][value_str])
8787
else:
88-
value["main"]["feels_like"] = int(list(element_value[0].vaules())[0])
88+
value["main"]["feels_like"] = int(list(element_value[0].values())[0])
8989
value["feels_like"]["max"] = int(list(element_value[0].values())[0])
90-
elif "MinAT" == i[elementname] or "\u6700\u4f4e\u9ad4\u611f\u6eab\u5ea6" == i[elementname]:
90+
elif i[elementname] in ["MinAT", "\u6700\u4f4e\u9ad4\u611f\u6eab\u5ea6"]:
9191
if value_str in element_value[0]:
9292
value["feels_like"]["min"] = int(element_value[0][value_str])
9393
else:
9494
value["feels_like"]["min"] = int(list(element_value[0].values())[0])
95-
elif "UVI" == i[elementname] or "\u7d2b\u5916\u7dda\u6307\u6578" == i[elementname]:
95+
elif i[elementname] in ["UVI", "\u7d2b\u5916\u7dda\u6307\u6578"]:
9696
value["uvi"] = 0
97-
for j in i["time"]:
97+
for j in i[time_str]:
9898
if start_time == j[starttime]:
9999
if value_str in element_value[0]:
100100
value["uvi"] = int(j[elementvalue][0][value_str])
101101
else:
102102
value["uvi"] = int(list(j[elementvalue][0].values())[0])
103103
break
104-
elif "T" == i[elementname] or "\u6eab\u5ea6" == i[elementname]:
104+
elif i[elementname] in ["T", "\u6eab\u5ea6", "\u5e73\u5747\u6eab\u5ea6"]:
105105
if value_str in element_value[0]:
106106
value["main"]["temp"] = int(element_value[0][value_str])
107107
else:
108108
value["main"]["temp"] = int(list(element_value[0].values())[0])
109-
elif "MaxT" == i[elementname] or "\u6700\u9ad8\u6eab\u5ea6" == i[elementname]:
109+
elif i[elementname] in ["MaxT", "\u6700\u9ad8\u6eab\u5ea6"]:
110110
if value_str in element_value[0]:
111111
value["main"]["temp_max"] = int(element_value[0][value_str])
112112
else:
113113
value["main"]["temp_max"] = int(list(element_value[0].values())[0])
114-
elif "MinT" == i[elementname] or "\u6700\u4f4e\u6eab\u5ea6" == i[elementname]:
114+
elif i[elementname] in ["MinT", "\u6700\u4f4e\u6eab\u5ea6"]:
115115
if value_str in element_value[0]:
116116
value["main"]["temp_min"] = int(element_value[0][value_str])
117117
else:
118118
value["main"]["temp_min"] = int(list(element_value[0].values())[0])
119-
elif "Td" == i[elementname] or "\u9732\u9ede\u6eab\u5ea6" == i[elementname]:
119+
elif i[elementname] in ["Td", "\u9732\u9ede\u6eab\u5ea6", "\u5e73\u5747\u9732\u9ede\u6eab\u5ea6"]:
120120
if value_str in element_value[0]:
121121
value["calc"]["dewpoint"] = int(element_value[0][value_str]) * 100
122122
else:
123123
value["calc"]["dewpoint"] = int(list(element_value[0].values())[0]) * 100
124-
elif "RH" == i[elementname] or "\u76f8\u5c0d\u6fd5\u5ea6" == i[elementname]:
124+
elif i[elementname] in ["RH", "\u76f8\u5c0d\u6fd5\u5ea6", "\u5e73\u5747\u76f8\u5c0d\u6fd5\u5ea6"]:
125125
if value_str in element_value[0]:
126126
value["humidity"] = int(element_value[0][value_str])
127127
else:
128128
value["humidity"] = int(list(element_value[0].values())[0])
129-
elif "MinCI" == i[elementname] or "\u8212\u9069\u5ea6\u6307\u6578" == i[elementname]:
129+
elif i[elementname] in ["MinCI", "\u8212\u9069\u5ea6\u6307\u6578"]:
130130
if value_str in element_value[0]:
131131
value["calc"]["humidex"] = int(element_value[0][value_str])
132132
else:
133133
value["calc"]["humidex"] = int(list(element_value[0].values())[0])
134-
elif "MaxCI" == i[elementname] or "\u8212\u9069\u5ea6\u6307\u6578" == i[elementname]:
134+
elif i[elementname] in ["MaxCI", "\u8212\u9069\u5ea6\u6307\u6578"]:
135135
if value_str in element_value[0]:
136136
value["calc"]["heatindex"] = int(element_value[0][value_str])
137137
else:
138138
value["calc"]["heatindex"] = int(list(element_value[0].values())[0])
139-
elif "WS" == i[elementname] or "\u98a8\u901f" == i[elementname]:
139+
elif i[elementname] in ["WS", "\u98a8\u901f"]:
140140
if value_str in element_value[0]:
141141
value["wind_speed"] = int(''.join(
142142
k for k in element_value[0][value_str] if k.isdigit()))
@@ -147,7 +147,7 @@ def _get_weather(the_dict, index, wx_index, last_pop, mode):
147147
k for k in list(element_value[0].values())[0] if k.isdigit()))
148148
value["wind_gust"] = int(''.join(
149149
c for c in list(element_value[0].values())[1] if c.isdigit()))
150-
elif "WD" == i[elementname] or "\u98a8\u5411" == i[elementname]:
150+
elif i[elementname] in ["WD", "\u98a8\u5411"]:
151151
if value_str in element_value[0]:
152152
value["wind_deg"] = element_value[0][value_str]
153153
else:

custom_components/opencwb/core/weatherapi12/weather_manager.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def weather_at_place(self, name, interval):
6464
6565
:param name: the location's toponym
6666
:type name: str
67-
:param interval: the granularity of the forecast, among `3h` and 'daily'
68-
:type interval: str among `3h` and 'daily'
67+
:param interval: the granularity of the forecast, among `hourly` and 'daily'
68+
:type interval: str among `hourly` and 'daily'
6969
:returns: an *Observation* instance or ``None`` if no weather data is
7070
available
7171
:raises: *ParseResponseException* when OCWB Weather API responses' data
@@ -78,7 +78,7 @@ def weather_at_place(self, name, interval):
7878
if loc_id is None:
7979
raise ValueError("%s is not support location".format(name))
8080
params = {'locationName': name}
81-
if interval == '3h':
81+
if interval == 'hourly':
8282
uri = loc_id
8383
elif interval == 'daily':
8484
uri = loc_id[0:loc_id.rindex("-") + 1] + str(
@@ -294,8 +294,8 @@ def forecast_at_place(self, name, interval, limit=None):
294294
295295
:param name: the location's toponym
296296
:type name: str
297-
:param interval: the granularity of the forecast, among `3h` and 'daily'
298-
:type interval: str among `3h` and 'daily'
297+
:param interval: the granularity of the forecast, among `hourly` and 'daily'
298+
:type interval: str among `hourly` and 'daily'
299299
:param limit: the maximum number of *Weather* items to be retrieved
300300
(default is ``None``, which stands for any number of items)
301301
:type limit: int or ``None``
@@ -317,7 +317,7 @@ def forecast_at_place(self, name, interval, limit=None):
317317
params = {'locationName': urllib.parse.quote_plus(name)}
318318
if limit is not None:
319319
params['cnt'] = limit
320-
if interval == '3h':
320+
if interval == 'hourly':
321321
uri = loc_id
322322
elif interval == 'daily':
323323
uri = loc_id[0:loc_id.rindex("-") + 1] + str(
@@ -343,8 +343,8 @@ def forecast_at_coords(self, lat, lon, interval, limit=None):
343343
:type lat: int/float
344344
:param lon: location's longitude, must be between -180.0 and 180.0
345345
:type lon: int/float
346-
:param interval: the granularity of the forecast, among `3h` and 'daily'
347-
:type interval: str among `3h` and 'daily'
346+
:param interval: the granularity of the forecast, among `hourly` and 'daily'
347+
:type interval: str among `hourly` and 'daily'
348348
:param limit: the maximum number of *Weather* items to be retrieved
349349
(default is ``None``, which stands for any number of items)
350350
:type limit: int or ``None``
@@ -364,7 +364,7 @@ def forecast_at_coords(self, lat, lon, interval, limit=None):
364364
params = {'lon': lon, 'lat': lat}
365365
if limit is not None:
366366
params['cnt'] = limit
367-
if interval == '3h':
367+
if interval == 'hourly':
368368
uri = THREE_HOURS_FORECAST_URI
369369
elif interval == 'daily':
370370
uri = DAILY_FORECAST_URI
@@ -387,8 +387,8 @@ def forecast_at_id(self, id, interval, limit=None):
387387
388388
:param id: the location's city ID
389389
:type id: int
390-
:param interval: the granularity of the forecast, among `3h` and 'daily'
391-
:type interval: str among `3h` and 'daily'
390+
:param interval: the granularity of the forecast, among `hourly` and 'daily'
391+
:type interval: str among `hourly` and 'daily'
392392
:param limit: the maximum number of *Weather* items to be retrieved
393393
(default is ``None``, which stands for any number of items)
394394
:type limit: int or ``None``
@@ -409,7 +409,7 @@ def forecast_at_id(self, id, interval, limit=None):
409409
params = {'id': id}
410410
if limit is not None:
411411
params['cnt'] = limit
412-
if interval == '3h':
412+
if interval == 'hourly':
413413
uri = THREE_HOURS_FORECAST_URI
414414
elif interval == 'daily':
415415
uri = DAILY_FORECAST_URI
@@ -536,7 +536,7 @@ def _retrieve_station_history(self, station_ID, limit, interval):
536536
return sh
537537

538538
def one_call(
539-
self, lat: Union[int, float], lon: Union[int, float], loc: Union[str, None], **kwargs
539+
self, lat: Union[int, float], lon: Union[int, float], loc: Union[str, None], intvl: Union[str, None], **kwargs
540540
) -> one_call.OneCall:
541541
"""
542542
Queries the OCWB Weather API with one call for current weather information and forecast for the
@@ -554,7 +554,7 @@ def one_call(
554554
:type lon: int/float
555555
:param lon: location's name
556556
:type lon: str or None
557-
:param intvl: internal
557+
:param intvl: interval
558558
:type intrl: str or None
559559
:returns: a *OneCall* instance or ``None`` if the data is not
560560
available for the specified location
@@ -567,15 +567,16 @@ def one_call(
567567

568568
loc_id = self.supported_city(loc)
569569
loc = self.remove_city_name(loc)
570-
uri = ONE_CALL_URI
571-
if loc_id != ONE_CALL_URI:
570+
uri = loc_id
571+
if intvl == "daily":
572572
uri = uri[0:uri.rindex("-") + 1] + str(
573573
int(uri[uri.rindex("-") + 1:]) + 2).zfill(3)
574574
params = {
575575
'lon': lon,
576576
'lat': lat,
577-
'locationId': loc_id,
578-
'locationName': loc}
577+
# 'locationId': loc_id,
578+
'locationName': loc,
579+
'interval': intvl}
579580
for key , value in kwargs.items():
580581
if key == 'exclude':
581582
params['exclude'] = value

custom_components/opencwb/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"domain": "opencwb",
33
"name": "OpenCWA",
44
"config_flow": true,
5-
"version": "1.1.0",
5+
"version": "1.2.0",
66
"documentation": "https://opendata.cwa.gov.tw/devManual/insrtuction",
77
"issue_tracker": "https://github.com/tsunglung/OpenCWB/issues",
88
"requirements": ["geojson"],

0 commit comments

Comments
 (0)