Skip to content

Commit 2998c48

Browse files
committed
Add --mode=wifi to config_builder
This will allow the creation of configuration based on a device's WiFi credentials, presented on the device's label. No Dyson Link/Cloud support required.
1 parent 4c635e5 commit 2998c48

File tree

1 file changed

+70
-21
lines changed

1 file changed

+70
-21
lines changed

config_builder.py

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
import logging
1111
import sys
1212

13-
from typing import Dict, List
13+
from typing import Dict, List, Tuple, Optional
1414

15+
from libdyson import DEVICE_TYPE_NAMES, get_mqtt_info_from_wifi_info
1516
from libdyson.cloud import DysonAccount, DysonDeviceInfo
1617
from libdyson.cloud.account import DysonAccountCN
1718
from libdyson.exceptions import DysonOTPTooFrequently, DysonLoginFailure
@@ -36,6 +37,25 @@ def _query_credentials() -> config.DysonLinkCredentials:
3637
return config.DysonLinkCredentials(username, password, country)
3738

3839

40+
def _query_wifi() -> Tuple[str, str, str]:
41+
"""Asks the user for their DysonLink/Cloud credentials.
42+
43+
Returns:
44+
DysonLinkCredentials based on what the user supplied
45+
"""
46+
print('This requires the WiFi credentials from the label on the Dyson')
47+
print('device. This will be used to calculate the secret required')
48+
print('to connect to this device locally. This script does NOT need')
49+
print('to modify WiFi settings in any way.')
50+
print('')
51+
print('The product SSID might look like: DYSON-AB0-XX-ABC1234D-123')
52+
print('')
53+
ssid = input('Enter product SSID : ')
54+
password = input('Enter product WiFi password : ')
55+
name = input('Device name (e.g; Living Room): ')
56+
return (ssid, password, name)
57+
58+
3959
def _query_dyson(creds: config.DysonLinkCredentials) -> List[DysonDeviceInfo]:
4060
"""Queries Dyson's APIs for a device list.
4161
@@ -77,7 +97,7 @@ def _query_dyson(creds: config.DysonLinkCredentials) -> List[DysonDeviceInfo]:
7797
sys.exit(-1)
7898

7999

80-
def write_config(filename: str, creds: config.DysonLinkCredentials,
100+
def write_config(filename: str, creds: Optional[config.DysonLinkCredentials],
81101
devices: List[DysonDeviceInfo], hosts: Dict[str, str]) -> None:
82102
"""Writes the config out to filename.
83103
@@ -89,11 +109,12 @@ def write_config(filename: str, creds: config.DysonLinkCredentials,
89109
"""
90110
cfg = configparser.ConfigParser()
91111

92-
cfg['Dyson Link'] = {
93-
'Username': creds.username,
94-
'Password': creds.password,
95-
'Country': creds.country
96-
}
112+
if creds:
113+
cfg['Dyson Link'] = {
114+
'Username': creds.username,
115+
'Password': creds.password,
116+
'Country': creds.country
117+
}
97118

98119
cfg['Hosts'] = hosts
99120

@@ -117,7 +138,7 @@ def write_config(filename: str, creds: config.DysonLinkCredentials,
117138
if len(ack) > 0 and ack.upper()[0] == 'Y':
118139
with open(filename, 'w') as f:
119140
cfg.write(f)
120-
print(f'Config written to {config}.')
141+
print(f'Config written to {filename}.')
121142
else:
122143
print('Received negative answer; nothing written.')
123144

@@ -131,7 +152,14 @@ def main(argv):
131152
type=str,
132153
default='ERROR')
133154
parser.add_argument(
134-
'--config', help='Configuration file (INI file)', default='/etc/prometheus-dyson/config.ini')
155+
'--config',
156+
help='Configuration file (INI file)',
157+
default='/etc/prometheus-dyson/config.ini')
158+
parser.add_argument(
159+
'--mode',
160+
help='Use "wifi" to add devices from WiFi credentials, "cloud" to try via Dyson Link"',
161+
default='cloud'
162+
)
135163
args = parser.parse_args()
136164

137165
try:
@@ -148,6 +176,10 @@ def main(argv):
148176

149177
print('Welcome to the prometheus-dyson config builder.')
150178

179+
if args.mode not in ('cloud', 'wifi'):
180+
print(f'Invalid --mode: {args.mode}, must be one of "cloud" or "wifi"')
181+
sys.exit(-2)
182+
151183
cfg = None
152184
creds = None
153185
hosts = {}
@@ -159,19 +191,36 @@ def main(argv):
159191
logging.info(
160192
'Could not load configuration: %s (assuming no configuration)', args.config)
161193

162-
if not creds:
163-
print('')
164-
creds = _query_credentials()
194+
if args.mode == 'cloud':
195+
if not creds:
196+
print('')
197+
creds = _query_credentials()
198+
else:
199+
print(f'Using Dyson credentials from {args.config}')
200+
201+
try:
202+
print()
203+
devices = _query_dyson(creds)
204+
print(f'Found {len(devices)} devices.')
205+
except DysonOTPTooFrequently:
206+
print(
207+
'DysonOTPTooFrequently: too many OTP attempts, please wait and try again')
208+
sys.exit(-1)
165209
else:
166-
print(f'Using Dyson credentials from {args.config}')
167-
168-
try:
169-
print()
170-
devices = _query_dyson(creds)
171-
print(f'Found {len(devices)} devices.')
172-
except DysonOTPTooFrequently:
173-
print('DysonOTPTooFrequently: too many OTP attempts, please wait and try again')
174-
sys.exit(-1)
210+
ssid, password, name = _query_wifi()
211+
serial, credential, product_type = get_mqtt_info_from_wifi_info(
212+
ssid, password)
213+
214+
devices = [DysonDeviceInfo(
215+
name=name,
216+
active=True,
217+
version='unknown',
218+
new_version_available=False,
219+
auto_update=False,
220+
serial=serial,
221+
credential=credential,
222+
product_type=product_type
223+
)]
175224

176225
print()
177226
write_config(args.config, creds, devices, hosts)

0 commit comments

Comments
 (0)