Merge lp:~alisonken1/openlp/pjlink2-n into lp:openlp
- pjlink2-n
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~alisonken1/openlp/pjlink2-n |
Merge into: | lp:openlp |
Diff against target: |
3646 lines (+1547/-1299) 7 files modified
openlp/core/projectors/constants.py (+300/-224) openlp/core/projectors/manager.py (+37/-33) openlp/core/projectors/pjlink.py (+114/-97) tests/functional/openlp_core/projectors/test_projector_constants.py (+39/-0) tests/functional/openlp_core/projectors/test_projector_pjlink_base.py (+3/-4) tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py (+183/-170) tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py (+871/-771) |
To merge this branch: | bzr merge lp:~alisonken1/openlp/pjlink2-n |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenLP Core | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2017-12-25.
Commit message
PJLink 2 update N
Description of the change
Jenkins cli at home dies at '02b-macOS-tests' [waiting], then timesout.
Passes local tests (pytest, nose2, pep8) with exception of
test_bible_
Large diff fixing test_projector_
- Update some comments
- Some PJLink code fixes/restructuring
- Restructure some projector tests for proper mocking
- Fix manager.py and pjlink.py for changes to constants.py
- Fix test_projector_
- Renamed test_process_
- Added test to verify assigned E_*/S_* codes are in STATUS_CODE and STATUS_MSG
- Added missing status/error codes to STATUS_MSG
- Added error checks to process_inpt
- Deleted unneeded test(s)
Updates to constants.py include:
- Reordered dictionaries and lists into alphabetical order
- Added PJLINK_ERST_LIST
- Added S_NETWORK_IDLE code (for future)
- Added PJLINK_STATUS list
- Move S_QSOCKET_STATUS to QSOCKET_STATE
- Move STATUS_STRING to STATUS_CODE
- Move PJLINK_CLASS, PJLINK_SUFFIX, and PJLINK_PREFIX from pjlink.py to constants.py
- Change CONNECTION_ERRORS from a dictionary to a list
- Change QSOCKET_STATE to map QAbstractSocket
- Merge ERROR_MSG with STATUS_MSG
- Merge ERROR_STRING into STATUS_CODE
- Clean out unused portion of PJLINK_ERST_STATUS
- Clean out unused portion of PJLINK_POWR_STATUS
- Clean out unused portion of QSOCKET_STATUS
- 2805. By Ken Roberts
-
Cleanups and assert updates
- 2806. By Ken Roberts
-
Merge trunk
Unmerged revisions
Preview Diff
1 | === modified file 'openlp/core/projectors/constants.py' |
2 | --- openlp/core/projectors/constants.py 2017-12-09 11:17:05 +0000 |
3 | +++ openlp/core/projectors/constants.py 2017-12-25 08:57:51 +0000 |
4 | @@ -32,9 +32,128 @@ |
5 | # Set common constants. |
6 | CR = chr(0x0D) # \r |
7 | LF = chr(0x0A) # \n |
8 | +PJLINK_CLASS = '1' # Default to class 1 until we query the projector |
9 | +PJLINK_MAX_PACKET = 136 |
10 | +PJLINK_PREFIX = '%' |
11 | PJLINK_PORT = 4352 |
12 | -TIMEOUT = 30.0 |
13 | -PJLINK_MAX_PACKET = 136 |
14 | +PJLINK_SUFFIX = CR |
15 | +PJLINK_TIMEOUT = 30.0 |
16 | + |
17 | +# Error and status codes |
18 | +S_OK = E_OK = 0 # E_OK included since I sometimes forget |
19 | + |
20 | +# Error codes. Start at 200 so we don't duplicate system error codes. |
21 | +E_GENERAL = 200 # Unknown error |
22 | +E_NOT_CONNECTED = 201 |
23 | +E_UNDEFINED = 202 # PJLink ERR1 |
24 | +E_PARAMETER = 203 # PJLink ERR2 |
25 | +E_UNAVAILABLE = 204 # PJLink ERR3 |
26 | +E_PROJECTOR = 205 # PJLink ERR4 |
27 | +E_AUTHENTICATION = 206 # PJLink ERRA |
28 | +E_NO_AUTHENTICATION = 207 # PJLink authentication mismatch between projector and program |
29 | +E_PREFIX = 208 # PJLink invalid prefix for packet |
30 | +E_CLASS = 209 # PJLink class version mismatch |
31 | +E_INVALID_DATA = 210 |
32 | +E_WARN = 211 |
33 | +E_ERROR = 212 |
34 | +E_FAN = 213 |
35 | +E_LAMP = 214 |
36 | +E_TEMP = 215 |
37 | +E_COVER = 216 |
38 | +E_FILTER = 217 |
39 | +E_UNKNOWN = 218 |
40 | + |
41 | +# Remap Qt socket error codes to local error codes |
42 | +E_CONNECTION_REFUSED = 230 |
43 | +E_REMOTE_HOST_CLOSED_CONNECTION = 231 |
44 | +E_HOST_NOT_FOUND = 232 |
45 | +E_SOCKET_ACCESS = 233 |
46 | +E_SOCKET_RESOURCE = 234 |
47 | +E_SOCKET_TIMEOUT = 235 |
48 | +E_DATAGRAM_TOO_LARGE = 236 |
49 | +E_NETWORK = 237 |
50 | +E_ADDRESS_IN_USE = 238 |
51 | +E_SOCKET_ADDRESS_NOT_AVAILABLE = 239 |
52 | +E_UNSUPPORTED_SOCKET_OPERATION = 240 |
53 | +E_PROXY_AUTHENTICATION_REQUIRED = 241 |
54 | +E_SLS_HANDSHAKE_FAILED = 242 |
55 | +E_UNFINISHED_SOCKET_OPERATION = 243 |
56 | +E_PROXY_CONNECTION_REFUSED = 244 |
57 | +E_PROXY_CONNECTION_CLOSED = 245 |
58 | +E_PROXY_CONNECTION_TIMEOUT = 246 |
59 | +E_PROXY_NOT_FOUND = 247 |
60 | +E_PROXY_PROTOCOL = 248 |
61 | +E_UNKNOWN_SOCKET_ERROR = 249 |
62 | + |
63 | +# Status codes start at 300 |
64 | + |
65 | +# Remap Qt socket states to local status codes |
66 | +S_NOT_CONNECTED = 300 |
67 | +S_HOST_LOOKUP = 301 |
68 | +S_CONNECTING = 302 |
69 | +S_CONNECTED = 303 |
70 | +S_BOUND = 304 |
71 | +S_LISTENING = 305 # Listed as internal use only in QAbstractSocket |
72 | +S_CLOSING = 306 |
73 | + |
74 | +# Projector states |
75 | +S_INITIALIZE = 310 |
76 | +S_STATUS = 311 |
77 | +S_OFF = 312 |
78 | +S_STANDBY = 313 |
79 | +S_WARMUP = 314 |
80 | +S_ON = 315 |
81 | +S_COOLDOWN = 316 |
82 | +S_INFO = 317 |
83 | + |
84 | +# Information that does not affect status |
85 | +S_NETWORK_IDLE = 400 |
86 | +S_NETWORK_SENDING = 401 |
87 | +S_NETWORK_RECEIVING = 402 |
88 | + |
89 | +# Map PJlink errors to local status |
90 | +PJLINK_ERRORS = { |
91 | + 'ERRA': E_AUTHENTICATION, # Authentication error |
92 | + 'ERR1': E_UNDEFINED, # Undefined command error |
93 | + 'ERR2': E_PARAMETER, # Invalid parameter error |
94 | + 'ERR3': E_UNAVAILABLE, # Projector busy |
95 | + 'ERR4': E_PROJECTOR, # Projector or display failure |
96 | + E_AUTHENTICATION: 'ERRA', |
97 | + E_UNDEFINED: 'ERR1', |
98 | + E_PARAMETER: 'ERR2', |
99 | + E_UNAVAILABLE: 'ERR3', |
100 | + E_PROJECTOR: 'ERR4' |
101 | +} |
102 | + |
103 | +# Map QAbstractSocketState enums to local status |
104 | +QSOCKET_STATE = { |
105 | + 0: S_NOT_CONNECTED, # 'UnconnectedState', |
106 | + 1: S_HOST_LOOKUP, # 'HostLookupState', |
107 | + 2: S_CONNECTING, # 'ConnectingState', |
108 | + 3: S_CONNECTED, # 'ConnectedState', |
109 | + 4: S_BOUND, # 'BoundState', |
110 | + 5: S_LISTENING, # 'ListeningState' - Noted as "Internal Use Only" on Qt website |
111 | + 6: S_CLOSING, # 'ClosingState', |
112 | + S_NOT_CONNECTED: 0, |
113 | + S_HOST_LOOKUP: 1, |
114 | + S_CONNECTING: 2, |
115 | + S_CONNECTED: 3, |
116 | + S_BOUND: 4, |
117 | + S_LISTENING: 5, |
118 | + S_CLOSING: 6 |
119 | +} |
120 | + |
121 | +PROJECTOR_STATE = [ |
122 | + S_INITIALIZE, |
123 | + S_STATUS, |
124 | + S_OFF, |
125 | + S_STANDBY, |
126 | + S_WARMUP, |
127 | + S_ON, |
128 | + S_COOLDOWN, |
129 | + S_INFO |
130 | +] |
131 | + |
132 | # NOTE: Changed format to account for some commands are both class 1 and 2 |
133 | PJLINK_VALID_CMD = { |
134 | 'ACKN': {'version': ['2', ], |
135 | @@ -144,227 +263,140 @@ |
136 | } |
137 | } |
138 | |
139 | -# QAbstractSocketState enums converted to string |
140 | -S_QSOCKET_STATE = { |
141 | - 0: 'QSocketState - UnconnectedState', |
142 | - 1: 'QSocketState - HostLookupState', |
143 | - 2: 'QSocketState - ConnectingState', |
144 | - 3: 'QSocketState - ConnectedState', |
145 | - 4: 'QSocketState - BoundState', |
146 | - 5: 'QSocketState - ListeningState (internal use only)', |
147 | - 6: 'QSocketState - ClosingState', |
148 | - 'UnconnectedState': 0, |
149 | - 'HostLookupState': 1, |
150 | - 'ConnectingState': 2, |
151 | - 'ConnectedState': 3, |
152 | - 'BoundState': 4, |
153 | - 'ListeningState': 5, |
154 | - 'ClosingState': 6 |
155 | -} |
156 | - |
157 | -# Error and status codes |
158 | -S_OK = E_OK = 0 # E_OK included since I sometimes forget |
159 | -# Error codes. Start at 200 so we don't duplicate system error codes. |
160 | -E_GENERAL = 200 # Unknown error |
161 | -E_NOT_CONNECTED = 201 |
162 | -E_FAN = 202 |
163 | -E_LAMP = 203 |
164 | -E_TEMP = 204 |
165 | -E_COVER = 205 |
166 | -E_FILTER = 206 |
167 | -E_NO_AUTHENTICATION = 207 # PIN set and no authentication set on projector |
168 | -E_UNDEFINED = 208 # ERR1 |
169 | -E_PARAMETER = 209 # ERR2 |
170 | -E_UNAVAILABLE = 210 # ERR3 |
171 | -E_PROJECTOR = 211 # ERR4 |
172 | -E_INVALID_DATA = 212 |
173 | -E_WARN = 213 |
174 | -E_ERROR = 214 |
175 | -E_AUTHENTICATION = 215 # ERRA |
176 | -E_CLASS = 216 |
177 | -E_PREFIX = 217 |
178 | - |
179 | -# Remap Qt socket error codes to projector error codes |
180 | -E_CONNECTION_REFUSED = 230 |
181 | -E_REMOTE_HOST_CLOSED_CONNECTION = 231 |
182 | -E_HOST_NOT_FOUND = 232 |
183 | -E_SOCKET_ACCESS = 233 |
184 | -E_SOCKET_RESOURCE = 234 |
185 | -E_SOCKET_TIMEOUT = 235 |
186 | -E_DATAGRAM_TOO_LARGE = 236 |
187 | -E_NETWORK = 237 |
188 | -E_ADDRESS_IN_USE = 238 |
189 | -E_SOCKET_ADDRESS_NOT_AVAILABLE = 239 |
190 | -E_UNSUPPORTED_SOCKET_OPERATION = 240 |
191 | -E_PROXY_AUTHENTICATION_REQUIRED = 241 |
192 | -E_SLS_HANDSHAKE_FAILED = 242 |
193 | -E_UNFINISHED_SOCKET_OPERATION = 243 |
194 | -E_PROXY_CONNECTION_REFUSED = 244 |
195 | -E_PROXY_CONNECTION_CLOSED = 245 |
196 | -E_PROXY_CONNECTION_TIMEOUT = 246 |
197 | -E_PROXY_NOT_FOUND = 247 |
198 | -E_PROXY_PROTOCOL = 248 |
199 | -E_UNKNOWN_SOCKET_ERROR = -1 |
200 | - |
201 | -# Status codes start at 300 |
202 | -S_NOT_CONNECTED = 300 |
203 | -S_CONNECTING = 301 |
204 | -S_CONNECTED = 302 |
205 | -S_INITIALIZE = 303 |
206 | -S_STATUS = 304 |
207 | -S_OFF = 305 |
208 | -S_STANDBY = 306 |
209 | -S_WARMUP = 307 |
210 | -S_ON = 308 |
211 | -S_COOLDOWN = 309 |
212 | -S_INFO = 310 |
213 | - |
214 | -# Information that does not affect status |
215 | -S_NETWORK_SENDING = 400 |
216 | -S_NETWORK_RECEIVED = 401 |
217 | - |
218 | -CONNECTION_ERRORS = { |
219 | - E_NOT_CONNECTED, E_NO_AUTHENTICATION, E_AUTHENTICATION, E_CLASS, |
220 | - E_PREFIX, E_CONNECTION_REFUSED, E_REMOTE_HOST_CLOSED_CONNECTION, |
221 | - E_HOST_NOT_FOUND, E_SOCKET_ACCESS, E_SOCKET_RESOURCE, E_SOCKET_TIMEOUT, |
222 | - E_DATAGRAM_TOO_LARGE, E_NETWORK, E_ADDRESS_IN_USE, E_SOCKET_ADDRESS_NOT_AVAILABLE, |
223 | - E_UNSUPPORTED_SOCKET_OPERATION, E_PROXY_AUTHENTICATION_REQUIRED, |
224 | - E_SLS_HANDSHAKE_FAILED, E_UNFINISHED_SOCKET_OPERATION, E_PROXY_CONNECTION_REFUSED, |
225 | - E_PROXY_CONNECTION_CLOSED, E_PROXY_CONNECTION_TIMEOUT, E_PROXY_NOT_FOUND, |
226 | - E_PROXY_PROTOCOL, E_UNKNOWN_SOCKET_ERROR |
227 | -} |
228 | - |
229 | -PJLINK_ERRORS = { |
230 | - 'ERRA': E_AUTHENTICATION, # Authentication error |
231 | - 'ERR1': E_UNDEFINED, # Undefined command error |
232 | - 'ERR2': E_PARAMETER, # Invalid parameter error |
233 | - 'ERR3': E_UNAVAILABLE, # Projector busy |
234 | - 'ERR4': E_PROJECTOR, # Projector or display failure |
235 | - E_AUTHENTICATION: 'ERRA', |
236 | - E_UNDEFINED: 'ERR1', |
237 | - E_PARAMETER: 'ERR2', |
238 | - E_UNAVAILABLE: 'ERR3', |
239 | - E_PROJECTOR: 'ERR4' |
240 | -} |
241 | - |
242 | -# Map error/status codes to string |
243 | -ERROR_STRING = { |
244 | - 0: 'S_OK', |
245 | +CONNECTION_ERRORS = [ |
246 | + E_ADDRESS_IN_USE, |
247 | + E_CONNECTION_REFUSED, |
248 | + E_DATAGRAM_TOO_LARGE, |
249 | + E_HOST_NOT_FOUND, |
250 | + E_NETWORK, |
251 | + E_NOT_CONNECTED, |
252 | + E_PROXY_AUTHENTICATION_REQUIRED, |
253 | + E_PROXY_CONNECTION_CLOSED, |
254 | + E_PROXY_CONNECTION_REFUSED, |
255 | + E_PROXY_CONNECTION_TIMEOUT, |
256 | + E_PROXY_NOT_FOUND, |
257 | + E_PROXY_PROTOCOL, |
258 | + E_REMOTE_HOST_CLOSED_CONNECTION, |
259 | + E_SLS_HANDSHAKE_FAILED, |
260 | + E_SOCKET_ACCESS, |
261 | + E_SOCKET_ADDRESS_NOT_AVAILABLE, |
262 | + E_SOCKET_RESOURCE, |
263 | + E_SOCKET_TIMEOUT, |
264 | + E_UNFINISHED_SOCKET_OPERATION, |
265 | + E_UNKNOWN_SOCKET_ERROR, |
266 | + E_UNSUPPORTED_SOCKET_OPERATION |
267 | +] |
268 | + |
269 | +PROJECTOR_ERRORS = [ |
270 | + E_AUTHENTICATION, |
271 | + E_CLASS, |
272 | + E_INVALID_DATA, |
273 | + E_NO_AUTHENTICATION, |
274 | + E_PARAMETER, |
275 | + E_PREFIX, |
276 | + E_PROJECTOR, |
277 | + E_UNAVAILABLE, |
278 | + E_UNDEFINED, |
279 | + E_UNKNOWN |
280 | +] |
281 | + |
282 | +# Show status code as string |
283 | +STATUS_CODE = { |
284 | + E_ADDRESS_IN_USE: 'E_ADDRESS_IN_USE', |
285 | + E_AUTHENTICATION: 'E_AUTHENTICATION', |
286 | + E_CLASS: 'E_CLASS', |
287 | + E_CONNECTION_REFUSED: 'E_CONNECTION_REFUSED', |
288 | + E_COVER: 'E_COVER', |
289 | + E_DATAGRAM_TOO_LARGE: 'E_DATAGRAM_TOO_LARGE', |
290 | + E_ERROR: 'E_ERROR', |
291 | + E_FAN: 'E_FAN', |
292 | + E_FILTER: 'E_FILTER', |
293 | E_GENERAL: 'E_GENERAL', |
294 | - E_NOT_CONNECTED: 'E_NOT_CONNECTED', |
295 | - E_FAN: 'E_FAN', |
296 | + E_HOST_NOT_FOUND: 'E_HOST_NOT_FOUND', |
297 | + E_INVALID_DATA: 'E_INVALID_DATA', |
298 | E_LAMP: 'E_LAMP', |
299 | - E_TEMP: 'E_TEMP', |
300 | - E_COVER: 'E_COVER', |
301 | - E_FILTER: 'E_FILTER', |
302 | - E_AUTHENTICATION: 'E_AUTHENTICATION', |
303 | + E_NETWORK: 'E_NETWORK', |
304 | E_NO_AUTHENTICATION: 'E_NO_AUTHENTICATION', |
305 | - E_UNDEFINED: 'E_UNDEFINED', |
306 | + E_NOT_CONNECTED: 'E_NOT_CONNECTED', |
307 | E_PARAMETER: 'E_PARAMETER', |
308 | - E_UNAVAILABLE: 'E_UNAVAILABLE', |
309 | + E_PREFIX: 'E_PREFIX', |
310 | E_PROJECTOR: 'E_PROJECTOR', |
311 | - E_INVALID_DATA: 'E_INVALID_DATA', |
312 | - E_WARN: 'E_WARN', |
313 | - E_ERROR: 'E_ERROR', |
314 | - E_CLASS: 'E_CLASS', |
315 | - E_PREFIX: 'E_PREFIX', # Last projector error |
316 | - E_CONNECTION_REFUSED: 'E_CONNECTION_REFUSED', # First QtSocket error |
317 | + E_PROXY_AUTHENTICATION_REQUIRED: 'E_PROXY_AUTHENTICATION_REQUIRED', |
318 | + E_PROXY_CONNECTION_CLOSED: 'E_PROXY_CONNECTION_CLOSED', |
319 | + E_PROXY_CONNECTION_REFUSED: 'E_PROXY_CONNECTION_REFUSED', |
320 | + E_PROXY_CONNECTION_TIMEOUT: 'E_PROXY_CONNECTION_TIMEOUT', |
321 | + E_PROXY_NOT_FOUND: 'E_PROXY_NOT_FOUND', |
322 | + E_PROXY_PROTOCOL: 'E_PROXY_PROTOCOL', |
323 | E_REMOTE_HOST_CLOSED_CONNECTION: 'E_REMOTE_HOST_CLOSED_CONNECTION', |
324 | - E_HOST_NOT_FOUND: 'E_HOST_NOT_FOUND', |
325 | + E_SLS_HANDSHAKE_FAILED: 'E_SLS_HANDSHAKE_FAILED', |
326 | E_SOCKET_ACCESS: 'E_SOCKET_ACCESS', |
327 | + E_SOCKET_ADDRESS_NOT_AVAILABLE: 'E_SOCKET_ADDRESS_NOT_AVAILABLE', |
328 | E_SOCKET_RESOURCE: 'E_SOCKET_RESOURCE', |
329 | E_SOCKET_TIMEOUT: 'E_SOCKET_TIMEOUT', |
330 | - E_DATAGRAM_TOO_LARGE: 'E_DATAGRAM_TOO_LARGE', |
331 | - E_NETWORK: 'E_NETWORK', |
332 | - E_ADDRESS_IN_USE: 'E_ADDRESS_IN_USE', |
333 | - E_SOCKET_ADDRESS_NOT_AVAILABLE: 'E_SOCKET_ADDRESS_NOT_AVAILABLE', |
334 | + E_TEMP: 'E_TEMP', |
335 | + E_UNAVAILABLE: 'E_UNAVAILABLE', |
336 | + E_UNDEFINED: 'E_UNDEFINED', |
337 | + E_UNFINISHED_SOCKET_OPERATION: 'E_UNFINISHED_SOCKET_OPERATION', |
338 | + E_UNKNOWN: 'E_UNKNOWN', |
339 | + E_UNKNOWN_SOCKET_ERROR: 'E_UNKNOWN_SOCKET_ERROR', |
340 | E_UNSUPPORTED_SOCKET_OPERATION: 'E_UNSUPPORTED_SOCKET_OPERATION', |
341 | - E_PROXY_AUTHENTICATION_REQUIRED: 'E_PROXY_AUTHENTICATION_REQUIRED', |
342 | - E_SLS_HANDSHAKE_FAILED: 'E_SLS_HANDSHAKE_FAILED', |
343 | - E_UNFINISHED_SOCKET_OPERATION: 'E_UNFINISHED_SOCKET_OPERATION', |
344 | - E_PROXY_CONNECTION_REFUSED: 'E_PROXY_CONNECTION_REFUSED', |
345 | - E_PROXY_CONNECTION_CLOSED: 'E_PROXY_CONNECTION_CLOSED', |
346 | - E_PROXY_CONNECTION_TIMEOUT: 'E_PROXY_CONNECTION_TIMEOUT', |
347 | - E_PROXY_NOT_FOUND: 'E_PROXY_NOT_FOUND', |
348 | - E_PROXY_PROTOCOL: 'E_PROXY_PROTOCOL', |
349 | - E_UNKNOWN_SOCKET_ERROR: 'E_UNKNOWN_SOCKET_ERROR' |
350 | -} |
351 | - |
352 | -STATUS_STRING = { |
353 | + E_WARN: 'E_WARN', |
354 | + S_BOUND: 'S_BOUND', |
355 | + S_COOLDOWN: 'S_COOLDOWN', |
356 | + S_CLOSING: 'S_CLOSING', |
357 | + S_CONNECTED: 'S_CONNECTED', |
358 | + S_CONNECTING: 'S_CONNECTING', |
359 | + S_HOST_LOOKUP: 'S_HOST_LOOKUP', |
360 | + S_INFO: 'S_INFO', |
361 | + S_INITIALIZE: 'S_INITIALIZE', |
362 | + S_LISTENING: 'S_LISTENING', |
363 | + S_NETWORK_RECEIVING: 'S_NETWORK_RECEIVING', |
364 | + S_NETWORK_SENDING: 'S_NETWORK_SENDING', |
365 | + S_NETWORK_IDLE: 'S_NETWORK_IDLE', |
366 | S_NOT_CONNECTED: 'S_NOT_CONNECTED', |
367 | - S_CONNECTING: 'S_CONNECTING', |
368 | - S_CONNECTED: 'S_CONNECTED', |
369 | - S_STATUS: 'S_STATUS', |
370 | S_OFF: 'S_OFF', |
371 | - S_INITIALIZE: 'S_INITIALIZE', |
372 | + S_OK: 'S_OK', # S_OK or E_OK |
373 | + S_ON: 'S_ON', |
374 | S_STANDBY: 'S_STANDBY', |
375 | + S_STATUS: 'S_STATUS', |
376 | S_WARMUP: 'S_WARMUP', |
377 | - S_ON: 'S_ON', |
378 | - S_COOLDOWN: 'S_COOLDOWN', |
379 | - S_INFO: 'S_INFO', |
380 | - S_NETWORK_SENDING: 'S_NETWORK_SENDING', |
381 | - S_NETWORK_RECEIVED: 'S_NETWORK_RECEIVED' |
382 | } |
383 | |
384 | -# Map error/status codes to message strings |
385 | -ERROR_MSG = { |
386 | - E_OK: translate('OpenLP.ProjectorConstants', 'OK'), # E_OK | S_OK |
387 | - E_GENERAL: translate('OpenLP.ProjectorConstants', 'General projector error'), |
388 | - E_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Not connected error'), |
389 | - E_LAMP: translate('OpenLP.ProjectorConstants', 'Lamp error'), |
390 | - E_FAN: translate('OpenLP.ProjectorConstants', 'Fan error'), |
391 | - E_TEMP: translate('OpenLP.ProjectorConstants', 'High temperature detected'), |
392 | - E_COVER: translate('OpenLP.ProjectorConstants', 'Cover open detected'), |
393 | - E_FILTER: translate('OpenLP.ProjectorConstants', 'Check filter'), |
394 | - E_AUTHENTICATION: translate('OpenLP.ProjectorConstants', 'Authentication Error'), |
395 | - E_UNDEFINED: translate('OpenLP.ProjectorConstants', 'Undefined Command'), |
396 | - E_PARAMETER: translate('OpenLP.ProjectorConstants', 'Invalid Parameter'), |
397 | - E_UNAVAILABLE: translate('OpenLP.ProjectorConstants', 'Projector Busy'), |
398 | - E_PROJECTOR: translate('OpenLP.ProjectorConstants', 'Projector/Display Error'), |
399 | - E_INVALID_DATA: translate('OpenLP.ProjectorConstants', 'Invalid packet received'), |
400 | - E_WARN: translate('OpenLP.ProjectorConstants', 'Warning condition detected'), |
401 | - E_ERROR: translate('OpenLP.ProjectorConstants', 'Error condition detected'), |
402 | - E_CLASS: translate('OpenLP.ProjectorConstants', 'PJLink class not supported'), |
403 | - E_PREFIX: translate('OpenLP.ProjectorConstants', 'Invalid prefix character'), |
404 | +# Map status codes to message strings |
405 | +STATUS_MSG = { |
406 | + E_ADDRESS_IN_USE: translate('OpenLP.ProjectorConstants', |
407 | + 'The address specified with socket.bind() ' |
408 | + 'is already in use and was set to be exclusive'), |
409 | + E_AUTHENTICATION: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERRA: Authentication Error"'), |
410 | E_CONNECTION_REFUSED: translate('OpenLP.ProjectorConstants', |
411 | 'The connection was refused by the peer (or timed out)'), |
412 | - E_REMOTE_HOST_CLOSED_CONNECTION: translate('OpenLP.ProjectorConstants', |
413 | - 'The remote host closed the connection'), |
414 | + E_COVER: translate('OpenLP.ProjectorConstants', 'Projector cover open detected'), |
415 | + E_CLASS: translate('OpenLP.ProjectorConstants', 'PJLink class not supported'), |
416 | + E_DATAGRAM_TOO_LARGE: translate('OpenLP.ProjectorConstants', |
417 | + "The datagram was larger than the operating system's limit"), |
418 | + E_ERROR: translate('OpenLP.ProjectorConstants', 'Error condition detected'), |
419 | + E_FAN: translate('OpenLP.ProjectorConstants', 'Projector fan error'), |
420 | + E_FILTER: translate('OpenLP.ProjectorConstants', 'Projector check filter'), |
421 | + E_GENERAL: translate('OpenLP.ProjectorConstants', 'General projector error'), |
422 | E_HOST_NOT_FOUND: translate('OpenLP.ProjectorConstants', 'The host address was not found'), |
423 | - E_SOCKET_ACCESS: translate('OpenLP.ProjectorConstants', |
424 | - 'The socket operation failed because the application ' |
425 | - 'lacked the required privileges'), |
426 | - E_SOCKET_RESOURCE: translate('OpenLP.ProjectorConstants', |
427 | - 'The local system ran out of resources (e.g., too many sockets)'), |
428 | - E_SOCKET_TIMEOUT: translate('OpenLP.ProjectorConstants', |
429 | - 'The socket operation timed out'), |
430 | - E_DATAGRAM_TOO_LARGE: translate('OpenLP.ProjectorConstants', |
431 | - 'The datagram was larger than the operating system\'s limit'), |
432 | + E_INVALID_DATA: translate('OpenLP.ProjectorConstants', 'PJLink invalid packet received'), |
433 | + E_LAMP: translate('OpenLP.ProjectorConstants', 'Projector lamp error'), |
434 | E_NETWORK: translate('OpenLP.ProjectorConstants', |
435 | 'An error occurred with the network (Possibly someone pulled the plug?)'), |
436 | - E_ADDRESS_IN_USE: translate('OpenLP.ProjectorConstants', |
437 | - 'The address specified with socket.bind() ' |
438 | - 'is already in use and was set to be exclusive'), |
439 | - E_SOCKET_ADDRESS_NOT_AVAILABLE: translate('OpenLP.ProjectorConstants', |
440 | - 'The address specified to socket.bind() ' |
441 | - 'does not belong to the host'), |
442 | - E_UNSUPPORTED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants', |
443 | - 'The requested socket operation is not supported by the local ' |
444 | - 'operating system (e.g., lack of IPv6 support)'), |
445 | + E_NO_AUTHENTICATION: translate('OpenLP.ProjectorConstants', 'PJlink authentication Mismatch Error'), |
446 | + E_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Projector not connected error'), |
447 | + E_PARAMETER: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR2: Invalid Parameter"'), |
448 | + E_PREFIX: translate('OpenLP.ProjectorConstants', 'PJLink Invalid prefix character'), |
449 | + E_PROJECTOR: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR4: Projector/Display Error"'), |
450 | E_PROXY_AUTHENTICATION_REQUIRED: translate('OpenLP.ProjectorConstants', |
451 | 'The socket is using a proxy, ' |
452 | 'and the proxy requires authentication'), |
453 | - E_SLS_HANDSHAKE_FAILED: translate('OpenLP.ProjectorConstants', |
454 | - 'The SSL/TLS handshake failed'), |
455 | - E_UNFINISHED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants', |
456 | - 'The last operation attempted has not finished yet ' |
457 | - '(still in progress in the background)'), |
458 | + E_PROXY_CONNECTION_CLOSED: translate('OpenLP.ProjectorConstants', |
459 | + 'The connection to the proxy server was closed unexpectedly ' |
460 | + '(before the connection to the final peer was established)'), |
461 | E_PROXY_CONNECTION_REFUSED: translate('OpenLP.ProjectorConstants', |
462 | 'Could not contact the proxy server because the connection ' |
463 | 'to that server was denied'), |
464 | - E_PROXY_CONNECTION_CLOSED: translate('OpenLP.ProjectorConstants', |
465 | - 'The connection to the proxy server was closed unexpectedly ' |
466 | - '(before the connection to the final peer was established)'), |
467 | E_PROXY_CONNECTION_TIMEOUT: translate('OpenLP.ProjectorConstants', |
468 | 'The connection to the proxy server timed out or the proxy ' |
469 | 'server stopped responding in the authentication phase.'), |
470 | @@ -373,51 +405,91 @@ |
471 | E_PROXY_PROTOCOL: translate('OpenLP.ProjectorConstants', |
472 | 'The connection negotiation with the proxy server failed because the ' |
473 | 'response from the proxy server could not be understood'), |
474 | - E_UNKNOWN_SOCKET_ERROR: translate('OpenLP.ProjectorConstants', 'An unidentified error occurred'), |
475 | - S_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Not connected'), |
476 | + E_REMOTE_HOST_CLOSED_CONNECTION: translate('OpenLP.ProjectorConstants', |
477 | + 'The remote host closed the connection'), |
478 | + E_SLS_HANDSHAKE_FAILED: translate('OpenLP.ProjectorConstants', |
479 | + 'The SSL/TLS handshake failed'), |
480 | + E_SOCKET_ADDRESS_NOT_AVAILABLE: translate('OpenLP.ProjectorConstants', |
481 | + 'The address specified to socket.bind() ' |
482 | + 'does not belong to the host'), |
483 | + E_SOCKET_ACCESS: translate('OpenLP.ProjectorConstants', |
484 | + 'The socket operation failed because the application ' |
485 | + 'lacked the required privileges'), |
486 | + E_SOCKET_RESOURCE: translate('OpenLP.ProjectorConstants', |
487 | + 'The local system ran out of resources (e.g., too many sockets)'), |
488 | + E_SOCKET_TIMEOUT: translate('OpenLP.ProjectorConstants', |
489 | + 'The socket operation timed out'), |
490 | + E_TEMP: translate('OpenLP.ProjectorConstants', 'Projector high temperature detected'), |
491 | + E_UNAVAILABLE: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR3: Busy"'), |
492 | + E_UNDEFINED: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR1: Undefined Command"'), |
493 | + E_UNFINISHED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants', |
494 | + 'The last operation attempted has not finished yet ' |
495 | + '(still in progress in the background)'), |
496 | + E_UNKNOWN: translate('OpenLP.ProjectorConstants', 'Unknown condiction detected'), |
497 | + E_UNKNOWN_SOCKET_ERROR: translate('OpenLP.ProjectorConstants', 'An unidentified socket error occurred'), |
498 | + E_UNSUPPORTED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants', |
499 | + 'The requested socket operation is not supported by the local ' |
500 | + 'operating system (e.g., lack of IPv6 support)'), |
501 | + E_WARN: translate('OpenLP.ProjectorConstants', 'Warning condition detected'), |
502 | + S_BOUND: translate('OpenLP.ProjectorConstants', 'Socket is bount to an address or port'), |
503 | + S_CLOSING: translate('OpenLP.ProjectorConstants', 'Socket is about to close'), |
504 | + S_CONNECTED: translate('OpenLP.ProjectorConstants', 'Connected'), |
505 | S_CONNECTING: translate('OpenLP.ProjectorConstants', 'Connecting'), |
506 | - S_CONNECTED: translate('OpenLP.ProjectorConstants', 'Connected'), |
507 | - S_STATUS: translate('OpenLP.ProjectorConstants', 'Getting status'), |
508 | + S_COOLDOWN: translate('OpenLP.ProjectorConstants', 'Cooldown in progress'), |
509 | + S_HOST_LOOKUP: translate('OpenLP.ProjectorConstants', 'Performing a host name lookup'), |
510 | + S_INFO: translate('OpenLP.ProjectorConstants', 'Projector Information available'), |
511 | + S_INITIALIZE: translate('OpenLP.ProjectorConstants', 'Initialize in progress'), |
512 | + S_LISTENING: translate('OpenLP.ProjectorConstants', 'Socket it listening (internal use only)'), |
513 | + S_NETWORK_IDLE: translate('OpenLP.ProjectorConstants', 'No network activity at this time'), |
514 | + S_NETWORK_RECEIVING: translate('OpenLP.ProjectorConstants', 'Received data'), |
515 | + S_NETWORK_SENDING: translate('OpenLP.ProjectorConstants', 'Sending data'), |
516 | + S_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Not Connected'), |
517 | S_OFF: translate('OpenLP.ProjectorConstants', 'Off'), |
518 | - S_INITIALIZE: translate('OpenLP.ProjectorConstants', 'Initialize in progress'), |
519 | + S_OK: translate('OpenLP.ProjectorConstants', 'OK'), |
520 | + S_ON: translate('OpenLP.ProjectorConstants', 'Power is on'), |
521 | S_STANDBY: translate('OpenLP.ProjectorConstants', 'Power in standby'), |
522 | + S_STATUS: translate('OpenLP.ProjectorConstants', 'Getting status'), |
523 | S_WARMUP: translate('OpenLP.ProjectorConstants', 'Warmup in progress'), |
524 | - S_ON: translate('OpenLP.ProjectorConstants', 'Power is on'), |
525 | - S_COOLDOWN: translate('OpenLP.ProjectorConstants', 'Cooldown in progress'), |
526 | - S_INFO: translate('OpenLP.ProjectorConstants', 'Projector Information available'), |
527 | - S_NETWORK_SENDING: translate('OpenLP.ProjectorConstants', 'Sending data'), |
528 | - S_NETWORK_RECEIVED: translate('OpenLP.ProjectorConstants', 'Received data') |
529 | -} |
530 | - |
531 | -# Map ERST return code positions to equipment |
532 | +} |
533 | + |
534 | +# Map ERST reply positions to equipment |
535 | +PJLINK_ERST_LIST = { |
536 | + "FAN": translate('OpenLP.PJLink', 'Fan'), |
537 | + "LAMP": translate('OpenLP.PJLink', 'Lamp'), |
538 | + "TEMP": translate('OpenLP.PJLink', 'Temperature'), |
539 | + "COVER": translate('OpenLP.PJLink', 'Cover'), |
540 | + "FILTER": translate('OpenLP.PJLink', 'Filter'), |
541 | + "OTHER": translate('OpenPL.PJLink', 'Other') |
542 | +} |
543 | + |
544 | +# Map projector item to ERST data position |
545 | PJLINK_ERST_DATA = { |
546 | - 'DATA_LENGTH': 6, |
547 | + 'DATA_LENGTH': 6, # Zero based so enums are 0-5 |
548 | + 'FAN': 0, |
549 | + 'LAMP': 1, |
550 | + 'TEMP': 2, |
551 | + 'COVER': 3, |
552 | + 'FILTER': 4, |
553 | + 'OTHER': 5, |
554 | 0: 'FAN', |
555 | 1: 'LAMP', |
556 | 2: 'TEMP', |
557 | 3: 'COVER', |
558 | 4: 'FILTER', |
559 | - 5: 'OTHER', |
560 | - 'FAN': 0, |
561 | - 'LAMP': 1, |
562 | - 'TEMP': 2, |
563 | - 'COVER': 3, |
564 | - 'FILTER': 4, |
565 | - 'OTHER': 5 |
566 | + 5: 'OTHER' |
567 | } |
568 | |
569 | -# Map for ERST return codes to string |
570 | +# Map ERST reply codes to string |
571 | PJLINK_ERST_STATUS = { |
572 | - '0': 'OK', |
573 | - '1': ERROR_STRING[E_WARN], |
574 | - '2': ERROR_STRING[E_ERROR], |
575 | - 'OK': '0', |
576 | - E_OK: '0', |
577 | + '0': S_OK, |
578 | + '1': E_WARN, |
579 | + '2': E_ERROR, |
580 | + S_OK: '0', |
581 | E_WARN: '1', |
582 | E_ERROR: '2' |
583 | } |
584 | |
585 | -# Map for POWR return codes to status code |
586 | +# Map POWR return codes to status code |
587 | PJLINK_POWR_STATUS = { |
588 | '0': S_STANDBY, |
589 | '1': S_ON, |
590 | @@ -485,3 +557,7 @@ |
591 | label = "{source}{item}".format(source=source, item=item) |
592 | PJLINK_DEFAULT_CODES[label] = "{source} {item}".format(source=PJLINK_DEFAULT_SOURCES[source], |
593 | item=PJLINK_DEFAULT_ITEMS[item]) |
594 | +# Remove temp variables so they don't become part of the module dict |
595 | +del(source) |
596 | +del(item) |
597 | +del(label) |
598 | |
599 | === modified file 'openlp/core/projectors/manager.py' |
600 | --- openlp/core/projectors/manager.py 2017-11-24 19:08:23 +0000 |
601 | +++ openlp/core/projectors/manager.py 2017-12-25 08:57:51 +0000 |
602 | @@ -35,9 +35,25 @@ |
603 | from openlp.core.common.settings import Settings |
604 | from openlp.core.lib.ui import create_widget_action |
605 | from openlp.core.projectors import DialogSourceStyle |
606 | -from openlp.core.projectors.constants import ERROR_MSG, ERROR_STRING, E_AUTHENTICATION, E_ERROR, \ |
607 | - E_NETWORK, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, STATUS_STRING, S_CONNECTED, S_CONNECTING, S_COOLDOWN, \ |
608 | - S_INITIALIZE, S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP |
609 | +from openlp.core.projectors.constants import \ |
610 | + E_AUTHENTICATION, \ |
611 | + E_ERROR, \ |
612 | + E_NETWORK, \ |
613 | + E_NOT_CONNECTED, \ |
614 | + E_UNKNOWN_SOCKET_ERROR, \ |
615 | + S_CONNECTED, \ |
616 | + S_CONNECTING, \ |
617 | + S_COOLDOWN, \ |
618 | + S_INITIALIZE, \ |
619 | + S_NOT_CONNECTED, \ |
620 | + S_OFF, \ |
621 | + S_ON, \ |
622 | + S_STANDBY, \ |
623 | + S_WARMUP, \ |
624 | + STATUS_CODE, \ |
625 | + STATUS_MSG, \ |
626 | + QSOCKET_STATE |
627 | + |
628 | from openlp.core.projectors.db import ProjectorDB |
629 | from openlp.core.projectors.pjlink import PJLink, PJLinkUDP |
630 | from openlp.core.projectors.editform import ProjectorEditForm |
631 | @@ -440,11 +456,12 @@ |
632 | :param opt: Needed by PyQt5 |
633 | """ |
634 | projector = item.data(QtCore.Qt.UserRole) |
635 | - if projector.link.state() != projector.link.ConnectedState: |
636 | + if QSOCKET_STATE[projector.link.state()] != S_CONNECTED: |
637 | try: |
638 | + log.debug('ProjectorManager: Calling connect_to_host() on "{ip}"'.format(ip=projector.link.ip)) |
639 | projector.link.connect_to_host() |
640 | except: |
641 | - pass |
642 | + log.debug('ProjectorManager: "{ip}" already connected - skipping'.format(ip=projector.link.ip)) |
643 | return |
644 | |
645 | def on_connect_projector(self, opt=None): |
646 | @@ -647,7 +664,7 @@ |
647 | 'Other info'), |
648 | data=projector.link.other_info) |
649 | message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager', 'Power status'), |
650 | - data=ERROR_MSG[projector.link.power]) |
651 | + data=STATUS_MSG[projector.link.power]) |
652 | message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager', 'Shutter is'), |
653 | data=translate('OpenLP.ProjectorManager', 'Closed') |
654 | if projector.link.shutter |
655 | @@ -692,7 +709,7 @@ |
656 | else: |
657 | message += '<b>{data}</b>'.format(data=translate('OpenLP.ProjectorManager', 'Current errors/warnings')) |
658 | for (key, val) in projector.link.projector_errors.items(): |
659 | - message += '<b>{key}</b>: {data}<br />'.format(key=key, data=ERROR_MSG[val]) |
660 | + message += '<b>{key}</b>: {data}<br />'.format(key=key, data=STATUS_MSG[val]) |
661 | QtWidgets.QMessageBox.information(self, translate('OpenLP.ProjectorManager', 'Projector Information'), message) |
662 | |
663 | def _add_projector(self, projector): |
664 | @@ -817,31 +834,18 @@ |
665 | if ip == list_item.link.ip: |
666 | item = list_item |
667 | break |
668 | - message = translate('OpenLP.ProjectorManager', 'No message') if msg is None else msg |
669 | - if status in STATUS_STRING: |
670 | - status_code = STATUS_STRING[status] |
671 | - message = ERROR_MSG[status] if msg is None else msg |
672 | - elif status in ERROR_STRING: |
673 | - status_code = ERROR_STRING[status] |
674 | - message = ERROR_MSG[status] if msg is None else msg |
675 | - else: |
676 | - status_code = status |
677 | - message = ERROR_MSG[status] if msg is None else msg |
678 | - log.debug('({name}) updateStatus(status={status}) message: "{message}"'.format(name=item.link.name, |
679 | - status=status_code, |
680 | - message=message)) |
681 | - if status in STATUS_ICONS: |
682 | - if item.status == status: |
683 | - return |
684 | - item.status = status |
685 | - item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status])) |
686 | - if status in ERROR_STRING: |
687 | - status_code = ERROR_STRING[status] |
688 | - elif status in STATUS_STRING: |
689 | - status_code = STATUS_STRING[status] |
690 | - log.debug('({name}) Updating icon with {code}'.format(name=item.link.name, code=status_code)) |
691 | - item.widget.setIcon(item.icon) |
692 | - self.update_icons() |
693 | + if item is None: |
694 | + log.error('ProjectorManager: Unknown item "{ip}" - not updating status'.format(ip=ip)) |
695 | + return |
696 | + elif item.status == status: |
697 | + log.debug('ProjectorManager: No status change for "{ip}" - not updating status'.format(ip=ip)) |
698 | + return |
699 | + |
700 | + item.status = status |
701 | + item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status])) |
702 | + log.debug('({name}) Updating icon with {code}'.format(name=item.link.name, code=STATUS_CODE[status])) |
703 | + item.widget.setIcon(item.icon) |
704 | + return self.update_icons() |
705 | |
706 | def get_toolbar_item(self, name, enabled=False, hidden=False): |
707 | item = self.one_toolbar.findChild(QtWidgets.QAction, name) |
708 | @@ -877,7 +881,7 @@ |
709 | self.get_toolbar_item('show_projector_multiple', hidden=True) |
710 | elif count == 1: |
711 | projector = self.projector_list_widget.selectedItems()[0].data(QtCore.Qt.UserRole) |
712 | - connected = projector.link.state() == projector.link.ConnectedState |
713 | + connected = QSOCKET_STATE[projector.link.state()] == S_CONNECTED |
714 | power = projector.link.power == S_ON |
715 | self.get_toolbar_item('connect_projector_multiple', hidden=True) |
716 | self.get_toolbar_item('disconnect_projector_multiple', hidden=True) |
717 | |
718 | === modified file 'openlp/core/projectors/pjlink.py' |
719 | --- openlp/core/projectors/pjlink.py 2017-12-09 11:17:05 +0000 |
720 | +++ openlp/core/projectors/pjlink.py 2017-12-25 08:57:51 +0000 |
721 | @@ -54,11 +54,12 @@ |
722 | |
723 | from openlp.core.common import qmd5_hash |
724 | from openlp.core.common.i18n import translate |
725 | -from openlp.core.projectors.constants import CONNECTION_ERRORS, CR, ERROR_MSG, ERROR_STRING, \ |
726 | - E_AUTHENTICATION, E_CONNECTION_REFUSED, E_GENERAL, E_INVALID_DATA, E_NETWORK, E_NOT_CONNECTED, E_OK, \ |
727 | - E_PARAMETER, E_PROJECTOR, E_SOCKET_TIMEOUT, E_UNAVAILABLE, E_UNDEFINED, PJLINK_ERRORS, PJLINK_ERST_DATA, \ |
728 | - PJLINK_ERST_STATUS, PJLINK_MAX_PACKET, PJLINK_PORT, PJLINK_POWR_STATUS, PJLINK_VALID_CMD, \ |
729 | - STATUS_STRING, S_CONNECTED, S_CONNECTING, S_INFO, S_NOT_CONNECTED, S_OFF, S_OK, S_ON, S_QSOCKET_STATE, S_STATUS |
730 | +from openlp.core.projectors.constants import CONNECTION_ERRORS, PJLINK_CLASS, PJLINK_DEFAULT_CODES, PJLINK_ERRORS, \ |
731 | + PJLINK_ERST_DATA, PJLINK_ERST_STATUS, PJLINK_MAX_PACKET, PJLINK_PREFIX, PJLINK_PORT, PJLINK_POWR_STATUS, \ |
732 | + PJLINK_SUFFIX, PJLINK_VALID_CMD, PROJECTOR_STATE, STATUS_CODE, STATUS_MSG, QSOCKET_STATE, \ |
733 | + E_AUTHENTICATION, E_CONNECTION_REFUSED, E_GENERAL, E_INVALID_DATA, E_NETWORK, E_NOT_CONNECTED, \ |
734 | + E_OK, E_SOCKET_TIMEOUT, \ |
735 | + S_CONNECTED, S_CONNECTING, S_INFO, S_NOT_CONNECTED, S_OFF, S_OK, S_ON, S_STATUS |
736 | |
737 | log = logging.getLogger(__name__) |
738 | log.debug('pjlink loaded') |
739 | @@ -69,12 +70,9 @@ |
740 | SocketError = QtNetwork.QAbstractSocket.SocketError |
741 | SocketSTate = QtNetwork.QAbstractSocket.SocketState |
742 | |
743 | -PJLINK_PREFIX = '%' |
744 | -PJLINK_CLASS = '1' # Default to class 1 until we query the projector |
745 | # Add prefix here, but defer linkclass expansion until later when we have the actual |
746 | # PJLink class for the command |
747 | PJLINK_HEADER = '{prefix}{{linkclass}}'.format(prefix=PJLINK_PREFIX) |
748 | -PJLINK_SUFFIX = CR |
749 | |
750 | |
751 | class PJLinkUDP(QtNetwork.QUdpSocket): |
752 | @@ -136,8 +134,9 @@ |
753 | """ |
754 | Initialize instance variables. Also used to reset projector-specific information to default. |
755 | """ |
756 | + conn_state = STATUS_CODE[QSOCKET_STATE[self.state()]] |
757 | log.debug('({ip}) reset_information() connect status is {state}'.format(ip=self.ip, |
758 | - state=S_QSOCKET_STATE[self.state()])) |
759 | + state=conn_state)) |
760 | self.fan = None # ERST |
761 | self.filter_time = None # FILT |
762 | self.lamp = None # LAMP |
763 | @@ -183,42 +182,25 @@ |
764 | # Due to some replies should stay as mixed-case, validate using separate uppercase check |
765 | _data = data.upper() |
766 | # Check if we have a future command not available yet |
767 | - if cmd not in PJLINK_VALID_CMD: |
768 | - log.error('({ip}) Ignoring command="{cmd}" (Invalid/Unknown)'.format(ip=self.ip, cmd=cmd)) |
769 | + if cmd not in self.pjlink_functions: |
770 | + log.warning('({ip}) Unable to process command="{cmd}" (Future option?)'.format(ip=self.ip, cmd=cmd)) |
771 | return |
772 | elif _data == 'OK': |
773 | log.debug('({ip}) Command "{cmd}" returned OK'.format(ip=self.ip, cmd=cmd)) |
774 | # A command returned successfully, so do a query on command to verify status |
775 | return self.send_command(cmd=cmd) |
776 | - elif cmd not in self.pjlink_functions: |
777 | - log.warning('({ip}) Unable to process command="{cmd}" (Future option?)'.format(ip=self.ip, cmd=cmd)) |
778 | - return |
779 | elif _data in PJLINK_ERRORS: |
780 | # Oops - projector error |
781 | - log.error('({ip}) Projector returned error "{data}"'.format(ip=self.ip, data=data)) |
782 | - if _data == PJLINK_ERRORS[E_AUTHENTICATION]: |
783 | - # Authentication error |
784 | + log.error('({ip}) {cmd}: {err}'.format(ip=self.ip, |
785 | + cmd=cmd, |
786 | + err=STATUS_MSG[PJLINK_ERRORS[_data]])) |
787 | + if PJLINK_ERRORS[_data] == E_AUTHENTICATION: |
788 | self.disconnect_from_host() |
789 | - self.change_status(E_AUTHENTICATION) |
790 | - log.debug('({ip}) emitting projectorAuthentication() signal'.format(ip=self.ip)) |
791 | self.projectorAuthentication.emit(self.name) |
792 | - elif _data == PJLINK_ERRORS[E_UNDEFINED]: |
793 | - # Projector does not recognize command |
794 | - self.change_status(E_UNDEFINED, '{error}: "{data}"'.format(error=ERROR_MSG[E_UNDEFINED], |
795 | - data=cmd)) |
796 | - elif _data == PJLINK_ERRORS[E_PARAMETER]: |
797 | - # Invalid parameter |
798 | - self.change_status(E_PARAMETER) |
799 | - elif _data == PJLINK_ERRORS[E_UNAVAILABLE]: |
800 | - # Projector busy |
801 | - self.change_status(E_UNAVAILABLE) |
802 | - elif _data == PJLINK_ERRORS[E_PROJECTOR]: |
803 | - # Projector/display error |
804 | - self.change_status(E_PROJECTOR) |
805 | - return |
806 | + return self.change_status(status=E_AUTHENTICATION) |
807 | # Command checks already passed |
808 | log.debug('({ip}) Calling function for {cmd}'.format(ip=self.ip, cmd=cmd)) |
809 | - self.pjlink_functions[cmd](data) |
810 | + self.pjlink_functions[cmd](data=data) |
811 | |
812 | def process_avmt(self, data): |
813 | """ |
814 | @@ -313,22 +295,22 @@ |
815 | data[PJLINK_ERST_DATA['COVER']], |
816 | data[PJLINK_ERST_DATA['FILTER']], |
817 | data[PJLINK_ERST_DATA['OTHER']]) |
818 | - if fan != PJLINK_ERST_STATUS[E_OK]: |
819 | + if fan != PJLINK_ERST_STATUS[S_OK]: |
820 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Fan')] = \ |
821 | PJLINK_ERST_STATUS[fan] |
822 | - if lamp != PJLINK_ERST_STATUS[E_OK]: |
823 | + if lamp != PJLINK_ERST_STATUS[S_OK]: |
824 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Lamp')] = \ |
825 | PJLINK_ERST_STATUS[lamp] |
826 | - if temp != PJLINK_ERST_STATUS[E_OK]: |
827 | + if temp != PJLINK_ERST_STATUS[S_OK]: |
828 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Temperature')] = \ |
829 | PJLINK_ERST_STATUS[temp] |
830 | - if cover != PJLINK_ERST_STATUS[E_OK]: |
831 | + if cover != PJLINK_ERST_STATUS[S_OK]: |
832 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Cover')] = \ |
833 | PJLINK_ERST_STATUS[cover] |
834 | - if filt != PJLINK_ERST_STATUS[E_OK]: |
835 | + if filt != PJLINK_ERST_STATUS[S_OK]: |
836 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Filter')] = \ |
837 | PJLINK_ERST_STATUS[filt] |
838 | - if other != PJLINK_ERST_STATUS[E_OK]: |
839 | + if other != PJLINK_ERST_STATUS[S_OK]: |
840 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Other')] = \ |
841 | PJLINK_ERST_STATUS[other] |
842 | return |
843 | @@ -373,8 +355,18 @@ |
844 | |
845 | :param data: Currently selected source |
846 | """ |
847 | + # First, see if we have a valid input based on what is installed (if available) |
848 | + if self.source_available is not None: |
849 | + # We have available inputs, so verify it's in the list |
850 | + if data not in self.source_available: |
851 | + log.warn('({ip}) Input source not listed in available sources - ignoring'.format(ip=self.ip)) |
852 | + return |
853 | + elif data not in PJLINK_DEFAULT_CODES: |
854 | + # Hmm - no sources available yet, so check with PJLink defaults |
855 | + log.warn('({ip}) Input source not listed as a PJLink available source - ignoring'.format(ip=self.ip)) |
856 | + return |
857 | self.source = data |
858 | - log.info('({ip}) Setting data source to "{data}"'.format(ip=self.ip, data=self.source)) |
859 | + log.debug('({ip}) Setting data source to "{data}"'.format(ip=self.ip, data=self.source)) |
860 | return |
861 | |
862 | def process_inst(self, data): |
863 | @@ -390,7 +382,6 @@ |
864 | sources.append(source) |
865 | sources.sort() |
866 | self.source_available = sources |
867 | - self.projectorUpdateIcons.emit() |
868 | log.debug('({ip}) Setting projector sources_available to "{data}"'.format(ip=self.ip, |
869 | data=self.source_available)) |
870 | return |
871 | @@ -551,17 +542,15 @@ |
872 | return |
873 | elif self.sw_version is None: |
874 | log.debug('({ip}) Setting projector software version to "{data}"'.format(ip=self.ip, data=data)) |
875 | - self.sw_version = data |
876 | - self.db_update = True |
877 | else: |
878 | - # Compare software version and see if we got the same projector |
879 | - if self.serial_no != data: |
880 | + if self.sw_version != data: |
881 | log.warning('({ip}) Projector software version does not match saved ' |
882 | 'software version'.format(ip=self.ip)) |
883 | log.warning('({ip}) Saved: "{old}"'.format(ip=self.ip, old=self.sw_version)) |
884 | log.warning('({ip}) Received: "{new}"'.format(ip=self.ip, new=data)) |
885 | - log.warning('({ip}) Saving new serial number as sw_version_received'.format(ip=self.ip)) |
886 | - self.sw_version_received = data |
887 | + log.warning('({ip}) Updating software version'.format(ip=self.ip)) |
888 | + self.sw_version = data |
889 | + self.db_update = True |
890 | |
891 | |
892 | class PJLink(QtNetwork.QTcpSocket, PJLinkCommands): |
893 | @@ -678,7 +667,7 @@ |
894 | Retrieve information from projector that changes. |
895 | Normally called by timer(). |
896 | """ |
897 | - if self.state() != S_QSOCKET_STATE['ConnectedState']: |
898 | + if QSOCKET_STATE[self.state()] != S_CONNECTED: |
899 | log.warning('({ip}) poll_loop(): Not connected - returning'.format(ip=self.ip)) |
900 | return |
901 | log.debug('({ip}) poll_loop(): Updating projector status'.format(ip=self.ip)) |
902 | @@ -688,13 +677,8 @@ |
903 | self.timer.setInterval(self.poll_time) |
904 | # Restart timer |
905 | self.timer.start() |
906 | - # These commands may change during connection |
907 | - check_list = ['POWR', 'ERST', 'LAMP', 'AVMT', 'INPT'] |
908 | - if self.pjlink_class == '2': |
909 | - check_list.extend(['FILT', 'FREZ']) |
910 | - for command in check_list: |
911 | - self.send_command(command) |
912 | # The following commands do not change, so only check them once |
913 | + # Call them first in case other functions rely on something here |
914 | if self.power == S_ON and self.source_available is None: |
915 | self.send_command('INST') |
916 | if self.other_info is None: |
917 | @@ -715,22 +699,28 @@ |
918 | self.send_command('RFIL') |
919 | if self.model_lamp is None: |
920 | self.send_command('RLMP') |
921 | + # These commands may change during connection |
922 | + check_list = ['POWR', 'ERST', 'LAMP', 'AVMT', 'INPT'] |
923 | + if self.pjlink_class == '2': |
924 | + check_list.extend(['FILT', 'FREZ']) |
925 | + for command in check_list: |
926 | + self.send_command(command) |
927 | |
928 | def _get_status(self, status): |
929 | """ |
930 | Helper to retrieve status/error codes and convert to strings. |
931 | |
932 | :param status: Status/Error code |
933 | - :returns: (Status/Error code, String) |
934 | + :returns: tuple (-1 if code not INT, None) |
935 | + :returns: tuple (string: code as string, None if no description) |
936 | + :returns: tuple (string: code as string, string: Status/Error description) |
937 | """ |
938 | if not isinstance(status, int): |
939 | - return -1, 'Invalid status code' |
940 | - elif status in ERROR_STRING: |
941 | - return ERROR_STRING[status], ERROR_MSG[status] |
942 | - elif status in STATUS_STRING: |
943 | - return STATUS_STRING[status], ERROR_MSG[status] |
944 | + return -1, None |
945 | + elif status not in STATUS_MSG: |
946 | + return None, None |
947 | else: |
948 | - return status, translate('OpenLP.PJLink', 'Unknown status') |
949 | + return STATUS_CODE[status], STATUS_MSG[status] |
950 | |
951 | def change_status(self, status, msg=None): |
952 | """ |
953 | @@ -740,19 +730,27 @@ |
954 | :param status: Status code |
955 | :param msg: Optional message |
956 | """ |
957 | - message = translate('OpenLP.PJLink', 'No message') if msg is None else msg |
958 | - (code, message) = self._get_status(status) |
959 | - if msg is not None: |
960 | - message = msg |
961 | + if status in STATUS_CODE: |
962 | + log.debug('({ip}) Changing status to {status} ' |
963 | + '"{msg}"'.format(ip=self.ip, |
964 | + status=STATUS_CODE[status], |
965 | + msg=msg if msg is not None else STATUS_MSG[status])) |
966 | + else: |
967 | + log.warning('({ip}) Unknown status change code: {code}'.format(ip=self.ip, |
968 | + code=status)) |
969 | + return |
970 | if status in CONNECTION_ERRORS: |
971 | - # Projector, connection state |
972 | - self.projector_status = self.error_status = self.status_connect = E_NOT_CONNECTED |
973 | - elif status >= S_NOT_CONNECTED and status < S_STATUS: |
974 | + # Connection state error affects both socket and projector |
975 | + self.error_status = status |
976 | + self.status_connect = E_NOT_CONNECTED |
977 | + elif status >= S_NOT_CONNECTED and status in QSOCKET_STATE: |
978 | + # Socket connection status update |
979 | self.status_connect = status |
980 | - self.projector_status = S_NOT_CONNECTED |
981 | - elif status <= S_INFO: |
982 | - self.status_connect = S_CONNECTED |
983 | + elif status >= S_NOT_CONNECTED and status in PROJECTOR_STATE: |
984 | + # Only affects the projector status |
985 | self.projector_status = status |
986 | + |
987 | + # These log entries are for troubleshooting only |
988 | (status_code, status_message) = self._get_status(self.status_connect) |
989 | log.debug('({ip}) status_connect: {code}: "{message}"'.format(ip=self.ip, |
990 | code=status_code, |
991 | @@ -765,6 +763,15 @@ |
992 | log.debug('({ip}) error_status: {code}: "{message}"'.format(ip=self.ip, |
993 | code=status_code, |
994 | message=status_message if msg is None else msg)) |
995 | + |
996 | + # Now that we logged extra information for debugging, broadcast the original change/message |
997 | + (code, message) = self._get_status(status) |
998 | + if msg is not None: |
999 | + message = msg |
1000 | + elif message is None: |
1001 | + # No message for status code |
1002 | + message = translate('OpenLP.PJLink', 'No message') if msg is None else msg |
1003 | + |
1004 | self.changeStatus.emit(self.ip, status, message) |
1005 | self.projectorUpdateIcons.emit() |
1006 | |
1007 | @@ -794,7 +801,7 @@ |
1008 | data = decode(read, 'utf-8') |
1009 | # Possibility of extraneous data on input when reading. |
1010 | # Clean out extraneous characters in buffer. |
1011 | - self.readLine(self.max_size) |
1012 | + self.read(2048) |
1013 | log.debug('({ip}) check_login() read "{data}"'.format(ip=self.ip, data=data.strip())) |
1014 | # At this point, we should only have the initial login prompt with |
1015 | # possible authentication |
1016 | @@ -805,6 +812,7 @@ |
1017 | # Invalid initial packet - close socket |
1018 | log.error('({ip}) Invalid initial packet received - closing socket'.format(ip=self.ip)) |
1019 | return self.disconnect_from_host() |
1020 | + # Convert the initial login prompt with the expected PJLink normal command format for processing |
1021 | log.debug('({ip}) check_login(): Formatting initial connection prompt to PJLink packet'.format(ip=self.ip)) |
1022 | return self.get_data('{start}{clss}{data}'.format(start=PJLINK_PREFIX, |
1023 | clss='1', |
1024 | @@ -895,7 +903,7 @@ |
1025 | Get data from TCP socket. |
1026 | """ |
1027 | log.debug('({ip}) get_socket(): Reading data'.format(ip=self.ip)) |
1028 | - if self.state() != self.ConnectedState: |
1029 | + if QSOCKET_STATE[self.state()] != S_CONNECTED: |
1030 | log.debug('({ip}) get_socket(): Not connected - returning'.format(ip=self.ip)) |
1031 | self.send_busy = False |
1032 | return |
1033 | @@ -907,8 +915,7 @@ |
1034 | log.debug('({ip}) get_socket(): No data available (-1)'.format(ip=self.ip)) |
1035 | return self.receive_data_signal() |
1036 | self.socket_timer.stop() |
1037 | - self.get_data(buff=read, ip=self.ip) |
1038 | - return self.receive_data_signal() |
1039 | + return self.get_data(buff=read, ip=self.ip) |
1040 | |
1041 | def get_data(self, buff, ip=None): |
1042 | """ |
1043 | @@ -927,13 +934,17 @@ |
1044 | data = data_in.strip() |
1045 | # Initial packet checks |
1046 | if (len(data) < 7): |
1047 | - return self._trash_buffer(msg='get_data(): Invalid packet - length') |
1048 | + self._trash_buffer(msg='get_data(): Invalid packet - length') |
1049 | + return self.receive_data_signal() |
1050 | elif len(data) > self.max_size: |
1051 | - return self._trash_buffer(msg='get_data(): Invalid packet - too long') |
1052 | + self._trash_buffer(msg='get_data(): Invalid packet - too long') |
1053 | + return self.receive_data_signal() |
1054 | elif not data.startswith(PJLINK_PREFIX): |
1055 | - return self._trash_buffer(msg='get_data(): Invalid packet - PJLink prefix missing') |
1056 | + self._trash_buffer(msg='get_data(): Invalid packet - PJLink prefix missing') |
1057 | + return self.receive_data_signal() |
1058 | elif '=' not in data: |
1059 | - return self._trash_buffer(msg='get_data(): Invalid reply - Does not have "="') |
1060 | + self._trash_buffer(msg='get_data(): Invalid reply - Does not have "="') |
1061 | + return self.receive_data_signal() |
1062 | log.debug('({ip}) get_data(): Checking new data "{data}"'.format(ip=self.ip, data=data)) |
1063 | header, data = data.split('=') |
1064 | # At this point, the header should contain: |
1065 | @@ -947,15 +958,17 @@ |
1066 | except ValueError as e: |
1067 | self.change_status(E_INVALID_DATA) |
1068 | log.warning('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in)) |
1069 | - return self._trash_buffer('get_data(): Expected header + command + data') |
1070 | + self._trash_buffer('get_data(): Expected header + command + data') |
1071 | + return self.receive_data_signal() |
1072 | if cmd not in PJLINK_VALID_CMD: |
1073 | log.warning('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd)) |
1074 | - return self._trash_buffer(msg='get_data(): Unknown command "{data}"'.format(data=cmd)) |
1075 | + self._trash_buffer(msg='get_data(): Unknown command "{data}"'.format(data=cmd)) |
1076 | + return self.receive_data_signal() |
1077 | if int(self.pjlink_class) < int(version): |
1078 | log.warning('({ip}) get_data(): Projector returned class reply higher ' |
1079 | 'than projector stated class'.format(ip=self.ip)) |
1080 | - self.send_busy = False |
1081 | - return self.process_command(cmd, data) |
1082 | + self.process_command(cmd, data) |
1083 | + return self.receive_data_signal() |
1084 | |
1085 | @QtCore.pyqtSlot(QtNetwork.QAbstractSocket.SocketError) |
1086 | def get_error(self, err): |
1087 | @@ -993,7 +1006,7 @@ |
1088 | :param salt: Optional salt for md5 hash initial authentication |
1089 | :param priority: Option to send packet now rather than queue it up |
1090 | """ |
1091 | - if self.state() != self.ConnectedState: |
1092 | + if QSOCKET_STATE[self.state()] != S_CONNECTED: |
1093 | log.warning('({ip}) send_command(): Not connected - returning'.format(ip=self.ip)) |
1094 | return self.reset_information() |
1095 | if cmd not in PJLINK_VALID_CMD: |
1096 | @@ -1018,7 +1031,7 @@ |
1097 | header=header, |
1098 | command=cmd, |
1099 | options=opts, |
1100 | - suffix=CR) |
1101 | + suffix=PJLINK_SUFFIX) |
1102 | if out in self.priority_queue: |
1103 | log.debug('({ip}) send_command(): Already in priority queue - skipping'.format(ip=self.ip)) |
1104 | elif out in self.send_queue: |
1105 | @@ -1044,9 +1057,10 @@ |
1106 | """ |
1107 | # Funny looking data check, but it's a quick check for data=None |
1108 | log.debug('({ip}) _send_command(data="{data}")'.format(ip=self.ip, data=data.strip() if data else data)) |
1109 | + conn_state = STATUS_CODE[QSOCKET_STATE[self.state()]] |
1110 | log.debug('({ip}) _send_command(): Connection status: {data}'.format(ip=self.ip, |
1111 | - data=S_QSOCKET_STATE[self.state()])) |
1112 | - if self.state() != self.ConnectedState: |
1113 | + data=conn_state)) |
1114 | + if QSOCKET_STATE[self.state()] != S_CONNECTED: |
1115 | log.debug('({ip}) _send_command() Not connected - abort'.format(ip=self.ip)) |
1116 | self.send_busy = False |
1117 | return self.disconnect_from_host() |
1118 | @@ -1088,10 +1102,11 @@ |
1119 | """ |
1120 | Initiate connection to projector. |
1121 | """ |
1122 | - log.debug('{ip}) connect_to_host(): Starting connection'.format(ip=self.ip)) |
1123 | - if self.state() == self.ConnectedState: |
1124 | + log.debug('({ip}) connect_to_host(): Starting connection'.format(ip=self.ip)) |
1125 | + if QSOCKET_STATE[self.state()] == S_CONNECTED: |
1126 | log.warning('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip)) |
1127 | return |
1128 | + self.error_status = S_OK |
1129 | self.change_status(S_CONNECTING) |
1130 | self.connectToHost(self.ip, self.port if isinstance(self.port, int) else int(self.port)) |
1131 | |
1132 | @@ -1100,12 +1115,13 @@ |
1133 | """ |
1134 | Close socket and cleanup. |
1135 | """ |
1136 | - if abort or self.state() != self.ConnectedState: |
1137 | + if abort or QSOCKET_STATE[self.state()] != S_NOT_CONNECTED: |
1138 | if abort: |
1139 | log.warning('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip)) |
1140 | + self.abort() |
1141 | else: |
1142 | log.warning('({ip}) disconnect_from_host(): Not connected'.format(ip=self.ip)) |
1143 | - self.disconnectFromHost() |
1144 | + self.disconnectFromHost() |
1145 | try: |
1146 | self.readyRead.disconnect(self.get_socket) |
1147 | except TypeError: |
1148 | @@ -1201,7 +1217,7 @@ |
1149 | elif src not in self.source_available: |
1150 | return |
1151 | log.debug('({ip}) Setting input source to "{data}"'.format(ip=self.ip, data=src)) |
1152 | - self.send_command(cmd='INPT', opts=src) |
1153 | + self.send_command(cmd='INPT', opts=src, priority=True) |
1154 | self.poll_loop() |
1155 | |
1156 | def set_power_on(self): |
1157 | @@ -1209,7 +1225,7 @@ |
1158 | Send command to turn power to on. |
1159 | """ |
1160 | log.debug('({ip}) Setting POWR to 1 (on)'.format(ip=self.ip)) |
1161 | - self.send_command(cmd='POWR', opts='1') |
1162 | + self.send_command(cmd='POWR', opts='1', priority=True) |
1163 | self.poll_loop() |
1164 | |
1165 | def set_power_off(self): |
1166 | @@ -1217,7 +1233,7 @@ |
1167 | Send command to turn power to standby. |
1168 | """ |
1169 | log.debug('({ip}) Setting POWR to 0 (standby)'.format(ip=self.ip)) |
1170 | - self.send_command(cmd='POWR', opts='0') |
1171 | + self.send_command(cmd='POWR', opts='0', priority=True) |
1172 | self.poll_loop() |
1173 | |
1174 | def set_shutter_closed(self): |
1175 | @@ -1225,7 +1241,7 @@ |
1176 | Send command to set shutter to closed position. |
1177 | """ |
1178 | log.debug('({ip}) Setting AVMT to 11 (shutter closed)'.format(ip=self.ip)) |
1179 | - self.send_command(cmd='AVMT', opts='11') |
1180 | + self.send_command(cmd='AVMT', opts='11', priority=True) |
1181 | self.poll_loop() |
1182 | |
1183 | def set_shutter_open(self): |
1184 | @@ -1233,8 +1249,9 @@ |
1185 | Send command to set shutter to open position. |
1186 | """ |
1187 | log.debug('({ip}) Setting AVMT to "10" (shutter open)'.format(ip=self.ip)) |
1188 | - self.send_command(cmd='AVMT', opts='10') |
1189 | + self.send_command(cmd='AVMT', opts='10', priority=True) |
1190 | self.poll_loop() |
1191 | + self.projectorUpdateIcons.emit() |
1192 | |
1193 | def receive_data_signal(self): |
1194 | """ |
1195 | |
1196 | === modified file 'tests/functional/openlp_core/projectors/test_projector_constants.py' |
1197 | --- tests/functional/openlp_core/projectors/test_projector_constants.py 2017-11-10 11:59:38 +0000 |
1198 | +++ tests/functional/openlp_core/projectors/test_projector_constants.py 2017-12-25 08:57:51 +0000 |
1199 | @@ -23,12 +23,51 @@ |
1200 | Package to test the openlp.core.projectors.constants module. |
1201 | """ |
1202 | from unittest import TestCase |
1203 | +from openlp.core.projectors import constants |
1204 | +from openlp.core.projectors.constants import STATUS_CODE, STATUS_MSG |
1205 | |
1206 | |
1207 | class TestProjectorConstants(TestCase): |
1208 | """ |
1209 | Test specific functions in the projector constants module. |
1210 | """ |
1211 | + def test_defined_codes_in_status_code(self): |
1212 | + """ |
1213 | + Test defined status/error codes have equivalent strings |
1214 | + """ |
1215 | + check = [] |
1216 | + missing_str = [] |
1217 | + |
1218 | + # GIVEN: List of defined E_* and S_* items defined in constants |
1219 | + for item in constants.__dict__: |
1220 | + if item.startswith('E_') or item.startswith('S_'): |
1221 | + check.append(item) |
1222 | + |
1223 | + # WHEN: Verify defined list against STATUS_STR |
1224 | + for item in check: |
1225 | + if constants.__dict__[item] not in STATUS_CODE: |
1226 | + missing_str.append(item) |
1227 | + |
1228 | + # THEN: There should be no missing items |
1229 | + assert 0 == len(missing_str), 'Status string missing: {msg}'.format(msg=missing_str) |
1230 | + |
1231 | + def test_status_code_in_status_message(self): |
1232 | + """ |
1233 | + Test if entries in STATUS_CODE have equivalent descriptions in STATUS_MSG |
1234 | + """ |
1235 | + missing_msg = [] |
1236 | + |
1237 | + # GIVEN: Test items |
1238 | + check = STATUS_CODE |
1239 | + |
1240 | + # WHEN: Verify each entry in STATUS_MSG against STATUS_CODE |
1241 | + for item in check: |
1242 | + if item not in STATUS_MSG: |
1243 | + missing_msg.append(item) |
1244 | + |
1245 | + # THEN: There should be no missing items |
1246 | + assert 0 == len(missing_msg), 'Status message missing: {msg}'.format(msg=missing_msg) |
1247 | + |
1248 | def test_build_pjlink_video_label(self): |
1249 | """ |
1250 | Test building PJLINK_DEFAULT_CODES dictionary |
1251 | |
1252 | === modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_base.py' |
1253 | --- tests/functional/openlp_core/projectors/test_projector_pjlink_base.py 2017-12-04 00:24:47 +0000 |
1254 | +++ tests/functional/openlp_core/projectors/test_projector_pjlink_base.py 2017-12-25 08:57:51 +0000 |
1255 | @@ -25,7 +25,7 @@ |
1256 | from unittest import TestCase |
1257 | from unittest.mock import call, patch, MagicMock |
1258 | |
1259 | -from openlp.core.projectors.constants import E_PARAMETER, ERROR_STRING, S_ON, S_CONNECTED, S_QSOCKET_STATE |
1260 | +from openlp.core.projectors.constants import E_PARAMETER, STATUS_CODE, S_ON, S_CONNECTED, QSOCKET_STATE |
1261 | from openlp.core.projectors.db import Projector |
1262 | from openlp.core.projectors.pjlink import PJLink |
1263 | |
1264 | @@ -65,7 +65,7 @@ |
1265 | # as first parameter |
1266 | mock_change_status.called_with(E_PARAMETER, |
1267 | 'change_status should have been called with "{}"'.format( |
1268 | - ERROR_STRING[E_PARAMETER])) |
1269 | + STATUS_CODE[E_PARAMETER])) |
1270 | |
1271 | @patch.object(pjlink_test, 'disconnect_from_host') |
1272 | def test_socket_abort(self, mock_disconnect): |
1273 | @@ -104,7 +104,7 @@ |
1274 | """ |
1275 | # GIVEN: Mocks and test data |
1276 | mock_state = patch.object(self.pjlink_test, 'state').start() |
1277 | - mock_state.return_value = S_QSOCKET_STATE['ConnectedState'] |
1278 | + mock_state.return_value = QSOCKET_STATE[S_CONNECTED] |
1279 | mock_timer = patch.object(self.pjlink_test, 'timer').start() |
1280 | mock_timer.interval.return_value = 10 |
1281 | mock_send_command = patch.object(self.pjlink_test, 'send_command').start() |
1282 | @@ -117,7 +117,6 @@ |
1283 | pjlink.manufacturer = None |
1284 | pjlink.model = None |
1285 | pjlink.pjlink_name = None |
1286 | - pjlink.ConnectedState = S_CONNECTED |
1287 | call_list = [ |
1288 | call('POWR'), |
1289 | call('ERST'), |
1290 | |
1291 | === modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py' |
1292 | --- tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py 2017-12-09 11:17:05 +0000 |
1293 | +++ tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py 2017-12-25 08:57:51 +0000 |
1294 | @@ -24,209 +24,222 @@ |
1295 | """ |
1296 | |
1297 | from unittest import TestCase |
1298 | -from unittest.mock import patch, MagicMock |
1299 | +from unittest.mock import MagicMock, call, patch |
1300 | |
1301 | import openlp.core.projectors.pjlink |
1302 | -from openlp.core.projectors.constants import PJLINK_ERRORS, \ |
1303 | +from openlp.core.projectors.constants import PJLINK_ERRORS, PJLINK_PREFIX, STATUS_MSG, \ |
1304 | E_AUTHENTICATION, E_PARAMETER, E_PROJECTOR, E_UNAVAILABLE, E_UNDEFINED |
1305 | from openlp.core.projectors.db import Projector |
1306 | from openlp.core.projectors.pjlink import PJLink |
1307 | |
1308 | -''' |
1309 | -from openlp.core.projectors.constants import ERROR_STRING, PJLINK_ERST_DATA, PJLINK_ERST_STATUS, \ |
1310 | - PJLINK_POWR_STATUS, PJLINK_VALID_CMD, E_WARN, E_ERROR, S_OFF, S_STANDBY, S_ON |
1311 | -''' |
1312 | -from tests.resources.projector.data import TEST_PIN, TEST1_DATA |
1313 | - |
1314 | -pjlink_test = PJLink(Projector(**TEST1_DATA), pin=TEST_PIN, no_poll=True) |
1315 | -pjlink_test.ip = '127.0.0.1' |
1316 | +from tests.resources.projector.data import TEST1_DATA |
1317 | |
1318 | |
1319 | class TestPJLinkRouting(TestCase): |
1320 | """ |
1321 | Tests for the PJLink module command routing |
1322 | """ |
1323 | - def setUp(self): |
1324 | - ''' |
1325 | - TestPJLinkCommands part 2 initialization |
1326 | - ''' |
1327 | - self.pjlink_test = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1328 | - |
1329 | - def tearDown(self): |
1330 | - ''' |
1331 | - TestPJLinkCommands part 2 cleanups |
1332 | - ''' |
1333 | - self.pjlink_test = None |
1334 | - |
1335 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1336 | - def test_process_command_call_clss(self, mock_log): |
1337 | + def test_get_data_unknown_command(self): |
1338 | + """ |
1339 | + Test not a valid command |
1340 | + """ |
1341 | + # GIVEN: Test object |
1342 | + log_warning_text = [call('(111.111.111.111) get_data(): Invalid packet - unknown command "UNK"')] |
1343 | + log_debug_text = [call('(111.111.111.111) get_data(ip="111.111.111.111" buffer="b\'%1UNK=Huh?\'"'), |
1344 | + call('(111.111.111.111) get_data(): Checking new data "%1UNK=Huh?"')] |
1345 | + |
1346 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1347 | + patch.object(openlp.core.projectors.pjlink.PJLink, '_trash_buffer') as mock_buffer: |
1348 | + |
1349 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1350 | + pjlink.pjlink_functions = MagicMock() |
1351 | + |
1352 | + # WHEN: get_data called with an unknown command |
1353 | + pjlink.get_data(buff='{prefix}1UNK=Huh?'.format(prefix=PJLINK_PREFIX).encode('utf-8')) |
1354 | + |
1355 | + # THEN: Appropriate log entries should have been made and methods called/not called |
1356 | + mock_log.debug.assert_has_calls(log_debug_text) |
1357 | + mock_log.warning.assert_has_calls(log_warning_text) |
1358 | + self.assertFalse(pjlink.pjlink_functions.called, 'Should not have accessed pjlink_functions') |
1359 | + self.assertTrue(mock_buffer.called, 'Should have called _trash_buffer') |
1360 | + |
1361 | + def test_process_command_call_clss(self): |
1362 | """ |
1363 | Test process_command calls proper function |
1364 | """ |
1365 | + # GIVEN: Test object and mocks |
1366 | + log_debug_calls = [call('(111.111.111.111) Processing command "CLSS" with data "1"'), |
1367 | + call('(111.111.111.111) Calling function for CLSS')] |
1368 | + |
1369 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1370 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1371 | + |
1372 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1373 | + |
1374 | + # WHEN: process_command is called with valid function and data |
1375 | + pjlink.process_command(cmd='CLSS', data='1') |
1376 | + |
1377 | + # THEN: Appropriate log entries should have been made and methods called |
1378 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1379 | + mock_process_clss.assert_called_once_with(data='1') |
1380 | + |
1381 | + def test_process_command_erra(self): |
1382 | + """ |
1383 | + Test ERRA - Authentication Error |
1384 | + """ |
1385 | # GIVEN: Test object |
1386 | - pjlink = pjlink_test |
1387 | - log_text = '(127.0.0.1) Calling function for CLSS' |
1388 | - mock_log.reset_mock() |
1389 | - mock_process_clss = MagicMock() |
1390 | - pjlink.pjlink_functions['CLSS'] = mock_process_clss |
1391 | - |
1392 | - # WHEN: process_command is called with valid function and data |
1393 | - pjlink.process_command(cmd='CLSS', data='1') |
1394 | - |
1395 | - # THEN: Process method should have been called properly |
1396 | - mock_log.debug.assert_called_with(log_text) |
1397 | - mock_process_clss.assert_called_with('1') |
1398 | - |
1399 | - @patch.object(pjlink_test, 'change_status') |
1400 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1401 | - def test_process_command_err1(self, mock_log, mock_change_status): |
1402 | + log_error_calls = [call('(111.111.111.111) PJLINK: {msg}'.format(msg=STATUS_MSG[E_AUTHENTICATION]))] |
1403 | + log_debug_calls = [call('(111.111.111.111) Processing command "PJLINK" with data "ERRA"')] |
1404 | + |
1405 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1406 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_pjlink') as mock_process_pjlink, \ |
1407 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
1408 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'disconnect_from_host') as mock_disconnect, \ |
1409 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorAuthentication') as mock_authentication: |
1410 | + |
1411 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1412 | + |
1413 | + # WHEN: process_command called with ERRA |
1414 | + pjlink.process_command(cmd='PJLINK', data=PJLINK_ERRORS[E_AUTHENTICATION]) |
1415 | + |
1416 | + # THEN: Appropriate log entries should have been made and methods called/not called |
1417 | + mock_log.error.assert_has_calls(log_error_calls) |
1418 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1419 | + self.assertTrue(mock_disconnect.called, 'disconnect_from_host should have been called') |
1420 | + mock_change_status.assert_called_once_with(status=E_AUTHENTICATION) |
1421 | + mock_authentication.emit.assert_called_once_with(pjlink.name) |
1422 | + mock_process_pjlink.assert_not_called() |
1423 | + |
1424 | + def test_process_command_err1(self): |
1425 | """ |
1426 | Test ERR1 - Undefined projector function |
1427 | """ |
1428 | # GIVEN: Test object |
1429 | - pjlink = pjlink_test |
1430 | - log_text = '(127.0.0.1) Projector returned error "ERR1"' |
1431 | - mock_change_status.reset_mock() |
1432 | - mock_log.reset_mock() |
1433 | - |
1434 | - # WHEN: process_command called with ERR1 |
1435 | - pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNDEFINED]) |
1436 | - |
1437 | - # THEN: Error should be logged and status_change should be called |
1438 | - mock_change_status.assert_called_once_with(E_UNDEFINED, 'Undefined Command: "CLSS"') |
1439 | - mock_log.error.assert_called_with(log_text) |
1440 | - |
1441 | - @patch.object(pjlink_test, 'change_status') |
1442 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1443 | - def test_process_command_err2(self, mock_log, mock_change_status): |
1444 | + log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_UNDEFINED]))] |
1445 | + log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "ERR1"'), |
1446 | + call('(111.111.111.111) Calling function for CLSS')] |
1447 | + |
1448 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1449 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1450 | + |
1451 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1452 | + |
1453 | + # WHEN: process_command called with ERR1 |
1454 | + pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNDEFINED]) |
1455 | + |
1456 | + # THEN: Appropriate log entries should have been made and methods called |
1457 | + mock_log.error.assert_has_calls(log_error_text) |
1458 | + mock_log.debug.assert_has_calls(log_debug_text) |
1459 | + mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_UNDEFINED]) |
1460 | + |
1461 | + def test_process_command_err2(self): |
1462 | """ |
1463 | Test ERR2 - Parameter Error |
1464 | """ |
1465 | # GIVEN: Test object |
1466 | - pjlink = pjlink_test |
1467 | - log_text = '(127.0.0.1) Projector returned error "ERR2"' |
1468 | - mock_change_status.reset_mock() |
1469 | - mock_log.reset_mock() |
1470 | - |
1471 | - # WHEN: process_command called with ERR2 |
1472 | - pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_PARAMETER]) |
1473 | - |
1474 | - # THEN: Error should be logged and status_change should be called |
1475 | - mock_change_status.assert_called_once_with(E_PARAMETER) |
1476 | - mock_log.error.assert_called_with(log_text) |
1477 | - |
1478 | - @patch.object(pjlink_test, 'change_status') |
1479 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1480 | - def test_process_command_err3(self, mock_log, mock_change_status): |
1481 | - """ |
1482 | - Test ERR3 - Unavailable error |
1483 | - """ |
1484 | - # GIVEN: Test object |
1485 | - pjlink = pjlink_test |
1486 | - log_text = '(127.0.0.1) Projector returned error "ERR3"' |
1487 | - mock_change_status.reset_mock() |
1488 | - mock_log.reset_mock() |
1489 | - |
1490 | - # WHEN: process_command called with ERR3 |
1491 | - pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNAVAILABLE]) |
1492 | - |
1493 | - # THEN: Error should be logged and status_change should be called |
1494 | - mock_change_status.assert_called_once_with(E_UNAVAILABLE) |
1495 | - mock_log.error.assert_called_with(log_text) |
1496 | - |
1497 | - @patch.object(pjlink_test, 'change_status') |
1498 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1499 | - def test_process_command_err4(self, mock_log, mock_change_status): |
1500 | - """ |
1501 | - Test ERR3 - Unavailable error |
1502 | - """ |
1503 | - # GIVEN: Test object |
1504 | - pjlink = pjlink_test |
1505 | - log_text = '(127.0.0.1) Projector returned error "ERR4"' |
1506 | - mock_change_status.reset_mock() |
1507 | - mock_log.reset_mock() |
1508 | - |
1509 | - # WHEN: process_command called with ERR3 |
1510 | - pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_PROJECTOR]) |
1511 | - |
1512 | - # THEN: Error should be logged and status_change should be called |
1513 | - mock_change_status.assert_called_once_with(E_PROJECTOR) |
1514 | - mock_log.error.assert_called_with(log_text) |
1515 | - |
1516 | - @patch.object(pjlink_test, 'projectorAuthentication') |
1517 | - @patch.object(pjlink_test, 'change_status') |
1518 | - @patch.object(pjlink_test, 'disconnect_from_host') |
1519 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1520 | - def test_process_command_erra(self, mock_log, mock_disconnect, mock_change_status, mock_err_authenticate): |
1521 | - """ |
1522 | - Test ERRA - Authentication Error |
1523 | - """ |
1524 | - # GIVEN: Test object |
1525 | - pjlink = pjlink_test |
1526 | - log_text = '(127.0.0.1) Projector returned error "ERRA"' |
1527 | - mock_change_status.reset_mock() |
1528 | - mock_log.reset_mock() |
1529 | - |
1530 | - # WHEN: process_command called with ERRA |
1531 | - pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_AUTHENTICATION]) |
1532 | - |
1533 | - # THEN: Error should be logged and several methods should be called |
1534 | - self.assertTrue(mock_disconnect.called, 'disconnect_from_host should have been called') |
1535 | - mock_change_status.assert_called_once_with(E_AUTHENTICATION) |
1536 | - mock_log.error.assert_called_with(log_text) |
1537 | + log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_PARAMETER]))] |
1538 | + log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "ERR2"'), |
1539 | + call('(111.111.111.111) Calling function for CLSS')] |
1540 | + |
1541 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1542 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1543 | + |
1544 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1545 | + |
1546 | + # WHEN: process_command called with ERR2 |
1547 | + pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_PARAMETER]) |
1548 | + |
1549 | + # THEN: Appropriate log entries should have been made and methods called/not called |
1550 | + mock_log.error.assert_has_calls(log_error_text) |
1551 | + mock_log.debug.assert_has_calls(log_debug_text) |
1552 | + mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_PARAMETER]) |
1553 | + |
1554 | + def test_process_command_err3(self): |
1555 | + """ |
1556 | + Test ERR3 - Unavailable error |
1557 | + """ |
1558 | + # GIVEN: Test object |
1559 | + log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_UNAVAILABLE]))] |
1560 | + log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "ERR3"'), |
1561 | + call('(111.111.111.111) Calling function for CLSS')] |
1562 | + |
1563 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1564 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1565 | + |
1566 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1567 | + |
1568 | + # WHEN: process_command called with ERR3 |
1569 | + pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNAVAILABLE]) |
1570 | + |
1571 | + # THEN: Appropriate log entries should have been made and methods called |
1572 | + mock_log.error.assert_has_calls(log_error_text) |
1573 | + mock_log.debug.assert_has_calls(log_debug_text) |
1574 | + mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_UNAVAILABLE]) |
1575 | + |
1576 | + def test_process_command_err4(self): |
1577 | + """ |
1578 | + Test ERR3 - Unavailable error |
1579 | + """ |
1580 | + # GIVEN: Test object |
1581 | + log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_PROJECTOR]))] |
1582 | + log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "ERR4"'), |
1583 | + call('(111.111.111.111) Calling function for CLSS')] |
1584 | + |
1585 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1586 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1587 | + |
1588 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1589 | + |
1590 | + # WHEN: process_command called with ERR4 |
1591 | + pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_PROJECTOR]) |
1592 | + |
1593 | + # THEN: Appropriate log entries should have been made and methods called |
1594 | + mock_log.error.assert_has_calls(log_error_text) |
1595 | + mock_log.debug.assert_has_calls(log_debug_text) |
1596 | + mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_PROJECTOR]) |
1597 | |
1598 | def test_process_command_future(self): |
1599 | """ |
1600 | Test command valid but no method to process yet |
1601 | """ |
1602 | - # GIVEN: Initial mocks and data |
1603 | - mock_log = patch.object(openlp.core.projectors.pjlink, 'log').start() |
1604 | - mock_functions = patch.object(self.pjlink_test, 'pjlink_functions').start() |
1605 | - mock_functions.return_value = [] |
1606 | - |
1607 | - pjlink = self.pjlink_test |
1608 | - log_text = '(111.111.111.111) Unable to process command="CLSS" (Future option?)' |
1609 | - |
1610 | - # WHEN: process_command called with an unknown command |
1611 | - pjlink.process_command(cmd='CLSS', data='DONT CARE') |
1612 | - |
1613 | - # THEN: Error should be logged and no command called |
1614 | - self.assertFalse(mock_functions.called, 'Should not have gotten to the end of the method') |
1615 | - mock_log.warning.assert_called_once_with(log_text) |
1616 | - |
1617 | - @patch.object(pjlink_test, 'pjlink_functions') |
1618 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1619 | - def test_process_command_invalid(self, mock_log, mock_functions): |
1620 | - """ |
1621 | - Test not a valid command |
1622 | - """ |
1623 | # GIVEN: Test object |
1624 | - pjlink = pjlink_test |
1625 | - mock_functions.reset_mock() |
1626 | - mock_log.reset_mock() |
1627 | - |
1628 | - # WHEN: process_command called with an unknown command |
1629 | - pjlink.process_command(cmd='Unknown', data='Dont Care') |
1630 | - log_text = '(127.0.0.1) Ignoring command="Unknown" (Invalid/Unknown)' |
1631 | - |
1632 | - # THEN: Error should be logged and no command called |
1633 | - self.assertFalse(mock_functions.called, 'Should not have gotten to the end of the method') |
1634 | - mock_log.error.assert_called_once_with(log_text) |
1635 | + log_warning_text = [call('(111.111.111.111) Unable to process command="CLSS" (Future option?)')] |
1636 | + log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "Huh?"')] |
1637 | + |
1638 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1639 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1640 | + |
1641 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1642 | + pjlink.pjlink_functions = MagicMock() |
1643 | + |
1644 | + # WHEN: Processing a possible future command |
1645 | + pjlink.process_command(cmd='CLSS', data="Huh?") |
1646 | + |
1647 | + # THEN: Appropriate log entries should have been made and methods called/not called |
1648 | + mock_log.debug.assert_has_calls(log_debug_text) |
1649 | + mock_log.warning.assert_has_calls(log_warning_text) |
1650 | + self.assertFalse(pjlink.pjlink_functions.called, 'Should not have accessed pjlink_functions') |
1651 | + self.assertFalse(mock_process_clss.called, 'Should not have called process_clss') |
1652 | |
1653 | def test_process_command_ok(self): |
1654 | """ |
1655 | Test command returned success |
1656 | """ |
1657 | # GIVEN: Initial mocks and data |
1658 | - mock_log = patch.object(openlp.core.projectors.pjlink, 'log').start() |
1659 | - mock_send_command = patch.object(self.pjlink_test, 'send_command').start() |
1660 | - |
1661 | - pjlink = self.pjlink_test |
1662 | - log_text = '(111.111.111.111) Command "POWR" returned OK' |
1663 | - |
1664 | - # WHEN: process_command called with a command that returns OK |
1665 | - pjlink.process_command(cmd='POWR', data='OK') |
1666 | - |
1667 | - # THEN: Appropriate calls should have been made |
1668 | - mock_log.debug.assert_called_with(log_text) |
1669 | - mock_send_command.assert_called_once_with(cmd='POWR') |
1670 | + # GIVEN: Test object and mocks |
1671 | + log_debug_calls = [call('(111.111.111.111) Processing command "CLSS" with data "OK"'), |
1672 | + call('(111.111.111.111) Command "CLSS" returned OK')] |
1673 | + |
1674 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1675 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ |
1676 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1677 | + |
1678 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1679 | + |
1680 | + # WHEN: process_command is called with valid function and data |
1681 | + pjlink.process_command(cmd='CLSS', data='OK') |
1682 | + |
1683 | + # THEN: Appropriate log entries should have been made and methods called |
1684 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1685 | + mock_send_command.assert_called_once_with(cmd='CLSS') |
1686 | + mock_process_clss.assert_not_called() |
1687 | |
1688 | === modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py' |
1689 | --- tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py 2017-12-09 11:17:05 +0000 |
1690 | +++ tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py 2017-12-25 08:57:51 +0000 |
1691 | @@ -23,372 +23,402 @@ |
1692 | Package to test the openlp.core.projectors.pjlink commands package. |
1693 | """ |
1694 | from unittest import TestCase |
1695 | -from unittest.mock import patch |
1696 | +from unittest.mock import call, patch |
1697 | |
1698 | import openlp.core.projectors.pjlink |
1699 | -from openlp.core.projectors.constants import ERROR_STRING, PJLINK_ERST_DATA, PJLINK_ERST_STATUS, \ |
1700 | - PJLINK_POWR_STATUS, \ |
1701 | - E_ERROR, E_NOT_CONNECTED, E_SOCKET_ADDRESS_NOT_AVAILABLE, E_UNKNOWN_SOCKET_ERROR, E_WARN, \ |
1702 | - S_CONNECTED, S_OFF, S_ON, S_NOT_CONNECTED, S_CONNECTING, S_STANDBY |
1703 | +from openlp.core.projectors.constants import PJLINK_ERST_DATA, PJLINK_ERST_STATUS, PJLINK_POWR_STATUS, \ |
1704 | + STATUS_CODE, STATUS_MSG, E_ERROR, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, E_WARN, \ |
1705 | + S_CONNECTED, S_CONNECTING, S_OFF, S_OK, S_ON, S_NOT_CONNECTED, S_STANDBY |
1706 | from openlp.core.projectors.db import Projector |
1707 | from openlp.core.projectors.pjlink import PJLink |
1708 | |
1709 | -from tests.resources.projector.data import TEST_PIN, TEST1_DATA |
1710 | - |
1711 | -pjlink_test = PJLink(Projector(**TEST1_DATA), pin=TEST_PIN, no_poll=True) |
1712 | -pjlink_test.ip = '127.0.0.1' |
1713 | - |
1714 | -# Create a list of ERST positional data so we don't have to redo the same buildup multiple times |
1715 | -PJLINK_ERST_POSITIONS = [] |
1716 | -for pos in range(0, len(PJLINK_ERST_DATA)): |
1717 | - if pos in PJLINK_ERST_DATA: |
1718 | - PJLINK_ERST_POSITIONS.append(PJLINK_ERST_DATA[pos]) |
1719 | +from tests.resources.projector.data import TEST1_DATA |
1720 | |
1721 | |
1722 | class TestPJLinkCommands(TestCase): |
1723 | """ |
1724 | Tests for the PJLinkCommands class part 1 |
1725 | """ |
1726 | - @patch.object(pjlink_test, 'changeStatus') |
1727 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1728 | - def test_projector_change_status_connection_error(self, mock_log, mock_change_status): |
1729 | + def test_projector_change_status_unknown_socket_error(self): |
1730 | """ |
1731 | Test change_status with connection error |
1732 | """ |
1733 | - # GIVEN: Test object |
1734 | - pjlink = pjlink_test |
1735 | - pjlink.projector_status = 0 |
1736 | - pjlink.status_connect = 0 |
1737 | - test_code = E_UNKNOWN_SOCKET_ERROR |
1738 | - mock_change_status.reset_mock() |
1739 | - mock_log.reset_mock() |
1740 | - |
1741 | - # WHEN: change_status called with unknown socket error |
1742 | - pjlink.change_status(status=test_code, msg=None) |
1743 | - |
1744 | - # THEN: Proper settings should change and signals sent |
1745 | - self.assertEqual(pjlink.projector_status, E_NOT_CONNECTED, 'Projector status should be NOT CONNECTED') |
1746 | - self.assertEqual(pjlink.status_connect, E_NOT_CONNECTED, 'Status connect should be NOT CONNECTED') |
1747 | - mock_change_status.emit.assert_called_once_with(pjlink.ip, E_UNKNOWN_SOCKET_ERROR, |
1748 | - 'An unidentified error occurred') |
1749 | - self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
1750 | - |
1751 | - @patch.object(pjlink_test, 'changeStatus') |
1752 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1753 | - def test_projector_change_status_connection_status_connecting(self, mock_log, mock_change_status): |
1754 | - """ |
1755 | - Test change_status with connection status |
1756 | - """ |
1757 | - # GIVEN: Test object |
1758 | - pjlink = pjlink_test |
1759 | - pjlink.projector_status = 0 |
1760 | - pjlink.status_connect = 0 |
1761 | - test_code = S_CONNECTING |
1762 | - mock_change_status.reset_mock() |
1763 | - mock_log.reset_mock() |
1764 | - |
1765 | - # WHEN: change_status called with unknown socket error |
1766 | - pjlink.change_status(status=test_code, msg=None) |
1767 | - |
1768 | - # THEN: Proper settings should change and signals sent |
1769 | - self.assertEqual(pjlink.projector_status, S_NOT_CONNECTED, 'Projector status should be NOT CONNECTED') |
1770 | - self.assertEqual(pjlink.status_connect, S_CONNECTING, 'Status connect should be CONNECTING') |
1771 | - mock_change_status.emit.assert_called_once_with(pjlink.ip, S_CONNECTING, 'Connecting') |
1772 | - self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
1773 | - |
1774 | - @patch.object(pjlink_test, 'changeStatus') |
1775 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1776 | - def test_projector_change_status_connection_status_connected(self, mock_log, mock_change_status): |
1777 | - """ |
1778 | - Test change_status with connection status |
1779 | - """ |
1780 | - # GIVEN: Test object |
1781 | - pjlink = pjlink_test |
1782 | - pjlink.projector_status = 0 |
1783 | - pjlink.status_connect = 0 |
1784 | - test_code = S_ON |
1785 | - mock_change_status.reset_mock() |
1786 | - mock_log.reset_mock() |
1787 | - |
1788 | - # WHEN: change_status called with unknown socket error |
1789 | - pjlink.change_status(status=test_code, msg=None) |
1790 | - |
1791 | - # THEN: Proper settings should change and signals sent |
1792 | - self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') |
1793 | - self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') |
1794 | - mock_change_status.emit.assert_called_once_with(pjlink.ip, S_ON, 'Power is on') |
1795 | - self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
1796 | - |
1797 | - @patch.object(pjlink_test, 'changeStatus') |
1798 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1799 | - def test_projector_change_status_connection_status_with_message(self, mock_log, mock_change_status): |
1800 | - """ |
1801 | - Test change_status with connection status |
1802 | - """ |
1803 | - # GIVEN: Test object |
1804 | - pjlink = pjlink_test |
1805 | - pjlink.projector_status = 0 |
1806 | - pjlink.status_connect = 0 |
1807 | + log_debug_calls = [ |
1808 | + call('(111.111.111.111) Changing status to ' |
1809 | + '{status} "{msg}"'.format(status=STATUS_CODE[E_UNKNOWN_SOCKET_ERROR], |
1810 | + msg=STATUS_MSG[E_UNKNOWN_SOCKET_ERROR])), |
1811 | + call('(111.111.111.111) status_connect: ' |
1812 | + '{code}: "{msg}"'.format(code=STATUS_CODE[E_NOT_CONNECTED], |
1813 | + msg=STATUS_MSG[E_NOT_CONNECTED])), |
1814 | + call('(111.111.111.111) projector_status: ' |
1815 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1816 | + msg=STATUS_MSG[S_OK])), |
1817 | + call('(111.111.111.111) error_status: ' |
1818 | + '{code}: "{msg}"'.format(code=STATUS_CODE[E_UNKNOWN_SOCKET_ERROR], |
1819 | + msg=STATUS_MSG[E_UNKNOWN_SOCKET_ERROR]))] |
1820 | + |
1821 | + # GIVEN: Test object and mocks |
1822 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1823 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus, \ |
1824 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
1825 | + |
1826 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1827 | + pjlink.projector_status = 0 |
1828 | + pjlink.status_connect = 0 |
1829 | + |
1830 | + # WHEN: change_status called with unknown socket error |
1831 | + pjlink.change_status(status=E_UNKNOWN_SOCKET_ERROR) |
1832 | + |
1833 | + # THEN: Proper settings should change and signals sent |
1834 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1835 | + self.assertEqual(pjlink.projector_status, S_OK, 'Projector status should not have changed') |
1836 | + self.assertEqual(pjlink.status_connect, E_NOT_CONNECTED, |
1837 | + 'Status connect should be NOT CONNECTED') |
1838 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Should have called UpdateIcons') |
1839 | + mock_changeStatus.emit.assert_called_once_with(pjlink.ip, E_UNKNOWN_SOCKET_ERROR, |
1840 | + STATUS_MSG[E_UNKNOWN_SOCKET_ERROR]) |
1841 | + |
1842 | + def test_projector_change_status_connection_status_connecting(self): |
1843 | + """ |
1844 | + Test change_status with connecting status |
1845 | + """ |
1846 | + log_debug_calls = [ |
1847 | + call('(111.111.111.111) Changing status to ' |
1848 | + '{status} "{msg}"'.format(status=STATUS_CODE[S_CONNECTING], |
1849 | + msg=STATUS_MSG[S_CONNECTING])), |
1850 | + call('(111.111.111.111) status_connect: ' |
1851 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_CONNECTING], |
1852 | + msg=STATUS_MSG[S_CONNECTING])), |
1853 | + call('(111.111.111.111) projector_status: ' |
1854 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1855 | + msg=STATUS_MSG[S_OK])), |
1856 | + call('(111.111.111.111) error_status: ' |
1857 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1858 | + msg=STATUS_MSG[S_OK]))] |
1859 | + |
1860 | + # GIVEN: Test object and mocks |
1861 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1862 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus, \ |
1863 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
1864 | + |
1865 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1866 | + pjlink.projector_status = 0 |
1867 | + pjlink.status_connect = 0 |
1868 | + |
1869 | + # WHEN: change_status called with CONNECTING |
1870 | + pjlink.change_status(status=S_CONNECTING) |
1871 | + |
1872 | + # THEN: Proper settings should change and signals sent |
1873 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1874 | + self.assertEqual(pjlink.projector_status, S_OK, 'Projector status should not have changed') |
1875 | + self.assertEqual(pjlink.status_connect, S_CONNECTING, 'Status connect should be CONNECTING') |
1876 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Should have called UpdateIcons') |
1877 | + mock_changeStatus.emit.assert_called_once_with(pjlink.ip, S_CONNECTING, STATUS_MSG[S_CONNECTING]) |
1878 | + |
1879 | + def test_projector_change_status_connection_status_connected(self): |
1880 | + """ |
1881 | + Test change_status with connected status |
1882 | + """ |
1883 | + log_debug_calls = [ |
1884 | + call('(111.111.111.111) Changing status to ' |
1885 | + '{status} "{msg}"'.format(status=STATUS_CODE[S_CONNECTED], |
1886 | + msg=STATUS_MSG[S_CONNECTED])), |
1887 | + call('(111.111.111.111) status_connect: ' |
1888 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_CONNECTED], |
1889 | + msg=STATUS_MSG[S_CONNECTED])), |
1890 | + call('(111.111.111.111) projector_status: ' |
1891 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1892 | + msg=STATUS_MSG[S_OK])), |
1893 | + call('(111.111.111.111) error_status: ' |
1894 | + '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1895 | + msg=STATUS_MSG[S_OK]))] |
1896 | + |
1897 | + # GIVEN: Test object and mocks |
1898 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1899 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus: |
1900 | + |
1901 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1902 | + pjlink.projector_status = 0 |
1903 | + pjlink.status_connect = 0 |
1904 | + |
1905 | + # WHEN: change_status called with CONNECTED |
1906 | + pjlink.change_status(status=S_CONNECTED) |
1907 | + |
1908 | + # THEN: Proper settings should change and signals sent |
1909 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1910 | + self.assertEqual(pjlink.projector_status, S_OK, 'Projector status should not have changed') |
1911 | + self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') |
1912 | + mock_changeStatus.emit.assert_called_once_with(pjlink.ip, S_CONNECTED, 'Connected') |
1913 | + |
1914 | + def test_projector_change_status_connection_status_with_message(self): |
1915 | + """ |
1916 | + Test change_status with connection status |
1917 | + """ |
1918 | test_message = 'Different Status Message than default' |
1919 | - test_code = S_ON |
1920 | - mock_change_status.reset_mock() |
1921 | - mock_log.reset_mock() |
1922 | - |
1923 | - # WHEN: change_status called with unknown socket error |
1924 | - pjlink.change_status(status=test_code, msg=test_message) |
1925 | - |
1926 | - # THEN: Proper settings should change and signals sent |
1927 | - self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') |
1928 | - self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') |
1929 | - mock_change_status.emit.assert_called_once_with(pjlink.ip, S_ON, test_message) |
1930 | - self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
1931 | - |
1932 | - @patch.object(pjlink_test, 'send_command') |
1933 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1934 | - def test_projector_get_av_mute_status(self, mock_log, mock_send_command): |
1935 | + log_debug_calls = [ |
1936 | + call('(111.111.111.111) Changing status to {status} "{msg}"'.format(status=STATUS_CODE[S_ON], |
1937 | + msg=test_message)), |
1938 | + call('(111.111.111.111) status_connect: {code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1939 | + msg=test_message)), |
1940 | + call('(111.111.111.111) projector_status: {code}: "{msg}"'.format(code=STATUS_CODE[S_ON], |
1941 | + msg=test_message)), |
1942 | + call('(111.111.111.111) error_status: {code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1943 | + msg=test_message))] |
1944 | + |
1945 | + # GIVEN: Test object and mocks |
1946 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1947 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus: |
1948 | + |
1949 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1950 | + pjlink.projector_status = 0 |
1951 | + pjlink.status_connect = 0 |
1952 | + |
1953 | + # WHEN: change_status called with projector ON status |
1954 | + pjlink.change_status(status=S_ON, msg=test_message) |
1955 | + |
1956 | + # THEN: Proper settings should change and signals sent |
1957 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1958 | + self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') |
1959 | + self.assertEqual(pjlink.status_connect, S_OK, 'Status connect should not have changed') |
1960 | + mock_changeStatus.emit.assert_called_once_with(pjlink.ip, S_ON, test_message) |
1961 | + |
1962 | + def test_projector_get_av_mute_status(self): |
1963 | """ |
1964 | Test sending command to retrieve shutter/audio state |
1965 | """ |
1966 | - # GIVEN: Test object |
1967 | - pjlink = pjlink_test |
1968 | - mock_log.reset_mock() |
1969 | - mock_send_command.reset_mock() |
1970 | test_data = 'AVMT' |
1971 | - test_log = '(127.0.0.1) Sending AVMT command' |
1972 | - |
1973 | - # WHEN: get_av_mute_status is called |
1974 | - pjlink.get_av_mute_status() |
1975 | - |
1976 | - # THEN: log data and send_command should have been called |
1977 | - mock_log.debug.assert_called_once_with(test_log) |
1978 | - mock_send_command.assert_called_once_with(cmd=test_data) |
1979 | - |
1980 | - @patch.object(pjlink_test, 'send_command') |
1981 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
1982 | - def test_projector_get_available_inputs(self, mock_log, mock_send_command): |
1983 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
1984 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
1985 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
1986 | + |
1987 | + # GIVEN: Test object and mocks |
1988 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1989 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
1990 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1991 | + |
1992 | + # WHEN: get_av_mute_status is called |
1993 | + pjlink.get_av_mute_status() |
1994 | + |
1995 | + # THEN: log data and send_command should have been called |
1996 | + mock_log.debug.assert_has_calls(log_debug_calls) |
1997 | + mock_send_command.assert_called_once_with(cmd=test_data) |
1998 | + |
1999 | + def test_projector_get_available_inputs(self): |
2000 | """ |
2001 | Test sending command to retrieve avaliable inputs |
2002 | """ |
2003 | - # GIVEN: Test object |
2004 | - pjlink = pjlink_test |
2005 | - mock_log.reset_mock() |
2006 | - mock_send_command.reset_mock() |
2007 | test_data = 'INST' |
2008 | - test_log = '(127.0.0.1) Sending INST command' |
2009 | - |
2010 | - # WHEN: get_available_inputs is called |
2011 | - pjlink.get_available_inputs() |
2012 | - |
2013 | - # THEN: log data and send_command should have been called |
2014 | - mock_log.debug.assert_called_once_with(test_log) |
2015 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2016 | - |
2017 | - @patch.object(pjlink_test, 'send_command') |
2018 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2019 | - def test_projector_get_error_status(self, mock_log, mock_send_command): |
2020 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2021 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2022 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2023 | + |
2024 | + # GIVEN: Test object and mocks |
2025 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2026 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2027 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2028 | + |
2029 | + # WHEN: get_available_inputs is called |
2030 | + pjlink.get_available_inputs() |
2031 | + |
2032 | + # THEN: log data and send_command should have been called |
2033 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2034 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2035 | + |
2036 | + def test_projector_get_error_status(self): |
2037 | """ |
2038 | Test sending command to retrieve projector error status |
2039 | """ |
2040 | - # GIVEN: Test object |
2041 | - pjlink = pjlink_test |
2042 | - mock_log.reset_mock() |
2043 | - mock_send_command.reset_mock() |
2044 | test_data = 'ERST' |
2045 | - test_log = '(127.0.0.1) Sending ERST command' |
2046 | - |
2047 | - # WHEN: get_error_status is called |
2048 | - pjlink.get_error_status() |
2049 | - |
2050 | - # THEN: log data and send_command should have been called |
2051 | - mock_log.debug.assert_called_once_with(test_log) |
2052 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2053 | - |
2054 | - @patch.object(pjlink_test, 'send_command') |
2055 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2056 | - def test_projector_get_input_source(self, mock_log, mock_send_command): |
2057 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2058 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2059 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2060 | + # GIVEN: Test object and mocks |
2061 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2062 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2063 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2064 | + |
2065 | + # WHEN: get_error_status is called |
2066 | + pjlink.get_error_status() |
2067 | + |
2068 | + # THEN: log data and send_command should have been called |
2069 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2070 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2071 | + |
2072 | + def test_projector_get_input_source(self): |
2073 | """ |
2074 | Test sending command to retrieve current input |
2075 | """ |
2076 | - # GIVEN: Test object |
2077 | - pjlink = pjlink_test |
2078 | - mock_log.reset_mock() |
2079 | - mock_send_command.reset_mock() |
2080 | test_data = 'INPT' |
2081 | - test_log = '(127.0.0.1) Sending INPT command' |
2082 | - |
2083 | - # WHEN: get_input_source is called |
2084 | - pjlink.get_input_source() |
2085 | - |
2086 | - # THEN: log data and send_command should have been called |
2087 | - mock_log.debug.assert_called_once_with(test_log) |
2088 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2089 | - |
2090 | - @patch.object(pjlink_test, 'send_command') |
2091 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2092 | - def test_projector_get_lamp_status(self, mock_log, mock_send_command): |
2093 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2094 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2095 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2096 | + |
2097 | + # GIVEN: Test object and mocks |
2098 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2099 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2100 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2101 | + |
2102 | + # WHEN: get_input_source is called |
2103 | + pjlink.get_input_source() |
2104 | + |
2105 | + # THEN: log data and send_command should have been called |
2106 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2107 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2108 | + |
2109 | + def test_projector_get_lamp_status(self): |
2110 | """ |
2111 | Test sending command to retrieve lamp(s) status |
2112 | """ |
2113 | - # GIVEN: Test object |
2114 | - pjlink = pjlink_test |
2115 | - mock_log.reset_mock() |
2116 | - mock_send_command.reset_mock() |
2117 | test_data = 'LAMP' |
2118 | - test_log = '(127.0.0.1) Sending LAMP command' |
2119 | - |
2120 | - # WHEN: get_lamp_status is called |
2121 | - pjlink.get_lamp_status() |
2122 | - |
2123 | - # THEN: log data and send_command should have been called |
2124 | - mock_log.debug.assert_called_once_with(test_log) |
2125 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2126 | - |
2127 | - @patch.object(pjlink_test, 'send_command') |
2128 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2129 | - def test_projector_get_manufacturer(self, mock_log, mock_send_command): |
2130 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2131 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2132 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2133 | + |
2134 | + # GIVEN: Test object and mocks |
2135 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2136 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2137 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2138 | + |
2139 | + # WHEN: get_input_source is called |
2140 | + pjlink.get_lamp_status() |
2141 | + |
2142 | + # THEN: log data and send_command should have been called |
2143 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2144 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2145 | + |
2146 | + def test_projector_get_manufacturer(self): |
2147 | """ |
2148 | Test sending command to retrieve manufacturer name |
2149 | """ |
2150 | - # GIVEN: Test object |
2151 | - pjlink = pjlink_test |
2152 | - mock_log.reset_mock() |
2153 | - mock_send_command.reset_mock() |
2154 | test_data = 'INF1' |
2155 | - test_log = '(127.0.0.1) Sending INF1 command' |
2156 | - |
2157 | - # WHEN: get_manufacturer is called |
2158 | - pjlink.get_manufacturer() |
2159 | - |
2160 | - # THEN: log data and send_command should have been called |
2161 | - mock_log.debug.assert_called_once_with(test_log) |
2162 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2163 | - |
2164 | - @patch.object(pjlink_test, 'send_command') |
2165 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2166 | - def test_projector_get_model(self, mock_log, mock_send_command): |
2167 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2168 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2169 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2170 | + |
2171 | + # GIVEN: Test object and mocks |
2172 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2173 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2174 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2175 | + |
2176 | + # WHEN: get_input_source is called |
2177 | + pjlink.get_manufacturer() |
2178 | + |
2179 | + # THEN: log data and send_command should have been called |
2180 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2181 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2182 | + |
2183 | + def test_projector_get_model(self): |
2184 | """ |
2185 | Test sending command to get model information |
2186 | """ |
2187 | - # GIVEN: Test object |
2188 | - pjlink = pjlink_test |
2189 | - mock_log.reset_mock() |
2190 | - mock_send_command.reset_mock() |
2191 | test_data = 'INF2' |
2192 | - test_log = '(127.0.0.1) Sending INF2 command' |
2193 | - |
2194 | - # WHEN: get_model is called |
2195 | - pjlink.get_model() |
2196 | - |
2197 | - # THEN: log data and send_command should have been called |
2198 | - mock_log.debug.assert_called_once_with(test_log) |
2199 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2200 | - |
2201 | - @patch.object(pjlink_test, 'send_command') |
2202 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2203 | - def test_projector_get_name(self, mock_log, mock_send_command): |
2204 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2205 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2206 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2207 | + |
2208 | + # GIVEN: Test object and mocks |
2209 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2210 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2211 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2212 | + |
2213 | + # WHEN: get_input_source is called |
2214 | + pjlink.get_model() |
2215 | + |
2216 | + # THEN: log data and send_command should have been called |
2217 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2218 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2219 | + |
2220 | + def test_projector_get_name(self): |
2221 | """ |
2222 | Test sending command to get user-assigned name |
2223 | """ |
2224 | - # GIVEN: Test object |
2225 | - pjlink = pjlink_test |
2226 | - mock_log.reset_mock() |
2227 | - mock_send_command.reset_mock() |
2228 | test_data = 'NAME' |
2229 | - test_log = '(127.0.0.1) Sending NAME command' |
2230 | - |
2231 | - # WHEN: get_name is called |
2232 | - pjlink.get_name() |
2233 | - |
2234 | - # THEN: log data and send_command should have been called |
2235 | - mock_log.debug.assert_called_once_with(test_log) |
2236 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2237 | - |
2238 | - @patch.object(pjlink_test, 'send_command') |
2239 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2240 | - def test_projector_get_other_info(self, mock_log, mock_send_command): |
2241 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2242 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2243 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2244 | + |
2245 | + # GIVEN: Test object and mocks |
2246 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2247 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2248 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2249 | + |
2250 | + # WHEN: get_input_source is called |
2251 | + pjlink.get_name() |
2252 | + |
2253 | + # THEN: log data and send_command should have been called |
2254 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2255 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2256 | + |
2257 | + def test_projector_get_other_info(self): |
2258 | """ |
2259 | Test sending command to retrieve other information |
2260 | """ |
2261 | - # GIVEN: Test object |
2262 | - pjlink = pjlink_test |
2263 | - mock_log.reset_mock() |
2264 | - mock_send_command.reset_mock() |
2265 | test_data = 'INFO' |
2266 | - test_log = '(127.0.0.1) Sending INFO command' |
2267 | - |
2268 | - # WHEN: get_other_info is called |
2269 | - pjlink.get_other_info() |
2270 | - |
2271 | - # THEN: log data and send_command should have been called |
2272 | - mock_log.debug.assert_called_once_with(test_log) |
2273 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2274 | - |
2275 | - @patch.object(pjlink_test, 'send_command') |
2276 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2277 | - def test_projector_get_power_status(self, mock_log, mock_send_command): |
2278 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2279 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2280 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2281 | + |
2282 | + # GIVEN: Test object and mocks |
2283 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2284 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2285 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2286 | + |
2287 | + # WHEN: get_input_source is called |
2288 | + pjlink.get_other_info() |
2289 | + |
2290 | + # THEN: log data and send_command should have been called |
2291 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2292 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2293 | + |
2294 | + def test_projector_get_power_status(self): |
2295 | """ |
2296 | Test sending command to retrieve current power state |
2297 | """ |
2298 | - # GIVEN: Test object |
2299 | - pjlink = pjlink_test |
2300 | - mock_log.reset_mock() |
2301 | - mock_send_command.reset_mock() |
2302 | test_data = 'POWR' |
2303 | - test_log = '(127.0.0.1) Sending POWR command' |
2304 | - |
2305 | - # WHEN: get_power_status called |
2306 | - pjlink.get_power_status() |
2307 | - |
2308 | - # THEN: log data and send_command should have been called |
2309 | - mock_log.debug.assert_called_once_with(test_log) |
2310 | - mock_send_command.assert_called_once_with(cmd=test_data) |
2311 | - |
2312 | - def test_projector_get_status_error(self): |
2313 | - """ |
2314 | - Test to check returned information for error code |
2315 | - """ |
2316 | - # GIVEN: Test object |
2317 | - pjlink = pjlink_test |
2318 | - test_string = 'E_SOCKET_ADDRESS_NOT_AVAILABLE' |
2319 | - test_message = 'The address specified to socket.bind() does not belong to the host' |
2320 | - |
2321 | - # WHEN: get_status called |
2322 | - string, message = pjlink._get_status(status=E_SOCKET_ADDRESS_NOT_AVAILABLE) |
2323 | - |
2324 | - # THEN: Proper strings should have been returned |
2325 | - self.assertEqual(string, test_string, 'Code as string should have been returned') |
2326 | - self.assertEqual(message, test_message, 'Description of code should have been returned') |
2327 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2328 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2329 | + call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2330 | + |
2331 | + # GIVEN: Test object and mocks |
2332 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2333 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2334 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2335 | + |
2336 | + # WHEN: get_input_source is called |
2337 | + pjlink.get_power_status() |
2338 | + |
2339 | + # THEN: log data and send_command should have been called |
2340 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2341 | + mock_send_command.assert_called_once_with(cmd=test_data) |
2342 | |
2343 | def test_projector_get_status_invalid(self): |
2344 | """ |
2345 | Test to check returned information for error code |
2346 | """ |
2347 | # GIVEN: Test object |
2348 | - pjlink = pjlink_test |
2349 | - test_string = 'Test string since get_status will only work with int' |
2350 | - test_message = 'Invalid status code' |
2351 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2352 | + test_string = 'NaN test' |
2353 | |
2354 | # WHEN: get_status called |
2355 | - string, message = pjlink._get_status(status=test_string) |
2356 | - |
2357 | - # THEN: Proper strings should have been returned |
2358 | - self.assertEqual(string, -1, 'Should have returned -1 as a bad status check') |
2359 | - self.assertEqual(message, test_message, 'Error message should have been returned') |
2360 | - |
2361 | - def test_projector_get_status_status(self): |
2362 | + code, message = pjlink._get_status(status=test_string) |
2363 | + |
2364 | + # THEN: Proper data should have been returned |
2365 | + self.assertEqual(code, -1, 'Should have returned -1 as a bad status check') |
2366 | + self.assertIsNone(message, 'Invalid code type should have returned None for message') |
2367 | + |
2368 | + def test_projector_get_status_valid(self): |
2369 | """ |
2370 | Test to check returned information for status codes |
2371 | """ |
2372 | # GIVEN: Test object |
2373 | - pjlink = pjlink_test |
2374 | - test_string = 'S_NOT_CONNECTED' |
2375 | - test_message = 'Not connected' |
2376 | + test_message = 'Not Connected' |
2377 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2378 | |
2379 | # WHEN: get_status called |
2380 | - string, message = pjlink._get_status(status=S_NOT_CONNECTED) |
2381 | + code, message = pjlink._get_status(status=S_NOT_CONNECTED) |
2382 | |
2383 | # THEN: Proper strings should have been returned |
2384 | - self.assertEqual(string, test_string, 'Code as string should have been returned') |
2385 | + self.assertEqual(code, 'S_NOT_CONNECTED', 'Code returned should have been the same code that was sent') |
2386 | self.assertEqual(message, test_message, 'Description of code should have been returned') |
2387 | |
2388 | def test_projector_get_status_unknown(self): |
2389 | @@ -396,25 +426,24 @@ |
2390 | Test to check returned information for unknown code |
2391 | """ |
2392 | # GIVEN: Test object |
2393 | - pjlink = pjlink_test |
2394 | - test_string = 999999 |
2395 | - test_message = 'Unknown status' |
2396 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2397 | |
2398 | # WHEN: get_status called |
2399 | - string, message = pjlink._get_status(status=test_string) |
2400 | + code, message = pjlink._get_status(status=9999) |
2401 | |
2402 | # THEN: Proper strings should have been returned |
2403 | - self.assertEqual(string, test_string, 'Received code should have been returned') |
2404 | - self.assertEqual(message, test_message, 'Unknown status string should have been returned') |
2405 | + self.assertIsNone(code, 'Code returned should have been the same code that was sent') |
2406 | + self.assertIsNone(message, 'Should have returned None as message') |
2407 | |
2408 | def test_projector_process_inf1(self): |
2409 | """ |
2410 | Test saving INF1 data (manufacturer) |
2411 | """ |
2412 | + test_data = 'TEst INformation MultiCase' |
2413 | + |
2414 | # GIVEN: Test object |
2415 | - pjlink = pjlink_test |
2416 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2417 | pjlink.manufacturer = None |
2418 | - test_data = 'TEst INformation MultiCase' |
2419 | |
2420 | # WHEN: process_inf called with test data |
2421 | pjlink.process_inf1(data=test_data) |
2422 | @@ -426,10 +455,11 @@ |
2423 | """ |
2424 | Test saving INF2 data (model) |
2425 | """ |
2426 | + test_data = 'TEst moDEl MultiCase' |
2427 | + |
2428 | # GIVEN: Test object |
2429 | - pjlink = pjlink_test |
2430 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2431 | pjlink.model = None |
2432 | - test_data = 'TEst moDEl MultiCase' |
2433 | |
2434 | # WHEN: process_inf called with test data |
2435 | pjlink.process_inf2(data=test_data) |
2436 | @@ -441,10 +471,11 @@ |
2437 | """ |
2438 | Test saving INFO data (other information) |
2439 | """ |
2440 | + test_data = 'TEst ExtrANEous MultiCase INformatoin that MFGR might Set' |
2441 | + |
2442 | # GIVEN: Test object |
2443 | - pjlink = pjlink_test |
2444 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2445 | pjlink.other_info = None |
2446 | - test_data = 'TEst ExtrANEous MultiCase INformatoin that MFGR might Set' |
2447 | |
2448 | # WHEN: process_inf called with test data |
2449 | pjlink.process_info(data=test_data) |
2450 | @@ -452,509 +483,558 @@ |
2451 | # THEN: Data should be saved |
2452 | self.assertEqual(pjlink.other_info, test_data, 'Test data should have been saved') |
2453 | |
2454 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
2455 | - def test_projector_process_avmt_bad_data(self, mock_UpdateIcons): |
2456 | + def test_projector_process_avmt_bad_data(self): |
2457 | """ |
2458 | Test avmt bad data fail |
2459 | """ |
2460 | # GIVEN: Test object |
2461 | - pjlink = pjlink_test |
2462 | - pjlink.shutter = True |
2463 | - pjlink.mute = True |
2464 | - |
2465 | - # WHEN: Called with an invalid setting |
2466 | - pjlink.process_avmt('36') |
2467 | - |
2468 | - # THEN: Shutter should be closed and mute should be True |
2469 | - self.assertTrue(pjlink.shutter, 'Shutter should changed') |
2470 | - self.assertTrue(pjlink.mute, 'Audio should not have changed') |
2471 | - self.assertFalse(mock_UpdateIcons.emit.called, 'Update icons should NOT have been called') |
2472 | - |
2473 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
2474 | - def test_projector_process_avmt_closed_muted(self, mock_UpdateIcons): |
2475 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2476 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2477 | + pjlink.shutter = True |
2478 | + pjlink.mute = True |
2479 | + |
2480 | + # WHEN: Called with an invalid setting |
2481 | + pjlink.process_avmt('36') |
2482 | + |
2483 | + # THEN: Shutter should be closed and mute should be True |
2484 | + self.assertTrue(pjlink.shutter, 'Shutter should changed') |
2485 | + self.assertTrue(pjlink.mute, 'Audio should not have changed') |
2486 | + self.assertFalse(mock_UpdateIcons.emit.called, 'Update icons should NOT have been called') |
2487 | + |
2488 | + def test_projector_process_avmt_closed_muted(self): |
2489 | """ |
2490 | Test avmt status shutter closed and mute off |
2491 | """ |
2492 | # GIVEN: Test object |
2493 | - pjlink = pjlink_test |
2494 | - pjlink.shutter = False |
2495 | - pjlink.mute = False |
2496 | - |
2497 | - # WHEN: Called with setting shutter to closed and mute on |
2498 | - pjlink.process_avmt('31') |
2499 | - |
2500 | - # THEN: Shutter should be closed and mute should be True |
2501 | - self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed') |
2502 | - self.assertTrue(pjlink.mute, 'Audio should be muted') |
2503 | - self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2504 | - |
2505 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
2506 | - def test_projector_process_avmt_shutter_closed(self, mock_UpdateIcons): |
2507 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2508 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2509 | + pjlink.shutter = False |
2510 | + pjlink.mute = False |
2511 | + |
2512 | + # WHEN: Called with setting shutter to closed and mute on |
2513 | + pjlink.process_avmt('31') |
2514 | + |
2515 | + # THEN: Shutter should be closed and mute should be True |
2516 | + self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed') |
2517 | + self.assertTrue(pjlink.mute, 'Audio should be muted') |
2518 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2519 | + |
2520 | + def test_projector_process_avmt_shutter_closed(self): |
2521 | """ |
2522 | Test avmt status shutter closed and audio unchanged |
2523 | """ |
2524 | # GIVEN: Test object |
2525 | - pjlink = pjlink_test |
2526 | - pjlink.shutter = False |
2527 | - pjlink.mute = True |
2528 | - |
2529 | - # WHEN: Called with setting shutter closed and mute off |
2530 | - pjlink.process_avmt('11') |
2531 | - |
2532 | - # THEN: Shutter should be True and mute should be False |
2533 | - self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed') |
2534 | - self.assertTrue(pjlink.mute, 'Audio should not have changed') |
2535 | - self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2536 | - |
2537 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
2538 | - def test_projector_process_avmt_audio_muted(self, mock_UpdateIcons): |
2539 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2540 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2541 | + pjlink.shutter = False |
2542 | + pjlink.mute = True |
2543 | + |
2544 | + # WHEN: Called with setting shutter closed and mute off |
2545 | + pjlink.process_avmt('11') |
2546 | + |
2547 | + # THEN: Shutter should be True and mute should be False |
2548 | + self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed') |
2549 | + self.assertTrue(pjlink.mute, 'Audio should not have changed') |
2550 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2551 | + |
2552 | + def test_projector_process_avmt_audio_muted(self): |
2553 | """ |
2554 | Test avmt status shutter unchanged and mute on |
2555 | """ |
2556 | # GIVEN: Test object |
2557 | - pjlink = pjlink_test |
2558 | - pjlink.shutter = True |
2559 | - pjlink.mute = False |
2560 | - |
2561 | - # WHEN: Called with setting shutter closed and mute on |
2562 | - pjlink.process_avmt('21') |
2563 | - |
2564 | - # THEN: Shutter should be closed and mute should be True |
2565 | - self.assertTrue(pjlink.shutter, 'Shutter should not have changed') |
2566 | - self.assertTrue(pjlink.mute, 'Audio should be off') |
2567 | - self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2568 | - |
2569 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
2570 | - def test_projector_process_avmt_open_unmuted(self, mock_UpdateIcons): |
2571 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2572 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2573 | + pjlink.shutter = True |
2574 | + pjlink.mute = False |
2575 | + |
2576 | + # WHEN: Called with setting shutter closed and mute on |
2577 | + pjlink.process_avmt('21') |
2578 | + |
2579 | + # THEN: Shutter should be closed and mute should be True |
2580 | + self.assertTrue(pjlink.shutter, 'Shutter should not have changed') |
2581 | + self.assertTrue(pjlink.mute, 'Audio should be off') |
2582 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2583 | + |
2584 | + def test_projector_process_avmt_open_unmuted(self): |
2585 | """ |
2586 | Test avmt status shutter open and mute off |
2587 | """ |
2588 | # GIVEN: Test object |
2589 | - pjlink = pjlink_test |
2590 | - pjlink.shutter = True |
2591 | - pjlink.mute = True |
2592 | - |
2593 | - # WHEN: Called with setting shutter to closed and mute on |
2594 | - pjlink.process_avmt('30') |
2595 | - |
2596 | - # THEN: Shutter should be closed and mute should be True |
2597 | - self.assertFalse(pjlink.shutter, 'Shutter should have been set to open') |
2598 | - self.assertFalse(pjlink.mute, 'Audio should be on') |
2599 | - self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2600 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2601 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2602 | + pjlink.shutter = True |
2603 | + pjlink.mute = True |
2604 | + |
2605 | + # WHEN: Called with setting shutter to closed and mute on |
2606 | + pjlink.process_avmt('30') |
2607 | + |
2608 | + # THEN: Shutter should be closed and mute should be True |
2609 | + self.assertFalse(pjlink.shutter, 'Shutter should have been set to open') |
2610 | + self.assertFalse(pjlink.mute, 'Audio should be on') |
2611 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') |
2612 | |
2613 | def test_projector_process_clss_one(self): |
2614 | """ |
2615 | Test class 1 sent from projector |
2616 | """ |
2617 | # GIVEN: Test object |
2618 | - pjlink = pjlink_test |
2619 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2620 | |
2621 | # WHEN: Process class response |
2622 | pjlink.process_clss('1') |
2623 | |
2624 | # THEN: Projector class should be set to 1 |
2625 | - self.assertEqual(pjlink.pjlink_class, '1', |
2626 | - 'Projector should have set class=1') |
2627 | + self.assertEqual(pjlink.pjlink_class, '1', 'Projector should have set class=1') |
2628 | |
2629 | def test_projector_process_clss_two(self): |
2630 | """ |
2631 | Test class 2 sent from projector |
2632 | """ |
2633 | # GIVEN: Test object |
2634 | - pjlink = pjlink_test |
2635 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2636 | |
2637 | # WHEN: Process class response |
2638 | pjlink.process_clss('2') |
2639 | |
2640 | # THEN: Projector class should be set to 1 |
2641 | - self.assertEqual(pjlink.pjlink_class, '2', |
2642 | - 'Projector should have set class=2') |
2643 | - |
2644 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2645 | - def test_projector_process_clss_invalid_nan(self, mock_log): |
2646 | - """ |
2647 | - Test CLSS reply has no class number |
2648 | - """ |
2649 | - # GIVEN: Test object |
2650 | - pjlink = pjlink_test |
2651 | - |
2652 | - # WHEN: Process invalid reply |
2653 | - pjlink.process_clss('Z') |
2654 | - log_text = '(127.0.0.1) NAN CLSS version reply "Z" - defaulting to class "1"' |
2655 | - |
2656 | - # THEN: Projector class should be set with default value |
2657 | - self.assertEqual(pjlink.pjlink_class, '1', |
2658 | - 'Non-standard class reply should have set class=1') |
2659 | - mock_log.error.assert_called_once_with(log_text) |
2660 | - |
2661 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2662 | - def test_projector_process_clss_invalid_no_version(self, mock_log): |
2663 | - """ |
2664 | - Test CLSS reply has no class number |
2665 | - """ |
2666 | - # GIVEN: Test object |
2667 | - pjlink = pjlink_test |
2668 | - |
2669 | - # WHEN: Process invalid reply |
2670 | - pjlink.process_clss('Invalid') |
2671 | - log_text = '(127.0.0.1) No numbers found in class version reply "Invalid" - defaulting to class "1"' |
2672 | - |
2673 | - # THEN: Projector class should be set with default value |
2674 | - self.assertEqual(pjlink.pjlink_class, '1', |
2675 | - 'Non-standard class reply should have set class=1') |
2676 | - mock_log.error.assert_called_once_with(log_text) |
2677 | + self.assertEqual(pjlink.pjlink_class, '2', 'Projector should have set class=2') |
2678 | + |
2679 | + def test_projector_process_clss_invalid_nan(self): |
2680 | + """ |
2681 | + Test CLSS reply has no class number |
2682 | + """ |
2683 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2684 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2685 | + call('(111.111.111.111) Setting pjlink_class for this projector to "1"')] |
2686 | + log_error_calls = [call('(111.111.111.111) NAN CLSS version reply "Z" - defaulting to class "1"')] |
2687 | + |
2688 | + # GIVEN: Test object |
2689 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2690 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2691 | + |
2692 | + # WHEN: Process invalid reply |
2693 | + pjlink.process_clss('Z') |
2694 | + |
2695 | + # THEN: Projector class should be set with default value |
2696 | + self.assertEqual(pjlink.pjlink_class, '1', 'Invalid NaN class reply should have set class=1') |
2697 | + mock_log.error.assert_has_calls(log_error_calls) |
2698 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2699 | + |
2700 | + def test_projector_process_clss_invalid_no_version(self): |
2701 | + """ |
2702 | + Test CLSS reply has no class number |
2703 | + """ |
2704 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2705 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2706 | + call('(111.111.111.111) Setting pjlink_class for this projector to "1"')] |
2707 | + log_error_calls = [call('(111.111.111.111) No numbers found in class version reply "Invalid" ' |
2708 | + '- defaulting to class "1"')] |
2709 | + |
2710 | + # GIVEN: Test object |
2711 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2712 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2713 | + |
2714 | + # WHEN: Process invalid reply |
2715 | + pjlink.process_clss('Invalid') |
2716 | + |
2717 | + # THEN: Projector class should be set with default value |
2718 | + self.assertEqual(pjlink.pjlink_class, '1', 'Invalid class reply should have set class=1') |
2719 | + mock_log.error.assert_has_calls(log_error_calls) |
2720 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2721 | |
2722 | def test_projector_process_erst_all_ok(self): |
2723 | """ |
2724 | - Test test_projector_process_erst_all_ok |
2725 | + Test to verify pjlink.projector_errors is set to None when no errors |
2726 | """ |
2727 | + chk_data = '0' * PJLINK_ERST_DATA['DATA_LENGTH'] |
2728 | + |
2729 | # GIVEN: Test object |
2730 | - pjlink = pjlink_test |
2731 | - chk_test = PJLINK_ERST_STATUS['OK'] |
2732 | - chk_param = chk_test * len(PJLINK_ERST_POSITIONS) |
2733 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2734 | |
2735 | # WHEN: process_erst with no errors |
2736 | - pjlink.process_erst(chk_param) |
2737 | + pjlink.process_erst(chk_data) |
2738 | |
2739 | # THEN: PJLink instance errors should be None |
2740 | self.assertIsNone(pjlink.projector_errors, 'projector_errors should have been set to None') |
2741 | |
2742 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2743 | - def test_projector_process_erst_data_invalid_length(self, mock_log): |
2744 | + def test_projector_process_erst_data_invalid_length(self): |
2745 | """ |
2746 | Test test_projector_process_erst_data_invalid_length |
2747 | """ |
2748 | + chk_data = '0' * (PJLINK_ERST_DATA['DATA_LENGTH'] + 1) |
2749 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2750 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED]))] |
2751 | + log_warn_calls = [call('111.111.111.111) Invalid error status response "0000000": ' |
2752 | + 'length != {chk}'.format(chk=PJLINK_ERST_DATA['DATA_LENGTH']))] |
2753 | + |
2754 | # GIVEN: Test object |
2755 | - pjlink = pjlink_test |
2756 | - pjlink.projector_errors = None |
2757 | - log_text = '127.0.0.1) Invalid error status response "11111111": length != 6' |
2758 | - |
2759 | - # WHEN: process_erst called with invalid data (too many values |
2760 | - pjlink.process_erst('11111111') |
2761 | - |
2762 | - # THEN: pjlink.projector_errors should be empty and warning logged |
2763 | - self.assertIsNone(pjlink.projector_errors, 'There should be no errors') |
2764 | - self.assertTrue(mock_log.warning.called, 'Warning should have been logged') |
2765 | - mock_log.warning.assert_called_once_with(log_text) |
2766 | - |
2767 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2768 | - def test_projector_process_erst_data_invalid_nan(self, mock_log): |
2769 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2770 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2771 | + pjlink.projector_errors = None |
2772 | + |
2773 | + # WHEN: process_erst called with invalid data (too many values |
2774 | + pjlink.process_erst(chk_data) |
2775 | + |
2776 | + # THEN: pjlink.projector_errors should be empty and warning logged |
2777 | + self.assertIsNone(pjlink.projector_errors, 'There should be no errors') |
2778 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2779 | + mock_log.warning.assert_has_calls(log_warn_calls) |
2780 | + |
2781 | + def test_projector_process_erst_data_invalid_nan(self): |
2782 | """ |
2783 | Test test_projector_process_erst_data_invalid_nan |
2784 | """ |
2785 | + chk_data = 'Z' + ('0' * (PJLINK_ERST_DATA['DATA_LENGTH'] - 1)) |
2786 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2787 | + '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED]))] |
2788 | + log_warn_calls = [call('(111.111.111.111) Invalid error status response "Z00000"')] |
2789 | + |
2790 | # GIVEN: Test object |
2791 | - pjlink = pjlink_test |
2792 | - pjlink.projector_errors = None |
2793 | - log_text = '(127.0.0.1) Invalid error status response "1111Z1"' |
2794 | - |
2795 | - # WHEN: process_erst called with invalid data (too many values |
2796 | - pjlink.process_erst('1111Z1') |
2797 | - |
2798 | - # THEN: pjlink.projector_errors should be empty and warning logged |
2799 | - self.assertIsNone(pjlink.projector_errors, 'There should be no errors') |
2800 | - self.assertTrue(mock_log.warning.called, 'Warning should have been logged') |
2801 | - mock_log.warning.assert_called_once_with(log_text) |
2802 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2803 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2804 | + pjlink.projector_errors = None |
2805 | + |
2806 | + # WHEN: process_erst called with invalid data (too many values |
2807 | + pjlink.process_erst(chk_data) |
2808 | + |
2809 | + # THEN: pjlink.projector_errors should be empty and warning logged |
2810 | + self.assertIsNone(pjlink.projector_errors, 'There should be no errors') |
2811 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2812 | + mock_log.warning.assert_has_calls(log_warn_calls) |
2813 | |
2814 | def test_projector_process_erst_all_warn(self): |
2815 | """ |
2816 | Test test_projector_process_erst_all_warn |
2817 | """ |
2818 | + chk_data = '{fan}{lamp}{temp}{cover}{filt}{other}'.format(fan=PJLINK_ERST_STATUS[E_WARN], |
2819 | + lamp=PJLINK_ERST_STATUS[E_WARN], |
2820 | + temp=PJLINK_ERST_STATUS[E_WARN], |
2821 | + cover=PJLINK_ERST_STATUS[E_WARN], |
2822 | + filt=PJLINK_ERST_STATUS[E_WARN], |
2823 | + other=PJLINK_ERST_STATUS[E_WARN]) |
2824 | + chk_test = {'Fan': E_WARN, |
2825 | + 'Lamp': E_WARN, |
2826 | + 'Temperature': E_WARN, |
2827 | + 'Cover': E_WARN, |
2828 | + 'Filter': E_WARN, |
2829 | + 'Other': E_WARN} |
2830 | + |
2831 | # GIVEN: Test object |
2832 | - pjlink = pjlink_test |
2833 | - chk_test = PJLINK_ERST_STATUS[E_WARN] |
2834 | - chk_string = ERROR_STRING[E_WARN] |
2835 | - chk_param = chk_test * len(PJLINK_ERST_POSITIONS) |
2836 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2837 | + pjlink.projector_errors = None |
2838 | |
2839 | # WHEN: process_erst with status set to WARN |
2840 | - pjlink.process_erst(chk_param) |
2841 | + pjlink.process_erst(chk_data) |
2842 | |
2843 | # THEN: PJLink instance errors should match chk_value |
2844 | - for chk in pjlink.projector_errors: |
2845 | - self.assertEqual(pjlink.projector_errors[chk], chk_string, |
2846 | - 'projector_errors["{chk}"] should have been set to "{err}"'.format(chk=chk, |
2847 | - err=chk_string)) |
2848 | + self.assertEqual(pjlink.projector_errors, chk_test, 'Projector errors should be all E_WARN') |
2849 | |
2850 | def test_projector_process_erst_all_error(self): |
2851 | """ |
2852 | Test test_projector_process_erst_all_error |
2853 | """ |
2854 | + chk_data = '{fan}{lamp}{temp}{cover}{filt}{other}'.format(fan=PJLINK_ERST_STATUS[E_ERROR], |
2855 | + lamp=PJLINK_ERST_STATUS[E_ERROR], |
2856 | + temp=PJLINK_ERST_STATUS[E_ERROR], |
2857 | + cover=PJLINK_ERST_STATUS[E_ERROR], |
2858 | + filt=PJLINK_ERST_STATUS[E_ERROR], |
2859 | + other=PJLINK_ERST_STATUS[E_ERROR]) |
2860 | + chk_test = {'Fan': E_ERROR, |
2861 | + 'Lamp': E_ERROR, |
2862 | + 'Temperature': E_ERROR, |
2863 | + 'Cover': E_ERROR, |
2864 | + 'Filter': E_ERROR, |
2865 | + 'Other': E_ERROR} |
2866 | + |
2867 | # GIVEN: Test object |
2868 | - pjlink = pjlink_test |
2869 | - chk_test = PJLINK_ERST_STATUS[E_ERROR] |
2870 | - chk_string = ERROR_STRING[E_ERROR] |
2871 | - chk_param = chk_test * len(PJLINK_ERST_POSITIONS) |
2872 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2873 | + pjlink.projector_errors = None |
2874 | |
2875 | # WHEN: process_erst with status set to WARN |
2876 | - pjlink.process_erst(chk_param) |
2877 | + pjlink.process_erst(chk_data) |
2878 | |
2879 | # THEN: PJLink instance errors should match chk_value |
2880 | - for chk in pjlink.projector_errors: |
2881 | - self.assertEqual(pjlink.projector_errors[chk], chk_string, |
2882 | - 'projector_errors["{chk}"] should have been set to "{err}"'.format(chk=chk, |
2883 | - err=chk_string)) |
2884 | + self.assertEqual(pjlink.projector_errors, chk_test, 'Projector errors should be all E_ERROR') |
2885 | |
2886 | def test_projector_process_erst_warn_cover_only(self): |
2887 | """ |
2888 | Test test_projector_process_erst_warn_cover_only |
2889 | """ |
2890 | + chk_data = '{fan}{lamp}{temp}{cover}{filt}{other}'.format(fan=PJLINK_ERST_STATUS[S_OK], |
2891 | + lamp=PJLINK_ERST_STATUS[S_OK], |
2892 | + temp=PJLINK_ERST_STATUS[S_OK], |
2893 | + cover=PJLINK_ERST_STATUS[E_WARN], |
2894 | + filt=PJLINK_ERST_STATUS[S_OK], |
2895 | + other=PJLINK_ERST_STATUS[S_OK]) |
2896 | + chk_test = {'Cover': E_WARN} |
2897 | + |
2898 | # GIVEN: Test object |
2899 | - pjlink = pjlink_test |
2900 | - chk_test = PJLINK_ERST_STATUS[E_WARN] |
2901 | - chk_string = ERROR_STRING[E_WARN] |
2902 | - pos = PJLINK_ERST_DATA['COVER'] |
2903 | - build_chk = [] |
2904 | - for check in range(0, len(PJLINK_ERST_POSITIONS)): |
2905 | - if check == pos: |
2906 | - build_chk.append(chk_test) |
2907 | - else: |
2908 | - build_chk.append(PJLINK_ERST_STATUS['OK']) |
2909 | - chk_param = ''.join(build_chk) |
2910 | - |
2911 | - # WHEN: process_erst with cover only set to WARN and all others set to OK |
2912 | - pjlink.process_erst(chk_param) |
2913 | - |
2914 | - # THEN: Only COVER should have an error |
2915 | - self.assertEqual(len(pjlink.projector_errors), 1, 'projector_errors should only have 1 error') |
2916 | - self.assertTrue(('Cover' in pjlink.projector_errors), 'projector_errors should have an error for "Cover"') |
2917 | - self.assertEqual(pjlink.projector_errors['Cover'], |
2918 | - chk_string, |
2919 | - 'projector_errors["Cover"] should have error "{err}"'.format(err=chk_string)) |
2920 | - |
2921 | - def test_projector_process_inpt(self): |
2922 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2923 | + pjlink.projector_errors = None |
2924 | + |
2925 | + # WHEN: process_erst with status set to WARN |
2926 | + pjlink.process_erst(chk_data) |
2927 | + |
2928 | + # THEN: PJLink instance errors should match only cover warning |
2929 | + assert 1 == len(pjlink.projector_errors), 'There should only be 1 error listed in projector_errors' |
2930 | + assert 'Cover' in pjlink.projector_errors, '"Cover" should be the only error listed' |
2931 | + assert pjlink.projector_errors['Cover'] == E_WARN, '"Cover" should have E_WARN listed as error' |
2932 | + assert chk_test == pjlink.projector_errors, 'projector_errors should match test errors' |
2933 | + |
2934 | + def test_projector_process_inpt_valid(self): |
2935 | """ |
2936 | Test input source status shows current input |
2937 | """ |
2938 | + log_debug_calls = [call('(111.111.111.111) reset_information() connect status is S_NOT_CONNECTED')] |
2939 | + chk_source_available = ['11', '12', '21', '22', '31', '32'] |
2940 | + |
2941 | # GIVEN: Test object |
2942 | - pjlink = pjlink_test |
2943 | - pjlink.source = '0' |
2944 | - |
2945 | - # WHEN: Called with input source |
2946 | - pjlink.process_inpt('1') |
2947 | - |
2948 | - # THEN: Input selected should reflect current input |
2949 | - self.assertEqual(pjlink.source, '1', 'Input source should be set to "1"') |
2950 | - |
2951 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
2952 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
2953 | - def test_projector_process_inst(self, mock_log, mock_UpdateIcons): |
2954 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2955 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2956 | + pjlink.source_available = chk_source_available |
2957 | + pjlink.source = '11' |
2958 | + |
2959 | + # WHEN: Called with input source |
2960 | + pjlink.process_inpt('21') |
2961 | + |
2962 | + # THEN: Input selected should reflect current input |
2963 | + assert pjlink.source == '21', 'Input source should be set to "21"' |
2964 | + mock_log.debug.assert_has_calls(log_debug_calls) |
2965 | + |
2966 | + def test_projector_process_input_not_in_list(self): |
2967 | + """ |
2968 | + Test setting input outside of available inputs |
2969 | + |
2970 | + TODO: Future test |
2971 | + """ |
2972 | + pass |
2973 | + |
2974 | + def test_projector_process_input_not_in_default(self): |
2975 | + """ |
2976 | + Test setting input with no sources available |
2977 | + TODO: Future test |
2978 | + """ |
2979 | + pass |
2980 | + |
2981 | + def test_projector_process_input_invalid(self): |
2982 | + """ |
2983 | + Test setting input with an invalid value |
2984 | + |
2985 | + TODO: Future test |
2986 | + """ |
2987 | + |
2988 | + def test_projector_process_inst_class_1(self): |
2989 | """ |
2990 | Test saving video source available information |
2991 | """ |
2992 | + log_debug_calls = [call('(111.111.111.111) Setting projector sources_available to ' |
2993 | + '"[\'11\', \'12\', \'21\', \'22\', \'31\', \'32\']"')] |
2994 | + chk_data = '21 12 11 22 32 31' # Although they should already be sorted, use unsorted to verify method |
2995 | + chk_test = ['11', '12', '21', '22', '31', '32'] |
2996 | + |
2997 | # GIVEN: Test object |
2998 | - pjlink = pjlink_test |
2999 | - pjlink.source_available = [] |
3000 | - test_data = '21 10 30 31 11 20' |
3001 | - test_saved = ["10", "11", "20", "21", "30", "31"] |
3002 | - log_data = "(127.0.0.1) Setting projector sources_available to " \ |
3003 | - "\"['10', '11', '20', '21', '30', '31']\"" |
3004 | - mock_UpdateIcons.reset_mock() |
3005 | - mock_log.reset_mock() |
3006 | - |
3007 | - # WHEN: process_inst called with test data |
3008 | - pjlink.process_inst(data=test_data) |
3009 | - |
3010 | - # THEN: Data should have been sorted and saved properly |
3011 | - self.assertEqual(pjlink.source_available, test_saved, "Sources should have been sorted and saved") |
3012 | - mock_log.debug.assert_called_once_with(log_data) |
3013 | - self.assertTrue(mock_UpdateIcons.emit.called, 'Update Icons should have been called') |
3014 | - |
3015 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
3016 | - def test_projector_process_lamp_invalid(self, mock_log): |
3017 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3018 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3019 | + pjlink.source_available = [] |
3020 | + |
3021 | + # WHEN: process_inst called with test data |
3022 | + pjlink.process_inst(data=chk_data) |
3023 | + |
3024 | + # THEN: Data should have been sorted and saved properly |
3025 | + assert pjlink.source_available == chk_test, "Sources should have been sorted and saved" |
3026 | + mock_log.debug.assert_has_calls(log_debug_calls) |
3027 | + |
3028 | + def test_projector_process_lamp_invalid(self): |
3029 | """ |
3030 | Test status multiple lamp on/off and hours |
3031 | """ |
3032 | + log_data = [call('(111.111.111.111) process_lamp(): Invalid data "11111 1 22222 0 333A3 1"')] |
3033 | + |
3034 | # GIVEN: Test object |
3035 | - pjlink = pjlink_test |
3036 | - pjlink.lamp = [{'Hours': 00000, 'On': True}, |
3037 | - {'Hours': 11111, 'On': False}] |
3038 | - log_data = '(127.0.0.1) process_lamp(): Invalid data "11111 1 22222 0 333A3 1"' |
3039 | - |
3040 | - # WHEN: Call process_command with invalid lamp data |
3041 | - pjlink.process_lamp('11111 1 22222 0 333A3 1') |
3042 | - |
3043 | - # THEN: lamps should not have changed |
3044 | - self.assertEqual(len(pjlink.lamp), 2, |
3045 | - 'Projector should have kept 2 lamps specified') |
3046 | - self.assertEqual(pjlink.lamp[0]['On'], True, |
3047 | - 'Lamp 1 power status should have been set to TRUE') |
3048 | - self.assertEqual(pjlink.lamp[0]['Hours'], 00000, |
3049 | - 'Lamp 1 hours should have been left at 00000') |
3050 | - self.assertEqual(pjlink.lamp[1]['On'], False, |
3051 | - 'Lamp 2 power status should have been set to FALSE') |
3052 | - self.assertEqual(pjlink.lamp[1]['Hours'], 11111, |
3053 | - 'Lamp 2 hours should have been left at 11111') |
3054 | - mock_log.warning.assert_called_once_with(log_data) |
3055 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3056 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3057 | + pjlink.lamp = [{'Hours': 00000, 'On': True}, |
3058 | + {'Hours': 11111, 'On': False}] |
3059 | + |
3060 | + # WHEN: Call process_command with invalid lamp data |
3061 | + pjlink.process_lamp('11111 1 22222 0 333A3 1') |
3062 | + |
3063 | + # THEN: lamps should not have changed |
3064 | + assert 2 == len(pjlink.lamp), 'Projector should have kept 2 lamps specified' |
3065 | + assert pjlink.lamp[0]['On'] is True, 'Lamp 1 power status should have stayed TRUE' |
3066 | + assert 00000 == pjlink.lamp[0]['Hours'], 'Lamp 1 hours should have been left at 00000' |
3067 | + assert pjlink.lamp[1]['On'] is False, 'Lamp 2 power status should have stayed FALSE' |
3068 | + assert 11111 == pjlink.lamp[1]['Hours'], 'Lamp 2 hours should have been left at 11111' |
3069 | + mock_log.warning.assert_has_calls(log_data) |
3070 | |
3071 | def test_projector_process_lamp_multiple(self): |
3072 | """ |
3073 | Test status multiple lamp on/off and hours |
3074 | """ |
3075 | # GIVEN: Test object |
3076 | - pjlink = pjlink_test |
3077 | - pjlink.lamps = [] |
3078 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3079 | + pjlink.lamp = [] |
3080 | |
3081 | - # WHEN: Call process_command with lamp data |
3082 | + # WHEN: Call process_command with invalid lamp data |
3083 | pjlink.process_lamp('11111 1 22222 0 33333 1') |
3084 | |
3085 | # THEN: Lamp should have been set with proper lamp status |
3086 | - self.assertEqual(len(pjlink.lamp), 3, |
3087 | - 'Projector should have 3 lamps specified') |
3088 | - self.assertEqual(pjlink.lamp[0]['On'], True, |
3089 | - 'Lamp 1 power status should have been set to TRUE') |
3090 | - self.assertEqual(pjlink.lamp[0]['Hours'], 11111, |
3091 | - 'Lamp 1 hours should have been set to 11111') |
3092 | - self.assertEqual(pjlink.lamp[1]['On'], False, |
3093 | - 'Lamp 2 power status should have been set to FALSE') |
3094 | - self.assertEqual(pjlink.lamp[1]['Hours'], 22222, |
3095 | - 'Lamp 2 hours should have been set to 22222') |
3096 | - self.assertEqual(pjlink.lamp[2]['On'], True, |
3097 | - 'Lamp 3 power status should have been set to TRUE') |
3098 | - self.assertEqual(pjlink.lamp[2]['Hours'], 33333, |
3099 | - 'Lamp 3 hours should have been set to 33333') |
3100 | + assert 3 == len(pjlink.lamp), 'Projector should have 3 lamps specified' |
3101 | + assert pjlink.lamp[0]['On'] is True, 'Lamp 1 power status should have been set to TRUE' |
3102 | + assert 11111 == pjlink.lamp[0]['Hours'], 'Lamp 1 hours should have been set to 11111' |
3103 | + assert pjlink.lamp[1]['On'] is False, 'Lamp 2 power status should have been set to FALSE' |
3104 | + assert 22222 == pjlink.lamp[1]['Hours'], 'Lamp 2 hours should have been set to 22222' |
3105 | + assert pjlink.lamp[2]['On'] is True, 'Lamp 3 power status should have been set to TRUE' |
3106 | + assert 33333 == pjlink.lamp[2]['Hours'], 'Lamp 3 hours should have been set to 33333' |
3107 | |
3108 | def test_projector_process_lamp_single(self): |
3109 | """ |
3110 | Test status lamp on/off and hours |
3111 | """ |
3112 | + |
3113 | # GIVEN: Test object |
3114 | - pjlink = pjlink_test |
3115 | - pjlink.lamps = [] |
3116 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3117 | + pjlink.lamp = [] |
3118 | |
3119 | - # WHEN: Call process_command with lamp data |
3120 | + # WHEN: Call process_command with invalid lamp data |
3121 | pjlink.process_lamp('22222 1') |
3122 | |
3123 | # THEN: Lamp should have been set with status=ON and hours=22222 |
3124 | - self.assertEqual(pjlink.lamp[0]['On'], True, |
3125 | - 'Lamp power status should have been set to TRUE') |
3126 | - self.assertEqual(pjlink.lamp[0]['Hours'], 22222, |
3127 | - 'Lamp hours should have been set to 22222') |
3128 | + assert 1 == len(pjlink.lamp), 'Projector should have only 1 lamp' |
3129 | + assert pjlink.lamp[0]['On'] is True, 'Lamp power status should have been set to TRUE' |
3130 | + assert 22222 == pjlink.lamp[0]['Hours'], 'Lamp hours should have been set to 22222' |
3131 | |
3132 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
3133 | - def test_projector_process_name(self, mock_log): |
3134 | + def test_projector_process_name(self): |
3135 | """ |
3136 | Test saving NAME data from projector |
3137 | """ |
3138 | - # GIVEN: Test data |
3139 | - pjlink = pjlink_test |
3140 | - test_data = "Some Name the End-User Set IN Projector" |
3141 | - test_log = '(127.0.0.1) Setting projector PJLink name to "Some Name the End-User Set IN Projector"' |
3142 | - mock_log.reset_mock() |
3143 | - |
3144 | - # WHEN: process_name called with test data |
3145 | - pjlink.process_name(data=test_data) |
3146 | - |
3147 | - # THEN: name should be set and logged |
3148 | - self.assertEqual(pjlink.pjlink_name, test_data, 'Name test data should have been saved') |
3149 | - mock_log.debug.assert_called_once_with(test_log) |
3150 | - |
3151 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
3152 | - @patch.object(pjlink_test, 'send_command') |
3153 | - @patch.object(pjlink_test, 'change_status') |
3154 | - def test_projector_process_powr_on(self, |
3155 | - mock_change_status, |
3156 | - mock_send_command, |
3157 | - mock_UpdateIcons): |
3158 | + chk_data = "Some Name the End-User Set IN Projector" |
3159 | + log_debug_calls = [call('(111.111.111.111) Setting projector PJLink name to ' |
3160 | + '"Some Name the End-User Set IN Projector"')] |
3161 | + |
3162 | + # GIVEN: Test object |
3163 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3164 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3165 | + |
3166 | + # WHEN: process_name called with test data |
3167 | + pjlink.process_name(data=chk_data) |
3168 | + |
3169 | + # THEN: name should be set and logged |
3170 | + assert pjlink.pjlink_name == chk_data, 'Name test data should have been saved' |
3171 | + mock_log.debug.assert_has_calls(log_debug_calls) |
3172 | + |
3173 | + def test_projector_process_powr_on(self): |
3174 | """ |
3175 | Test status power to ON |
3176 | """ |
3177 | - # GIVEN: Test object and preset |
3178 | - pjlink = pjlink_test |
3179 | - pjlink.power = S_STANDBY |
3180 | - test_data = PJLINK_POWR_STATUS[S_ON] |
3181 | - |
3182 | - # WHEN: Call process_command with turn power on command |
3183 | - pjlink.process_command(cmd='POWR', data=test_data) |
3184 | - |
3185 | - # THEN: Power should be set to ON |
3186 | - self.assertEqual(pjlink.power, S_ON, 'Power should have been set to ON') |
3187 | - mock_send_command.assert_called_once_with('INST') |
3188 | - mock_change_status.assert_called_once_with(PJLINK_POWR_STATUS[test_data]) |
3189 | - self.assertEqual(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called') |
3190 | - |
3191 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
3192 | - @patch.object(pjlink_test, 'send_command') |
3193 | - @patch.object(pjlink_test, 'change_status') |
3194 | - def test_projector_process_powr_invalid(self, |
3195 | - mock_change_status, |
3196 | - mock_send_command, |
3197 | - mock_UpdateIcons): |
3198 | + # GIVEN: Test object |
3199 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ |
3200 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
3201 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
3202 | + |
3203 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3204 | + pjlink.power = S_STANDBY |
3205 | + |
3206 | + # WHEN: process_name called with test data |
3207 | + pjlink.process_powr(data=PJLINK_POWR_STATUS[S_ON]) |
3208 | + |
3209 | + # THEN: Power should be set to ON |
3210 | + assert pjlink.power == S_ON, 'Power should have been set to ON' |
3211 | + assert mock_UpdateIcons.emit.called is True, 'projectorUpdateIcons should have been called' |
3212 | + mock_send_command.assert_called_once_with('INST') |
3213 | + mock_change_status.assert_called_once_with(S_ON) |
3214 | + |
3215 | + def test_projector_process_powr_invalid(self): |
3216 | """ |
3217 | Test process_powr invalid call |
3218 | """ |
3219 | - # GIVEN: Test object and preset |
3220 | - pjlink = pjlink_test |
3221 | - pjlink.power = S_STANDBY |
3222 | - test_data = '99' |
3223 | - |
3224 | - # WHEN: Call process_command with turn power on command |
3225 | - pjlink.process_command(cmd='POWR', data=test_data) |
3226 | - |
3227 | - # THEN: Power should be set to ON |
3228 | - self.assertEqual(pjlink.power, S_STANDBY, 'Power should not have changed') |
3229 | - self.assertFalse(mock_change_status.called, 'Change status should not have been called') |
3230 | - self.assertFalse(mock_send_command.called, 'send_command("INST") should not have been called') |
3231 | - self.assertFalse(mock_UpdateIcons.emit.called, 'projectorUpdateIcons should not have been called') |
3232 | - |
3233 | - @patch.object(pjlink_test, 'projectorUpdateIcons') |
3234 | - @patch.object(pjlink_test, 'send_command') |
3235 | - @patch.object(pjlink_test, 'change_status') |
3236 | - def test_projector_process_powr_off(self, |
3237 | - mock_change_status, |
3238 | - mock_send_command, |
3239 | - mock_UpdateIcons): |
3240 | + log_warn_calls = [call('(111.111.111.111) Unknown power response: "99"')] |
3241 | + |
3242 | + # GIVEN: Test object |
3243 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
3244 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ |
3245 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
3246 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
3247 | + |
3248 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3249 | + pjlink.power = S_STANDBY |
3250 | + |
3251 | + # WHEN: process_name called with test data |
3252 | + pjlink.process_powr(data='99') |
3253 | + |
3254 | + # THEN: Power should be set to ON |
3255 | + assert pjlink.power == S_STANDBY, 'Power should not have changed' |
3256 | + assert mock_UpdateIcons.emit.called is False, 'projectorUpdateIcons() should not have been called' |
3257 | + mock_change_status.called is False, 'change_status() should not have been called' |
3258 | + mock_send_command.called is False, 'send_command() should not have been called' |
3259 | + mock_log.warning.assert_has_calls(log_warn_calls) |
3260 | + |
3261 | + def test_projector_process_powr_off(self): |
3262 | """ |
3263 | Test status power to STANDBY |
3264 | """ |
3265 | - # GIVEN: Test object and preset |
3266 | - pjlink = pjlink_test |
3267 | - pjlink.power = S_ON |
3268 | - test_data = PJLINK_POWR_STATUS[S_STANDBY] |
3269 | - |
3270 | - # WHEN: Call process_command with turn power on command |
3271 | - pjlink.process_command(cmd='POWR', data=test_data) |
3272 | - |
3273 | - # THEN: Power should be set to STANDBY |
3274 | - self.assertEqual(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY') |
3275 | - self.assertEqual(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called') |
3276 | - mock_change_status.assert_called_once_with(PJLINK_POWR_STATUS[test_data]) |
3277 | - self.assertFalse(mock_send_command.called, "send_command['INST'] should not have been called") |
3278 | + # GIVEN: Test object |
3279 | + with patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ |
3280 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
3281 | + patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
3282 | + |
3283 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3284 | + pjlink.power = S_ON |
3285 | + |
3286 | + # WHEN: process_name called with test data |
3287 | + pjlink.process_powr(data=PJLINK_POWR_STATUS[S_STANDBY]) |
3288 | + |
3289 | + # THEN: Power should be set to ON |
3290 | + assert pjlink.power == S_STANDBY, 'Power should have changed to S_STANDBY' |
3291 | + assert mock_UpdateIcons.emit.called is True, 'projectorUpdateIcons should have been called' |
3292 | + mock_change_status.called is True, 'change_status should have been called' |
3293 | + mock_send_command.called is False, 'send_command should not have been called' |
3294 | |
3295 | def test_projector_process_rfil_save(self): |
3296 | """ |
3297 | Test saving filter type |
3298 | """ |
3299 | + filter_model = 'Filter Type Test' |
3300 | + |
3301 | # GIVEN: Test object |
3302 | - pjlink = pjlink_test |
3303 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3304 | pjlink.model_filter = None |
3305 | - filter_model = 'Filter Type Test' |
3306 | |
3307 | # WHEN: Filter model is received |
3308 | pjlink.process_rfil(data=filter_model) |
3309 | |
3310 | # THEN: Filter model number should be saved |
3311 | - self.assertEqual(pjlink.model_filter, filter_model, 'Filter type should have been saved') |
3312 | + assert pjlink.model_filter == filter_model, 'Filter type should have been saved' |
3313 | |
3314 | def test_projector_process_rfil_nosave(self): |
3315 | """ |
3316 | Test saving filter type previously saved |
3317 | """ |
3318 | + filter_model = 'Filter Type Test' |
3319 | + log_warn_calls = [call('(111.111.111.111) Filter model already set'), |
3320 | + call('(111.111.111.111) Saved model: "Old filter type"'), |
3321 | + call('(111.111.111.111) New model: "Filter Type Test"')] |
3322 | + |
3323 | # GIVEN: Test object |
3324 | - pjlink = pjlink_test |
3325 | - pjlink.model_filter = 'Old filter type' |
3326 | - filter_model = 'Filter Type Test' |
3327 | - |
3328 | - # WHEN: Filter model is received |
3329 | - pjlink.process_rfil(data=filter_model) |
3330 | - |
3331 | - # THEN: Filter model number should be saved |
3332 | - self.assertNotEquals(pjlink.model_filter, filter_model, 'Filter type should NOT have been saved') |
3333 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3334 | + |
3335 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3336 | + pjlink.model_filter = 'Old filter type' |
3337 | + |
3338 | + # WHEN: Filter model is received |
3339 | + pjlink.process_rfil(data=filter_model) |
3340 | + |
3341 | + # THEN: Filter model number should be saved |
3342 | + assert pjlink.model_filter != filter_model, 'Filter type should NOT have been saved' |
3343 | + mock_log.warning.assert_has_calls(log_warn_calls) |
3344 | |
3345 | def test_projector_process_rlmp_save(self): |
3346 | """ |
3347 | Test saving lamp type |
3348 | """ |
3349 | # GIVEN: Test object |
3350 | - pjlink = pjlink_test |
3351 | + # GIVEN: Test object |
3352 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3353 | pjlink.model_lamp = None |
3354 | lamp_model = 'Lamp Type Test' |
3355 | |
3356 | @@ -968,153 +1048,173 @@ |
3357 | """ |
3358 | Test saving lamp type previously saved |
3359 | """ |
3360 | + lamp_model = 'Lamp Type Test' |
3361 | + log_warn_calls = [call('(111.111.111.111) Lamp model already set'), |
3362 | + call('(111.111.111.111) Saved lamp: "Old lamp type"'), |
3363 | + call('(111.111.111.111) New lamp: "Lamp Type Test"')] |
3364 | + |
3365 | # GIVEN: Test object |
3366 | - pjlink = pjlink_test |
3367 | - pjlink.model_lamp = 'Old lamp type' |
3368 | - lamp_model = 'Filter Type Test' |
3369 | - |
3370 | - # WHEN: Filter model is received |
3371 | - pjlink.process_rlmp(data=lamp_model) |
3372 | - |
3373 | - # THEN: Filter model number should be saved |
3374 | - self.assertNotEquals(pjlink.model_lamp, lamp_model, 'Lamp type should NOT have been saved') |
3375 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3376 | + |
3377 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3378 | + pjlink.model_lamp = 'Old lamp type' |
3379 | + |
3380 | + # WHEN: Filter model is received |
3381 | + pjlink.process_rlmp(data=lamp_model) |
3382 | + |
3383 | + # THEN: Filter model number should be saved |
3384 | + assert pjlink.model_lamp != lamp_model, 'Lamp type should NOT have been saved' |
3385 | + mock_log.warning.assert_has_calls(log_warn_calls) |
3386 | |
3387 | def test_projector_process_snum_set(self): |
3388 | """ |
3389 | Test saving serial number from projector |
3390 | """ |
3391 | + log_debug_calls = [call('(111.111.111.111) Setting projector serial number to "Test Serial Number"')] |
3392 | + test_number = 'Test Serial Number' |
3393 | + |
3394 | # GIVEN: Test object |
3395 | - pjlink = pjlink_test |
3396 | - pjlink.serial_no = None |
3397 | - test_number = 'Test Serial Number' |
3398 | - |
3399 | - # WHEN: No serial number is set and we receive serial number command |
3400 | - pjlink.process_snum(data=test_number) |
3401 | - |
3402 | - # THEN: Serial number should be set |
3403 | - self.assertEqual(pjlink.serial_no, test_number, |
3404 | - 'Projector serial number should have been set') |
3405 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3406 | + |
3407 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3408 | + pjlink.serial_no = None |
3409 | + |
3410 | + # WHEN: No serial number is set and we receive serial number command |
3411 | + pjlink.process_snum(data=test_number) |
3412 | + |
3413 | + # THEN: Serial number should be set |
3414 | + assert pjlink.serial_no == test_number, 'Projector serial number should have been set' |
3415 | + mock_log.debug.assert_has_calls(log_debug_calls) |
3416 | |
3417 | def test_projector_process_snum_different(self): |
3418 | """ |
3419 | Test projector serial number different than saved serial number |
3420 | """ |
3421 | - # GIVEN: Test object |
3422 | - pjlink = pjlink_test |
3423 | - pjlink.serial_no = 'Previous serial number' |
3424 | + log_warn_calls = [call('(111.111.111.111) Projector serial number does not match saved serial number'), |
3425 | + call('(111.111.111.111) Saved: "Previous serial number"'), |
3426 | + call('(111.111.111.111) Received: "Test Serial Number"'), |
3427 | + call('(111.111.111.111) NOT saving serial number')] |
3428 | test_number = 'Test Serial Number' |
3429 | |
3430 | - # WHEN: No serial number is set and we receive serial number command |
3431 | - pjlink.process_snum(data=test_number) |
3432 | - |
3433 | - # THEN: Serial number should be set |
3434 | - self.assertNotEquals(pjlink.serial_no, test_number, |
3435 | - 'Projector serial number should NOT have been set') |
3436 | - |
3437 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
3438 | - def test_projector_process_sver(self, mock_log): |
3439 | + # GIVEN: Test object |
3440 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3441 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3442 | + pjlink.serial_no = 'Previous serial number' |
3443 | + |
3444 | + # WHEN: No serial number is set and we receive serial number command |
3445 | + pjlink.process_snum(data=test_number) |
3446 | + |
3447 | + # THEN: Serial number should be set |
3448 | + assert pjlink.serial_no != test_number, 'Projector serial number should NOT have been set' |
3449 | + mock_log.warning.assert_has_calls(log_warn_calls) |
3450 | + |
3451 | + def test_projector_process_sver(self): |
3452 | """ |
3453 | Test invalid software version information - too long |
3454 | """ |
3455 | - # GIVEN: Test object |
3456 | - pjlink = pjlink_test |
3457 | - pjlink.sw_version = None |
3458 | - pjlink.sw_version_received = None |
3459 | test_data = 'Test 1 Subtest 1' |
3460 | - test_log = '(127.0.0.1) Setting projector software version to "Test 1 Subtest 1"' |
3461 | - mock_log.reset_mock() |
3462 | - |
3463 | - # WHEN: process_sver called with invalid data |
3464 | - pjlink.process_sver(data=test_data) |
3465 | - |
3466 | - # THEN: Version information should not change |
3467 | - self.assertEqual(pjlink.sw_version, test_data, 'Software version should have been updated') |
3468 | - self.assertIsNone(pjlink.sw_version_received, 'Received software version should not have changed') |
3469 | - mock_log.debug.assert_called_once_with(test_log) |
3470 | - |
3471 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
3472 | - def test_projector_process_sver_changed(self, mock_log): |
3473 | + log_debug_calls = [call('(111.111.111.111) Setting projector software version to "Test 1 Subtest 1"')] |
3474 | + |
3475 | + # GIVEN: Test object |
3476 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3477 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3478 | + pjlink.sw_version = None |
3479 | + pjlink.sw_version_received = None |
3480 | + |
3481 | + # WHEN: process_sver called with invalid data |
3482 | + pjlink.process_sver(data=test_data) |
3483 | + |
3484 | + # THEN: Version information should not change |
3485 | + assert pjlink.sw_version == test_data, 'Software version should have been updated' |
3486 | + mock_log.debug.assert_has_calls(log_debug_calls) |
3487 | + |
3488 | + def test_projector_process_sver_changed(self): |
3489 | """ |
3490 | Test invalid software version information - Received different than saved |
3491 | """ |
3492 | - # GIVEN: Test object |
3493 | - pjlink = pjlink_test |
3494 | + test_data_old = 'Test 1 Subtest 1' |
3495 | test_data_new = 'Test 1 Subtest 2' |
3496 | - test_data_old = 'Test 1 Subtest 1' |
3497 | - pjlink.sw_version = test_data_old |
3498 | - pjlink.sw_version_received = None |
3499 | - test_log = '(127.0.0.1) Saving new serial number as sw_version_received' |
3500 | - mock_log.reset_mock() |
3501 | - |
3502 | - # WHEN: process_sver called with invalid data |
3503 | - pjlink.process_sver(data=test_data_new) |
3504 | - |
3505 | - # THEN: Version information should not change |
3506 | - self.assertEqual(pjlink.sw_version, test_data_old, 'Software version should not have been updated') |
3507 | - self.assertEqual(pjlink.sw_version_received, test_data_new, |
3508 | - 'Received software version should have been changed') |
3509 | - self.assertEqual(mock_log.warning.call_count, 4, 'log.warn should have been called 4 times') |
3510 | - # There was 4 calls, but only the last one is checked with this method |
3511 | - mock_log.warning.assert_called_with(test_log) |
3512 | - |
3513 | - @patch.object(openlp.core.projectors.pjlink, 'log') |
3514 | - def test_projector_process_sver_invalid(self, mock_log): |
3515 | + log_warn_calls = [call('(111.111.111.111) Projector software version does not match saved software version'), |
3516 | + call('(111.111.111.111) Saved: "Test 1 Subtest 1"'), |
3517 | + call('(111.111.111.111) Received: "Test 1 Subtest 2"'), |
3518 | + call('(111.111.111.111) Updating software version')] |
3519 | + |
3520 | + # GIVEN: Test object |
3521 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3522 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3523 | + pjlink.sw_version = test_data_old |
3524 | + |
3525 | + # WHEN: process_sver called with invalid data |
3526 | + pjlink.process_sver(data=test_data_new) |
3527 | + |
3528 | + # THEN: Version information should not change |
3529 | + assert pjlink.sw_version == test_data_new, 'Software version should have changed' |
3530 | + mock_log.warning.assert_has_calls(log_warn_calls) |
3531 | + |
3532 | + def test_projector_process_sver_invalid(self): |
3533 | """ |
3534 | Test invalid software version information - too long |
3535 | """ |
3536 | - # GIVEN: Test object |
3537 | - pjlink = pjlink_test |
3538 | - pjlink.sw_version = None |
3539 | - pjlink.sw_version_received = None |
3540 | test_data = 'This is a test software version line that is too long based on PJLink version 2 specs' |
3541 | - test_log = "Invalid software version - too long" |
3542 | - mock_log.reset_mock() |
3543 | - |
3544 | - # WHEN: process_sver called with invalid data |
3545 | - pjlink.process_sver(data=test_data) |
3546 | - |
3547 | - # THEN: Version information should not change |
3548 | - self.assertIsNone(pjlink.sw_version, 'Software version should not have changed') |
3549 | - self.assertIsNone(pjlink.sw_version_received, 'Received software version should not have changed') |
3550 | - mock_log.warning.assert_called_once_with(test_log) |
3551 | + log_warn_calls = [call('Invalid software version - too long')] |
3552 | + |
3553 | + # GIVEN: Test object |
3554 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3555 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3556 | + pjlink.sw_version = None |
3557 | + |
3558 | + # WHEN: process_sver called with invalid data |
3559 | + pjlink.process_sver(data=test_data) |
3560 | + |
3561 | + # THEN: Version information should not change |
3562 | + assert pjlink.sw_version is None, 'Software version should not have changed' |
3563 | + assert pjlink.sw_version_received is None, 'Received software version should not have changed' |
3564 | + mock_log.warning.assert_has_calls(log_warn_calls) |
3565 | |
3566 | def test_projector_reset_information(self): |
3567 | """ |
3568 | Test reset_information() resets all information and stops timers |
3569 | """ |
3570 | - # GIVEN: Test object and test data |
3571 | - pjlink = pjlink_test |
3572 | - pjlink.power = S_ON |
3573 | - pjlink.pjlink_name = 'OPENLPTEST' |
3574 | - pjlink.manufacturer = 'PJLINK' |
3575 | - pjlink.model = '1' |
3576 | - pjlink.shutter = True |
3577 | - pjlink.mute = True |
3578 | - pjlink.lamp = True |
3579 | - pjlink.fan = True |
3580 | - pjlink.source_available = True |
3581 | - pjlink.other_info = 'ANOTHER TEST' |
3582 | - pjlink.send_queue = True |
3583 | - pjlink.send_busy = True |
3584 | - |
3585 | - # WHEN: reset_information() is called |
3586 | - with patch.object(pjlink, 'timer') as mock_timer: |
3587 | - with patch.object(pjlink, 'socket_timer') as mock_socket_timer: |
3588 | + log_debug_calls = [call('(111.111.111.111): Calling timer.stop()'), |
3589 | + call('(111.111.111.111): Calling socket_timer.stop()')] |
3590 | + |
3591 | + # GIVEN: Test object |
3592 | + with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3593 | + pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3594 | + # timer and socket_timer not available until instantiation, so mock here |
3595 | + with patch.object(pjlink, 'socket_timer') as mock_socket_timer, \ |
3596 | + patch.object(pjlink, 'timer') as mock_timer: |
3597 | + |
3598 | + pjlink.power = S_ON |
3599 | + pjlink.pjlink_name = 'OPENLPTEST' |
3600 | + pjlink.manufacturer = 'PJLINK' |
3601 | + pjlink.model = '1' |
3602 | + pjlink.shutter = True |
3603 | + pjlink.mute = True |
3604 | + pjlink.lamp = True |
3605 | + pjlink.fan = True |
3606 | + pjlink.source_available = True |
3607 | + pjlink.other_info = 'ANOTHER TEST' |
3608 | + pjlink.send_queue = True |
3609 | + pjlink.send_busy = True |
3610 | + |
3611 | + # WHEN: reset_information() is called |
3612 | pjlink.reset_information() |
3613 | |
3614 | - # THEN: All information should be reset and timers stopped |
3615 | - self.assertEqual(pjlink.power, S_OFF, 'Projector power should be OFF') |
3616 | - self.assertIsNone(pjlink.pjlink_name, 'Projector pjlink_name should be None') |
3617 | - self.assertIsNone(pjlink.manufacturer, 'Projector manufacturer should be None') |
3618 | - self.assertIsNone(pjlink.model, 'Projector model should be None') |
3619 | - self.assertIsNone(pjlink.shutter, 'Projector shutter should be None') |
3620 | - self.assertIsNone(pjlink.mute, 'Projector shuttter should be None') |
3621 | - self.assertIsNone(pjlink.lamp, 'Projector lamp should be None') |
3622 | - self.assertIsNone(pjlink.fan, 'Projector fan should be None') |
3623 | - self.assertIsNone(pjlink.source_available, 'Projector source_available should be None') |
3624 | - self.assertIsNone(pjlink.source, 'Projector source should be None') |
3625 | - self.assertIsNone(pjlink.other_info, 'Projector other_info should be None') |
3626 | - self.assertEqual(pjlink.send_queue, [], 'Projector send_queue should be an empty list') |
3627 | - self.assertFalse(pjlink.send_busy, 'Projector send_busy should be False') |
3628 | - self.assertTrue(mock_timer.stop.called, 'Projector timer.stop() should have been called') |
3629 | - self.assertTrue(mock_socket_timer.stop.called, 'Projector socket_timer.stop() should have been called') |
3630 | + # THEN: All information should be reset and timers stopped |
3631 | + assert pjlink.power == S_OFF, 'Projector power should be OFF' |
3632 | + assert pjlink.pjlink_name is None, 'Projector pjlink_name should be None' |
3633 | + assert pjlink.manufacturer is None, 'Projector manufacturer should be None' |
3634 | + assert pjlink.model is None, 'Projector model should be None' |
3635 | + assert pjlink.shutter is None, 'Projector shutter should be None' |
3636 | + assert pjlink.mute is None, 'Projector shuttter should be None' |
3637 | + assert pjlink.lamp is None, 'Projector lamp should be None' |
3638 | + assert pjlink.fan is None, 'Projector fan should be None' |
3639 | + assert pjlink.source_available is None, 'Projector source_available should be None' |
3640 | + assert pjlink.source is None, 'Projector source should be None' |
3641 | + assert pjlink.other_info is None, 'Projector other_info should be None' |
3642 | + assert pjlink.send_queue == [], 'Projector send_queue should be an empty list' |
3643 | + assert pjlink.send_busy is False, 'Projector send_busy should be False' |
3644 | + assert mock_timer.stop.called is True, 'Projector timer.stop() should have been called' |
3645 | + assert mock_socket_timer.stop.called is True, 'Projector socket_timer.stop() should have been called' |
3646 | + mock_log.debug.assert_has_calls(log_debug_calls) |