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: |
3657 lines (+1548/-1305) 7 files modified
openlp/core/projectors/constants.py (+296/-224) openlp/core/projectors/manager.py (+37/-33) openlp/core/projectors/pjlink.py (+114/-97) tests/functional/openlp_core/projectors/test_projector_constants.py (+39/-0) tests/functional/openlp_core/projectors/test_projector_pjlink_base.py (+3/-4) tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py (+183/-170) tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py (+876/-777) |
To merge this branch: | bzr merge lp:~alisonken1/openlp/pjlink2-n |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Bentley | Needs Fixing | ||
Review via email: mp+335588@code.launchpad.net |
This proposal supersedes a proposal from 2017-12-25.
This proposal has been superseded by a proposal from 2017-12-26.
Commit message
PJLink 2 update N
Description of the change
-------
lp:~alisonken1/openlp/pjlink2-n (revision 2804)
https:/
https:/
https:/
https:/
https:/
https:/
https:/
https:/
Large diff fixing projector tests
- Update some comments
- Some PJLink code fixes/restructuring
- Restructure some projector tests for proper mocking
- Fix manager.py and pjlink.py for changes to constants.py
- Fix test_projector_
- Renamed test_process_
- Added test to verify assigned E_*/S_* codes are in STATUS_CODE and STATUS_MSG
- Added missing status/error codes to STATUS_MSG
- Added error checks to process_inpt
- Deleted unneeded test(s)
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-26 04:14:59 +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 | 424 | 496 | ||
591 | === modified file 'openlp/core/projectors/manager.py' | |||
592 | --- openlp/core/projectors/manager.py 2017-11-24 19:08:23 +0000 | |||
593 | +++ openlp/core/projectors/manager.py 2017-12-26 04:14:59 +0000 | |||
594 | @@ -35,9 +35,25 @@ | |||
595 | 35 | from openlp.core.common.settings import Settings | 35 | from openlp.core.common.settings import Settings |
596 | 36 | from openlp.core.lib.ui import create_widget_action | 36 | from openlp.core.lib.ui import create_widget_action |
597 | 37 | from openlp.core.projectors import DialogSourceStyle | 37 | from openlp.core.projectors import DialogSourceStyle |
601 | 38 | from openlp.core.projectors.constants import ERROR_MSG, ERROR_STRING, E_AUTHENTICATION, E_ERROR, \ | 38 | from openlp.core.projectors.constants import \ |
602 | 39 | E_NETWORK, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, STATUS_STRING, S_CONNECTED, S_CONNECTING, S_COOLDOWN, \ | 39 | E_AUTHENTICATION, \ |
603 | 40 | S_INITIALIZE, S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP | 40 | E_ERROR, \ |
604 | 41 | E_NETWORK, \ | ||
605 | 42 | E_NOT_CONNECTED, \ | ||
606 | 43 | E_UNKNOWN_SOCKET_ERROR, \ | ||
607 | 44 | S_CONNECTED, \ | ||
608 | 45 | S_CONNECTING, \ | ||
609 | 46 | S_COOLDOWN, \ | ||
610 | 47 | S_INITIALIZE, \ | ||
611 | 48 | S_NOT_CONNECTED, \ | ||
612 | 49 | S_OFF, \ | ||
613 | 50 | S_ON, \ | ||
614 | 51 | S_STANDBY, \ | ||
615 | 52 | S_WARMUP, \ | ||
616 | 53 | STATUS_CODE, \ | ||
617 | 54 | STATUS_MSG, \ | ||
618 | 55 | QSOCKET_STATE | ||
619 | 56 | |||
620 | 41 | from openlp.core.projectors.db import ProjectorDB | 57 | from openlp.core.projectors.db import ProjectorDB |
621 | 42 | from openlp.core.projectors.pjlink import PJLink, PJLinkUDP | 58 | from openlp.core.projectors.pjlink import PJLink, PJLinkUDP |
622 | 43 | from openlp.core.projectors.editform import ProjectorEditForm | 59 | from openlp.core.projectors.editform import ProjectorEditForm |
623 | @@ -440,11 +456,12 @@ | |||
624 | 440 | :param opt: Needed by PyQt5 | 456 | :param opt: Needed by PyQt5 |
625 | 441 | """ | 457 | """ |
626 | 442 | projector = item.data(QtCore.Qt.UserRole) | 458 | projector = item.data(QtCore.Qt.UserRole) |
628 | 443 | if projector.link.state() != projector.link.ConnectedState: | 459 | if QSOCKET_STATE[projector.link.state()] != S_CONNECTED: |
629 | 444 | try: | 460 | try: |
630 | 461 | log.debug('ProjectorManager: Calling connect_to_host() on "{ip}"'.format(ip=projector.link.ip)) | ||
631 | 445 | projector.link.connect_to_host() | 462 | projector.link.connect_to_host() |
632 | 446 | except: | 463 | except: |
634 | 447 | pass | 464 | log.debug('ProjectorManager: "{ip}" already connected - skipping'.format(ip=projector.link.ip)) |
635 | 448 | return | 465 | return |
636 | 449 | 466 | ||
637 | 450 | def on_connect_projector(self, opt=None): | 467 | def on_connect_projector(self, opt=None): |
638 | @@ -647,7 +664,7 @@ | |||
639 | 647 | 'Other info'), | 664 | 'Other info'), |
640 | 648 | data=projector.link.other_info) | 665 | data=projector.link.other_info) |
641 | 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'), |
643 | 650 | data=ERROR_MSG[projector.link.power]) | 667 | data=STATUS_MSG[projector.link.power]) |
644 | 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'), |
645 | 652 | data=translate('OpenLP.ProjectorManager', 'Closed') | 669 | data=translate('OpenLP.ProjectorManager', 'Closed') |
646 | 653 | if projector.link.shutter | 670 | if projector.link.shutter |
647 | @@ -692,7 +709,7 @@ | |||
648 | 692 | else: | 709 | else: |
649 | 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')) |
650 | 694 | for (key, val) in projector.link.projector_errors.items(): | 711 | for (key, val) in projector.link.projector_errors.items(): |
652 | 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]) |
653 | 696 | QtWidgets.QMessageBox.information(self, translate('OpenLP.ProjectorManager', 'Projector Information'), message) | 713 | QtWidgets.QMessageBox.information(self, translate('OpenLP.ProjectorManager', 'Projector Information'), message) |
654 | 697 | 714 | ||
655 | 698 | def _add_projector(self, projector): | 715 | def _add_projector(self, projector): |
656 | @@ -817,31 +834,18 @@ | |||
657 | 817 | if ip == list_item.link.ip: | 834 | if ip == list_item.link.ip: |
658 | 818 | item = list_item | 835 | item = list_item |
659 | 819 | break | 836 | break |
685 | 820 | message = translate('OpenLP.ProjectorManager', 'No message') if msg is None else msg | 837 | if item is None: |
686 | 821 | if status in STATUS_STRING: | 838 | log.error('ProjectorManager: Unknown item "{ip}" - not updating status'.format(ip=ip)) |
687 | 822 | status_code = STATUS_STRING[status] | 839 | return |
688 | 823 | message = ERROR_MSG[status] if msg is None else msg | 840 | elif item.status == status: |
689 | 824 | elif status in ERROR_STRING: | 841 | log.debug('ProjectorManager: No status change for "{ip}" - not updating status'.format(ip=ip)) |
690 | 825 | status_code = ERROR_STRING[status] | 842 | return |
691 | 826 | message = ERROR_MSG[status] if msg is None else msg | 843 | |
692 | 827 | else: | 844 | item.status = status |
693 | 828 | status_code = status | 845 | item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status])) |
694 | 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])) |
695 | 830 | log.debug('({name}) updateStatus(status={status}) message: "{message}"'.format(name=item.link.name, | 847 | item.widget.setIcon(item.icon) |
696 | 831 | status=status_code, | 848 | return self.update_icons() |
672 | 832 | message=message)) | ||
673 | 833 | if status in STATUS_ICONS: | ||
674 | 834 | if item.status == status: | ||
675 | 835 | return | ||
676 | 836 | item.status = status | ||
677 | 837 | item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status])) | ||
678 | 838 | if status in ERROR_STRING: | ||
679 | 839 | status_code = ERROR_STRING[status] | ||
680 | 840 | elif status in STATUS_STRING: | ||
681 | 841 | status_code = STATUS_STRING[status] | ||
682 | 842 | log.debug('({name}) Updating icon with {code}'.format(name=item.link.name, code=status_code)) | ||
683 | 843 | item.widget.setIcon(item.icon) | ||
684 | 844 | self.update_icons() | ||
697 | 845 | 849 | ||
698 | 846 | def get_toolbar_item(self, name, enabled=False, hidden=False): | 850 | def get_toolbar_item(self, name, enabled=False, hidden=False): |
699 | 847 | item = self.one_toolbar.findChild(QtWidgets.QAction, name) | 851 | item = self.one_toolbar.findChild(QtWidgets.QAction, name) |
700 | @@ -877,7 +881,7 @@ | |||
701 | 877 | self.get_toolbar_item('show_projector_multiple', hidden=True) | 881 | self.get_toolbar_item('show_projector_multiple', hidden=True) |
702 | 878 | elif count == 1: | 882 | elif count == 1: |
703 | 879 | projector = self.projector_list_widget.selectedItems()[0].data(QtCore.Qt.UserRole) | 883 | projector = self.projector_list_widget.selectedItems()[0].data(QtCore.Qt.UserRole) |
705 | 880 | connected = projector.link.state() == projector.link.ConnectedState | 884 | connected = QSOCKET_STATE[projector.link.state()] == S_CONNECTED |
706 | 881 | power = projector.link.power == S_ON | 885 | power = projector.link.power == S_ON |
707 | 882 | self.get_toolbar_item('connect_projector_multiple', hidden=True) | 886 | self.get_toolbar_item('connect_projector_multiple', hidden=True) |
708 | 883 | self.get_toolbar_item('disconnect_projector_multiple', hidden=True) | 887 | self.get_toolbar_item('disconnect_projector_multiple', hidden=True) |
709 | 884 | 888 | ||
710 | === modified file 'openlp/core/projectors/pjlink.py' | |||
711 | --- openlp/core/projectors/pjlink.py 2017-12-09 11:17:05 +0000 | |||
712 | +++ openlp/core/projectors/pjlink.py 2017-12-26 04:14:59 +0000 | |||
713 | @@ -54,11 +54,12 @@ | |||
714 | 54 | 54 | ||
715 | 55 | from openlp.core.common import qmd5_hash | 55 | from openlp.core.common import qmd5_hash |
716 | 56 | from openlp.core.common.i18n import translate | 56 | from openlp.core.common.i18n import translate |
722 | 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, \ |
723 | 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, \ |
724 | 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, \ |
725 | 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, \ |
726 | 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, \ |
727 | 62 | S_CONNECTED, S_CONNECTING, S_INFO, S_NOT_CONNECTED, S_OFF, S_OK, S_ON, S_STATUS | ||
728 | 62 | 63 | ||
729 | 63 | log = logging.getLogger(__name__) | 64 | log = logging.getLogger(__name__) |
730 | 64 | log.debug('pjlink loaded') | 65 | log.debug('pjlink loaded') |
731 | @@ -69,12 +70,9 @@ | |||
732 | 69 | SocketError = QtNetwork.QAbstractSocket.SocketError | 70 | SocketError = QtNetwork.QAbstractSocket.SocketError |
733 | 70 | SocketSTate = QtNetwork.QAbstractSocket.SocketState | 71 | SocketSTate = QtNetwork.QAbstractSocket.SocketState |
734 | 71 | 72 | ||
735 | 72 | PJLINK_PREFIX = '%' | ||
736 | 73 | PJLINK_CLASS = '1' # Default to class 1 until we query the projector | ||
737 | 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 |
738 | 75 | # PJLink class for the command | 74 | # PJLink class for the command |
739 | 76 | PJLINK_HEADER = '{prefix}{{linkclass}}'.format(prefix=PJLINK_PREFIX) | 75 | PJLINK_HEADER = '{prefix}{{linkclass}}'.format(prefix=PJLINK_PREFIX) |
740 | 77 | PJLINK_SUFFIX = CR | ||
741 | 78 | 76 | ||
742 | 79 | 77 | ||
743 | 80 | class PJLinkUDP(QtNetwork.QUdpSocket): | 78 | class PJLinkUDP(QtNetwork.QUdpSocket): |
744 | @@ -136,8 +134,9 @@ | |||
745 | 136 | """ | 134 | """ |
746 | 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. |
747 | 138 | """ | 136 | """ |
748 | 137 | conn_state = STATUS_CODE[QSOCKET_STATE[self.state()]] | ||
749 | 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, |
751 | 140 | state=S_QSOCKET_STATE[self.state()])) | 139 | state=conn_state)) |
752 | 141 | self.fan = None # ERST | 140 | self.fan = None # ERST |
753 | 142 | self.filter_time = None # FILT | 141 | self.filter_time = None # FILT |
754 | 143 | self.lamp = None # LAMP | 142 | self.lamp = None # LAMP |
755 | @@ -183,42 +182,25 @@ | |||
756 | 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 |
757 | 184 | _data = data.upper() | 183 | _data = data.upper() |
758 | 185 | # Check if we have a future command not available yet | 184 | # Check if we have a future command not available yet |
761 | 186 | if cmd not in PJLINK_VALID_CMD: | 185 | if cmd not in self.pjlink_functions: |
762 | 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)) |
763 | 188 | return | 187 | return |
764 | 189 | elif _data == 'OK': | 188 | elif _data == 'OK': |
765 | 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)) |
766 | 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 |
767 | 192 | return self.send_command(cmd=cmd) | 191 | return self.send_command(cmd=cmd) |
768 | 193 | elif cmd not in self.pjlink_functions: | ||
769 | 194 | log.warning('({ip}) Unable to process command="{cmd}" (Future option?)'.format(ip=self.ip, cmd=cmd)) | ||
770 | 195 | return | ||
771 | 196 | elif _data in PJLINK_ERRORS: | 192 | elif _data in PJLINK_ERRORS: |
772 | 197 | # Oops - projector error | 193 | # Oops - projector error |
776 | 198 | log.error('({ip}) Projector returned error "{data}"'.format(ip=self.ip, data=data)) | 194 | log.error('({ip}) {cmd}: {err}'.format(ip=self.ip, |
777 | 199 | if _data == PJLINK_ERRORS[E_AUTHENTICATION]: | 195 | cmd=cmd, |
778 | 200 | # Authentication error | 196 | err=STATUS_MSG[PJLINK_ERRORS[_data]])) |
779 | 197 | if PJLINK_ERRORS[_data] == E_AUTHENTICATION: | ||
780 | 201 | self.disconnect_from_host() | 198 | self.disconnect_from_host() |
781 | 202 | self.change_status(E_AUTHENTICATION) | ||
782 | 203 | log.debug('({ip}) emitting projectorAuthentication() signal'.format(ip=self.ip)) | ||
783 | 204 | self.projectorAuthentication.emit(self.name) | 199 | self.projectorAuthentication.emit(self.name) |
798 | 205 | elif _data == PJLINK_ERRORS[E_UNDEFINED]: | 200 | return self.change_status(status=E_AUTHENTICATION) |
785 | 206 | # Projector does not recognize command | ||
786 | 207 | self.change_status(E_UNDEFINED, '{error}: "{data}"'.format(error=ERROR_MSG[E_UNDEFINED], | ||
787 | 208 | data=cmd)) | ||
788 | 209 | elif _data == PJLINK_ERRORS[E_PARAMETER]: | ||
789 | 210 | # Invalid parameter | ||
790 | 211 | self.change_status(E_PARAMETER) | ||
791 | 212 | elif _data == PJLINK_ERRORS[E_UNAVAILABLE]: | ||
792 | 213 | # Projector busy | ||
793 | 214 | self.change_status(E_UNAVAILABLE) | ||
794 | 215 | elif _data == PJLINK_ERRORS[E_PROJECTOR]: | ||
795 | 216 | # Projector/display error | ||
796 | 217 | self.change_status(E_PROJECTOR) | ||
797 | 218 | return | ||
799 | 219 | # Command checks already passed | 201 | # Command checks already passed |
800 | 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)) |
802 | 221 | self.pjlink_functions[cmd](data) | 203 | self.pjlink_functions[cmd](data=data) |
803 | 222 | 204 | ||
804 | 223 | def process_avmt(self, data): | 205 | def process_avmt(self, data): |
805 | 224 | """ | 206 | """ |
806 | @@ -313,22 +295,22 @@ | |||
807 | 313 | data[PJLINK_ERST_DATA['COVER']], | 295 | data[PJLINK_ERST_DATA['COVER']], |
808 | 314 | data[PJLINK_ERST_DATA['FILTER']], | 296 | data[PJLINK_ERST_DATA['FILTER']], |
809 | 315 | data[PJLINK_ERST_DATA['OTHER']]) | 297 | data[PJLINK_ERST_DATA['OTHER']]) |
811 | 316 | if fan != PJLINK_ERST_STATUS[E_OK]: | 298 | if fan != PJLINK_ERST_STATUS[S_OK]: |
812 | 317 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Fan')] = \ | 299 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Fan')] = \ |
813 | 318 | PJLINK_ERST_STATUS[fan] | 300 | PJLINK_ERST_STATUS[fan] |
815 | 319 | if lamp != PJLINK_ERST_STATUS[E_OK]: | 301 | if lamp != PJLINK_ERST_STATUS[S_OK]: |
816 | 320 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Lamp')] = \ | 302 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Lamp')] = \ |
817 | 321 | PJLINK_ERST_STATUS[lamp] | 303 | PJLINK_ERST_STATUS[lamp] |
819 | 322 | if temp != PJLINK_ERST_STATUS[E_OK]: | 304 | if temp != PJLINK_ERST_STATUS[S_OK]: |
820 | 323 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Temperature')] = \ | 305 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Temperature')] = \ |
821 | 324 | PJLINK_ERST_STATUS[temp] | 306 | PJLINK_ERST_STATUS[temp] |
823 | 325 | if cover != PJLINK_ERST_STATUS[E_OK]: | 307 | if cover != PJLINK_ERST_STATUS[S_OK]: |
824 | 326 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Cover')] = \ | 308 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Cover')] = \ |
825 | 327 | PJLINK_ERST_STATUS[cover] | 309 | PJLINK_ERST_STATUS[cover] |
827 | 328 | if filt != PJLINK_ERST_STATUS[E_OK]: | 310 | if filt != PJLINK_ERST_STATUS[S_OK]: |
828 | 329 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Filter')] = \ | 311 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Filter')] = \ |
829 | 330 | PJLINK_ERST_STATUS[filt] | 312 | PJLINK_ERST_STATUS[filt] |
831 | 331 | if other != PJLINK_ERST_STATUS[E_OK]: | 313 | if other != PJLINK_ERST_STATUS[S_OK]: |
832 | 332 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Other')] = \ | 314 | self.projector_errors[translate('OpenLP.ProjectorPJLink', 'Other')] = \ |
833 | 333 | PJLINK_ERST_STATUS[other] | 315 | PJLINK_ERST_STATUS[other] |
834 | 334 | return | 316 | return |
835 | @@ -373,8 +355,18 @@ | |||
836 | 373 | 355 | ||
837 | 374 | :param data: Currently selected source | 356 | :param data: Currently selected source |
838 | 375 | """ | 357 | """ |
839 | 358 | # First, see if we have a valid input based on what is installed (if available) | ||
840 | 359 | if self.source_available is not None: | ||
841 | 360 | # We have available inputs, so verify it's in the list | ||
842 | 361 | if data not in self.source_available: | ||
843 | 362 | log.warn('({ip}) Input source not listed in available sources - ignoring'.format(ip=self.ip)) | ||
844 | 363 | return | ||
845 | 364 | elif data not in PJLINK_DEFAULT_CODES: | ||
846 | 365 | # Hmm - no sources available yet, so check with PJLink defaults | ||
847 | 366 | log.warn('({ip}) Input source not listed as a PJLink available source - ignoring'.format(ip=self.ip)) | ||
848 | 367 | return | ||
849 | 376 | self.source = data | 368 | self.source = data |
851 | 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)) |
852 | 378 | return | 370 | return |
853 | 379 | 371 | ||
854 | 380 | def process_inst(self, data): | 372 | def process_inst(self, data): |
855 | @@ -390,7 +382,6 @@ | |||
856 | 390 | sources.append(source) | 382 | sources.append(source) |
857 | 391 | sources.sort() | 383 | sources.sort() |
858 | 392 | self.source_available = sources | 384 | self.source_available = sources |
859 | 393 | self.projectorUpdateIcons.emit() | ||
860 | 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, |
861 | 395 | data=self.source_available)) | 386 | data=self.source_available)) |
862 | 396 | return | 387 | return |
863 | @@ -551,17 +542,15 @@ | |||
864 | 551 | return | 542 | return |
865 | 552 | elif self.sw_version is None: | 543 | elif self.sw_version is None: |
866 | 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)) |
867 | 554 | self.sw_version = data | ||
868 | 555 | self.db_update = True | ||
869 | 556 | else: | 545 | else: |
872 | 557 | # Compare software version and see if we got the same projector | 546 | if self.sw_version != data: |
871 | 558 | if self.serial_no != data: | ||
873 | 559 | log.warning('({ip}) Projector software version does not match saved ' | 547 | log.warning('({ip}) Projector software version does not match saved ' |
874 | 560 | 'software version'.format(ip=self.ip)) | 548 | 'software version'.format(ip=self.ip)) |
875 | 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)) |
876 | 562 | log.warning('({ip}) Received: "{new}"'.format(ip=self.ip, new=data)) | 550 | log.warning('({ip}) Received: "{new}"'.format(ip=self.ip, new=data)) |
879 | 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)) |
880 | 564 | self.sw_version_received = data | 552 | self.sw_version = data |
881 | 553 | self.db_update = True | ||
882 | 565 | 554 | ||
883 | 566 | 555 | ||
884 | 567 | class PJLink(QtNetwork.QTcpSocket, PJLinkCommands): | 556 | class PJLink(QtNetwork.QTcpSocket, PJLinkCommands): |
885 | @@ -678,7 +667,7 @@ | |||
886 | 678 | Retrieve information from projector that changes. | 667 | Retrieve information from projector that changes. |
887 | 679 | Normally called by timer(). | 668 | Normally called by timer(). |
888 | 680 | """ | 669 | """ |
890 | 681 | if self.state() != S_QSOCKET_STATE['ConnectedState']: | 670 | if QSOCKET_STATE[self.state()] != S_CONNECTED: |
891 | 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)) |
892 | 683 | return | 672 | return |
893 | 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)) |
894 | @@ -688,13 +677,8 @@ | |||
895 | 688 | self.timer.setInterval(self.poll_time) | 677 | self.timer.setInterval(self.poll_time) |
896 | 689 | # Restart timer | 678 | # Restart timer |
897 | 690 | self.timer.start() | 679 | self.timer.start() |
898 | 691 | # These commands may change during connection | ||
899 | 692 | check_list = ['POWR', 'ERST', 'LAMP', 'AVMT', 'INPT'] | ||
900 | 693 | if self.pjlink_class == '2': | ||
901 | 694 | check_list.extend(['FILT', 'FREZ']) | ||
902 | 695 | for command in check_list: | ||
903 | 696 | self.send_command(command) | ||
904 | 697 | # The following commands do not change, so only check them once | 680 | # The following commands do not change, so only check them once |
905 | 681 | # Call them first in case other functions rely on something here | ||
906 | 698 | if self.power == S_ON and self.source_available is None: | 682 | if self.power == S_ON and self.source_available is None: |
907 | 699 | self.send_command('INST') | 683 | self.send_command('INST') |
908 | 700 | if self.other_info is None: | 684 | if self.other_info is None: |
909 | @@ -715,22 +699,28 @@ | |||
910 | 715 | self.send_command('RFIL') | 699 | self.send_command('RFIL') |
911 | 716 | if self.model_lamp is None: | 700 | if self.model_lamp is None: |
912 | 717 | self.send_command('RLMP') | 701 | self.send_command('RLMP') |
913 | 702 | # These commands may change during connection | ||
914 | 703 | check_list = ['POWR', 'ERST', 'LAMP', 'AVMT', 'INPT'] | ||
915 | 704 | if self.pjlink_class == '2': | ||
916 | 705 | check_list.extend(['FILT', 'FREZ']) | ||
917 | 706 | for command in check_list: | ||
918 | 707 | self.send_command(command) | ||
919 | 718 | 708 | ||
920 | 719 | def _get_status(self, status): | 709 | def _get_status(self, status): |
921 | 720 | """ | 710 | """ |
922 | 721 | Helper to retrieve status/error codes and convert to strings. | 711 | Helper to retrieve status/error codes and convert to strings. |
923 | 722 | 712 | ||
924 | 723 | :param status: Status/Error code | 713 | :param status: Status/Error code |
926 | 724 | :returns: (Status/Error code, String) | 714 | :returns: tuple (-1 if code not INT, None) |
927 | 715 | :returns: tuple (string: code as string, None if no description) | ||
928 | 716 | :returns: tuple (string: code as string, string: Status/Error description) | ||
929 | 725 | """ | 717 | """ |
930 | 726 | if not isinstance(status, int): | 718 | if not isinstance(status, int): |
936 | 727 | return -1, 'Invalid status code' | 719 | return -1, None |
937 | 728 | elif status in ERROR_STRING: | 720 | elif status not in STATUS_MSG: |
938 | 729 | return ERROR_STRING[status], ERROR_MSG[status] | 721 | return None, None |
934 | 730 | elif status in STATUS_STRING: | ||
935 | 731 | return STATUS_STRING[status], ERROR_MSG[status] | ||
939 | 732 | else: | 722 | else: |
941 | 733 | return status, translate('OpenLP.PJLink', 'Unknown status') | 723 | return STATUS_CODE[status], STATUS_MSG[status] |
942 | 734 | 724 | ||
943 | 735 | def change_status(self, status, msg=None): | 725 | def change_status(self, status, msg=None): |
944 | 736 | """ | 726 | """ |
945 | @@ -740,19 +730,27 @@ | |||
946 | 740 | :param status: Status code | 730 | :param status: Status code |
947 | 741 | :param msg: Optional message | 731 | :param msg: Optional message |
948 | 742 | """ | 732 | """ |
953 | 743 | message = translate('OpenLP.PJLink', 'No message') if msg is None else msg | 733 | if status in STATUS_CODE: |
954 | 744 | (code, message) = self._get_status(status) | 734 | log.debug('({ip}) Changing status to {status} ' |
955 | 745 | if msg is not None: | 735 | '"{msg}"'.format(ip=self.ip, |
956 | 746 | message = msg | 736 | status=STATUS_CODE[status], |
957 | 737 | msg=msg if msg is not None else STATUS_MSG[status])) | ||
958 | 738 | else: | ||
959 | 739 | log.warning('({ip}) Unknown status change code: {code}'.format(ip=self.ip, | ||
960 | 740 | code=status)) | ||
961 | 741 | return | ||
962 | 747 | if status in CONNECTION_ERRORS: | 742 | if status in CONNECTION_ERRORS: |
966 | 748 | # Projector, connection state | 743 | # Connection state error affects both socket and projector |
967 | 749 | self.projector_status = self.error_status = self.status_connect = E_NOT_CONNECTED | 744 | self.error_status = status |
968 | 750 | elif status >= S_NOT_CONNECTED and status < S_STATUS: | 745 | self.status_connect = E_NOT_CONNECTED |
969 | 746 | elif status >= S_NOT_CONNECTED and status in QSOCKET_STATE: | ||
970 | 747 | # Socket connection status update | ||
971 | 751 | self.status_connect = status | 748 | self.status_connect = status |
975 | 752 | self.projector_status = S_NOT_CONNECTED | 749 | elif status >= S_NOT_CONNECTED and status in PROJECTOR_STATE: |
976 | 753 | elif status <= S_INFO: | 750 | # Only affects the projector status |
974 | 754 | self.status_connect = S_CONNECTED | ||
977 | 755 | self.projector_status = status | 751 | self.projector_status = status |
978 | 752 | |||
979 | 753 | # These log entries are for troubleshooting only | ||
980 | 756 | (status_code, status_message) = self._get_status(self.status_connect) | 754 | (status_code, status_message) = self._get_status(self.status_connect) |
981 | 757 | log.debug('({ip}) status_connect: {code}: "{message}"'.format(ip=self.ip, | 755 | log.debug('({ip}) status_connect: {code}: "{message}"'.format(ip=self.ip, |
982 | 758 | code=status_code, | 756 | code=status_code, |
983 | @@ -765,6 +763,15 @@ | |||
984 | 765 | log.debug('({ip}) error_status: {code}: "{message}"'.format(ip=self.ip, | 763 | log.debug('({ip}) error_status: {code}: "{message}"'.format(ip=self.ip, |
985 | 766 | code=status_code, | 764 | code=status_code, |
986 | 767 | message=status_message if msg is None else msg)) | 765 | message=status_message if msg is None else msg)) |
987 | 766 | |||
988 | 767 | # Now that we logged extra information for debugging, broadcast the original change/message | ||
989 | 768 | (code, message) = self._get_status(status) | ||
990 | 769 | if msg is not None: | ||
991 | 770 | message = msg | ||
992 | 771 | elif message is None: | ||
993 | 772 | # No message for status code | ||
994 | 773 | message = translate('OpenLP.PJLink', 'No message') if msg is None else msg | ||
995 | 774 | |||
996 | 768 | self.changeStatus.emit(self.ip, status, message) | 775 | self.changeStatus.emit(self.ip, status, message) |
997 | 769 | self.projectorUpdateIcons.emit() | 776 | self.projectorUpdateIcons.emit() |
998 | 770 | 777 | ||
999 | @@ -794,7 +801,7 @@ | |||
1000 | 794 | data = decode(read, 'utf-8') | 801 | data = decode(read, 'utf-8') |
1001 | 795 | # Possibility of extraneous data on input when reading. | 802 | # Possibility of extraneous data on input when reading. |
1002 | 796 | # Clean out extraneous characters in buffer. | 803 | # Clean out extraneous characters in buffer. |
1004 | 797 | self.readLine(self.max_size) | 804 | self.read(1024) |
1005 | 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())) |
1006 | 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 |
1007 | 800 | # possible authentication | 807 | # possible authentication |
1008 | @@ -805,6 +812,7 @@ | |||
1009 | 805 | # Invalid initial packet - close socket | 812 | # Invalid initial packet - close socket |
1010 | 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)) |
1011 | 807 | return self.disconnect_from_host() | 814 | return self.disconnect_from_host() |
1012 | 815 | # Convert the initial login prompt with the expected PJLink normal command format for processing | ||
1013 | 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)) |
1014 | 809 | return self.get_data('{start}{clss}{data}'.format(start=PJLINK_PREFIX, | 817 | return self.get_data('{start}{clss}{data}'.format(start=PJLINK_PREFIX, |
1015 | 810 | clss='1', | 818 | clss='1', |
1016 | @@ -895,7 +903,7 @@ | |||
1017 | 895 | Get data from TCP socket. | 903 | Get data from TCP socket. |
1018 | 896 | """ | 904 | """ |
1019 | 897 | log.debug('({ip}) get_socket(): Reading data'.format(ip=self.ip)) | 905 | log.debug('({ip}) get_socket(): Reading data'.format(ip=self.ip)) |
1021 | 898 | if self.state() != self.ConnectedState: | 906 | if QSOCKET_STATE[self.state()] != S_CONNECTED: |
1022 | 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)) |
1023 | 900 | self.send_busy = False | 908 | self.send_busy = False |
1024 | 901 | return | 909 | return |
1025 | @@ -907,8 +915,7 @@ | |||
1026 | 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)) |
1027 | 908 | return self.receive_data_signal() | 916 | return self.receive_data_signal() |
1028 | 909 | self.socket_timer.stop() | 917 | self.socket_timer.stop() |
1031 | 910 | self.get_data(buff=read, ip=self.ip) | 918 | return self.get_data(buff=read, ip=self.ip) |
1030 | 911 | return self.receive_data_signal() | ||
1032 | 912 | 919 | ||
1033 | 913 | def get_data(self, buff, ip=None): | 920 | def get_data(self, buff, ip=None): |
1034 | 914 | """ | 921 | """ |
1035 | @@ -927,13 +934,17 @@ | |||
1036 | 927 | data = data_in.strip() | 934 | data = data_in.strip() |
1037 | 928 | # Initial packet checks | 935 | # Initial packet checks |
1038 | 929 | if (len(data) < 7): | 936 | if (len(data) < 7): |
1040 | 930 | return self._trash_buffer(msg='get_data(): Invalid packet - length') | 937 | self._trash_buffer(msg='get_data(): Invalid packet - length') |
1041 | 938 | return self.receive_data_signal() | ||
1042 | 931 | elif len(data) > self.max_size: | 939 | elif len(data) > self.max_size: |
1044 | 932 | return self._trash_buffer(msg='get_data(): Invalid packet - too long') | 940 | self._trash_buffer(msg='get_data(): Invalid packet - too long') |
1045 | 941 | return self.receive_data_signal() | ||
1046 | 933 | elif not data.startswith(PJLINK_PREFIX): | 942 | elif not data.startswith(PJLINK_PREFIX): |
1048 | 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') |
1049 | 944 | return self.receive_data_signal() | ||
1050 | 935 | elif '=' not in data: | 945 | elif '=' not in data: |
1052 | 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 "="') |
1053 | 947 | return self.receive_data_signal() | ||
1054 | 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)) |
1055 | 938 | header, data = data.split('=') | 949 | header, data = data.split('=') |
1056 | 939 | # At this point, the header should contain: | 950 | # At this point, the header should contain: |
1057 | @@ -947,15 +958,17 @@ | |||
1058 | 947 | except ValueError as e: | 958 | except ValueError as e: |
1059 | 948 | self.change_status(E_INVALID_DATA) | 959 | self.change_status(E_INVALID_DATA) |
1060 | 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)) |
1062 | 950 | return self._trash_buffer('get_data(): Expected header + command + data') | 961 | self._trash_buffer('get_data(): Expected header + command + data') |
1063 | 962 | return self.receive_data_signal() | ||
1064 | 951 | if cmd not in PJLINK_VALID_CMD: | 963 | if cmd not in PJLINK_VALID_CMD: |
1065 | 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)) |
1067 | 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)) |
1068 | 966 | return self.receive_data_signal() | ||
1069 | 954 | if int(self.pjlink_class) < int(version): | 967 | if int(self.pjlink_class) < int(version): |
1070 | 955 | log.warning('({ip}) get_data(): Projector returned class reply higher ' | 968 | log.warning('({ip}) get_data(): Projector returned class reply higher ' |
1071 | 956 | 'than projector stated class'.format(ip=self.ip)) | 969 | 'than projector stated class'.format(ip=self.ip)) |
1074 | 957 | self.send_busy = False | 970 | self.process_command(cmd, data) |
1075 | 958 | return self.process_command(cmd, data) | 971 | return self.receive_data_signal() |
1076 | 959 | 972 | ||
1077 | 960 | @QtCore.pyqtSlot(QtNetwork.QAbstractSocket.SocketError) | 973 | @QtCore.pyqtSlot(QtNetwork.QAbstractSocket.SocketError) |
1078 | 961 | def get_error(self, err): | 974 | def get_error(self, err): |
1079 | @@ -993,7 +1006,7 @@ | |||
1080 | 993 | :param salt: Optional salt for md5 hash initial authentication | 1006 | :param salt: Optional salt for md5 hash initial authentication |
1081 | 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 |
1082 | 995 | """ | 1008 | """ |
1084 | 996 | if self.state() != self.ConnectedState: | 1009 | if QSOCKET_STATE[self.state()] != S_CONNECTED: |
1085 | 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)) |
1086 | 998 | return self.reset_information() | 1011 | return self.reset_information() |
1087 | 999 | if cmd not in PJLINK_VALID_CMD: | 1012 | if cmd not in PJLINK_VALID_CMD: |
1088 | @@ -1018,7 +1031,7 @@ | |||
1089 | 1018 | header=header, | 1031 | header=header, |
1090 | 1019 | command=cmd, | 1032 | command=cmd, |
1091 | 1020 | options=opts, | 1033 | options=opts, |
1093 | 1021 | suffix=CR) | 1034 | suffix=PJLINK_SUFFIX) |
1094 | 1022 | if out in self.priority_queue: | 1035 | if out in self.priority_queue: |
1095 | 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)) |
1096 | 1024 | elif out in self.send_queue: | 1037 | elif out in self.send_queue: |
1097 | @@ -1044,9 +1057,10 @@ | |||
1098 | 1044 | """ | 1057 | """ |
1099 | 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 |
1100 | 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)) |
1101 | 1060 | conn_state = STATUS_CODE[QSOCKET_STATE[self.state()]] | ||
1102 | 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, |
1105 | 1048 | data=S_QSOCKET_STATE[self.state()])) | 1062 | data=conn_state)) |
1106 | 1049 | if self.state() != self.ConnectedState: | 1063 | if QSOCKET_STATE[self.state()] != S_CONNECTED: |
1107 | 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)) |
1108 | 1051 | self.send_busy = False | 1065 | self.send_busy = False |
1109 | 1052 | return self.disconnect_from_host() | 1066 | return self.disconnect_from_host() |
1110 | @@ -1088,10 +1102,11 @@ | |||
1111 | 1088 | """ | 1102 | """ |
1112 | 1089 | Initiate connection to projector. | 1103 | Initiate connection to projector. |
1113 | 1090 | """ | 1104 | """ |
1116 | 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)) |
1117 | 1092 | if self.state() == self.ConnectedState: | 1106 | if QSOCKET_STATE[self.state()] == S_CONNECTED: |
1118 | 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)) |
1119 | 1094 | return | 1108 | return |
1120 | 1109 | self.error_status = S_OK | ||
1121 | 1095 | self.change_status(S_CONNECTING) | 1110 | self.change_status(S_CONNECTING) |
1122 | 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)) |
1123 | 1097 | 1112 | ||
1124 | @@ -1100,12 +1115,13 @@ | |||
1125 | 1100 | """ | 1115 | """ |
1126 | 1101 | Close socket and cleanup. | 1116 | Close socket and cleanup. |
1127 | 1102 | """ | 1117 | """ |
1129 | 1103 | if abort or self.state() != self.ConnectedState: | 1118 | if abort or QSOCKET_STATE[self.state()] != S_NOT_CONNECTED: |
1130 | 1104 | if abort: | 1119 | if abort: |
1131 | 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)) |
1132 | 1121 | self.abort() | ||
1133 | 1106 | else: | 1122 | else: |
1134 | 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)) |
1136 | 1108 | self.disconnectFromHost() | 1124 | self.disconnectFromHost() |
1137 | 1109 | try: | 1125 | try: |
1138 | 1110 | self.readyRead.disconnect(self.get_socket) | 1126 | self.readyRead.disconnect(self.get_socket) |
1139 | 1111 | except TypeError: | 1127 | except TypeError: |
1140 | @@ -1201,7 +1217,7 @@ | |||
1141 | 1201 | elif src not in self.source_available: | 1217 | elif src not in self.source_available: |
1142 | 1202 | return | 1218 | return |
1143 | 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)) |
1145 | 1204 | self.send_command(cmd='INPT', opts=src) | 1220 | self.send_command(cmd='INPT', opts=src, priority=True) |
1146 | 1205 | self.poll_loop() | 1221 | self.poll_loop() |
1147 | 1206 | 1222 | ||
1148 | 1207 | def set_power_on(self): | 1223 | def set_power_on(self): |
1149 | @@ -1209,7 +1225,7 @@ | |||
1150 | 1209 | Send command to turn power to on. | 1225 | Send command to turn power to on. |
1151 | 1210 | """ | 1226 | """ |
1152 | 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)) |
1154 | 1212 | self.send_command(cmd='POWR', opts='1') | 1228 | self.send_command(cmd='POWR', opts='1', priority=True) |
1155 | 1213 | self.poll_loop() | 1229 | self.poll_loop() |
1156 | 1214 | 1230 | ||
1157 | 1215 | def set_power_off(self): | 1231 | def set_power_off(self): |
1158 | @@ -1217,7 +1233,7 @@ | |||
1159 | 1217 | Send command to turn power to standby. | 1233 | Send command to turn power to standby. |
1160 | 1218 | """ | 1234 | """ |
1161 | 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)) |
1163 | 1220 | self.send_command(cmd='POWR', opts='0') | 1236 | self.send_command(cmd='POWR', opts='0', priority=True) |
1164 | 1221 | self.poll_loop() | 1237 | self.poll_loop() |
1165 | 1222 | 1238 | ||
1166 | 1223 | def set_shutter_closed(self): | 1239 | def set_shutter_closed(self): |
1167 | @@ -1225,7 +1241,7 @@ | |||
1168 | 1225 | Send command to set shutter to closed position. | 1241 | Send command to set shutter to closed position. |
1169 | 1226 | """ | 1242 | """ |
1170 | 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)) |
1172 | 1228 | self.send_command(cmd='AVMT', opts='11') | 1244 | self.send_command(cmd='AVMT', opts='11', priority=True) |
1173 | 1229 | self.poll_loop() | 1245 | self.poll_loop() |
1174 | 1230 | 1246 | ||
1175 | 1231 | def set_shutter_open(self): | 1247 | def set_shutter_open(self): |
1176 | @@ -1233,8 +1249,9 @@ | |||
1177 | 1233 | Send command to set shutter to open position. | 1249 | Send command to set shutter to open position. |
1178 | 1234 | """ | 1250 | """ |
1179 | 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)) |
1181 | 1236 | self.send_command(cmd='AVMT', opts='10') | 1252 | self.send_command(cmd='AVMT', opts='10', priority=True) |
1182 | 1237 | self.poll_loop() | 1253 | self.poll_loop() |
1183 | 1254 | self.projectorUpdateIcons.emit() | ||
1184 | 1238 | 1255 | ||
1185 | 1239 | def receive_data_signal(self): | 1256 | def receive_data_signal(self): |
1186 | 1240 | """ | 1257 | """ |
1187 | 1241 | 1258 | ||
1188 | === modified file 'tests/functional/openlp_core/projectors/test_projector_constants.py' | |||
1189 | --- tests/functional/openlp_core/projectors/test_projector_constants.py 2017-11-10 11:59:38 +0000 | |||
1190 | +++ tests/functional/openlp_core/projectors/test_projector_constants.py 2017-12-26 04:14:59 +0000 | |||
1191 | @@ -23,12 +23,51 @@ | |||
1192 | 23 | Package to test the openlp.core.projectors.constants module. | 23 | Package to test the openlp.core.projectors.constants module. |
1193 | 24 | """ | 24 | """ |
1194 | 25 | from unittest import TestCase | 25 | from unittest import TestCase |
1195 | 26 | from openlp.core.projectors import constants | ||
1196 | 27 | from openlp.core.projectors.constants import STATUS_CODE, STATUS_MSG | ||
1197 | 26 | 28 | ||
1198 | 27 | 29 | ||
1199 | 28 | class TestProjectorConstants(TestCase): | 30 | class TestProjectorConstants(TestCase): |
1200 | 29 | """ | 31 | """ |
1201 | 30 | Test specific functions in the projector constants module. | 32 | Test specific functions in the projector constants module. |
1202 | 31 | """ | 33 | """ |
1203 | 34 | def test_defined_codes_in_status_code(self): | ||
1204 | 35 | """ | ||
1205 | 36 | Test defined status/error codes have equivalent strings | ||
1206 | 37 | """ | ||
1207 | 38 | check = [] | ||
1208 | 39 | missing_str = [] | ||
1209 | 40 | |||
1210 | 41 | # GIVEN: List of defined E_* and S_* items defined in constants | ||
1211 | 42 | for item in constants.__dict__: | ||
1212 | 43 | if item.startswith('E_') or item.startswith('S_'): | ||
1213 | 44 | check.append(item) | ||
1214 | 45 | |||
1215 | 46 | # WHEN: Verify defined list against STATUS_STR | ||
1216 | 47 | for item in check: | ||
1217 | 48 | if constants.__dict__[item] not in STATUS_CODE: | ||
1218 | 49 | missing_str.append(item) | ||
1219 | 50 | |||
1220 | 51 | # THEN: There should be no missing items | ||
1221 | 52 | assert 0 == len(missing_str), 'Status string missing: {msg}'.format(msg=missing_str) | ||
1222 | 53 | |||
1223 | 54 | def test_status_code_in_status_message(self): | ||
1224 | 55 | """ | ||
1225 | 56 | Test if entries in STATUS_CODE have equivalent descriptions in STATUS_MSG | ||
1226 | 57 | """ | ||
1227 | 58 | missing_msg = [] | ||
1228 | 59 | |||
1229 | 60 | # GIVEN: Test items | ||
1230 | 61 | check = STATUS_CODE | ||
1231 | 62 | |||
1232 | 63 | # WHEN: Verify each entry in STATUS_MSG against STATUS_CODE | ||
1233 | 64 | for item in check: | ||
1234 | 65 | if item not in STATUS_MSG: | ||
1235 | 66 | missing_msg.append(item) | ||
1236 | 67 | |||
1237 | 68 | # THEN: There should be no missing items | ||
1238 | 69 | assert 0 == len(missing_msg), 'Status message missing: {msg}'.format(msg=missing_msg) | ||
1239 | 70 | |||
1240 | 32 | def test_build_pjlink_video_label(self): | 71 | def test_build_pjlink_video_label(self): |
1241 | 33 | """ | 72 | """ |
1242 | 34 | Test building PJLINK_DEFAULT_CODES dictionary | 73 | Test building PJLINK_DEFAULT_CODES dictionary |
1243 | 35 | 74 | ||
1244 | === modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_base.py' | |||
1245 | --- tests/functional/openlp_core/projectors/test_projector_pjlink_base.py 2017-12-04 00:24:47 +0000 | |||
1246 | +++ tests/functional/openlp_core/projectors/test_projector_pjlink_base.py 2017-12-26 04:14:59 +0000 | |||
1247 | @@ -25,7 +25,7 @@ | |||
1248 | 25 | from unittest import TestCase | 25 | from unittest import TestCase |
1249 | 26 | from unittest.mock import call, patch, MagicMock | 26 | from unittest.mock import call, patch, MagicMock |
1250 | 27 | 27 | ||
1252 | 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 |
1253 | 29 | from openlp.core.projectors.db import Projector | 29 | from openlp.core.projectors.db import Projector |
1254 | 30 | from openlp.core.projectors.pjlink import PJLink | 30 | from openlp.core.projectors.pjlink import PJLink |
1255 | 31 | 31 | ||
1256 | @@ -65,7 +65,7 @@ | |||
1257 | 65 | # as first parameter | 65 | # as first parameter |
1258 | 66 | mock_change_status.called_with(E_PARAMETER, | 66 | mock_change_status.called_with(E_PARAMETER, |
1259 | 67 | 'change_status should have been called with "{}"'.format( | 67 | 'change_status should have been called with "{}"'.format( |
1261 | 68 | ERROR_STRING[E_PARAMETER])) | 68 | STATUS_CODE[E_PARAMETER])) |
1262 | 69 | 69 | ||
1263 | 70 | @patch.object(pjlink_test, 'disconnect_from_host') | 70 | @patch.object(pjlink_test, 'disconnect_from_host') |
1264 | 71 | def test_socket_abort(self, mock_disconnect): | 71 | def test_socket_abort(self, mock_disconnect): |
1265 | @@ -104,7 +104,7 @@ | |||
1266 | 104 | """ | 104 | """ |
1267 | 105 | # GIVEN: Mocks and test data | 105 | # GIVEN: Mocks and test data |
1268 | 106 | mock_state = patch.object(self.pjlink_test, 'state').start() | 106 | mock_state = patch.object(self.pjlink_test, 'state').start() |
1270 | 107 | mock_state.return_value = S_QSOCKET_STATE['ConnectedState'] | 107 | mock_state.return_value = QSOCKET_STATE[S_CONNECTED] |
1271 | 108 | mock_timer = patch.object(self.pjlink_test, 'timer').start() | 108 | mock_timer = patch.object(self.pjlink_test, 'timer').start() |
1272 | 109 | mock_timer.interval.return_value = 10 | 109 | mock_timer.interval.return_value = 10 |
1273 | 110 | mock_send_command = patch.object(self.pjlink_test, 'send_command').start() | 110 | mock_send_command = patch.object(self.pjlink_test, 'send_command').start() |
1274 | @@ -117,7 +117,6 @@ | |||
1275 | 117 | pjlink.manufacturer = None | 117 | pjlink.manufacturer = None |
1276 | 118 | pjlink.model = None | 118 | pjlink.model = None |
1277 | 119 | pjlink.pjlink_name = None | 119 | pjlink.pjlink_name = None |
1278 | 120 | pjlink.ConnectedState = S_CONNECTED | ||
1279 | 121 | call_list = [ | 120 | call_list = [ |
1280 | 122 | call('POWR'), | 121 | call('POWR'), |
1281 | 123 | call('ERST'), | 122 | call('ERST'), |
1282 | 124 | 123 | ||
1283 | === modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py' | |||
1284 | --- tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py 2017-12-09 11:17:05 +0000 | |||
1285 | +++ tests/functional/openlp_core/projectors/test_projector_pjlink_cmd_routing.py 2017-12-26 04:14:59 +0000 | |||
1286 | @@ -24,209 +24,222 @@ | |||
1287 | 24 | """ | 24 | """ |
1288 | 25 | 25 | ||
1289 | 26 | from unittest import TestCase | 26 | from unittest import TestCase |
1291 | 27 | from unittest.mock import patch, MagicMock | 27 | from unittest.mock import MagicMock, call, patch |
1292 | 28 | 28 | ||
1293 | 29 | import openlp.core.projectors.pjlink | 29 | import openlp.core.projectors.pjlink |
1295 | 30 | from openlp.core.projectors.constants import PJLINK_ERRORS, \ | 30 | from openlp.core.projectors.constants import PJLINK_ERRORS, PJLINK_PREFIX, STATUS_MSG, \ |
1296 | 31 | E_AUTHENTICATION, E_PARAMETER, E_PROJECTOR, E_UNAVAILABLE, E_UNDEFINED | 31 | E_AUTHENTICATION, E_PARAMETER, E_PROJECTOR, E_UNAVAILABLE, E_UNDEFINED |
1297 | 32 | from openlp.core.projectors.db import Projector | 32 | from openlp.core.projectors.db import Projector |
1298 | 33 | from openlp.core.projectors.pjlink import PJLink | 33 | from openlp.core.projectors.pjlink import PJLink |
1299 | 34 | 34 | ||
1308 | 35 | ''' | 35 | from tests.resources.projector.data import TEST1_DATA |
1301 | 36 | from openlp.core.projectors.constants import ERROR_STRING, PJLINK_ERST_DATA, PJLINK_ERST_STATUS, \ | ||
1302 | 37 | PJLINK_POWR_STATUS, PJLINK_VALID_CMD, E_WARN, E_ERROR, S_OFF, S_STANDBY, S_ON | ||
1303 | 38 | ''' | ||
1304 | 39 | from tests.resources.projector.data import TEST_PIN, TEST1_DATA | ||
1305 | 40 | |||
1306 | 41 | pjlink_test = PJLink(Projector(**TEST1_DATA), pin=TEST_PIN, no_poll=True) | ||
1307 | 42 | pjlink_test.ip = '127.0.0.1' | ||
1309 | 43 | 36 | ||
1310 | 44 | 37 | ||
1311 | 45 | class TestPJLinkRouting(TestCase): | 38 | class TestPJLinkRouting(TestCase): |
1312 | 46 | """ | 39 | """ |
1313 | 47 | Tests for the PJLink module command routing | 40 | Tests for the PJLink module command routing |
1314 | 48 | """ | 41 | """ |
1329 | 49 | def setUp(self): | 42 | def test_get_data_unknown_command(self): |
1330 | 50 | ''' | 43 | """ |
1331 | 51 | TestPJLinkCommands part 2 initialization | 44 | Test not a valid command |
1332 | 52 | ''' | 45 | """ |
1333 | 53 | self.pjlink_test = PJLink(Projector(**TEST1_DATA), no_poll=True) | 46 | # GIVEN: Test object |
1334 | 54 | 47 | log_warning_text = [call('(111.111.111.111) get_data(): Invalid packet - unknown command "UNK"')] | |
1335 | 55 | def tearDown(self): | 48 | log_debug_text = [call('(111.111.111.111) get_data(ip="111.111.111.111" buffer="b\'%1UNK=Huh?\'"'), |
1336 | 56 | ''' | 49 | call('(111.111.111.111) get_data(): Checking new data "%1UNK=Huh?"')] |
1337 | 57 | TestPJLinkCommands part 2 cleanups | 50 | |
1338 | 58 | ''' | 51 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1339 | 59 | self.pjlink_test = None | 52 | patch.object(openlp.core.projectors.pjlink.PJLink, '_trash_buffer') as mock_buffer: |
1340 | 60 | 53 | ||
1341 | 61 | @patch.object(openlp.core.projectors.pjlink, 'log') | 54 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1342 | 62 | def test_process_command_call_clss(self, mock_log): | 55 | pjlink.pjlink_functions = MagicMock() |
1343 | 56 | |||
1344 | 57 | # WHEN: get_data called with an unknown command | ||
1345 | 58 | pjlink.get_data(buff='{prefix}1UNK=Huh?'.format(prefix=PJLINK_PREFIX).encode('utf-8')) | ||
1346 | 59 | |||
1347 | 60 | # THEN: Appropriate log entries should have been made and methods called/not called | ||
1348 | 61 | mock_log.debug.assert_has_calls(log_debug_text) | ||
1349 | 62 | mock_log.warning.assert_has_calls(log_warning_text) | ||
1350 | 63 | assert pjlink.pjlink_functions.called is False, 'Should not have accessed pjlink_functions' | ||
1351 | 64 | assert mock_buffer.called is True, 'Should have called _trash_buffer' | ||
1352 | 65 | |||
1353 | 66 | def test_process_command_call_clss(self): | ||
1354 | 63 | """ | 67 | """ |
1355 | 64 | Test process_command calls proper function | 68 | Test process_command calls proper function |
1356 | 65 | """ | 69 | """ |
1357 | 70 | # GIVEN: Test object and mocks | ||
1358 | 71 | log_debug_calls = [call('(111.111.111.111) Processing command "CLSS" with data "1"'), | ||
1359 | 72 | call('(111.111.111.111) Calling function for CLSS')] | ||
1360 | 73 | |||
1361 | 74 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | ||
1362 | 75 | patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: | ||
1363 | 76 | |||
1364 | 77 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | ||
1365 | 78 | |||
1366 | 79 | # WHEN: process_command is called with valid function and data | ||
1367 | 80 | pjlink.process_command(cmd='CLSS', data='1') | ||
1368 | 81 | |||
1369 | 82 | # THEN: Appropriate log entries should have been made and methods called | ||
1370 | 83 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
1371 | 84 | mock_process_clss.assert_called_once_with(data='1') | ||
1372 | 85 | |||
1373 | 86 | def test_process_command_erra(self): | ||
1374 | 87 | """ | ||
1375 | 88 | Test ERRA - Authentication Error | ||
1376 | 89 | """ | ||
1377 | 66 | # GIVEN: Test object | 90 | # GIVEN: Test object |
1394 | 67 | pjlink = pjlink_test | 91 | log_error_calls = [call('(111.111.111.111) PJLINK: {msg}'.format(msg=STATUS_MSG[E_AUTHENTICATION]))] |
1395 | 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"')] |
1396 | 69 | mock_log.reset_mock() | 93 | |
1397 | 70 | mock_process_clss = MagicMock() | 94 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1398 | 71 | pjlink.pjlink_functions['CLSS'] = mock_process_clss | 95 | patch.object(openlp.core.projectors.pjlink.PJLink, 'process_pjlink') as mock_process_pjlink, \ |
1399 | 72 | 96 | patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ | |
1400 | 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, \ |
1401 | 74 | pjlink.process_command(cmd='CLSS', data='1') | 98 | patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorAuthentication') as mock_authentication: |
1402 | 75 | 99 | ||
1403 | 76 | # THEN: Process method should have been called properly | 100 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1404 | 77 | mock_log.debug.assert_called_with(log_text) | 101 | |
1405 | 78 | mock_process_clss.assert_called_with('1') | 102 | # WHEN: process_command called with ERRA |
1406 | 79 | 103 | pjlink.process_command(cmd='PJLINK', data=PJLINK_ERRORS[E_AUTHENTICATION]) | |
1407 | 80 | @patch.object(pjlink_test, 'change_status') | 104 | |
1408 | 81 | @patch.object(openlp.core.projectors.pjlink, 'log') | 105 | # THEN: Appropriate log entries should have been made and methods called/not called |
1409 | 82 | def test_process_command_err1(self, mock_log, mock_change_status): | 106 | assert mock_disconnect.called is True, 'disconnect_from_host should have been called' |
1410 | 107 | mock_log.error.assert_has_calls(log_error_calls) | ||
1411 | 108 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
1412 | 109 | mock_change_status.assert_called_once_with(status=E_AUTHENTICATION) | ||
1413 | 110 | mock_authentication.emit.assert_called_once_with(pjlink.name) | ||
1414 | 111 | mock_process_pjlink.assert_not_called() | ||
1415 | 112 | |||
1416 | 113 | def test_process_command_err1(self): | ||
1417 | 83 | """ | 114 | """ |
1418 | 84 | Test ERR1 - Undefined projector function | 115 | Test ERR1 - Undefined projector function |
1419 | 85 | """ | 116 | """ |
1420 | 86 | # GIVEN: Test object | 117 | # GIVEN: Test object |
1436 | 87 | pjlink = pjlink_test | 118 | log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_UNDEFINED]))] |
1437 | 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"'), |
1438 | 89 | mock_change_status.reset_mock() | 120 | call('(111.111.111.111) Calling function for CLSS')] |
1439 | 90 | mock_log.reset_mock() | 121 | |
1440 | 91 | 122 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | |
1441 | 92 | # WHEN: process_command called with ERR1 | 123 | patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1442 | 93 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNDEFINED]) | 124 | |
1443 | 94 | 125 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | |
1444 | 95 | # THEN: Error should be logged and status_change should be called | 126 | |
1445 | 96 | mock_change_status.assert_called_once_with(E_UNDEFINED, 'Undefined Command: "CLSS"') | 127 | # WHEN: process_command called with ERR1 |
1446 | 97 | mock_log.error.assert_called_with(log_text) | 128 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNDEFINED]) |
1447 | 98 | 129 | ||
1448 | 99 | @patch.object(pjlink_test, 'change_status') | 130 | # THEN: Appropriate log entries should have been made and methods called |
1449 | 100 | @patch.object(openlp.core.projectors.pjlink, 'log') | 131 | mock_log.error.assert_has_calls(log_error_text) |
1450 | 101 | def test_process_command_err2(self, mock_log, mock_change_status): | 132 | mock_log.debug.assert_has_calls(log_debug_text) |
1451 | 133 | mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_UNDEFINED]) | ||
1452 | 134 | |||
1453 | 135 | def test_process_command_err2(self): | ||
1454 | 102 | """ | 136 | """ |
1455 | 103 | Test ERR2 - Parameter Error | 137 | Test ERR2 - Parameter Error |
1456 | 104 | """ | 138 | """ |
1457 | 105 | # GIVEN: Test object | 139 | # GIVEN: Test object |
1529 | 106 | pjlink = pjlink_test | 140 | log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_PARAMETER]))] |
1530 | 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"'), |
1531 | 108 | mock_change_status.reset_mock() | 142 | call('(111.111.111.111) Calling function for CLSS')] |
1532 | 109 | mock_log.reset_mock() | 143 | |
1533 | 110 | 144 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | |
1534 | 111 | # WHEN: process_command called with ERR2 | 145 | patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1535 | 112 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_PARAMETER]) | 146 | |
1536 | 113 | 147 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | |
1537 | 114 | # THEN: Error should be logged and status_change should be called | 148 | |
1538 | 115 | mock_change_status.assert_called_once_with(E_PARAMETER) | 149 | # WHEN: process_command called with ERR2 |
1539 | 116 | mock_log.error.assert_called_with(log_text) | 150 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_PARAMETER]) |
1540 | 117 | 151 | ||
1541 | 118 | @patch.object(pjlink_test, 'change_status') | 152 | # THEN: Appropriate log entries should have been made and methods called/not called |
1542 | 119 | @patch.object(openlp.core.projectors.pjlink, 'log') | 153 | mock_log.error.assert_has_calls(log_error_text) |
1543 | 120 | def test_process_command_err3(self, mock_log, mock_change_status): | 154 | mock_log.debug.assert_has_calls(log_debug_text) |
1544 | 121 | """ | 155 | mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_PARAMETER]) |
1545 | 122 | Test ERR3 - Unavailable error | 156 | |
1546 | 123 | """ | 157 | def test_process_command_err3(self): |
1547 | 124 | # GIVEN: Test object | 158 | """ |
1548 | 125 | pjlink = pjlink_test | 159 | Test ERR3 - Unavailable error |
1549 | 126 | log_text = '(127.0.0.1) Projector returned error "ERR3"' | 160 | """ |
1550 | 127 | mock_change_status.reset_mock() | 161 | # GIVEN: Test object |
1551 | 128 | mock_log.reset_mock() | 162 | log_error_text = [call('(111.111.111.111) CLSS: {msg}'.format(msg=STATUS_MSG[E_UNAVAILABLE]))] |
1552 | 129 | 163 | log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "ERR3"'), | |
1553 | 130 | # WHEN: process_command called with ERR3 | 164 | call('(111.111.111.111) Calling function for CLSS')] |
1554 | 131 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNAVAILABLE]) | 165 | |
1555 | 132 | 166 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | |
1556 | 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: |
1557 | 134 | mock_change_status.assert_called_once_with(E_UNAVAILABLE) | 168 | |
1558 | 135 | mock_log.error.assert_called_with(log_text) | 169 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1559 | 136 | 170 | ||
1560 | 137 | @patch.object(pjlink_test, 'change_status') | 171 | # WHEN: process_command called with ERR3 |
1561 | 138 | @patch.object(openlp.core.projectors.pjlink, 'log') | 172 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_UNAVAILABLE]) |
1562 | 139 | def test_process_command_err4(self, mock_log, mock_change_status): | 173 | |
1563 | 140 | """ | 174 | # THEN: Appropriate log entries should have been made and methods called |
1564 | 141 | Test ERR3 - Unavailable error | 175 | mock_log.error.assert_has_calls(log_error_text) |
1565 | 142 | """ | 176 | mock_log.debug.assert_has_calls(log_debug_text) |
1566 | 143 | # GIVEN: Test object | 177 | mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_UNAVAILABLE]) |
1567 | 144 | pjlink = pjlink_test | 178 | |
1568 | 145 | log_text = '(127.0.0.1) Projector returned error "ERR4"' | 179 | def test_process_command_err4(self): |
1569 | 146 | mock_change_status.reset_mock() | 180 | """ |
1570 | 147 | mock_log.reset_mock() | 181 | Test ERR3 - Unavailable error |
1571 | 148 | 182 | """ | |
1572 | 149 | # WHEN: process_command called with ERR3 | 183 | # GIVEN: Test object |
1573 | 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]))] |
1574 | 151 | 185 | log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "ERR4"'), | |
1575 | 152 | # THEN: Error should be logged and status_change should be called | 186 | call('(111.111.111.111) Calling function for CLSS')] |
1576 | 153 | mock_change_status.assert_called_once_with(E_PROJECTOR) | 187 | |
1577 | 154 | mock_log.error.assert_called_with(log_text) | 188 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1578 | 155 | 189 | patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: | |
1579 | 156 | @patch.object(pjlink_test, 'projectorAuthentication') | 190 | |
1580 | 157 | @patch.object(pjlink_test, 'change_status') | 191 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1581 | 158 | @patch.object(pjlink_test, 'disconnect_from_host') | 192 | |
1582 | 159 | @patch.object(openlp.core.projectors.pjlink, 'log') | 193 | # WHEN: process_command called with ERR4 |
1583 | 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]) |
1584 | 161 | """ | 195 | |
1585 | 162 | Test ERRA - Authentication Error | 196 | # THEN: Appropriate log entries should have been made and methods called |
1586 | 163 | """ | 197 | mock_log.error.assert_has_calls(log_error_text) |
1587 | 164 | # GIVEN: Test object | 198 | mock_log.debug.assert_has_calls(log_debug_text) |
1588 | 165 | pjlink = pjlink_test | 199 | mock_process_clss.assert_called_once_with(data=PJLINK_ERRORS[E_PROJECTOR]) |
1518 | 166 | log_text = '(127.0.0.1) Projector returned error "ERRA"' | ||
1519 | 167 | mock_change_status.reset_mock() | ||
1520 | 168 | mock_log.reset_mock() | ||
1521 | 169 | |||
1522 | 170 | # WHEN: process_command called with ERRA | ||
1523 | 171 | pjlink.process_command(cmd='CLSS', data=PJLINK_ERRORS[E_AUTHENTICATION]) | ||
1524 | 172 | |||
1525 | 173 | # THEN: Error should be logged and several methods should be called | ||
1526 | 174 | self.assertTrue(mock_disconnect.called, 'disconnect_from_host should have been called') | ||
1527 | 175 | mock_change_status.assert_called_once_with(E_AUTHENTICATION) | ||
1528 | 176 | mock_log.error.assert_called_with(log_text) | ||
1589 | 177 | 200 | ||
1590 | 178 | def test_process_command_future(self): | 201 | def test_process_command_future(self): |
1591 | 179 | """ | 202 | """ |
1592 | 180 | Test command valid but no method to process yet | 203 | Test command valid but no method to process yet |
1593 | 181 | """ | 204 | """ |
1594 | 182 | # GIVEN: Initial mocks and data | ||
1595 | 183 | mock_log = patch.object(openlp.core.projectors.pjlink, 'log').start() | ||
1596 | 184 | mock_functions = patch.object(self.pjlink_test, 'pjlink_functions').start() | ||
1597 | 185 | mock_functions.return_value = [] | ||
1598 | 186 | |||
1599 | 187 | pjlink = self.pjlink_test | ||
1600 | 188 | log_text = '(111.111.111.111) Unable to process command="CLSS" (Future option?)' | ||
1601 | 189 | |||
1602 | 190 | # WHEN: process_command called with an unknown command | ||
1603 | 191 | pjlink.process_command(cmd='CLSS', data='DONT CARE') | ||
1604 | 192 | |||
1605 | 193 | # THEN: Error should be logged and no command called | ||
1606 | 194 | self.assertFalse(mock_functions.called, 'Should not have gotten to the end of the method') | ||
1607 | 195 | mock_log.warning.assert_called_once_with(log_text) | ||
1608 | 196 | |||
1609 | 197 | @patch.object(pjlink_test, 'pjlink_functions') | ||
1610 | 198 | @patch.object(openlp.core.projectors.pjlink, 'log') | ||
1611 | 199 | def test_process_command_invalid(self, mock_log, mock_functions): | ||
1612 | 200 | """ | ||
1613 | 201 | Test not a valid command | ||
1614 | 202 | """ | ||
1615 | 203 | # GIVEN: Test object | 205 | # GIVEN: Test object |
1627 | 204 | pjlink = pjlink_test | 206 | log_warning_text = [call('(111.111.111.111) Unable to process command="CLSS" (Future option?)')] |
1628 | 205 | mock_functions.reset_mock() | 207 | log_debug_text = [call('(111.111.111.111) Processing command "CLSS" with data "Huh?"')] |
1629 | 206 | mock_log.reset_mock() | 208 | |
1630 | 207 | 209 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | |
1631 | 208 | # WHEN: process_command called with an unknown command | 210 | patch.object(openlp.core.projectors.pjlink.PJLink, 'process_clss') as mock_process_clss: |
1632 | 209 | pjlink.process_command(cmd='Unknown', data='Dont Care') | 211 | |
1633 | 210 | log_text = '(127.0.0.1) Ignoring command="Unknown" (Invalid/Unknown)' | 212 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1634 | 211 | 213 | pjlink.pjlink_functions = MagicMock() | |
1635 | 212 | # THEN: Error should be logged and no command called | 214 | |
1636 | 213 | self.assertFalse(mock_functions.called, 'Should not have gotten to the end of the method') | 215 | # WHEN: Processing a possible future command |
1637 | 214 | mock_log.error.assert_called_once_with(log_text) | 216 | pjlink.process_command(cmd='CLSS', data="Huh?") |
1638 | 217 | |||
1639 | 218 | # THEN: Appropriate log entries should have been made and methods called/not called | ||
1640 | 219 | mock_log.debug.assert_has_calls(log_debug_text) | ||
1641 | 220 | mock_log.warning.assert_has_calls(log_warning_text) | ||
1642 | 221 | assert pjlink.pjlink_functions.called is False, 'Should not have accessed pjlink_functions' | ||
1643 | 222 | assert mock_process_clss.called is False, 'Should not have called process_clss' | ||
1644 | 215 | 223 | ||
1645 | 216 | def test_process_command_ok(self): | 224 | def test_process_command_ok(self): |
1646 | 217 | """ | 225 | """ |
1647 | 218 | Test command returned success | 226 | Test command returned success |
1648 | 219 | """ | 227 | """ |
1649 | 220 | # GIVEN: Initial mocks and data | 228 | # GIVEN: Initial mocks and data |
1662 | 221 | mock_log = patch.object(openlp.core.projectors.pjlink, 'log').start() | 229 | # GIVEN: Test object and mocks |
1663 | 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"'), |
1664 | 223 | 231 | call('(111.111.111.111) Command "CLSS" returned OK')] | |
1665 | 224 | pjlink = self.pjlink_test | 232 | |
1666 | 225 | log_text = '(111.111.111.111) Command "POWR" returned OK' | 233 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1667 | 226 | 234 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ | |
1668 | 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: |
1669 | 228 | pjlink.process_command(cmd='POWR', data='OK') | 236 | |
1670 | 229 | 237 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | |
1671 | 230 | # THEN: Appropriate calls should have been made | 238 | |
1672 | 231 | mock_log.debug.assert_called_with(log_text) | 239 | # WHEN: process_command is called with valid function and data |
1673 | 232 | mock_send_command.assert_called_once_with(cmd='POWR') | 240 | pjlink.process_command(cmd='CLSS', data='OK') |
1674 | 241 | |||
1675 | 242 | # THEN: Appropriate log entries should have been made and methods called | ||
1676 | 243 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
1677 | 244 | mock_send_command.assert_called_once_with(cmd='CLSS') | ||
1678 | 245 | mock_process_clss.assert_not_called() | ||
1679 | 233 | 246 | ||
1680 | === modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py' | |||
1681 | --- tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py 2017-12-09 11:17:05 +0000 | |||
1682 | +++ tests/functional/openlp_core/projectors/test_projector_pjlink_commands_01.py 2017-12-26 04:14:59 +0000 | |||
1683 | @@ -23,938 +23,1017 @@ | |||
1684 | 23 | Package to test the openlp.core.projectors.pjlink commands package. | 23 | Package to test the openlp.core.projectors.pjlink commands package. |
1685 | 24 | """ | 24 | """ |
1686 | 25 | from unittest import TestCase | 25 | from unittest import TestCase |
1688 | 26 | from unittest.mock import patch | 26 | from unittest.mock import call, patch |
1689 | 27 | 27 | ||
1690 | 28 | import openlp.core.projectors.pjlink | 28 | import openlp.core.projectors.pjlink |
1695 | 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, \ |
1696 | 30 | PJLINK_POWR_STATUS, \ | 30 | STATUS_CODE, STATUS_MSG, E_ERROR, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, E_WARN, \ |
1697 | 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 |
1694 | 32 | S_CONNECTED, S_OFF, S_ON, S_NOT_CONNECTED, S_CONNECTING, S_STANDBY | ||
1698 | 33 | from openlp.core.projectors.db import Projector | 32 | from openlp.core.projectors.db import Projector |
1699 | 34 | from openlp.core.projectors.pjlink import PJLink | 33 | from openlp.core.projectors.pjlink import PJLink |
1700 | 35 | 34 | ||
1711 | 36 | from tests.resources.projector.data import TEST_PIN, TEST1_DATA | 35 | from tests.resources.projector.data import TEST1_DATA |
1702 | 37 | |||
1703 | 38 | pjlink_test = PJLink(Projector(**TEST1_DATA), pin=TEST_PIN, no_poll=True) | ||
1704 | 39 | pjlink_test.ip = '127.0.0.1' | ||
1705 | 40 | |||
1706 | 41 | # Create a list of ERST positional data so we don't have to redo the same buildup multiple times | ||
1707 | 42 | PJLINK_ERST_POSITIONS = [] | ||
1708 | 43 | for pos in range(0, len(PJLINK_ERST_DATA)): | ||
1709 | 44 | if pos in PJLINK_ERST_DATA: | ||
1710 | 45 | PJLINK_ERST_POSITIONS.append(PJLINK_ERST_DATA[pos]) | ||
1712 | 46 | 36 | ||
1713 | 47 | 37 | ||
1714 | 48 | class TestPJLinkCommands(TestCase): | 38 | class TestPJLinkCommands(TestCase): |
1715 | 49 | """ | 39 | """ |
1716 | 50 | Tests for the PJLinkCommands class part 1 | 40 | Tests for the PJLinkCommands class part 1 |
1717 | 51 | """ | 41 | """ |
1721 | 52 | @patch.object(pjlink_test, 'changeStatus') | 42 | def test_projector_change_status_unknown_socket_error(self): |
1719 | 53 | @patch.object(openlp.core.projectors.pjlink, 'log') | ||
1720 | 54 | def test_projector_change_status_connection_error(self, mock_log, mock_change_status): | ||
1722 | 55 | """ | 43 | """ |
1723 | 56 | Test change_status with connection error | 44 | Test change_status with connection error |
1724 | 57 | """ | 45 | """ |
1799 | 58 | # GIVEN: Test object | 46 | log_debug_calls = [ |
1800 | 59 | pjlink = pjlink_test | 47 | call('(111.111.111.111) Changing status to ' |
1801 | 60 | pjlink.projector_status = 0 | 48 | '{status} "{msg}"'.format(status=STATUS_CODE[E_UNKNOWN_SOCKET_ERROR], |
1802 | 61 | pjlink.status_connect = 0 | 49 | msg=STATUS_MSG[E_UNKNOWN_SOCKET_ERROR])), |
1803 | 62 | test_code = E_UNKNOWN_SOCKET_ERROR | 50 | call('(111.111.111.111) status_connect: ' |
1804 | 63 | mock_change_status.reset_mock() | 51 | '{code}: "{msg}"'.format(code=STATUS_CODE[E_NOT_CONNECTED], |
1805 | 64 | mock_log.reset_mock() | 52 | msg=STATUS_MSG[E_NOT_CONNECTED])), |
1806 | 65 | 53 | call('(111.111.111.111) projector_status: ' | |
1807 | 66 | # WHEN: change_status called with unknown socket error | 54 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1808 | 67 | pjlink.change_status(status=test_code, msg=None) | 55 | msg=STATUS_MSG[S_OK])), |
1809 | 68 | 56 | call('(111.111.111.111) error_status: ' | |
1810 | 69 | # THEN: Proper settings should change and signals sent | 57 | '{code}: "{msg}"'.format(code=STATUS_CODE[E_UNKNOWN_SOCKET_ERROR], |
1811 | 70 | self.assertEqual(pjlink.projector_status, E_NOT_CONNECTED, 'Projector status should be NOT CONNECTED') | 58 | msg=STATUS_MSG[E_UNKNOWN_SOCKET_ERROR]))] |
1812 | 71 | self.assertEqual(pjlink.status_connect, E_NOT_CONNECTED, 'Status connect should be NOT CONNECTED') | 59 | |
1813 | 72 | mock_change_status.emit.assert_called_once_with(pjlink.ip, E_UNKNOWN_SOCKET_ERROR, | 60 | # GIVEN: Test object and mocks |
1814 | 73 | 'An unidentified error occurred') | 61 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1815 | 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, \ |
1816 | 75 | 63 | patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: | |
1817 | 76 | @patch.object(pjlink_test, 'changeStatus') | 64 | |
1818 | 77 | @patch.object(openlp.core.projectors.pjlink, 'log') | 65 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1819 | 78 | def test_projector_change_status_connection_status_connecting(self, mock_log, mock_change_status): | 66 | pjlink.projector_status = 0 |
1820 | 79 | """ | 67 | pjlink.status_connect = 0 |
1821 | 80 | Test change_status with connection status | 68 | |
1822 | 81 | """ | 69 | # WHEN: change_status called with unknown socket error |
1823 | 82 | # GIVEN: Test object | 70 | pjlink.change_status(status=E_UNKNOWN_SOCKET_ERROR) |
1824 | 83 | pjlink = pjlink_test | 71 | |
1825 | 84 | pjlink.projector_status = 0 | 72 | # THEN: Proper settings should change and signals sent |
1826 | 85 | pjlink.status_connect = 0 | 73 | mock_log.debug.assert_has_calls(log_debug_calls) |
1827 | 86 | test_code = S_CONNECTING | 74 | assert pjlink.projector_status == S_OK, 'Projector status should not have changed' |
1828 | 87 | mock_change_status.reset_mock() | 75 | assert pjlink.status_connect == E_NOT_CONNECTED, 'Status connect should be NOT CONNECTED' |
1829 | 88 | mock_log.reset_mock() | 76 | assert mock_UpdateIcons.emit.called is True, 'Should have called UpdateIcons' |
1830 | 89 | 77 | mock_changeStatus.emit.assert_called_once_with(pjlink.ip, E_UNKNOWN_SOCKET_ERROR, | |
1831 | 90 | # WHEN: change_status called with unknown socket error | 78 | STATUS_MSG[E_UNKNOWN_SOCKET_ERROR]) |
1832 | 91 | pjlink.change_status(status=test_code, msg=None) | 79 | |
1833 | 92 | 80 | def test_projector_change_status_connection_status_connecting(self): | |
1834 | 93 | # THEN: Proper settings should change and signals sent | 81 | """ |
1835 | 94 | self.assertEqual(pjlink.projector_status, S_NOT_CONNECTED, 'Projector status should be NOT CONNECTED') | 82 | Test change_status with connecting status |
1836 | 95 | self.assertEqual(pjlink.status_connect, S_CONNECTING, 'Status connect should be CONNECTING') | 83 | """ |
1837 | 96 | mock_change_status.emit.assert_called_once_with(pjlink.ip, S_CONNECTING, 'Connecting') | 84 | log_debug_calls = [ |
1838 | 97 | self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') | 85 | call('(111.111.111.111) Changing status to ' |
1839 | 98 | 86 | '{status} "{msg}"'.format(status=STATUS_CODE[S_CONNECTING], | |
1840 | 99 | @patch.object(pjlink_test, 'changeStatus') | 87 | msg=STATUS_MSG[S_CONNECTING])), |
1841 | 100 | @patch.object(openlp.core.projectors.pjlink, 'log') | 88 | call('(111.111.111.111) status_connect: ' |
1842 | 101 | def test_projector_change_status_connection_status_connected(self, mock_log, mock_change_status): | 89 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_CONNECTING], |
1843 | 102 | """ | 90 | msg=STATUS_MSG[S_CONNECTING])), |
1844 | 103 | Test change_status with connection status | 91 | call('(111.111.111.111) projector_status: ' |
1845 | 104 | """ | 92 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1846 | 105 | # GIVEN: Test object | 93 | msg=STATUS_MSG[S_OK])), |
1847 | 106 | pjlink = pjlink_test | 94 | call('(111.111.111.111) error_status: ' |
1848 | 107 | pjlink.projector_status = 0 | 95 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1849 | 108 | pjlink.status_connect = 0 | 96 | msg=STATUS_MSG[S_OK]))] |
1850 | 109 | test_code = S_ON | 97 | |
1851 | 110 | mock_change_status.reset_mock() | 98 | # GIVEN: Test object and mocks |
1852 | 111 | mock_log.reset_mock() | 99 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1853 | 112 | 100 | patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus, \ | |
1854 | 113 | # WHEN: change_status called with unknown socket error | 101 | patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
1855 | 114 | pjlink.change_status(status=test_code, msg=None) | 102 | |
1856 | 115 | 103 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | |
1857 | 116 | # THEN: Proper settings should change and signals sent | 104 | pjlink.projector_status = 0 |
1858 | 117 | self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') | 105 | pjlink.status_connect = 0 |
1859 | 118 | self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') | 106 | |
1860 | 119 | mock_change_status.emit.assert_called_once_with(pjlink.ip, S_ON, 'Power is on') | 107 | # WHEN: change_status called with CONNECTING |
1861 | 120 | self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') | 108 | pjlink.change_status(status=S_CONNECTING) |
1862 | 121 | 109 | ||
1863 | 122 | @patch.object(pjlink_test, 'changeStatus') | 110 | # THEN: Proper settings should change and signals sent |
1864 | 123 | @patch.object(openlp.core.projectors.pjlink, 'log') | 111 | mock_log.debug.assert_has_calls(log_debug_calls) |
1865 | 124 | def test_projector_change_status_connection_status_with_message(self, mock_log, mock_change_status): | 112 | mock_changeStatus.emit.assert_called_once_with(pjlink.ip, S_CONNECTING, STATUS_MSG[S_CONNECTING]) |
1866 | 125 | """ | 113 | assert pjlink.projector_status == S_OK, 'Projector status should not have changed' |
1867 | 126 | Test change_status with connection status | 114 | assert pjlink.status_connect == S_CONNECTING, 'Status connect should be CONNECTING' |
1868 | 127 | """ | 115 | assert mock_UpdateIcons.emit.called is True, 'Should have called UpdateIcons' |
1869 | 128 | # GIVEN: Test object | 116 | |
1870 | 129 | pjlink = pjlink_test | 117 | def test_projector_change_status_connection_status_connected(self): |
1871 | 130 | pjlink.projector_status = 0 | 118 | """ |
1872 | 131 | pjlink.status_connect = 0 | 119 | Test change_status with connected status |
1873 | 120 | """ | ||
1874 | 121 | log_debug_calls = [ | ||
1875 | 122 | call('(111.111.111.111) Changing status to ' | ||
1876 | 123 | '{status} "{msg}"'.format(status=STATUS_CODE[S_CONNECTED], | ||
1877 | 124 | msg=STATUS_MSG[S_CONNECTED])), | ||
1878 | 125 | call('(111.111.111.111) status_connect: ' | ||
1879 | 126 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_CONNECTED], | ||
1880 | 127 | msg=STATUS_MSG[S_CONNECTED])), | ||
1881 | 128 | call('(111.111.111.111) projector_status: ' | ||
1882 | 129 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], | ||
1883 | 130 | msg=STATUS_MSG[S_OK])), | ||
1884 | 131 | call('(111.111.111.111) error_status: ' | ||
1885 | 132 | '{code}: "{msg}"'.format(code=STATUS_CODE[S_OK], | ||
1886 | 133 | msg=STATUS_MSG[S_OK]))] | ||
1887 | 134 | |||
1888 | 135 | # GIVEN: Test object and mocks | ||
1889 | 136 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | ||
1890 | 137 | patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus: | ||
1891 | 138 | |||
1892 | 139 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | ||
1893 | 140 | pjlink.projector_status = 0 | ||
1894 | 141 | pjlink.status_connect = 0 | ||
1895 | 142 | |||
1896 | 143 | # WHEN: change_status called with CONNECTED | ||
1897 | 144 | pjlink.change_status(status=S_CONNECTED) | ||
1898 | 145 | |||
1899 | 146 | # THEN: Proper settings should change and signals sent | ||
1900 | 147 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
1901 | 148 | mock_changeStatus.emit.assert_called_once_with(pjlink.ip, S_CONNECTED, 'Connected') | ||
1902 | 149 | assert pjlink.projector_status == S_OK, 'Projector status should not have changed' | ||
1903 | 150 | assert pjlink.status_connect == S_CONNECTED, 'Status connect should be CONNECTED' | ||
1904 | 151 | |||
1905 | 152 | def test_projector_change_status_connection_status_with_message(self): | ||
1906 | 153 | """ | ||
1907 | 154 | Test change_status with connection status | ||
1908 | 155 | """ | ||
1909 | 132 | test_message = 'Different Status Message than default' | 156 | test_message = 'Different Status Message than default' |
1926 | 133 | test_code = S_ON | 157 | log_debug_calls = [ |
1927 | 134 | mock_change_status.reset_mock() | 158 | call('(111.111.111.111) Changing status to {status} "{msg}"'.format(status=STATUS_CODE[S_ON], |
1928 | 135 | mock_log.reset_mock() | 159 | msg=test_message)), |
1929 | 136 | 160 | call('(111.111.111.111) status_connect: {code}: "{msg}"'.format(code=STATUS_CODE[S_OK], | |
1930 | 137 | # WHEN: change_status called with unknown socket error | 161 | msg=test_message)), |
1931 | 138 | pjlink.change_status(status=test_code, msg=test_message) | 162 | call('(111.111.111.111) projector_status: {code}: "{msg}"'.format(code=STATUS_CODE[S_ON], |
1932 | 139 | 163 | msg=test_message)), | |
1933 | 140 | # THEN: Proper settings should change and signals sent | 164 | call('(111.111.111.111) error_status: {code}: "{msg}"'.format(code=STATUS_CODE[S_OK], |
1934 | 141 | self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') | 165 | msg=test_message))] |
1935 | 142 | self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') | 166 | |
1936 | 143 | mock_change_status.emit.assert_called_once_with(pjlink.ip, S_ON, test_message) | 167 | # GIVEN: Test object and mocks |
1937 | 144 | self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') | 168 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1938 | 145 | 169 | patch.object(openlp.core.projectors.pjlink.PJLink, 'changeStatus') as mock_changeStatus: | |
1939 | 146 | @patch.object(pjlink_test, 'send_command') | 170 | |
1940 | 147 | @patch.object(openlp.core.projectors.pjlink, 'log') | 171 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1941 | 148 | def test_projector_get_av_mute_status(self, mock_log, mock_send_command): | 172 | pjlink.projector_status = 0 |
1942 | 173 | pjlink.status_connect = 0 | ||
1943 | 174 | |||
1944 | 175 | # WHEN: change_status called with projector ON status | ||
1945 | 176 | pjlink.change_status(status=S_ON, msg=test_message) | ||
1946 | 177 | |||
1947 | 178 | # THEN: Proper settings should change and signals sent | ||
1948 | 179 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
1949 | 180 | mock_changeStatus.emit.assert_called_once_with(pjlink.ip, S_ON, test_message) | ||
1950 | 181 | assert pjlink.projector_status == S_ON, 'Projector status should be ON' | ||
1951 | 182 | assert pjlink.status_connect == S_OK, 'Status connect should not have changed' | ||
1952 | 183 | |||
1953 | 184 | def test_projector_get_av_mute_status(self): | ||
1954 | 149 | """ | 185 | """ |
1955 | 150 | Test sending command to retrieve shutter/audio state | 186 | Test sending command to retrieve shutter/audio state |
1956 | 151 | """ | 187 | """ |
1957 | 152 | # GIVEN: Test object | ||
1958 | 153 | pjlink = pjlink_test | ||
1959 | 154 | mock_log.reset_mock() | ||
1960 | 155 | mock_send_command.reset_mock() | ||
1961 | 156 | test_data = 'AVMT' | 188 | test_data = 'AVMT' |
1974 | 157 | test_log = '(127.0.0.1) Sending AVMT command' | 189 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
1975 | 158 | 190 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
1976 | 159 | # WHEN: get_av_mute_status is called | 191 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
1977 | 160 | pjlink.get_av_mute_status() | 192 | |
1978 | 161 | 193 | # GIVEN: Test object and mocks | |
1979 | 162 | # THEN: log data and send_command should have been called | 194 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
1980 | 163 | mock_log.debug.assert_called_once_with(test_log) | 195 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
1981 | 164 | mock_send_command.assert_called_once_with(cmd=test_data) | 196 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
1982 | 165 | 197 | ||
1983 | 166 | @patch.object(pjlink_test, 'send_command') | 198 | # WHEN: get_av_mute_status is called |
1984 | 167 | @patch.object(openlp.core.projectors.pjlink, 'log') | 199 | pjlink.get_av_mute_status() |
1985 | 168 | def test_projector_get_available_inputs(self, mock_log, mock_send_command): | 200 | |
1986 | 201 | # THEN: log data and send_command should have been called | ||
1987 | 202 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
1988 | 203 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
1989 | 204 | |||
1990 | 205 | def test_projector_get_available_inputs(self): | ||
1991 | 169 | """ | 206 | """ |
1992 | 170 | Test sending command to retrieve avaliable inputs | 207 | Test sending command to retrieve avaliable inputs |
1993 | 171 | """ | 208 | """ |
1994 | 172 | # GIVEN: Test object | ||
1995 | 173 | pjlink = pjlink_test | ||
1996 | 174 | mock_log.reset_mock() | ||
1997 | 175 | mock_send_command.reset_mock() | ||
1998 | 176 | test_data = 'INST' | 209 | test_data = 'INST' |
2011 | 177 | test_log = '(127.0.0.1) Sending INST command' | 210 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2012 | 178 | 211 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2013 | 179 | # WHEN: get_available_inputs is called | 212 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2014 | 180 | pjlink.get_available_inputs() | 213 | |
2015 | 181 | 214 | # GIVEN: Test object and mocks | |
2016 | 182 | # THEN: log data and send_command should have been called | 215 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2017 | 183 | mock_log.debug.assert_called_once_with(test_log) | 216 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2018 | 184 | mock_send_command.assert_called_once_with(cmd=test_data) | 217 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2019 | 185 | 218 | ||
2020 | 186 | @patch.object(pjlink_test, 'send_command') | 219 | # WHEN: get_available_inputs is called |
2021 | 187 | @patch.object(openlp.core.projectors.pjlink, 'log') | 220 | pjlink.get_available_inputs() |
2022 | 188 | def test_projector_get_error_status(self, mock_log, mock_send_command): | 221 | |
2023 | 222 | # THEN: log data and send_command should have been called | ||
2024 | 223 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2025 | 224 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2026 | 225 | |||
2027 | 226 | def test_projector_get_error_status(self): | ||
2028 | 189 | """ | 227 | """ |
2029 | 190 | Test sending command to retrieve projector error status | 228 | Test sending command to retrieve projector error status |
2030 | 191 | """ | 229 | """ |
2031 | 192 | # GIVEN: Test object | ||
2032 | 193 | pjlink = pjlink_test | ||
2033 | 194 | mock_log.reset_mock() | ||
2034 | 195 | mock_send_command.reset_mock() | ||
2035 | 196 | test_data = 'ERST' | 230 | test_data = 'ERST' |
2048 | 197 | test_log = '(127.0.0.1) Sending ERST command' | 231 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2049 | 198 | 232 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2050 | 199 | # WHEN: get_error_status is called | 233 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2051 | 200 | pjlink.get_error_status() | 234 | # GIVEN: Test object and mocks |
2052 | 201 | 235 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ | |
2053 | 202 | # THEN: log data and send_command should have been called | 236 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2054 | 203 | mock_log.debug.assert_called_once_with(test_log) | 237 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2055 | 204 | mock_send_command.assert_called_once_with(cmd=test_data) | 238 | |
2056 | 205 | 239 | # WHEN: get_error_status is called | |
2057 | 206 | @patch.object(pjlink_test, 'send_command') | 240 | pjlink.get_error_status() |
2058 | 207 | @patch.object(openlp.core.projectors.pjlink, 'log') | 241 | |
2059 | 208 | def test_projector_get_input_source(self, mock_log, mock_send_command): | 242 | # THEN: log data and send_command should have been called |
2060 | 243 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2061 | 244 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2062 | 245 | |||
2063 | 246 | def test_projector_get_input_source(self): | ||
2064 | 209 | """ | 247 | """ |
2065 | 210 | Test sending command to retrieve current input | 248 | Test sending command to retrieve current input |
2066 | 211 | """ | 249 | """ |
2067 | 212 | # GIVEN: Test object | ||
2068 | 213 | pjlink = pjlink_test | ||
2069 | 214 | mock_log.reset_mock() | ||
2070 | 215 | mock_send_command.reset_mock() | ||
2071 | 216 | test_data = 'INPT' | 250 | test_data = 'INPT' |
2084 | 217 | test_log = '(127.0.0.1) Sending INPT command' | 251 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2085 | 218 | 252 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2086 | 219 | # WHEN: get_input_source is called | 253 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2087 | 220 | pjlink.get_input_source() | 254 | |
2088 | 221 | 255 | # GIVEN: Test object and mocks | |
2089 | 222 | # THEN: log data and send_command should have been called | 256 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2090 | 223 | mock_log.debug.assert_called_once_with(test_log) | 257 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2091 | 224 | mock_send_command.assert_called_once_with(cmd=test_data) | 258 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2092 | 225 | 259 | ||
2093 | 226 | @patch.object(pjlink_test, 'send_command') | 260 | # WHEN: get_input_source is called |
2094 | 227 | @patch.object(openlp.core.projectors.pjlink, 'log') | 261 | pjlink.get_input_source() |
2095 | 228 | def test_projector_get_lamp_status(self, mock_log, mock_send_command): | 262 | |
2096 | 263 | # THEN: log data and send_command should have been called | ||
2097 | 264 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2098 | 265 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2099 | 266 | |||
2100 | 267 | def test_projector_get_lamp_status(self): | ||
2101 | 229 | """ | 268 | """ |
2102 | 230 | Test sending command to retrieve lamp(s) status | 269 | Test sending command to retrieve lamp(s) status |
2103 | 231 | """ | 270 | """ |
2104 | 232 | # GIVEN: Test object | ||
2105 | 233 | pjlink = pjlink_test | ||
2106 | 234 | mock_log.reset_mock() | ||
2107 | 235 | mock_send_command.reset_mock() | ||
2108 | 236 | test_data = 'LAMP' | 271 | test_data = 'LAMP' |
2121 | 237 | test_log = '(127.0.0.1) Sending LAMP command' | 272 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2122 | 238 | 273 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2123 | 239 | # WHEN: get_lamp_status is called | 274 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2124 | 240 | pjlink.get_lamp_status() | 275 | |
2125 | 241 | 276 | # GIVEN: Test object and mocks | |
2126 | 242 | # THEN: log data and send_command should have been called | 277 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2127 | 243 | mock_log.debug.assert_called_once_with(test_log) | 278 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2128 | 244 | mock_send_command.assert_called_once_with(cmd=test_data) | 279 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2129 | 245 | 280 | ||
2130 | 246 | @patch.object(pjlink_test, 'send_command') | 281 | # WHEN: get_input_source is called |
2131 | 247 | @patch.object(openlp.core.projectors.pjlink, 'log') | 282 | pjlink.get_lamp_status() |
2132 | 248 | def test_projector_get_manufacturer(self, mock_log, mock_send_command): | 283 | |
2133 | 284 | # THEN: log data and send_command should have been called | ||
2134 | 285 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2135 | 286 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2136 | 287 | |||
2137 | 288 | def test_projector_get_manufacturer(self): | ||
2138 | 249 | """ | 289 | """ |
2139 | 250 | Test sending command to retrieve manufacturer name | 290 | Test sending command to retrieve manufacturer name |
2140 | 251 | """ | 291 | """ |
2141 | 252 | # GIVEN: Test object | ||
2142 | 253 | pjlink = pjlink_test | ||
2143 | 254 | mock_log.reset_mock() | ||
2144 | 255 | mock_send_command.reset_mock() | ||
2145 | 256 | test_data = 'INF1' | 292 | test_data = 'INF1' |
2158 | 257 | test_log = '(127.0.0.1) Sending INF1 command' | 293 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2159 | 258 | 294 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2160 | 259 | # WHEN: get_manufacturer is called | 295 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2161 | 260 | pjlink.get_manufacturer() | 296 | |
2162 | 261 | 297 | # GIVEN: Test object and mocks | |
2163 | 262 | # THEN: log data and send_command should have been called | 298 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2164 | 263 | mock_log.debug.assert_called_once_with(test_log) | 299 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2165 | 264 | mock_send_command.assert_called_once_with(cmd=test_data) | 300 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2166 | 265 | 301 | ||
2167 | 266 | @patch.object(pjlink_test, 'send_command') | 302 | # WHEN: get_input_source is called |
2168 | 267 | @patch.object(openlp.core.projectors.pjlink, 'log') | 303 | pjlink.get_manufacturer() |
2169 | 268 | def test_projector_get_model(self, mock_log, mock_send_command): | 304 | |
2170 | 305 | # THEN: log data and send_command should have been called | ||
2171 | 306 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2172 | 307 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2173 | 308 | |||
2174 | 309 | def test_projector_get_model(self): | ||
2175 | 269 | """ | 310 | """ |
2176 | 270 | Test sending command to get model information | 311 | Test sending command to get model information |
2177 | 271 | """ | 312 | """ |
2178 | 272 | # GIVEN: Test object | ||
2179 | 273 | pjlink = pjlink_test | ||
2180 | 274 | mock_log.reset_mock() | ||
2181 | 275 | mock_send_command.reset_mock() | ||
2182 | 276 | test_data = 'INF2' | 313 | test_data = 'INF2' |
2195 | 277 | test_log = '(127.0.0.1) Sending INF2 command' | 314 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2196 | 278 | 315 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2197 | 279 | # WHEN: get_model is called | 316 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2198 | 280 | pjlink.get_model() | 317 | |
2199 | 281 | 318 | # GIVEN: Test object and mocks | |
2200 | 282 | # THEN: log data and send_command should have been called | 319 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2201 | 283 | mock_log.debug.assert_called_once_with(test_log) | 320 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2202 | 284 | mock_send_command.assert_called_once_with(cmd=test_data) | 321 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2203 | 285 | 322 | ||
2204 | 286 | @patch.object(pjlink_test, 'send_command') | 323 | # WHEN: get_input_source is called |
2205 | 287 | @patch.object(openlp.core.projectors.pjlink, 'log') | 324 | pjlink.get_model() |
2206 | 288 | def test_projector_get_name(self, mock_log, mock_send_command): | 325 | |
2207 | 326 | # THEN: log data and send_command should have been called | ||
2208 | 327 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2209 | 328 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2210 | 329 | |||
2211 | 330 | def test_projector_get_name(self): | ||
2212 | 289 | """ | 331 | """ |
2213 | 290 | Test sending command to get user-assigned name | 332 | Test sending command to get user-assigned name |
2214 | 291 | """ | 333 | """ |
2215 | 292 | # GIVEN: Test object | ||
2216 | 293 | pjlink = pjlink_test | ||
2217 | 294 | mock_log.reset_mock() | ||
2218 | 295 | mock_send_command.reset_mock() | ||
2219 | 296 | test_data = 'NAME' | 334 | test_data = 'NAME' |
2232 | 297 | test_log = '(127.0.0.1) Sending NAME command' | 335 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2233 | 298 | 336 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2234 | 299 | # WHEN: get_name is called | 337 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2235 | 300 | pjlink.get_name() | 338 | |
2236 | 301 | 339 | # GIVEN: Test object and mocks | |
2237 | 302 | # THEN: log data and send_command should have been called | 340 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2238 | 303 | mock_log.debug.assert_called_once_with(test_log) | 341 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2239 | 304 | mock_send_command.assert_called_once_with(cmd=test_data) | 342 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2240 | 305 | 343 | ||
2241 | 306 | @patch.object(pjlink_test, 'send_command') | 344 | # WHEN: get_input_source is called |
2242 | 307 | @patch.object(openlp.core.projectors.pjlink, 'log') | 345 | pjlink.get_name() |
2243 | 308 | def test_projector_get_other_info(self, mock_log, mock_send_command): | 346 | |
2244 | 347 | # THEN: log data and send_command should have been called | ||
2245 | 348 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2246 | 349 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2247 | 350 | |||
2248 | 351 | def test_projector_get_other_info(self): | ||
2249 | 309 | """ | 352 | """ |
2250 | 310 | Test sending command to retrieve other information | 353 | Test sending command to retrieve other information |
2251 | 311 | """ | 354 | """ |
2252 | 312 | # GIVEN: Test object | ||
2253 | 313 | pjlink = pjlink_test | ||
2254 | 314 | mock_log.reset_mock() | ||
2255 | 315 | mock_send_command.reset_mock() | ||
2256 | 316 | test_data = 'INFO' | 355 | test_data = 'INFO' |
2269 | 317 | test_log = '(127.0.0.1) Sending INFO command' | 356 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2270 | 318 | 357 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2271 | 319 | # WHEN: get_other_info is called | 358 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2272 | 320 | pjlink.get_other_info() | 359 | |
2273 | 321 | 360 | # GIVEN: Test object and mocks | |
2274 | 322 | # THEN: log data and send_command should have been called | 361 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2275 | 323 | mock_log.debug.assert_called_once_with(test_log) | 362 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2276 | 324 | mock_send_command.assert_called_once_with(cmd=test_data) | 363 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2277 | 325 | 364 | ||
2278 | 326 | @patch.object(pjlink_test, 'send_command') | 365 | # WHEN: get_input_source is called |
2279 | 327 | @patch.object(openlp.core.projectors.pjlink, 'log') | 366 | pjlink.get_other_info() |
2280 | 328 | def test_projector_get_power_status(self, mock_log, mock_send_command): | 367 | |
2281 | 368 | # THEN: log data and send_command should have been called | ||
2282 | 369 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2283 | 370 | mock_send_command.assert_called_once_with(cmd=test_data) | ||
2284 | 371 | |||
2285 | 372 | def test_projector_get_power_status(self): | ||
2286 | 329 | """ | 373 | """ |
2287 | 330 | Test sending command to retrieve current power state | 374 | Test sending command to retrieve current power state |
2288 | 331 | """ | 375 | """ |
2289 | 332 | # GIVEN: Test object | ||
2290 | 333 | pjlink = pjlink_test | ||
2291 | 334 | mock_log.reset_mock() | ||
2292 | 335 | mock_send_command.reset_mock() | ||
2293 | 336 | test_data = 'POWR' | 376 | test_data = 'POWR' |
2318 | 337 | test_log = '(127.0.0.1) Sending POWR command' | 377 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2319 | 338 | 378 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), | |
2320 | 339 | # WHEN: get_power_status called | 379 | call('(111.111.111.111) Sending {cmd} command'.format(cmd=test_data))] |
2321 | 340 | pjlink.get_power_status() | 380 | |
2322 | 341 | 381 | # GIVEN: Test object and mocks | |
2323 | 342 | # THEN: log data and send_command should have been called | 382 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
2324 | 343 | mock_log.debug.assert_called_once_with(test_log) | 383 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command: |
2325 | 344 | mock_send_command.assert_called_once_with(cmd=test_data) | 384 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2326 | 345 | 385 | ||
2327 | 346 | def test_projector_get_status_error(self): | 386 | # WHEN: get_input_source is called |
2328 | 347 | """ | 387 | pjlink.get_power_status() |
2329 | 348 | Test to check returned information for error code | 388 | |
2330 | 349 | """ | 389 | # THEN: log data and send_command should have been called |
2331 | 350 | # GIVEN: Test object | 390 | mock_log.debug.assert_has_calls(log_debug_calls) |
2332 | 351 | pjlink = pjlink_test | 391 | mock_send_command.assert_called_once_with(cmd=test_data) |
2309 | 352 | test_string = 'E_SOCKET_ADDRESS_NOT_AVAILABLE' | ||
2310 | 353 | test_message = 'The address specified to socket.bind() does not belong to the host' | ||
2311 | 354 | |||
2312 | 355 | # WHEN: get_status called | ||
2313 | 356 | string, message = pjlink._get_status(status=E_SOCKET_ADDRESS_NOT_AVAILABLE) | ||
2314 | 357 | |||
2315 | 358 | # THEN: Proper strings should have been returned | ||
2316 | 359 | self.assertEqual(string, test_string, 'Code as string should have been returned') | ||
2317 | 360 | self.assertEqual(message, test_message, 'Description of code should have been returned') | ||
2333 | 361 | 392 | ||
2334 | 362 | def test_projector_get_status_invalid(self): | 393 | def test_projector_get_status_invalid(self): |
2335 | 363 | """ | 394 | """ |
2336 | 364 | Test to check returned information for error code | 395 | Test to check returned information for error code |
2337 | 365 | """ | 396 | """ |
2338 | 366 | # GIVEN: Test object | 397 | # GIVEN: Test object |
2342 | 367 | pjlink = pjlink_test | 398 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2343 | 368 | test_string = 'Test string since get_status will only work with int' | 399 | test_string = 'NaN test' |
2341 | 369 | test_message = 'Invalid status code' | ||
2344 | 370 | 400 | ||
2345 | 371 | # WHEN: get_status called | 401 | # WHEN: get_status called |
2353 | 372 | string, message = pjlink._get_status(status=test_string) | 402 | code, message = pjlink._get_status(status=test_string) |
2354 | 373 | 403 | ||
2355 | 374 | # THEN: Proper strings should have been returned | 404 | # THEN: Proper data should have been returned |
2356 | 375 | self.assertEqual(string, -1, 'Should have returned -1 as a bad status check') | 405 | assert code == -1, 'Should have returned -1 as a bad status check' |
2357 | 376 | self.assertEqual(message, test_message, 'Error message should have been returned') | 406 | assert message is None, 'Invalid code type should have returned None for message' |
2358 | 377 | 407 | ||
2359 | 378 | def test_projector_get_status_status(self): | 408 | def test_projector_get_status_valid(self): |
2360 | 379 | """ | 409 | """ |
2361 | 380 | Test to check returned information for status codes | 410 | Test to check returned information for status codes |
2362 | 381 | """ | 411 | """ |
2363 | 382 | # GIVEN: Test object | 412 | # GIVEN: Test object |
2367 | 383 | pjlink = pjlink_test | 413 | test_message = 'Not Connected' |
2368 | 384 | test_string = 'S_NOT_CONNECTED' | 414 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2366 | 385 | test_message = 'Not connected' | ||
2369 | 386 | 415 | ||
2370 | 387 | # WHEN: get_status called | 416 | # WHEN: get_status called |
2372 | 388 | string, message = pjlink._get_status(status=S_NOT_CONNECTED) | 417 | code, message = pjlink._get_status(status=S_NOT_CONNECTED) |
2373 | 389 | 418 | ||
2374 | 390 | # THEN: Proper strings should have been returned | 419 | # THEN: Proper strings should have been returned |
2377 | 391 | self.assertEqual(string, test_string, 'Code as string should have been returned') | 420 | assert code == 'S_NOT_CONNECTED', 'Code returned should have been the same code that was sent' |
2378 | 392 | self.assertEqual(message, test_message, 'Description of code should have been returned') | 421 | assert message == test_message, 'Description of code should have been returned' |
2379 | 393 | 422 | ||
2380 | 394 | def test_projector_get_status_unknown(self): | 423 | def test_projector_get_status_unknown(self): |
2381 | 395 | """ | 424 | """ |
2382 | 396 | Test to check returned information for unknown code | 425 | Test to check returned information for unknown code |
2383 | 397 | """ | 426 | """ |
2384 | 398 | # GIVEN: Test object | 427 | # GIVEN: Test object |
2388 | 399 | pjlink = pjlink_test | 428 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2386 | 400 | test_string = 999999 | ||
2387 | 401 | test_message = 'Unknown status' | ||
2389 | 402 | 429 | ||
2390 | 403 | # WHEN: get_status called | 430 | # WHEN: get_status called |
2392 | 404 | string, message = pjlink._get_status(status=test_string) | 431 | code, message = pjlink._get_status(status=9999) |
2393 | 405 | 432 | ||
2394 | 406 | # THEN: Proper strings should have been returned | 433 | # THEN: Proper strings should have been returned |
2397 | 407 | self.assertEqual(string, test_string, 'Received code should have been returned') | 434 | assert code is None, 'Code returned should have been the same code that was sent' |
2398 | 408 | self.assertEqual(message, test_message, 'Unknown status string should have been returned') | 435 | assert message is None, 'Should have returned None as message' |
2399 | 409 | 436 | ||
2400 | 410 | def test_projector_process_inf1(self): | 437 | def test_projector_process_inf1(self): |
2401 | 411 | """ | 438 | """ |
2402 | 412 | Test saving INF1 data (manufacturer) | 439 | Test saving INF1 data (manufacturer) |
2403 | 413 | """ | 440 | """ |
2404 | 441 | test_data = 'TEst INformation MultiCase' | ||
2405 | 442 | |||
2406 | 414 | # GIVEN: Test object | 443 | # GIVEN: Test object |
2408 | 415 | pjlink = pjlink_test | 444 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2409 | 416 | pjlink.manufacturer = None | 445 | pjlink.manufacturer = None |
2410 | 417 | test_data = 'TEst INformation MultiCase' | ||
2411 | 418 | 446 | ||
2412 | 419 | # WHEN: process_inf called with test data | 447 | # WHEN: process_inf called with test data |
2413 | 420 | pjlink.process_inf1(data=test_data) | 448 | pjlink.process_inf1(data=test_data) |
2414 | 421 | 449 | ||
2415 | 422 | # THEN: Data should be saved | 450 | # THEN: Data should be saved |
2417 | 423 | self.assertEqual(pjlink.manufacturer, test_data, 'Test data should have been saved') | 451 | assert pjlink.manufacturer == test_data, 'Test data should have been saved' |
2418 | 424 | 452 | ||
2419 | 425 | def test_projector_process_inf2(self): | 453 | def test_projector_process_inf2(self): |
2420 | 426 | """ | 454 | """ |
2421 | 427 | Test saving INF2 data (model) | 455 | Test saving INF2 data (model) |
2422 | 428 | """ | 456 | """ |
2423 | 457 | test_data = 'TEst moDEl MultiCase' | ||
2424 | 458 | |||
2425 | 429 | # GIVEN: Test object | 459 | # GIVEN: Test object |
2427 | 430 | pjlink = pjlink_test | 460 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2428 | 431 | pjlink.model = None | 461 | pjlink.model = None |
2429 | 432 | test_data = 'TEst moDEl MultiCase' | ||
2430 | 433 | 462 | ||
2431 | 434 | # WHEN: process_inf called with test data | 463 | # WHEN: process_inf called with test data |
2432 | 435 | pjlink.process_inf2(data=test_data) | 464 | pjlink.process_inf2(data=test_data) |
2433 | 436 | 465 | ||
2434 | 437 | # THEN: Data should be saved | 466 | # THEN: Data should be saved |
2436 | 438 | self.assertEqual(pjlink.model, test_data, 'Test data should have been saved') | 467 | assert pjlink.model == test_data, 'Test data should have been saved' |
2437 | 439 | 468 | ||
2438 | 440 | def test_projector_process_info(self): | 469 | def test_projector_process_info(self): |
2439 | 441 | """ | 470 | """ |
2440 | 442 | Test saving INFO data (other information) | 471 | Test saving INFO data (other information) |
2441 | 443 | """ | 472 | """ |
2442 | 473 | test_data = 'TEst ExtrANEous MultiCase INformatoin that MFGR might Set' | ||
2443 | 474 | |||
2444 | 444 | # GIVEN: Test object | 475 | # GIVEN: Test object |
2446 | 445 | pjlink = pjlink_test | 476 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2447 | 446 | pjlink.other_info = None | 477 | pjlink.other_info = None |
2448 | 447 | test_data = 'TEst ExtrANEous MultiCase INformatoin that MFGR might Set' | ||
2449 | 448 | 478 | ||
2450 | 449 | # WHEN: process_inf called with test data | 479 | # WHEN: process_inf called with test data |
2451 | 450 | pjlink.process_info(data=test_data) | 480 | pjlink.process_info(data=test_data) |
2452 | 451 | 481 | ||
2453 | 452 | # THEN: Data should be saved | 482 | # THEN: Data should be saved |
2455 | 453 | self.assertEqual(pjlink.other_info, test_data, 'Test data should have been saved') | 483 | assert pjlink.other_info == test_data, 'Test data should have been saved' |
2456 | 454 | 484 | ||
2459 | 455 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 485 | def test_projector_process_avmt_bad_data(self): |
2458 | 456 | def test_projector_process_avmt_bad_data(self, mock_UpdateIcons): | ||
2460 | 457 | """ | 486 | """ |
2461 | 458 | Test avmt bad data fail | 487 | Test avmt bad data fail |
2462 | 459 | """ | 488 | """ |
2463 | 460 | # GIVEN: Test object | 489 | # GIVEN: Test object |
2478 | 461 | pjlink = pjlink_test | 490 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2479 | 462 | pjlink.shutter = True | 491 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2480 | 463 | pjlink.mute = True | 492 | pjlink.shutter = True |
2481 | 464 | 493 | pjlink.mute = True | |
2482 | 465 | # WHEN: Called with an invalid setting | 494 | |
2483 | 466 | pjlink.process_avmt('36') | 495 | # WHEN: Called with an invalid setting |
2484 | 467 | 496 | pjlink.process_avmt('36') | |
2485 | 468 | # THEN: Shutter should be closed and mute should be True | 497 | |
2486 | 469 | self.assertTrue(pjlink.shutter, 'Shutter should changed') | 498 | # THEN: Shutter should be closed and mute should be True |
2487 | 470 | self.assertTrue(pjlink.mute, 'Audio should not have changed') | 499 | assert pjlink.shutter is True, 'Shutter should changed' |
2488 | 471 | self.assertFalse(mock_UpdateIcons.emit.called, 'Update icons should NOT have been called') | 500 | assert pjlink.mute is True, 'Audio should not have changed' |
2489 | 472 | 501 | assert mock_UpdateIcons.emit.called is False, 'Update icons should NOT have been called' | |
2490 | 473 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 502 | |
2491 | 474 | def test_projector_process_avmt_closed_muted(self, mock_UpdateIcons): | 503 | def test_projector_process_avmt_closed_muted(self): |
2492 | 475 | """ | 504 | """ |
2493 | 476 | Test avmt status shutter closed and mute off | 505 | Test avmt status shutter closed and mute off |
2494 | 477 | """ | 506 | """ |
2495 | 478 | # GIVEN: Test object | 507 | # GIVEN: Test object |
2510 | 479 | pjlink = pjlink_test | 508 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2511 | 480 | pjlink.shutter = False | 509 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2512 | 481 | pjlink.mute = False | 510 | pjlink.shutter = False |
2513 | 482 | 511 | pjlink.mute = False | |
2514 | 483 | # WHEN: Called with setting shutter to closed and mute on | 512 | |
2515 | 484 | pjlink.process_avmt('31') | 513 | # WHEN: Called with setting shutter to closed and mute on |
2516 | 485 | 514 | pjlink.process_avmt('31') | |
2517 | 486 | # THEN: Shutter should be closed and mute should be True | 515 | |
2518 | 487 | self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed') | 516 | # THEN: Shutter should be closed and mute should be True |
2519 | 488 | self.assertTrue(pjlink.mute, 'Audio should be muted') | 517 | assert pjlink.shutter is True, 'Shutter should have been set to closed' |
2520 | 489 | self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') | 518 | assert pjlink.mute is True, 'Audio should be muted' |
2521 | 490 | 519 | assert mock_UpdateIcons.emit.called is True, 'Update icons should have been called' | |
2522 | 491 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 520 | |
2523 | 492 | def test_projector_process_avmt_shutter_closed(self, mock_UpdateIcons): | 521 | def test_projector_process_avmt_shutter_closed(self): |
2524 | 493 | """ | 522 | """ |
2525 | 494 | Test avmt status shutter closed and audio unchanged | 523 | Test avmt status shutter closed and audio unchanged |
2526 | 495 | """ | 524 | """ |
2527 | 496 | # GIVEN: Test object | 525 | # GIVEN: Test object |
2542 | 497 | pjlink = pjlink_test | 526 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2543 | 498 | pjlink.shutter = False | 527 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2544 | 499 | pjlink.mute = True | 528 | pjlink.shutter = False |
2545 | 500 | 529 | pjlink.mute = True | |
2546 | 501 | # WHEN: Called with setting shutter closed and mute off | 530 | |
2547 | 502 | pjlink.process_avmt('11') | 531 | # WHEN: Called with setting shutter closed and mute off |
2548 | 503 | 532 | pjlink.process_avmt('11') | |
2549 | 504 | # THEN: Shutter should be True and mute should be False | 533 | |
2550 | 505 | self.assertTrue(pjlink.shutter, 'Shutter should have been set to closed') | 534 | # THEN: Shutter should be True and mute should be False |
2551 | 506 | self.assertTrue(pjlink.mute, 'Audio should not have changed') | 535 | assert pjlink.shutter is True, 'Shutter should have been set to closed' |
2552 | 507 | self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') | 536 | assert pjlink.mute is True, 'Audio should not have changed' |
2553 | 508 | 537 | assert mock_UpdateIcons.emit.called is True, 'Update icons should have been called' | |
2554 | 509 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 538 | |
2555 | 510 | def test_projector_process_avmt_audio_muted(self, mock_UpdateIcons): | 539 | def test_projector_process_avmt_audio_muted(self): |
2556 | 511 | """ | 540 | """ |
2557 | 512 | Test avmt status shutter unchanged and mute on | 541 | Test avmt status shutter unchanged and mute on |
2558 | 513 | """ | 542 | """ |
2559 | 514 | # GIVEN: Test object | 543 | # GIVEN: Test object |
2574 | 515 | pjlink = pjlink_test | 544 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2575 | 516 | pjlink.shutter = True | 545 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2576 | 517 | pjlink.mute = False | 546 | pjlink.shutter = True |
2577 | 518 | 547 | pjlink.mute = False | |
2578 | 519 | # WHEN: Called with setting shutter closed and mute on | 548 | |
2579 | 520 | pjlink.process_avmt('21') | 549 | # WHEN: Called with setting shutter closed and mute on |
2580 | 521 | 550 | pjlink.process_avmt('21') | |
2581 | 522 | # THEN: Shutter should be closed and mute should be True | 551 | |
2582 | 523 | self.assertTrue(pjlink.shutter, 'Shutter should not have changed') | 552 | # THEN: Shutter should be closed and mute should be True |
2583 | 524 | self.assertTrue(pjlink.mute, 'Audio should be off') | 553 | assert pjlink.shutter is True, 'Shutter should not have changed' |
2584 | 525 | self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') | 554 | assert pjlink.mute is True, 'Audio should be off' |
2585 | 526 | 555 | assert mock_UpdateIcons.emit.called is True, 'Update icons should have been called' | |
2586 | 527 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 556 | |
2587 | 528 | def test_projector_process_avmt_open_unmuted(self, mock_UpdateIcons): | 557 | def test_projector_process_avmt_open_unmuted(self): |
2588 | 529 | """ | 558 | """ |
2589 | 530 | Test avmt status shutter open and mute off | 559 | Test avmt status shutter open and mute off |
2590 | 531 | """ | 560 | """ |
2591 | 532 | # GIVEN: Test object | 561 | # GIVEN: Test object |
2603 | 533 | pjlink = pjlink_test | 562 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
2604 | 534 | pjlink.shutter = True | 563 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2605 | 535 | pjlink.mute = True | 564 | pjlink.shutter = True |
2606 | 536 | 565 | pjlink.mute = True | |
2607 | 537 | # WHEN: Called with setting shutter to closed and mute on | 566 | |
2608 | 538 | pjlink.process_avmt('30') | 567 | # WHEN: Called with setting shutter to closed and mute on |
2609 | 539 | 568 | pjlink.process_avmt('30') | |
2610 | 540 | # THEN: Shutter should be closed and mute should be True | 569 | |
2611 | 541 | self.assertFalse(pjlink.shutter, 'Shutter should have been set to open') | 570 | # THEN: Shutter should be closed and mute should be True |
2612 | 542 | self.assertFalse(pjlink.mute, 'Audio should be on') | 571 | assert pjlink.shutter is False, 'Shutter should have been set to open' |
2613 | 543 | self.assertTrue(mock_UpdateIcons.emit.called, 'Update icons should have been called') | 572 | assert pjlink.mute is False, 'Audio should be on' |
2614 | 573 | assert mock_UpdateIcons.emit.called is True, 'Update icons should have been called' | ||
2615 | 544 | 574 | ||
2616 | 545 | def test_projector_process_clss_one(self): | 575 | def test_projector_process_clss_one(self): |
2617 | 546 | """ | 576 | """ |
2618 | 547 | Test class 1 sent from projector | 577 | Test class 1 sent from projector |
2619 | 548 | """ | 578 | """ |
2620 | 549 | # GIVEN: Test object | 579 | # GIVEN: Test object |
2622 | 550 | pjlink = pjlink_test | 580 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2623 | 551 | 581 | ||
2624 | 552 | # WHEN: Process class response | 582 | # WHEN: Process class response |
2625 | 553 | pjlink.process_clss('1') | 583 | pjlink.process_clss('1') |
2626 | 554 | 584 | ||
2627 | 555 | # THEN: Projector class should be set to 1 | 585 | # THEN: Projector class should be set to 1 |
2630 | 556 | self.assertEqual(pjlink.pjlink_class, '1', | 586 | assert pjlink.pjlink_class == '1', 'Projector should have set class=1' |
2629 | 557 | 'Projector should have set class=1') | ||
2631 | 558 | 587 | ||
2632 | 559 | def test_projector_process_clss_two(self): | 588 | def test_projector_process_clss_two(self): |
2633 | 560 | """ | 589 | """ |
2634 | 561 | Test class 2 sent from projector | 590 | Test class 2 sent from projector |
2635 | 562 | """ | 591 | """ |
2636 | 563 | # GIVEN: Test object | 592 | # GIVEN: Test object |
2638 | 564 | pjlink = pjlink_test | 593 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2639 | 565 | 594 | ||
2640 | 566 | # WHEN: Process class response | 595 | # WHEN: Process class response |
2641 | 567 | pjlink.process_clss('2') | 596 | pjlink.process_clss('2') |
2642 | 568 | 597 | ||
2643 | 569 | # THEN: Projector class should be set to 1 | 598 | # THEN: Projector class should be set to 1 |
2680 | 570 | self.assertEqual(pjlink.pjlink_class, '2', | 599 | assert pjlink.pjlink_class == '2', 'Projector should have set class=2' |
2681 | 571 | 'Projector should have set class=2') | 600 | |
2682 | 572 | 601 | def test_projector_process_clss_invalid_nan(self): | |
2683 | 573 | @patch.object(openlp.core.projectors.pjlink, 'log') | 602 | """ |
2684 | 574 | def test_projector_process_clss_invalid_nan(self, mock_log): | 603 | Test CLSS reply has no class number |
2685 | 575 | """ | 604 | """ |
2686 | 576 | Test CLSS reply has no class number | 605 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' |
2687 | 577 | """ | 606 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2688 | 578 | # GIVEN: Test object | 607 | call('(111.111.111.111) Setting pjlink_class for this projector to "1"')] |
2689 | 579 | pjlink = pjlink_test | 608 | log_error_calls = [call('(111.111.111.111) NAN CLSS version reply "Z" - defaulting to class "1"')] |
2690 | 580 | 609 | ||
2691 | 581 | # WHEN: Process invalid reply | 610 | # GIVEN: Test object |
2692 | 582 | pjlink.process_clss('Z') | 611 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2693 | 583 | log_text = '(127.0.0.1) NAN CLSS version reply "Z" - defaulting to class "1"' | 612 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2694 | 584 | 613 | ||
2695 | 585 | # THEN: Projector class should be set with default value | 614 | # WHEN: Process invalid reply |
2696 | 586 | self.assertEqual(pjlink.pjlink_class, '1', | 615 | pjlink.process_clss('Z') |
2697 | 587 | 'Non-standard class reply should have set class=1') | 616 | |
2698 | 588 | mock_log.error.assert_called_once_with(log_text) | 617 | # THEN: Projector class should be set with default value |
2699 | 589 | 618 | assert pjlink.pjlink_class == '1', 'Invalid NaN class reply should have set class=1' | |
2700 | 590 | @patch.object(openlp.core.projectors.pjlink, 'log') | 619 | mock_log.error.assert_has_calls(log_error_calls) |
2701 | 591 | def test_projector_process_clss_invalid_no_version(self, mock_log): | 620 | mock_log.debug.assert_has_calls(log_debug_calls) |
2702 | 592 | """ | 621 | |
2703 | 593 | Test CLSS reply has no class number | 622 | def test_projector_process_clss_invalid_no_version(self): |
2704 | 594 | """ | 623 | """ |
2705 | 595 | # GIVEN: Test object | 624 | Test CLSS reply has no class number |
2706 | 596 | pjlink = pjlink_test | 625 | """ |
2707 | 597 | 626 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' | |
2708 | 598 | # WHEN: Process invalid reply | 627 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED])), |
2709 | 599 | pjlink.process_clss('Invalid') | 628 | call('(111.111.111.111) Setting pjlink_class for this projector to "1"')] |
2710 | 600 | log_text = '(127.0.0.1) No numbers found in class version reply "Invalid" - defaulting to class "1"' | 629 | log_error_calls = [call('(111.111.111.111) No numbers found in class version reply "Invalid" ' |
2711 | 601 | 630 | '- defaulting to class "1"')] | |
2712 | 602 | # THEN: Projector class should be set with default value | 631 | |
2713 | 603 | self.assertEqual(pjlink.pjlink_class, '1', | 632 | # GIVEN: Test object |
2714 | 604 | 'Non-standard class reply should have set class=1') | 633 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2715 | 605 | mock_log.error.assert_called_once_with(log_text) | 634 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2716 | 635 | |||
2717 | 636 | # WHEN: Process invalid reply | ||
2718 | 637 | pjlink.process_clss('Invalid') | ||
2719 | 638 | |||
2720 | 639 | # THEN: Projector class should be set with default value | ||
2721 | 640 | assert pjlink.pjlink_class == '1', 'Invalid class reply should have set class=1' | ||
2722 | 641 | mock_log.error.assert_has_calls(log_error_calls) | ||
2723 | 642 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
2724 | 606 | 643 | ||
2725 | 607 | def test_projector_process_erst_all_ok(self): | 644 | def test_projector_process_erst_all_ok(self): |
2726 | 608 | """ | 645 | """ |
2728 | 609 | Test test_projector_process_erst_all_ok | 646 | Test to verify pjlink.projector_errors is set to None when no errors |
2729 | 610 | """ | 647 | """ |
2730 | 648 | chk_data = '0' * PJLINK_ERST_DATA['DATA_LENGTH'] | ||
2731 | 649 | |||
2732 | 611 | # GIVEN: Test object | 650 | # GIVEN: Test object |
2736 | 612 | pjlink = pjlink_test | 651 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2734 | 613 | chk_test = PJLINK_ERST_STATUS['OK'] | ||
2735 | 614 | chk_param = chk_test * len(PJLINK_ERST_POSITIONS) | ||
2737 | 615 | 652 | ||
2738 | 616 | # WHEN: process_erst with no errors | 653 | # WHEN: process_erst with no errors |
2740 | 617 | pjlink.process_erst(chk_param) | 654 | pjlink.process_erst(chk_data) |
2741 | 618 | 655 | ||
2742 | 619 | # THEN: PJLink instance errors should be None | 656 | # THEN: PJLink instance errors should be None |
2744 | 620 | self.assertIsNone(pjlink.projector_errors, 'projector_errors should have been set to None') | 657 | assert pjlink.projector_errors is None, 'projector_errors should have been set to None' |
2745 | 621 | 658 | ||
2748 | 622 | @patch.object(openlp.core.projectors.pjlink, 'log') | 659 | def test_projector_process_erst_data_invalid_length(self): |
2747 | 623 | def test_projector_process_erst_data_invalid_length(self, mock_log): | ||
2749 | 624 | """ | 660 | """ |
2750 | 625 | Test test_projector_process_erst_data_invalid_length | 661 | Test test_projector_process_erst_data_invalid_length |
2751 | 626 | """ | 662 | """ |
2752 | 663 | chk_data = '0' * (PJLINK_ERST_DATA['DATA_LENGTH'] + 1) | ||
2753 | 664 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' | ||
2754 | 665 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED]))] | ||
2755 | 666 | log_warn_calls = [call('111.111.111.111) Invalid error status response "0000000": ' | ||
2756 | 667 | 'length != {chk}'.format(chk=PJLINK_ERST_DATA['DATA_LENGTH']))] | ||
2757 | 668 | |||
2758 | 627 | # GIVEN: Test object | 669 | # GIVEN: Test object |
2773 | 628 | pjlink = pjlink_test | 670 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2774 | 629 | pjlink.projector_errors = None | 671 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2775 | 630 | log_text = '127.0.0.1) Invalid error status response "11111111": length != 6' | 672 | pjlink.projector_errors = None |
2776 | 631 | 673 | ||
2777 | 632 | # WHEN: process_erst called with invalid data (too many values | 674 | # WHEN: process_erst called with invalid data (too many values |
2778 | 633 | pjlink.process_erst('11111111') | 675 | pjlink.process_erst(chk_data) |
2779 | 634 | 676 | ||
2780 | 635 | # THEN: pjlink.projector_errors should be empty and warning logged | 677 | # THEN: pjlink.projector_errors should be empty and warning logged |
2781 | 636 | self.assertIsNone(pjlink.projector_errors, 'There should be no errors') | 678 | assert pjlink.projector_errors is None, 'There should be no errors' |
2782 | 637 | self.assertTrue(mock_log.warning.called, 'Warning should have been logged') | 679 | mock_log.debug.assert_has_calls(log_debug_calls) |
2783 | 638 | mock_log.warning.assert_called_once_with(log_text) | 680 | mock_log.warning.assert_has_calls(log_warn_calls) |
2784 | 639 | 681 | ||
2785 | 640 | @patch.object(openlp.core.projectors.pjlink, 'log') | 682 | def test_projector_process_erst_data_invalid_nan(self): |
2772 | 641 | def test_projector_process_erst_data_invalid_nan(self, mock_log): | ||
2786 | 642 | """ | 683 | """ |
2787 | 643 | Test test_projector_process_erst_data_invalid_nan | 684 | Test test_projector_process_erst_data_invalid_nan |
2788 | 644 | """ | 685 | """ |
2789 | 686 | chk_data = 'Z' + ('0' * (PJLINK_ERST_DATA['DATA_LENGTH'] - 1)) | ||
2790 | 687 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is ' | ||
2791 | 688 | '{state}'.format(state=STATUS_CODE[S_NOT_CONNECTED]))] | ||
2792 | 689 | log_warn_calls = [call('(111.111.111.111) Invalid error status response "Z00000"')] | ||
2793 | 690 | |||
2794 | 645 | # GIVEN: Test object | 691 | # GIVEN: Test object |
2806 | 646 | pjlink = pjlink_test | 692 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2807 | 647 | pjlink.projector_errors = None | 693 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2808 | 648 | log_text = '(127.0.0.1) Invalid error status response "1111Z1"' | 694 | pjlink.projector_errors = None |
2809 | 649 | 695 | ||
2810 | 650 | # WHEN: process_erst called with invalid data (too many values | 696 | # WHEN: process_erst called with invalid data (too many values |
2811 | 651 | pjlink.process_erst('1111Z1') | 697 | pjlink.process_erst(chk_data) |
2812 | 652 | 698 | ||
2813 | 653 | # THEN: pjlink.projector_errors should be empty and warning logged | 699 | # THEN: pjlink.projector_errors should be empty and warning logged |
2814 | 654 | self.assertIsNone(pjlink.projector_errors, 'There should be no errors') | 700 | assert pjlink.projector_errors is None, 'There should be no errors' |
2815 | 655 | self.assertTrue(mock_log.warning.called, 'Warning should have been logged') | 701 | mock_log.debug.assert_has_calls(log_debug_calls) |
2816 | 656 | mock_log.warning.assert_called_once_with(log_text) | 702 | mock_log.warning.assert_has_calls(log_warn_calls) |
2817 | 657 | 703 | ||
2818 | 658 | def test_projector_process_erst_all_warn(self): | 704 | def test_projector_process_erst_all_warn(self): |
2819 | 659 | """ | 705 | """ |
2820 | 660 | Test test_projector_process_erst_all_warn | 706 | Test test_projector_process_erst_all_warn |
2821 | 661 | """ | 707 | """ |
2822 | 708 | chk_data = '{fan}{lamp}{temp}{cover}{filt}{other}'.format(fan=PJLINK_ERST_STATUS[E_WARN], | ||
2823 | 709 | lamp=PJLINK_ERST_STATUS[E_WARN], | ||
2824 | 710 | temp=PJLINK_ERST_STATUS[E_WARN], | ||
2825 | 711 | cover=PJLINK_ERST_STATUS[E_WARN], | ||
2826 | 712 | filt=PJLINK_ERST_STATUS[E_WARN], | ||
2827 | 713 | other=PJLINK_ERST_STATUS[E_WARN]) | ||
2828 | 714 | chk_test = {'Fan': E_WARN, | ||
2829 | 715 | 'Lamp': E_WARN, | ||
2830 | 716 | 'Temperature': E_WARN, | ||
2831 | 717 | 'Cover': E_WARN, | ||
2832 | 718 | 'Filter': E_WARN, | ||
2833 | 719 | 'Other': E_WARN} | ||
2834 | 720 | |||
2835 | 662 | # GIVEN: Test object | 721 | # GIVEN: Test object |
2840 | 663 | pjlink = pjlink_test | 722 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2841 | 664 | chk_test = PJLINK_ERST_STATUS[E_WARN] | 723 | pjlink.projector_errors = None |
2838 | 665 | chk_string = ERROR_STRING[E_WARN] | ||
2839 | 666 | chk_param = chk_test * len(PJLINK_ERST_POSITIONS) | ||
2842 | 667 | 724 | ||
2843 | 668 | # WHEN: process_erst with status set to WARN | 725 | # WHEN: process_erst with status set to WARN |
2845 | 669 | pjlink.process_erst(chk_param) | 726 | pjlink.process_erst(chk_data) |
2846 | 670 | 727 | ||
2847 | 671 | # THEN: PJLink instance errors should match chk_value | 728 | # THEN: PJLink instance errors should match chk_value |
2852 | 672 | for chk in pjlink.projector_errors: | 729 | assert pjlink.projector_errors == chk_test, 'Projector errors should be all E_WARN' |
2849 | 673 | self.assertEqual(pjlink.projector_errors[chk], chk_string, | ||
2850 | 674 | 'projector_errors["{chk}"] should have been set to "{err}"'.format(chk=chk, | ||
2851 | 675 | err=chk_string)) | ||
2853 | 676 | 730 | ||
2854 | 677 | def test_projector_process_erst_all_error(self): | 731 | def test_projector_process_erst_all_error(self): |
2855 | 678 | """ | 732 | """ |
2856 | 679 | Test test_projector_process_erst_all_error | 733 | Test test_projector_process_erst_all_error |
2857 | 680 | """ | 734 | """ |
2858 | 735 | chk_data = '{fan}{lamp}{temp}{cover}{filt}{other}'.format(fan=PJLINK_ERST_STATUS[E_ERROR], | ||
2859 | 736 | lamp=PJLINK_ERST_STATUS[E_ERROR], | ||
2860 | 737 | temp=PJLINK_ERST_STATUS[E_ERROR], | ||
2861 | 738 | cover=PJLINK_ERST_STATUS[E_ERROR], | ||
2862 | 739 | filt=PJLINK_ERST_STATUS[E_ERROR], | ||
2863 | 740 | other=PJLINK_ERST_STATUS[E_ERROR]) | ||
2864 | 741 | chk_test = {'Fan': E_ERROR, | ||
2865 | 742 | 'Lamp': E_ERROR, | ||
2866 | 743 | 'Temperature': E_ERROR, | ||
2867 | 744 | 'Cover': E_ERROR, | ||
2868 | 745 | 'Filter': E_ERROR, | ||
2869 | 746 | 'Other': E_ERROR} | ||
2870 | 747 | |||
2871 | 681 | # GIVEN: Test object | 748 | # GIVEN: Test object |
2876 | 682 | pjlink = pjlink_test | 749 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2877 | 683 | chk_test = PJLINK_ERST_STATUS[E_ERROR] | 750 | pjlink.projector_errors = None |
2874 | 684 | chk_string = ERROR_STRING[E_ERROR] | ||
2875 | 685 | chk_param = chk_test * len(PJLINK_ERST_POSITIONS) | ||
2878 | 686 | 751 | ||
2879 | 687 | # WHEN: process_erst with status set to WARN | 752 | # WHEN: process_erst with status set to WARN |
2881 | 688 | pjlink.process_erst(chk_param) | 753 | pjlink.process_erst(chk_data) |
2882 | 689 | 754 | ||
2883 | 690 | # THEN: PJLink instance errors should match chk_value | 755 | # THEN: PJLink instance errors should match chk_value |
2888 | 691 | for chk in pjlink.projector_errors: | 756 | assert pjlink.projector_errors == chk_test, 'Projector errors should be all E_ERROR' |
2885 | 692 | self.assertEqual(pjlink.projector_errors[chk], chk_string, | ||
2886 | 693 | 'projector_errors["{chk}"] should have been set to "{err}"'.format(chk=chk, | ||
2887 | 694 | err=chk_string)) | ||
2889 | 695 | 757 | ||
2890 | 696 | def test_projector_process_erst_warn_cover_only(self): | 758 | def test_projector_process_erst_warn_cover_only(self): |
2891 | 697 | """ | 759 | """ |
2892 | 698 | Test test_projector_process_erst_warn_cover_only | 760 | Test test_projector_process_erst_warn_cover_only |
2893 | 699 | """ | 761 | """ |
2894 | 762 | chk_data = '{fan}{lamp}{temp}{cover}{filt}{other}'.format(fan=PJLINK_ERST_STATUS[S_OK], | ||
2895 | 763 | lamp=PJLINK_ERST_STATUS[S_OK], | ||
2896 | 764 | temp=PJLINK_ERST_STATUS[S_OK], | ||
2897 | 765 | cover=PJLINK_ERST_STATUS[E_WARN], | ||
2898 | 766 | filt=PJLINK_ERST_STATUS[S_OK], | ||
2899 | 767 | other=PJLINK_ERST_STATUS[S_OK]) | ||
2900 | 768 | chk_test = {'Cover': E_WARN} | ||
2901 | 769 | |||
2902 | 700 | # GIVEN: Test object | 770 | # GIVEN: Test object |
2926 | 701 | pjlink = pjlink_test | 771 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2927 | 702 | chk_test = PJLINK_ERST_STATUS[E_WARN] | 772 | pjlink.projector_errors = None |
2928 | 703 | chk_string = ERROR_STRING[E_WARN] | 773 | |
2929 | 704 | pos = PJLINK_ERST_DATA['COVER'] | 774 | # WHEN: process_erst with status set to WARN |
2930 | 705 | build_chk = [] | 775 | pjlink.process_erst(chk_data) |
2931 | 706 | for check in range(0, len(PJLINK_ERST_POSITIONS)): | 776 | |
2932 | 707 | if check == pos: | 777 | # THEN: PJLink instance errors should match only cover warning |
2933 | 708 | build_chk.append(chk_test) | 778 | assert 1 == len(pjlink.projector_errors), 'There should only be 1 error listed in projector_errors' |
2934 | 709 | else: | 779 | assert 'Cover' in pjlink.projector_errors, '"Cover" should be the only error listed' |
2935 | 710 | build_chk.append(PJLINK_ERST_STATUS['OK']) | 780 | assert pjlink.projector_errors['Cover'] == E_WARN, '"Cover" should have E_WARN listed as error' |
2936 | 711 | chk_param = ''.join(build_chk) | 781 | assert chk_test == pjlink.projector_errors, 'projector_errors should match test errors' |
2937 | 712 | 782 | ||
2938 | 713 | # WHEN: process_erst with cover only set to WARN and all others set to OK | 783 | def test_projector_process_inpt_valid(self): |
2916 | 714 | pjlink.process_erst(chk_param) | ||
2917 | 715 | |||
2918 | 716 | # THEN: Only COVER should have an error | ||
2919 | 717 | self.assertEqual(len(pjlink.projector_errors), 1, 'projector_errors should only have 1 error') | ||
2920 | 718 | self.assertTrue(('Cover' in pjlink.projector_errors), 'projector_errors should have an error for "Cover"') | ||
2921 | 719 | self.assertEqual(pjlink.projector_errors['Cover'], | ||
2922 | 720 | chk_string, | ||
2923 | 721 | 'projector_errors["Cover"] should have error "{err}"'.format(err=chk_string)) | ||
2924 | 722 | |||
2925 | 723 | def test_projector_process_inpt(self): | ||
2939 | 724 | """ | 784 | """ |
2940 | 725 | Test input source status shows current input | 785 | Test input source status shows current input |
2941 | 726 | """ | 786 | """ |
2942 | 787 | log_debug_calls = [call('(111.111.111.111) reset_information() connect status is S_NOT_CONNECTED')] | ||
2943 | 788 | chk_source_available = ['11', '12', '21', '22', '31', '32'] | ||
2944 | 789 | |||
2945 | 727 | # GIVEN: Test object | 790 | # GIVEN: Test object |
2958 | 728 | pjlink = pjlink_test | 791 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
2959 | 729 | pjlink.source = '0' | 792 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
2960 | 730 | 793 | pjlink.source_available = chk_source_available | |
2961 | 731 | # WHEN: Called with input source | 794 | pjlink.source = '11' |
2962 | 732 | pjlink.process_inpt('1') | 795 | |
2963 | 733 | 796 | # WHEN: Called with input source | |
2964 | 734 | # THEN: Input selected should reflect current input | 797 | pjlink.process_inpt('21') |
2965 | 735 | self.assertEqual(pjlink.source, '1', 'Input source should be set to "1"') | 798 | |
2966 | 736 | 799 | # THEN: Input selected should reflect current input | |
2967 | 737 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 800 | assert pjlink.source == '21', 'Input source should be set to "21"' |
2968 | 738 | @patch.object(openlp.core.projectors.pjlink, 'log') | 801 | mock_log.debug.assert_has_calls(log_debug_calls) |
2969 | 739 | def test_projector_process_inst(self, mock_log, mock_UpdateIcons): | 802 | |
2970 | 803 | def test_projector_process_input_not_in_list(self): | ||
2971 | 804 | """ | ||
2972 | 805 | Test setting input outside of available inputs | ||
2973 | 806 | |||
2974 | 807 | TODO: Future test | ||
2975 | 808 | """ | ||
2976 | 809 | pass | ||
2977 | 810 | |||
2978 | 811 | def test_projector_process_input_not_in_default(self): | ||
2979 | 812 | """ | ||
2980 | 813 | Test setting input with no sources available | ||
2981 | 814 | TODO: Future test | ||
2982 | 815 | """ | ||
2983 | 816 | pass | ||
2984 | 817 | |||
2985 | 818 | def test_projector_process_input_invalid(self): | ||
2986 | 819 | """ | ||
2987 | 820 | Test setting input with an invalid value | ||
2988 | 821 | |||
2989 | 822 | TODO: Future test | ||
2990 | 823 | """ | ||
2991 | 824 | |||
2992 | 825 | def test_projector_process_inst_class_1(self): | ||
2993 | 740 | """ | 826 | """ |
2994 | 741 | Test saving video source available information | 827 | Test saving video source available information |
2995 | 742 | """ | 828 | """ |
2996 | 829 | log_debug_calls = [call('(111.111.111.111) Setting projector sources_available to ' | ||
2997 | 830 | '"[\'11\', \'12\', \'21\', \'22\', \'31\', \'32\']"')] | ||
2998 | 831 | chk_data = '21 12 11 22 32 31' # Although they should already be sorted, use unsorted to verify method | ||
2999 | 832 | chk_test = ['11', '12', '21', '22', '31', '32'] | ||
3000 | 833 | |||
3001 | 743 | # GIVEN: Test object | 834 | # GIVEN: Test object |
3021 | 744 | pjlink = pjlink_test | 835 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3022 | 745 | pjlink.source_available = [] | 836 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3023 | 746 | test_data = '21 10 30 31 11 20' | 837 | pjlink.source_available = [] |
3024 | 747 | test_saved = ["10", "11", "20", "21", "30", "31"] | 838 | |
3025 | 748 | log_data = "(127.0.0.1) Setting projector sources_available to " \ | 839 | # WHEN: process_inst called with test data |
3026 | 749 | "\"['10', '11', '20', '21', '30', '31']\"" | 840 | pjlink.process_inst(data=chk_data) |
3027 | 750 | mock_UpdateIcons.reset_mock() | 841 | |
3028 | 751 | mock_log.reset_mock() | 842 | # THEN: Data should have been sorted and saved properly |
3029 | 752 | 843 | assert pjlink.source_available == chk_test, "Sources should have been sorted and saved" | |
3030 | 753 | # WHEN: process_inst called with test data | 844 | mock_log.debug.assert_has_calls(log_debug_calls) |
3031 | 754 | pjlink.process_inst(data=test_data) | 845 | |
3032 | 755 | 846 | def test_projector_process_lamp_invalid(self): | |
3014 | 756 | # THEN: Data should have been sorted and saved properly | ||
3015 | 757 | self.assertEqual(pjlink.source_available, test_saved, "Sources should have been sorted and saved") | ||
3016 | 758 | mock_log.debug.assert_called_once_with(log_data) | ||
3017 | 759 | self.assertTrue(mock_UpdateIcons.emit.called, 'Update Icons should have been called') | ||
3018 | 760 | |||
3019 | 761 | @patch.object(openlp.core.projectors.pjlink, 'log') | ||
3020 | 762 | def test_projector_process_lamp_invalid(self, mock_log): | ||
3033 | 763 | """ | 847 | """ |
3034 | 764 | Test status multiple lamp on/off and hours | 848 | Test status multiple lamp on/off and hours |
3035 | 765 | """ | 849 | """ |
3036 | 850 | log_data = [call('(111.111.111.111) process_lamp(): Invalid data "11111 1 22222 0 333A3 1"')] | ||
3037 | 851 | |||
3038 | 766 | # GIVEN: Test object | 852 | # GIVEN: Test object |
3059 | 767 | pjlink = pjlink_test | 853 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3060 | 768 | pjlink.lamp = [{'Hours': 00000, 'On': True}, | 854 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3061 | 769 | {'Hours': 11111, 'On': False}] | 855 | pjlink.lamp = [{'Hours': 00000, 'On': True}, |
3062 | 770 | log_data = '(127.0.0.1) process_lamp(): Invalid data "11111 1 22222 0 333A3 1"' | 856 | {'Hours': 11111, 'On': False}] |
3063 | 771 | 857 | ||
3064 | 772 | # WHEN: Call process_command with invalid lamp data | 858 | # WHEN: Call process_command with invalid lamp data |
3065 | 773 | pjlink.process_lamp('11111 1 22222 0 333A3 1') | 859 | pjlink.process_lamp('11111 1 22222 0 333A3 1') |
3066 | 774 | 860 | ||
3067 | 775 | # THEN: lamps should not have changed | 861 | # THEN: lamps should not have changed |
3068 | 776 | self.assertEqual(len(pjlink.lamp), 2, | 862 | assert 2 == len(pjlink.lamp), 'Projector should have kept 2 lamps specified' |
3069 | 777 | 'Projector should have kept 2 lamps specified') | 863 | assert pjlink.lamp[0]['On'] is True, 'Lamp 1 power status should have stayed TRUE' |
3070 | 778 | self.assertEqual(pjlink.lamp[0]['On'], True, | 864 | assert 00000 == pjlink.lamp[0]['Hours'], 'Lamp 1 hours should have been left at 00000' |
3071 | 779 | 'Lamp 1 power status should have been set to TRUE') | 865 | assert pjlink.lamp[1]['On'] is False, 'Lamp 2 power status should have stayed FALSE' |
3072 | 780 | self.assertEqual(pjlink.lamp[0]['Hours'], 00000, | 866 | assert 11111 == pjlink.lamp[1]['Hours'], 'Lamp 2 hours should have been left at 11111' |
3073 | 781 | 'Lamp 1 hours should have been left at 00000') | 867 | mock_log.warning.assert_has_calls(log_data) |
3054 | 782 | self.assertEqual(pjlink.lamp[1]['On'], False, | ||
3055 | 783 | 'Lamp 2 power status should have been set to FALSE') | ||
3056 | 784 | self.assertEqual(pjlink.lamp[1]['Hours'], 11111, | ||
3057 | 785 | 'Lamp 2 hours should have been left at 11111') | ||
3058 | 786 | mock_log.warning.assert_called_once_with(log_data) | ||
3074 | 787 | 868 | ||
3075 | 788 | def test_projector_process_lamp_multiple(self): | 869 | def test_projector_process_lamp_multiple(self): |
3076 | 789 | """ | 870 | """ |
3077 | 790 | Test status multiple lamp on/off and hours | 871 | Test status multiple lamp on/off and hours |
3078 | 791 | """ | 872 | """ |
3079 | 792 | # GIVEN: Test object | 873 | # GIVEN: Test object |
3082 | 793 | pjlink = pjlink_test | 874 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3083 | 794 | pjlink.lamps = [] | 875 | pjlink.lamp = [] |
3084 | 795 | 876 | ||
3086 | 796 | # WHEN: Call process_command with lamp data | 877 | # WHEN: Call process_command with invalid lamp data |
3087 | 797 | pjlink.process_lamp('11111 1 22222 0 33333 1') | 878 | pjlink.process_lamp('11111 1 22222 0 33333 1') |
3088 | 798 | 879 | ||
3089 | 799 | # THEN: Lamp should have been set with proper lamp status | 880 | # THEN: Lamp should have been set with proper lamp status |
3104 | 800 | self.assertEqual(len(pjlink.lamp), 3, | 881 | assert 3 == len(pjlink.lamp), 'Projector should have 3 lamps specified' |
3105 | 801 | 'Projector should have 3 lamps specified') | 882 | assert pjlink.lamp[0]['On'] is True, 'Lamp 1 power status should have been set to TRUE' |
3106 | 802 | self.assertEqual(pjlink.lamp[0]['On'], True, | 883 | assert 11111 == pjlink.lamp[0]['Hours'], 'Lamp 1 hours should have been set to 11111' |
3107 | 803 | 'Lamp 1 power status should have been set to TRUE') | 884 | assert pjlink.lamp[1]['On'] is False, 'Lamp 2 power status should have been set to FALSE' |
3108 | 804 | self.assertEqual(pjlink.lamp[0]['Hours'], 11111, | 885 | assert 22222 == pjlink.lamp[1]['Hours'], 'Lamp 2 hours should have been set to 22222' |
3109 | 805 | 'Lamp 1 hours should have been set to 11111') | 886 | assert pjlink.lamp[2]['On'] is True, 'Lamp 3 power status should have been set to TRUE' |
3110 | 806 | self.assertEqual(pjlink.lamp[1]['On'], False, | 887 | assert 33333 == pjlink.lamp[2]['Hours'], 'Lamp 3 hours should have been set to 33333' |
3097 | 807 | 'Lamp 2 power status should have been set to FALSE') | ||
3098 | 808 | self.assertEqual(pjlink.lamp[1]['Hours'], 22222, | ||
3099 | 809 | 'Lamp 2 hours should have been set to 22222') | ||
3100 | 810 | self.assertEqual(pjlink.lamp[2]['On'], True, | ||
3101 | 811 | 'Lamp 3 power status should have been set to TRUE') | ||
3102 | 812 | self.assertEqual(pjlink.lamp[2]['Hours'], 33333, | ||
3103 | 813 | 'Lamp 3 hours should have been set to 33333') | ||
3111 | 814 | 888 | ||
3112 | 815 | def test_projector_process_lamp_single(self): | 889 | def test_projector_process_lamp_single(self): |
3113 | 816 | """ | 890 | """ |
3114 | 817 | Test status lamp on/off and hours | 891 | Test status lamp on/off and hours |
3115 | 818 | """ | 892 | """ |
3116 | 893 | |||
3117 | 819 | # GIVEN: Test object | 894 | # GIVEN: Test object |
3120 | 820 | pjlink = pjlink_test | 895 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3121 | 821 | pjlink.lamps = [] | 896 | pjlink.lamp = [] |
3122 | 822 | 897 | ||
3124 | 823 | # WHEN: Call process_command with lamp data | 898 | # WHEN: Call process_command with invalid lamp data |
3125 | 824 | pjlink.process_lamp('22222 1') | 899 | pjlink.process_lamp('22222 1') |
3126 | 825 | 900 | ||
3127 | 826 | # THEN: Lamp should have been set with status=ON and hours=22222 | 901 | # THEN: Lamp should have been set with status=ON and hours=22222 |
3132 | 827 | self.assertEqual(pjlink.lamp[0]['On'], True, | 902 | assert 1 == len(pjlink.lamp), 'Projector should have only 1 lamp' |
3133 | 828 | 'Lamp power status should have been set to TRUE') | 903 | assert pjlink.lamp[0]['On'] is True, 'Lamp power status should have been set to TRUE' |
3134 | 829 | self.assertEqual(pjlink.lamp[0]['Hours'], 22222, | 904 | assert 22222 == pjlink.lamp[0]['Hours'], 'Lamp hours should have been set to 22222' |
3131 | 830 | 'Lamp hours should have been set to 22222') | ||
3135 | 831 | 905 | ||
3138 | 832 | @patch.object(openlp.core.projectors.pjlink, 'log') | 906 | def test_projector_process_name(self): |
3137 | 833 | def test_projector_process_name(self, mock_log): | ||
3139 | 834 | """ | 907 | """ |
3140 | 835 | Test saving NAME data from projector | 908 | Test saving NAME data from projector |
3141 | 836 | """ | 909 | """ |
3162 | 837 | # GIVEN: Test data | 910 | chk_data = "Some Name the End-User Set IN Projector" |
3163 | 838 | pjlink = pjlink_test | 911 | log_debug_calls = [call('(111.111.111.111) Setting projector PJLink name to ' |
3164 | 839 | test_data = "Some Name the End-User Set IN Projector" | 912 | '"Some Name the End-User Set IN Projector"')] |
3165 | 840 | test_log = '(127.0.0.1) Setting projector PJLink name to "Some Name the End-User Set IN Projector"' | 913 | |
3166 | 841 | mock_log.reset_mock() | 914 | # GIVEN: Test object |
3167 | 842 | 915 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: | |
3168 | 843 | # WHEN: process_name called with test data | 916 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3169 | 844 | pjlink.process_name(data=test_data) | 917 | |
3170 | 845 | 918 | # WHEN: process_name called with test data | |
3171 | 846 | # THEN: name should be set and logged | 919 | pjlink.process_name(data=chk_data) |
3172 | 847 | self.assertEqual(pjlink.pjlink_name, test_data, 'Name test data should have been saved') | 920 | |
3173 | 848 | mock_log.debug.assert_called_once_with(test_log) | 921 | # THEN: name should be set and logged |
3174 | 849 | 922 | assert pjlink.pjlink_name == chk_data, 'Name test data should have been saved' | |
3175 | 850 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 923 | mock_log.debug.assert_has_calls(log_debug_calls) |
3176 | 851 | @patch.object(pjlink_test, 'send_command') | 924 | |
3177 | 852 | @patch.object(pjlink_test, 'change_status') | 925 | def test_projector_process_powr_on(self): |
3158 | 853 | def test_projector_process_powr_on(self, | ||
3159 | 854 | mock_change_status, | ||
3160 | 855 | mock_send_command, | ||
3161 | 856 | mock_UpdateIcons): | ||
3178 | 857 | """ | 926 | """ |
3179 | 858 | Test status power to ON | 927 | Test status power to ON |
3180 | 859 | """ | 928 | """ |
3202 | 860 | # GIVEN: Test object and preset | 929 | # GIVEN: Test object |
3203 | 861 | pjlink = pjlink_test | 930 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ |
3204 | 862 | pjlink.power = S_STANDBY | 931 | patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
3205 | 863 | test_data = PJLINK_POWR_STATUS[S_ON] | 932 | patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
3206 | 864 | 933 | ||
3207 | 865 | # WHEN: Call process_command with turn power on command | 934 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3208 | 866 | pjlink.process_command(cmd='POWR', data=test_data) | 935 | pjlink.power = S_STANDBY |
3209 | 867 | 936 | ||
3210 | 868 | # THEN: Power should be set to ON | 937 | # WHEN: process_name called with test data |
3211 | 869 | self.assertEqual(pjlink.power, S_ON, 'Power should have been set to ON') | 938 | pjlink.process_powr(data=PJLINK_POWR_STATUS[S_ON]) |
3212 | 870 | mock_send_command.assert_called_once_with('INST') | 939 | |
3213 | 871 | mock_change_status.assert_called_once_with(PJLINK_POWR_STATUS[test_data]) | 940 | # THEN: Power should be set to ON |
3214 | 872 | self.assertEqual(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called') | 941 | assert pjlink.power == S_ON, 'Power should have been set to ON' |
3215 | 873 | 942 | assert mock_UpdateIcons.emit.called is True, 'projectorUpdateIcons should have been called' | |
3216 | 874 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 943 | mock_send_command.assert_called_once_with('INST') |
3217 | 875 | @patch.object(pjlink_test, 'send_command') | 944 | mock_change_status.assert_called_once_with(S_ON) |
3218 | 876 | @patch.object(pjlink_test, 'change_status') | 945 | |
3219 | 877 | def test_projector_process_powr_invalid(self, | 946 | def test_projector_process_powr_invalid(self): |
3199 | 878 | mock_change_status, | ||
3200 | 879 | mock_send_command, | ||
3201 | 880 | mock_UpdateIcons): | ||
3220 | 881 | """ | 947 | """ |
3221 | 882 | Test process_powr invalid call | 948 | Test process_powr invalid call |
3222 | 883 | """ | 949 | """ |
3244 | 884 | # GIVEN: Test object and preset | 950 | log_warn_calls = [call('(111.111.111.111) Unknown power response: "99"')] |
3245 | 885 | pjlink = pjlink_test | 951 | |
3246 | 886 | pjlink.power = S_STANDBY | 952 | # GIVEN: Test object |
3247 | 887 | test_data = '99' | 953 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log, \ |
3248 | 888 | 954 | patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ | |
3249 | 889 | # WHEN: Call process_command with turn power on command | 955 | patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
3250 | 890 | pjlink.process_command(cmd='POWR', data=test_data) | 956 | patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
3251 | 891 | 957 | ||
3252 | 892 | # THEN: Power should be set to ON | 958 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3253 | 893 | self.assertEqual(pjlink.power, S_STANDBY, 'Power should not have changed') | 959 | pjlink.power = S_STANDBY |
3254 | 894 | self.assertFalse(mock_change_status.called, 'Change status should not have been called') | 960 | |
3255 | 895 | self.assertFalse(mock_send_command.called, 'send_command("INST") should not have been called') | 961 | # WHEN: process_name called with test data |
3256 | 896 | self.assertFalse(mock_UpdateIcons.emit.called, 'projectorUpdateIcons should not have been called') | 962 | pjlink.process_powr(data='99') |
3257 | 897 | 963 | ||
3258 | 898 | @patch.object(pjlink_test, 'projectorUpdateIcons') | 964 | # THEN: Power should be set to ON |
3259 | 899 | @patch.object(pjlink_test, 'send_command') | 965 | assert pjlink.power == S_STANDBY, 'Power should not have changed' |
3260 | 900 | @patch.object(pjlink_test, 'change_status') | 966 | assert mock_UpdateIcons.emit.called is False, 'projectorUpdateIcons() should not have been called' |
3261 | 901 | def test_projector_process_powr_off(self, | 967 | mock_change_status.called is False, 'change_status() should not have been called' |
3262 | 902 | mock_change_status, | 968 | mock_send_command.called is False, 'send_command() should not have been called' |
3263 | 903 | mock_send_command, | 969 | mock_log.warning.assert_has_calls(log_warn_calls) |
3264 | 904 | mock_UpdateIcons): | 970 | |
3265 | 971 | def test_projector_process_powr_off(self): | ||
3266 | 905 | """ | 972 | """ |
3267 | 906 | Test status power to STANDBY | 973 | Test status power to STANDBY |
3268 | 907 | """ | 974 | """ |
3282 | 908 | # GIVEN: Test object and preset | 975 | # GIVEN: Test object |
3283 | 909 | pjlink = pjlink_test | 976 | with patch.object(openlp.core.projectors.pjlink.PJLink, 'send_command') as mock_send_command, \ |
3284 | 910 | pjlink.power = S_ON | 977 | patch.object(openlp.core.projectors.pjlink.PJLink, 'change_status') as mock_change_status, \ |
3285 | 911 | test_data = PJLINK_POWR_STATUS[S_STANDBY] | 978 | patch.object(openlp.core.projectors.pjlink.PJLink, 'projectorUpdateIcons') as mock_UpdateIcons: |
3286 | 912 | 979 | ||
3287 | 913 | # WHEN: Call process_command with turn power on command | 980 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3288 | 914 | pjlink.process_command(cmd='POWR', data=test_data) | 981 | pjlink.power = S_ON |
3289 | 915 | 982 | ||
3290 | 916 | # THEN: Power should be set to STANDBY | 983 | # WHEN: process_name called with test data |
3291 | 917 | self.assertEqual(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY') | 984 | pjlink.process_powr(data=PJLINK_POWR_STATUS[S_STANDBY]) |
3292 | 918 | self.assertEqual(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called') | 985 | |
3293 | 919 | mock_change_status.assert_called_once_with(PJLINK_POWR_STATUS[test_data]) | 986 | # THEN: Power should be set to ON |
3294 | 920 | self.assertFalse(mock_send_command.called, "send_command['INST'] should not have been called") | 987 | assert pjlink.power == S_STANDBY, 'Power should have changed to S_STANDBY' |
3295 | 988 | assert mock_UpdateIcons.emit.called is True, 'projectorUpdateIcons should have been called' | ||
3296 | 989 | mock_change_status.called is True, 'change_status should have been called' | ||
3297 | 990 | mock_send_command.called is False, 'send_command should not have been called' | ||
3298 | 921 | 991 | ||
3299 | 922 | def test_projector_process_rfil_save(self): | 992 | def test_projector_process_rfil_save(self): |
3300 | 923 | """ | 993 | """ |
3301 | 924 | Test saving filter type | 994 | Test saving filter type |
3302 | 925 | """ | 995 | """ |
3303 | 996 | filter_model = 'Filter Type Test' | ||
3304 | 997 | |||
3305 | 926 | # GIVEN: Test object | 998 | # GIVEN: Test object |
3307 | 927 | pjlink = pjlink_test | 999 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3308 | 928 | pjlink.model_filter = None | 1000 | pjlink.model_filter = None |
3309 | 929 | filter_model = 'Filter Type Test' | ||
3310 | 930 | 1001 | ||
3311 | 931 | # WHEN: Filter model is received | 1002 | # WHEN: Filter model is received |
3312 | 932 | pjlink.process_rfil(data=filter_model) | 1003 | pjlink.process_rfil(data=filter_model) |
3313 | 933 | 1004 | ||
3314 | 934 | # THEN: Filter model number should be saved | 1005 | # THEN: Filter model number should be saved |
3316 | 935 | self.assertEqual(pjlink.model_filter, filter_model, 'Filter type should have been saved') | 1006 | assert pjlink.model_filter == filter_model, 'Filter type should have been saved' |
3317 | 936 | 1007 | ||
3318 | 937 | def test_projector_process_rfil_nosave(self): | 1008 | def test_projector_process_rfil_nosave(self): |
3319 | 938 | """ | 1009 | """ |
3320 | 939 | Test saving filter type previously saved | 1010 | Test saving filter type previously saved |
3321 | 940 | """ | 1011 | """ |
3322 | 1012 | filter_model = 'Filter Type Test' | ||
3323 | 1013 | log_warn_calls = [call('(111.111.111.111) Filter model already set'), | ||
3324 | 1014 | call('(111.111.111.111) Saved model: "Old filter type"'), | ||
3325 | 1015 | call('(111.111.111.111) New model: "Filter Type Test"')] | ||
3326 | 1016 | |||
3327 | 941 | # GIVEN: Test object | 1017 | # GIVEN: Test object |
3337 | 942 | pjlink = pjlink_test | 1018 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3338 | 943 | pjlink.model_filter = 'Old filter type' | 1019 | |
3339 | 944 | filter_model = 'Filter Type Test' | 1020 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3340 | 945 | 1021 | pjlink.model_filter = 'Old filter type' | |
3341 | 946 | # WHEN: Filter model is received | 1022 | |
3342 | 947 | pjlink.process_rfil(data=filter_model) | 1023 | # WHEN: Filter model is received |
3343 | 948 | 1024 | pjlink.process_rfil(data=filter_model) | |
3344 | 949 | # THEN: Filter model number should be saved | 1025 | |
3345 | 950 | self.assertNotEquals(pjlink.model_filter, filter_model, 'Filter type should NOT have been saved') | 1026 | # THEN: Filter model number should be saved |
3346 | 1027 | assert pjlink.model_filter != filter_model, 'Filter type should NOT have been saved' | ||
3347 | 1028 | mock_log.warning.assert_has_calls(log_warn_calls) | ||
3348 | 951 | 1029 | ||
3349 | 952 | def test_projector_process_rlmp_save(self): | 1030 | def test_projector_process_rlmp_save(self): |
3350 | 953 | """ | 1031 | """ |
3351 | 954 | Test saving lamp type | 1032 | Test saving lamp type |
3352 | 955 | """ | 1033 | """ |
3353 | 956 | # GIVEN: Test object | 1034 | # GIVEN: Test object |
3355 | 957 | pjlink = pjlink_test | 1035 | # GIVEN: Test object |
3356 | 1036 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | ||
3357 | 958 | pjlink.model_lamp = None | 1037 | pjlink.model_lamp = None |
3358 | 959 | lamp_model = 'Lamp Type Test' | 1038 | lamp_model = 'Lamp Type Test' |
3359 | 960 | 1039 | ||
3360 | @@ -962,159 +1041,179 @@ | |||
3361 | 962 | pjlink.process_rlmp(data=lamp_model) | 1041 | pjlink.process_rlmp(data=lamp_model) |
3362 | 963 | 1042 | ||
3363 | 964 | # THEN: Filter model number should be saved | 1043 | # THEN: Filter model number should be saved |
3365 | 965 | self.assertEqual(pjlink.model_lamp, lamp_model, 'Lamp type should have been saved') | 1044 | assert pjlink.model_lamp == lamp_model, 'Lamp type should have been saved' |
3366 | 966 | 1045 | ||
3367 | 967 | def test_projector_process_rlmp_nosave(self): | 1046 | def test_projector_process_rlmp_nosave(self): |
3368 | 968 | """ | 1047 | """ |
3369 | 969 | Test saving lamp type previously saved | 1048 | Test saving lamp type previously saved |
3370 | 970 | """ | 1049 | """ |
3371 | 1050 | lamp_model = 'Lamp Type Test' | ||
3372 | 1051 | log_warn_calls = [call('(111.111.111.111) Lamp model already set'), | ||
3373 | 1052 | call('(111.111.111.111) Saved lamp: "Old lamp type"'), | ||
3374 | 1053 | call('(111.111.111.111) New lamp: "Lamp Type Test"')] | ||
3375 | 1054 | |||
3376 | 971 | # GIVEN: Test object | 1055 | # GIVEN: Test object |
3386 | 972 | pjlink = pjlink_test | 1056 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3387 | 973 | pjlink.model_lamp = 'Old lamp type' | 1057 | |
3388 | 974 | lamp_model = 'Filter Type Test' | 1058 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3389 | 975 | 1059 | pjlink.model_lamp = 'Old lamp type' | |
3390 | 976 | # WHEN: Filter model is received | 1060 | |
3391 | 977 | pjlink.process_rlmp(data=lamp_model) | 1061 | # WHEN: Filter model is received |
3392 | 978 | 1062 | pjlink.process_rlmp(data=lamp_model) | |
3393 | 979 | # THEN: Filter model number should be saved | 1063 | |
3394 | 980 | self.assertNotEquals(pjlink.model_lamp, lamp_model, 'Lamp type should NOT have been saved') | 1064 | # THEN: Filter model number should be saved |
3395 | 1065 | assert pjlink.model_lamp != lamp_model, 'Lamp type should NOT have been saved' | ||
3396 | 1066 | mock_log.warning.assert_has_calls(log_warn_calls) | ||
3397 | 981 | 1067 | ||
3398 | 982 | def test_projector_process_snum_set(self): | 1068 | def test_projector_process_snum_set(self): |
3399 | 983 | """ | 1069 | """ |
3400 | 984 | Test saving serial number from projector | 1070 | Test saving serial number from projector |
3401 | 985 | """ | 1071 | """ |
3402 | 1072 | log_debug_calls = [call('(111.111.111.111) Setting projector serial number to "Test Serial Number"')] | ||
3403 | 1073 | test_number = 'Test Serial Number' | ||
3404 | 1074 | |||
3405 | 986 | # GIVEN: Test object | 1075 | # GIVEN: Test object |
3416 | 987 | pjlink = pjlink_test | 1076 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3417 | 988 | pjlink.serial_no = None | 1077 | |
3418 | 989 | test_number = 'Test Serial Number' | 1078 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3419 | 990 | 1079 | pjlink.serial_no = None | |
3420 | 991 | # WHEN: No serial number is set and we receive serial number command | 1080 | |
3421 | 992 | pjlink.process_snum(data=test_number) | 1081 | # WHEN: No serial number is set and we receive serial number command |
3422 | 993 | 1082 | pjlink.process_snum(data=test_number) | |
3423 | 994 | # THEN: Serial number should be set | 1083 | |
3424 | 995 | self.assertEqual(pjlink.serial_no, test_number, | 1084 | # THEN: Serial number should be set |
3425 | 996 | 'Projector serial number should have been set') | 1085 | assert pjlink.serial_no == test_number, 'Projector serial number should have been set' |
3426 | 1086 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
3427 | 997 | 1087 | ||
3428 | 998 | def test_projector_process_snum_different(self): | 1088 | def test_projector_process_snum_different(self): |
3429 | 999 | """ | 1089 | """ |
3430 | 1000 | Test projector serial number different than saved serial number | 1090 | Test projector serial number different than saved serial number |
3431 | 1001 | """ | 1091 | """ |
3435 | 1002 | # GIVEN: Test object | 1092 | log_warn_calls = [call('(111.111.111.111) Projector serial number does not match saved serial number'), |
3436 | 1003 | pjlink = pjlink_test | 1093 | call('(111.111.111.111) Saved: "Previous serial number"'), |
3437 | 1004 | pjlink.serial_no = 'Previous serial number' | 1094 | call('(111.111.111.111) Received: "Test Serial Number"'), |
3438 | 1095 | call('(111.111.111.111) NOT saving serial number')] | ||
3439 | 1005 | test_number = 'Test Serial Number' | 1096 | test_number = 'Test Serial Number' |
3440 | 1006 | 1097 | ||
3450 | 1007 | # WHEN: No serial number is set and we receive serial number command | 1098 | # GIVEN: Test object |
3451 | 1008 | pjlink.process_snum(data=test_number) | 1099 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3452 | 1009 | 1100 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) | |
3453 | 1010 | # THEN: Serial number should be set | 1101 | pjlink.serial_no = 'Previous serial number' |
3454 | 1011 | self.assertNotEquals(pjlink.serial_no, test_number, | 1102 | |
3455 | 1012 | 'Projector serial number should NOT have been set') | 1103 | # WHEN: No serial number is set and we receive serial number command |
3456 | 1013 | 1104 | pjlink.process_snum(data=test_number) | |
3457 | 1014 | @patch.object(openlp.core.projectors.pjlink, 'log') | 1105 | |
3458 | 1015 | def test_projector_process_sver(self, mock_log): | 1106 | # THEN: Serial number should be set |
3459 | 1107 | assert pjlink.serial_no != test_number, 'Projector serial number should NOT have been set' | ||
3460 | 1108 | mock_log.warning.assert_has_calls(log_warn_calls) | ||
3461 | 1109 | |||
3462 | 1110 | def test_projector_process_sver(self): | ||
3463 | 1016 | """ | 1111 | """ |
3464 | 1017 | Test invalid software version information - too long | 1112 | Test invalid software version information - too long |
3465 | 1018 | """ | 1113 | """ |
3466 | 1019 | # GIVEN: Test object | ||
3467 | 1020 | pjlink = pjlink_test | ||
3468 | 1021 | pjlink.sw_version = None | ||
3469 | 1022 | pjlink.sw_version_received = None | ||
3470 | 1023 | test_data = 'Test 1 Subtest 1' | 1114 | test_data = 'Test 1 Subtest 1' |
3484 | 1024 | test_log = '(127.0.0.1) Setting projector software version to "Test 1 Subtest 1"' | 1115 | log_debug_calls = [call('(111.111.111.111) Setting projector software version to "Test 1 Subtest 1"')] |
3485 | 1025 | mock_log.reset_mock() | 1116 | |
3486 | 1026 | 1117 | # GIVEN: Test object | |
3487 | 1027 | # WHEN: process_sver called with invalid data | 1118 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3488 | 1028 | pjlink.process_sver(data=test_data) | 1119 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3489 | 1029 | 1120 | pjlink.sw_version = None | |
3490 | 1030 | # THEN: Version information should not change | 1121 | pjlink.sw_version_received = None |
3491 | 1031 | self.assertEqual(pjlink.sw_version, test_data, 'Software version should have been updated') | 1122 | |
3492 | 1032 | self.assertIsNone(pjlink.sw_version_received, 'Received software version should not have changed') | 1123 | # WHEN: process_sver called with invalid data |
3493 | 1033 | mock_log.debug.assert_called_once_with(test_log) | 1124 | pjlink.process_sver(data=test_data) |
3494 | 1034 | 1125 | ||
3495 | 1035 | @patch.object(openlp.core.projectors.pjlink, 'log') | 1126 | # THEN: Version information should not change |
3496 | 1036 | def test_projector_process_sver_changed(self, mock_log): | 1127 | assert pjlink.sw_version == test_data, 'Software version should have been updated' |
3497 | 1128 | mock_log.debug.assert_has_calls(log_debug_calls) | ||
3498 | 1129 | |||
3499 | 1130 | def test_projector_process_sver_changed(self): | ||
3500 | 1037 | """ | 1131 | """ |
3501 | 1038 | Test invalid software version information - Received different than saved | 1132 | Test invalid software version information - Received different than saved |
3502 | 1039 | """ | 1133 | """ |
3505 | 1040 | # GIVEN: Test object | 1134 | test_data_old = 'Test 1 Subtest 1' |
3504 | 1041 | pjlink = pjlink_test | ||
3506 | 1042 | test_data_new = 'Test 1 Subtest 2' | 1135 | test_data_new = 'Test 1 Subtest 2' |
3526 | 1043 | test_data_old = 'Test 1 Subtest 1' | 1136 | log_warn_calls = [call('(111.111.111.111) Projector software version does not match saved software version'), |
3527 | 1044 | pjlink.sw_version = test_data_old | 1137 | call('(111.111.111.111) Saved: "Test 1 Subtest 1"'), |
3528 | 1045 | pjlink.sw_version_received = None | 1138 | call('(111.111.111.111) Received: "Test 1 Subtest 2"'), |
3529 | 1046 | test_log = '(127.0.0.1) Saving new serial number as sw_version_received' | 1139 | call('(111.111.111.111) Updating software version')] |
3530 | 1047 | mock_log.reset_mock() | 1140 | |
3531 | 1048 | 1141 | # GIVEN: Test object | |
3532 | 1049 | # WHEN: process_sver called with invalid data | 1142 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3533 | 1050 | pjlink.process_sver(data=test_data_new) | 1143 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3534 | 1051 | 1144 | pjlink.sw_version = test_data_old | |
3535 | 1052 | # THEN: Version information should not change | 1145 | |
3536 | 1053 | self.assertEqual(pjlink.sw_version, test_data_old, 'Software version should not have been updated') | 1146 | # WHEN: process_sver called with invalid data |
3537 | 1054 | self.assertEqual(pjlink.sw_version_received, test_data_new, | 1147 | pjlink.process_sver(data=test_data_new) |
3538 | 1055 | 'Received software version should have been changed') | 1148 | |
3539 | 1056 | self.assertEqual(mock_log.warning.call_count, 4, 'log.warn should have been called 4 times') | 1149 | # THEN: Version information should not change |
3540 | 1057 | # There was 4 calls, but only the last one is checked with this method | 1150 | assert pjlink.sw_version == test_data_new, 'Software version should have changed' |
3541 | 1058 | mock_log.warning.assert_called_with(test_log) | 1151 | mock_log.warning.assert_has_calls(log_warn_calls) |
3542 | 1059 | 1152 | ||
3543 | 1060 | @patch.object(openlp.core.projectors.pjlink, 'log') | 1153 | def test_projector_process_sver_invalid(self): |
3525 | 1061 | def test_projector_process_sver_invalid(self, mock_log): | ||
3544 | 1062 | """ | 1154 | """ |
3545 | 1063 | Test invalid software version information - too long | 1155 | Test invalid software version information - too long |
3546 | 1064 | """ | 1156 | """ |
3547 | 1065 | # GIVEN: Test object | ||
3548 | 1066 | pjlink = pjlink_test | ||
3549 | 1067 | pjlink.sw_version = None | ||
3550 | 1068 | pjlink.sw_version_received = None | ||
3551 | 1069 | test_data = 'This is a test software version line that is too long based on PJLink version 2 specs' | 1157 | test_data = 'This is a test software version line that is too long based on PJLink version 2 specs' |
3562 | 1070 | test_log = "Invalid software version - too long" | 1158 | log_warn_calls = [call('Invalid software version - too long')] |
3563 | 1071 | mock_log.reset_mock() | 1159 | |
3564 | 1072 | 1160 | # GIVEN: Test object | |
3565 | 1073 | # WHEN: process_sver called with invalid data | 1161 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3566 | 1074 | pjlink.process_sver(data=test_data) | 1162 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3567 | 1075 | 1163 | pjlink.sw_version = None | |
3568 | 1076 | # THEN: Version information should not change | 1164 | |
3569 | 1077 | self.assertIsNone(pjlink.sw_version, 'Software version should not have changed') | 1165 | # WHEN: process_sver called with invalid data |
3570 | 1078 | self.assertIsNone(pjlink.sw_version_received, 'Received software version should not have changed') | 1166 | pjlink.process_sver(data=test_data) |
3571 | 1079 | mock_log.warning.assert_called_once_with(test_log) | 1167 | |
3572 | 1168 | # THEN: Version information should not change | ||
3573 | 1169 | assert pjlink.sw_version is None, 'Software version should not have changed' | ||
3574 | 1170 | assert pjlink.sw_version_received is None, 'Received software version should not have changed' | ||
3575 | 1171 | mock_log.warning.assert_has_calls(log_warn_calls) | ||
3576 | 1080 | 1172 | ||
3577 | 1081 | def test_projector_reset_information(self): | 1173 | def test_projector_reset_information(self): |
3578 | 1082 | """ | 1174 | """ |
3579 | 1083 | Test reset_information() resets all information and stops timers | 1175 | Test reset_information() resets all information and stops timers |
3580 | 1084 | """ | 1176 | """ |
3599 | 1085 | # GIVEN: Test object and test data | 1177 | log_debug_calls = [call('(111.111.111.111): Calling timer.stop()'), |
3600 | 1086 | pjlink = pjlink_test | 1178 | call('(111.111.111.111): Calling socket_timer.stop()')] |
3601 | 1087 | pjlink.power = S_ON | 1179 | |
3602 | 1088 | pjlink.pjlink_name = 'OPENLPTEST' | 1180 | # GIVEN: Test object |
3603 | 1089 | pjlink.manufacturer = 'PJLINK' | 1181 | with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log: |
3604 | 1090 | pjlink.model = '1' | 1182 | pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True) |
3605 | 1091 | pjlink.shutter = True | 1183 | # timer and socket_timer not available until instantiation, so mock here |
3606 | 1092 | pjlink.mute = True | 1184 | with patch.object(pjlink, 'socket_timer') as mock_socket_timer, \ |
3607 | 1093 | pjlink.lamp = True | 1185 | patch.object(pjlink, 'timer') as mock_timer: |
3608 | 1094 | pjlink.fan = True | 1186 | |
3609 | 1095 | pjlink.source_available = True | 1187 | pjlink.power = S_ON |
3610 | 1096 | pjlink.other_info = 'ANOTHER TEST' | 1188 | pjlink.pjlink_name = 'OPENLPTEST' |
3611 | 1097 | pjlink.send_queue = True | 1189 | pjlink.manufacturer = 'PJLINK' |
3612 | 1098 | pjlink.send_busy = True | 1190 | pjlink.model = '1' |
3613 | 1099 | 1191 | pjlink.shutter = True | |
3614 | 1100 | # WHEN: reset_information() is called | 1192 | pjlink.mute = True |
3615 | 1101 | with patch.object(pjlink, 'timer') as mock_timer: | 1193 | pjlink.lamp = True |
3616 | 1102 | with patch.object(pjlink, 'socket_timer') as mock_socket_timer: | 1194 | pjlink.fan = True |
3617 | 1195 | pjlink.source_available = True | ||
3618 | 1196 | pjlink.other_info = 'ANOTHER TEST' | ||
3619 | 1197 | pjlink.send_queue = True | ||
3620 | 1198 | pjlink.send_busy = True | ||
3621 | 1199 | |||
3622 | 1200 | # WHEN: reset_information() is called | ||
3623 | 1103 | pjlink.reset_information() | 1201 | pjlink.reset_information() |
3624 | 1104 | 1202 | ||
3641 | 1105 | # THEN: All information should be reset and timers stopped | 1203 | # THEN: All information should be reset and timers stopped |
3642 | 1106 | self.assertEqual(pjlink.power, S_OFF, 'Projector power should be OFF') | 1204 | assert pjlink.power == S_OFF, 'Projector power should be OFF' |
3643 | 1107 | self.assertIsNone(pjlink.pjlink_name, 'Projector pjlink_name should be None') | 1205 | assert pjlink.pjlink_name is None, 'Projector pjlink_name should be None' |
3644 | 1108 | self.assertIsNone(pjlink.manufacturer, 'Projector manufacturer should be None') | 1206 | assert pjlink.manufacturer is None, 'Projector manufacturer should be None' |
3645 | 1109 | self.assertIsNone(pjlink.model, 'Projector model should be None') | 1207 | assert pjlink.model is None, 'Projector model should be None' |
3646 | 1110 | self.assertIsNone(pjlink.shutter, 'Projector shutter should be None') | 1208 | assert pjlink.shutter is None, 'Projector shutter should be None' |
3647 | 1111 | self.assertIsNone(pjlink.mute, 'Projector shuttter should be None') | 1209 | assert pjlink.mute is None, 'Projector shuttter should be None' |
3648 | 1112 | self.assertIsNone(pjlink.lamp, 'Projector lamp should be None') | 1210 | assert pjlink.lamp is None, 'Projector lamp should be None' |
3649 | 1113 | self.assertIsNone(pjlink.fan, 'Projector fan should be None') | 1211 | assert pjlink.fan is None, 'Projector fan should be None' |
3650 | 1114 | self.assertIsNone(pjlink.source_available, 'Projector source_available should be None') | 1212 | assert pjlink.source_available is None, 'Projector source_available should be None' |
3651 | 1115 | self.assertIsNone(pjlink.source, 'Projector source should be None') | 1213 | assert pjlink.source is None, 'Projector source should be None' |
3652 | 1116 | self.assertIsNone(pjlink.other_info, 'Projector other_info should be None') | 1214 | assert pjlink.other_info is None, 'Projector other_info should be None' |
3653 | 1117 | self.assertEqual(pjlink.send_queue, [], 'Projector send_queue should be an empty list') | 1215 | assert pjlink.send_queue == [], 'Projector send_queue should be an empty list' |
3654 | 1118 | self.assertFalse(pjlink.send_busy, 'Projector send_busy should be False') | 1216 | assert pjlink.send_busy is False, 'Projector send_busy should be False' |
3655 | 1119 | self.assertTrue(mock_timer.stop.called, 'Projector timer.stop() should have been called') | 1217 | assert mock_timer.stop.called is True, 'Projector timer.stop() should have been called' |
3656 | 1120 | self.assertTrue(mock_socket_timer.stop.called, 'Projector socket_timer.stop() should have been called') | 1218 | assert mock_socket_timer.stop.called is True, 'Projector socket_timer.stop() should have been called' |
3657 | 1219 | mock_log.debug.assert_has_calls(log_debug_calls) |
Some questions and old style asserts remain!