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