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