10
10
import logging
11
11
import sys
12
12
13
- from typing import Dict , List
13
+ from typing import Dict , List , Tuple , Optional
14
14
15
+ from libdyson import DEVICE_TYPE_NAMES , get_mqtt_info_from_wifi_info
15
16
from libdyson .cloud import DysonAccount , DysonDeviceInfo
16
17
from libdyson .cloud .account import DysonAccountCN
17
18
from libdyson .exceptions import DysonOTPTooFrequently , DysonLoginFailure
@@ -36,6 +37,25 @@ def _query_credentials() -> config.DysonLinkCredentials:
36
37
return config .DysonLinkCredentials (username , password , country )
37
38
38
39
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
+
39
59
def _query_dyson (creds : config .DysonLinkCredentials ) -> List [DysonDeviceInfo ]:
40
60
"""Queries Dyson's APIs for a device list.
41
61
@@ -77,7 +97,7 @@ def _query_dyson(creds: config.DysonLinkCredentials) -> List[DysonDeviceInfo]:
77
97
sys .exit (- 1 )
78
98
79
99
80
- def write_config (filename : str , creds : config .DysonLinkCredentials ,
100
+ def write_config (filename : str , creds : Optional [ config .DysonLinkCredentials ] ,
81
101
devices : List [DysonDeviceInfo ], hosts : Dict [str , str ]) -> None :
82
102
"""Writes the config out to filename.
83
103
@@ -89,11 +109,12 @@ def write_config(filename: str, creds: config.DysonLinkCredentials,
89
109
"""
90
110
cfg = configparser .ConfigParser ()
91
111
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
+ }
97
118
98
119
cfg ['Hosts' ] = hosts
99
120
@@ -117,7 +138,7 @@ def write_config(filename: str, creds: config.DysonLinkCredentials,
117
138
if len (ack ) > 0 and ack .upper ()[0 ] == 'Y' :
118
139
with open (filename , 'w' ) as f :
119
140
cfg .write (f )
120
- print (f'Config written to { config } .' )
141
+ print (f'Config written to { filename } .' )
121
142
else :
122
143
print ('Received negative answer; nothing written.' )
123
144
@@ -131,7 +152,14 @@ def main(argv):
131
152
type = str ,
132
153
default = 'ERROR' )
133
154
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
+ )
135
163
args = parser .parse_args ()
136
164
137
165
try :
@@ -148,6 +176,10 @@ def main(argv):
148
176
149
177
print ('Welcome to the prometheus-dyson config builder.' )
150
178
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
+
151
183
cfg = None
152
184
creds = None
153
185
hosts = {}
@@ -159,19 +191,36 @@ def main(argv):
159
191
logging .info (
160
192
'Could not load configuration: %s (assuming no configuration)' , args .config )
161
193
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 )
165
209
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
+ )]
175
224
176
225
print ()
177
226
write_config (args .config , creds , devices , hosts )
0 commit comments