"- Update string format to Python3 style

- Added projector lamp values test

Convert string format from Python2 
     '%s %s' % (value1, value2)
to Python3
     '{key1} {key2}'.format(key1=value1, key2=value2)

--------------------------------
lp:~alisonken1/openlp/strings_projector_pjlink (revision 2642)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1442/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1359/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1297/
..."

bzr-revno: 2645
This commit is contained in:
Ken Roberts 2016-04-17 17:33:08 +02:00 committed by Raoul Snyman
commit f6cb085b0d
3 changed files with 177 additions and 108 deletions

View File

@ -74,7 +74,7 @@ class Manufacturer(CommonBase, Base):
""" """
Returns a basic representation of a Manufacturer table entry. Returns a basic representation of a Manufacturer table entry.
""" """
return '<Manufacturer(name="%s")>' % self.name return '<Manufacturer(name="{name}")>'.format(name=self.name)
name = Column(String(30)) name = Column(String(30))
models = relationship('Model', models = relationship('Model',
@ -101,7 +101,7 @@ class Model(CommonBase, Base):
""" """
Returns a basic representation of a Model table entry. Returns a basic representation of a Model table entry.
""" """
return '<Model(name=%s)>' % self.name return '<Model(name={name})>'.format(name=self.name)
manufacturer_id = Column(Integer, ForeignKey('manufacturer.id')) manufacturer_id = Column(Integer, ForeignKey('manufacturer.id'))
name = Column(String(20)) name = Column(String(20))
@ -131,8 +131,9 @@ class Source(CommonBase, Base):
""" """
Return basic representation of Source table entry. Return basic representation of Source table entry.
""" """
return '<Source(pjlink_name="%s", pjlink_code="%s", text="%s")>' % \ return '<Source(pjlink_name="{name}", pjlink_code="{code}", text="{Text}")>'.format(name=self.pjlink_name,
(self.pjlink_name, self.pjlink_code, self.text) code=self.pjlink_code,
text=self.text)
model_id = Column(Integer, ForeignKey('model.id')) model_id = Column(Integer, ForeignKey('model.id'))
pjlink_name = Column(String(15)) pjlink_name = Column(String(15))
pjlink_code = Column(String(2)) pjlink_code = Column(String(2))
@ -162,11 +163,22 @@ class Projector(CommonBase, Base):
""" """
Return basic representation of Source table entry. Return basic representation of Source table entry.
""" """
return '< Projector(id="%s", ip="%s", port="%s", pin="%s", name="%s", location="%s",' \ return '< Projector(id="{data}", ip="{ip}", port="{port}", pin="{pin}", name="{name}", ' \
'notes="%s", pjlink_name="%s", manufacturer="%s", model="%s", other="%s",' \ 'location="{location}", notes="{notes}", pjlink_name="{pjlink_name}", ' \
'sources="%s", source_list="%s") >' % (self.id, self.ip, self.port, self.pin, self.name, self.location, 'manufacturer="{manufacturer}", model="{model}", other="{other}", ' \
self.notes, self.pjlink_name, self.manufacturer, self.model, 'sources="{sources}", source_list="{source_list}") >'.format(data=self.id,
self.other, self.sources, self.source_list) ip=self.ip,
port=self.port,
pin=self.pin,
name=self.name,
location=self.location,
notes=self.notes,
pjlink_name=self.pjlink_name,
manufacturer=self.manufacturer,
model=self.model,
other=self.other,
sources=self.sources,
source_list=self.source_list)
ip = Column(String(100)) ip = Column(String(100))
port = Column(String(8)) port = Column(String(8))
pin = Column(String(20)) pin = Column(String(20))
@ -203,10 +215,11 @@ class ProjectorSource(CommonBase, Base):
""" """
Return basic representation of Source table entry. Return basic representation of Source table entry.
""" """
return '<ProjectorSource(id="%s", code="%s", text="%s", projector_id="%s")>' % (self.id, return '<ProjectorSource(id="{data}", code="{code}", text="{text}", ' \
self.code, 'projector_id="{projector_id}")>'.format(data=self.id,
self.text, code=self.code,
self.projector_id) text=self.text,
projector_id=self.projector_id)
code = Column(String(3)) code = Column(String(3))
text = Column(String(20)) text = Column(String(20))
projector_id = Column(Integer, ForeignKey('projector.id')) projector_id = Column(Integer, ForeignKey('projector.id'))
@ -217,10 +230,10 @@ class ProjectorDB(Manager):
Class to access the projector database. Class to access the projector database.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
log.debug('ProjectorDB().__init__(args="%s", kwargs="%s")' % (args, kwargs)) log.debug('ProjectorDB().__init__(args="{arg}", kwargs="{kwarg}")'.format(arg=args, kwarg=kwargs))
super().__init__(plugin_name='projector', init_schema=self.init_schema) super().__init__(plugin_name='projector', init_schema=self.init_schema)
log.debug('ProjectorDB() Initialized using db url %s' % self.db_url) log.debug('ProjectorDB() Initialized using db url {db}'.format(db=self.db_url))
log.debug('Session: %s', self.session) log.debug('Session: {session}'.format(session=self.session))
def init_schema(self, *args, **kwargs): def init_schema(self, *args, **kwargs):
""" """
@ -240,13 +253,14 @@ class ProjectorDB(Manager):
:param dbid: DB record id :param dbid: DB record id
:returns: Projector() instance :returns: Projector() instance
""" """
log.debug('get_projector_by_id(id="%s")' % dbid) log.debug('get_projector_by_id(id="{data}")'.format(data=dbid))
projector = self.get_object_filtered(Projector, Projector.id == dbid) projector = self.get_object_filtered(Projector, Projector.id == dbid)
if projector is None: if projector is None:
# Not found # Not found
log.warn('get_projector_by_id() did not find %s' % id) log.warn('get_projector_by_id() did not find {data}'.format(data=id))
return None return None
log.debug('get_projectorby_id() returning 1 entry for "%s" id="%s"' % (dbid, projector.id)) log.debug('get_projectorby_id() returning 1 entry for "{entry}" id="{data}"'.format(entry=dbid,
data=projector.id))
return projector return projector
def get_projector_all(self): def get_projector_all(self):
@ -262,7 +276,7 @@ class ProjectorDB(Manager):
return return_list return return_list
for new_projector in new_list: for new_projector in new_list:
return_list.append(new_projector) return_list.append(new_projector)
log.debug('get_all() returning %s item(s)' % len(return_list)) log.debug('get_all() returning {items} item(s)'.format(items=len(return_list)))
return return_list return return_list
def get_projector_by_ip(self, ip): def get_projector_by_ip(self, ip):
@ -276,9 +290,10 @@ class ProjectorDB(Manager):
projector = self.get_object_filtered(Projector, Projector.ip == ip) projector = self.get_object_filtered(Projector, Projector.ip == ip)
if projector is None: if projector is None:
# Not found # Not found
log.warn('get_projector_by_ip() did not find %s' % ip) log.warn('get_projector_by_ip() did not find {ip}'.format(ip=ip))
return None return None
log.debug('get_projectorby_ip() returning 1 entry for "%s" id="%s"' % (ip, projector.id)) log.debug('get_projectorby_ip() returning 1 entry for "{ip}" id="{data}"'.format(ip=ip,
data=projector.id))
return projector return projector
def get_projector_by_name(self, name): def get_projector_by_name(self, name):
@ -288,13 +303,14 @@ class ProjectorDB(Manager):
:param name: Name of projector :param name: Name of projector
:returns: Projector() instance :returns: Projector() instance
""" """
log.debug('get_projector_by_name(name="%s")' % name) log.debug('get_projector_by_name(name="{name}")'.format(name=name))
projector = self.get_object_filtered(Projector, Projector.name == name) projector = self.get_object_filtered(Projector, Projector.name == name)
if projector is None: if projector is None:
# Not found # Not found
log.warn('get_projector_by_name() did not find "%s"' % name) log.warn('get_projector_by_name() did not find "{name}"'.format(name=name))
return None return None
log.debug('get_projector_by_name() returning one entry for "%s" id="%s"' % (name, projector.id)) log.debug('get_projector_by_name() returning one entry for "{name}" id="{data}"'.format(name=name,
data=projector.id))
return projector return projector
def add_projector(self, projector): def add_projector(self, projector):
@ -308,13 +324,13 @@ class ProjectorDB(Manager):
""" """
old_projector = self.get_object_filtered(Projector, Projector.ip == projector.ip) old_projector = self.get_object_filtered(Projector, Projector.ip == projector.ip)
if old_projector is not None: if old_projector is not None:
log.warn('add_new() skipping entry ip="%s" (Already saved)' % old_projector.ip) log.warn('add_new() skipping entry ip="{ip}" (Already saved)'.format(ip=old_projector.ip))
return False return False
log.debug('add_new() saving new entry') log.debug('add_new() saving new entry')
log.debug('ip="%s", name="%s", location="%s"' % (projector.ip, log.debug('ip="{ip}", name="{name}", location="{location}"'.format(ip=projector.ip,
projector.name, name=projector.name,
projector.location)) location=projector.location))
log.debug('notes="%s"' % projector.notes) log.debug('notes="{notes}"'.format(notes=projector.notes))
return self.save_object(projector) return self.save_object(projector)
def update_projector(self, projector=None): def update_projector(self, projector=None):
@ -333,7 +349,7 @@ class ProjectorDB(Manager):
if old_projector is None: if old_projector is None:
log.error('Edit called on projector instance not in database - cancelled') log.error('Edit called on projector instance not in database - cancelled')
return False return False
log.debug('(%s) Updating projector with dbid=%s' % (projector.ip, projector.id)) log.debug('({ip}) Updating projector with dbid={dbid}'.format(ip=projector.ip, dbid=projector.id))
old_projector.ip = projector.ip old_projector.ip = projector.ip
old_projector.name = projector.name old_projector.name = projector.name
old_projector.location = projector.location old_projector.location = projector.location
@ -357,9 +373,9 @@ class ProjectorDB(Manager):
""" """
deleted = self.delete_object(Projector, projector.id) deleted = self.delete_object(Projector, projector.id)
if deleted: if deleted:
log.debug('delete_by_id() Removed entry id="%s"' % projector.id) log.debug('delete_by_id() Removed entry id="{data}"'.format(data=projector.id))
else: else:
log.error('delete_by_id() Entry id="%s" not deleted for some reason' % projector.id) log.error('delete_by_id() Entry id="{data}" not deleted for some reason'.format(data=projector.id))
return deleted return deleted
def get_source_list(self, projector): def get_source_list(self, projector):
@ -395,9 +411,9 @@ class ProjectorDB(Manager):
source_entry = self.get_object_filtered(ProjetorSource, ProjectorSource.id == source) source_entry = self.get_object_filtered(ProjetorSource, ProjectorSource.id == source)
if source_entry is None: if source_entry is None:
# Not found # Not found
log.warn('get_source_by_id() did not find "%s"' % source) log.warn('get_source_by_id() did not find "{source}"'.format(source=source))
return None return None
log.debug('get_source_by_id() returning one entry for "%s""' % (source)) log.debug('get_source_by_id() returning one entry for "{source}""'.format(source=source))
return source_entry return source_entry
def get_source_by_code(self, code, projector_id): def get_source_by_code(self, code, projector_id):
@ -411,11 +427,14 @@ class ProjectorDB(Manager):
source_entry = self.get_object_filtered(ProjectorSource, source_entry = self.get_object_filtered(ProjectorSource,
and_(ProjectorSource.code == code, and_(ProjectorSource.code == code,
ProjectorSource.projector_id == projector_id)) ProjectorSource.projector_id == projector_id))
if source_entry is None: if source_entry is None:
# Not found # Not found
log.warn('get_source_by_id() did not find code="%s" projector_id="%s"' % (code, projector_id)) log.warn('get_source_by_id() not found')
log.warn('code="{code}" projector_id="{data}"'.format(code=code, data=projector_id))
return None return None
log.debug('get_source_by_id() returning one entry for code="%s" projector_id="%s"' % (code, projector_id)) log.debug('get_source_by_id() returning one entry')
log.debug('code="{code}" projector_id="{data}"'.format(code=code, data=projector_id))
return source_entry return source_entry
def add_source(self, source): def add_source(self, source):
@ -424,6 +443,6 @@ class ProjectorDB(Manager):
:param source: ProjectorSource() instance to add :param source: ProjectorSource() instance to add
""" """
log.debug('Saving ProjectorSource(projector_id="%s" code="%s" text="%s")' % (source.projector_id, log.debug('Saving ProjectorSource(projector_id="{data}" '
source.code, source.text)) 'code="{code}" text="{text}")'.format(data=source.projector_id, code=source.code, text=source.text))
return self.save_object(source) return self.save_object(source)

View File

@ -91,7 +91,7 @@ class PJLink1(QTcpSocket):
:param poll_time: Time (in seconds) to poll connected projector :param poll_time: Time (in seconds) to poll connected projector
:param socket_timeout: Time (in seconds) to abort the connection if no response :param socket_timeout: Time (in seconds) to abort the connection if no response
""" """
log.debug('PJlink(args="%s" kwargs="%s")' % (args, kwargs)) log.debug('PJlink(args={args} kwargs={kwargs})'.format(args=args, kwargs=kwargs))
self.name = name self.name = name
self.ip = ip self.ip = ip
self.port = port self.port = port
@ -147,7 +147,7 @@ class PJLink1(QTcpSocket):
""" """
Reset projector-specific information to default Reset projector-specific information to default
""" """
log.debug('(%s) reset_information() connect status is %s' % (self.ip, self.state())) log.debug('({ip}) reset_information() connect status is {state}'.format(ip=self.ip, state=self.state()))
self.power = S_OFF self.power = S_OFF
self.pjlink_name = None self.pjlink_name = None
self.manufacturer = None self.manufacturer = None
@ -170,7 +170,7 @@ class PJLink1(QTcpSocket):
""" """
Connects signals to methods when thread is started. Connects signals to methods when thread is started.
""" """
log.debug('(%s) Thread starting' % self.ip) log.debug('({ip}) Thread starting'.format(ip=self.ip))
self.i_am_running = True self.i_am_running = True
self.connected.connect(self.check_login) self.connected.connect(self.check_login)
self.disconnected.connect(self.disconnect_from_host) self.disconnected.connect(self.disconnect_from_host)
@ -180,7 +180,7 @@ class PJLink1(QTcpSocket):
""" """
Cleanups when thread is stopped. Cleanups when thread is stopped.
""" """
log.debug('(%s) Thread stopped' % self.ip) log.debug('({ip}) Thread stopped'.format(ip=self.ip))
try: try:
self.connected.disconnect(self.check_login) self.connected.disconnect(self.check_login)
except TypeError: except TypeError:
@ -206,7 +206,7 @@ class PJLink1(QTcpSocket):
Aborts connection and closes socket in case of brain-dead projectors. Aborts connection and closes socket in case of brain-dead projectors.
Should normally be called by socket_timer(). Should normally be called by socket_timer().
""" """
log.debug('(%s) socket_abort() - Killing connection' % self.ip) log.debug('({ip}) socket_abort() - Killing connection'.format(ip=self.ip))
self.disconnect_from_host(abort=True) self.disconnect_from_host(abort=True)
def poll_loop(self): def poll_loop(self):
@ -216,7 +216,7 @@ class PJLink1(QTcpSocket):
""" """
if self.state() != self.ConnectedState: if self.state() != self.ConnectedState:
return return
log.debug('(%s) Updating projector status' % self.ip) log.debug('({ip}) Updating projector status'.format(ip=self.ip))
# Reset timer in case we were called from a set command # Reset timer in case we were called from a set command
if self.timer.interval() < self.poll_time: if self.timer.interval() < self.poll_time:
# Reset timer to 5 seconds # Reset timer to 5 seconds
@ -276,11 +276,17 @@ class PJLink1(QTcpSocket):
self.status_connect = S_CONNECTED self.status_connect = S_CONNECTED
self.projector_status = status self.projector_status = status
(status_code, status_message) = self._get_status(self.status_connect) (status_code, status_message) = self._get_status(self.status_connect)
log.debug('(%s) status_connect: %s: %s' % (self.ip, status_code, status_message if msg is None else msg)) log.debug('({ip}) status_connect: {code}: "{message}"'.format(ip=self.ip,
code=status_code,
message=status_message if msg is None else msg))
(status_code, status_message) = self._get_status(self.projector_status) (status_code, status_message) = self._get_status(self.projector_status)
log.debug('(%s) projector_status: %s: %s' % (self.ip, status_code, status_message if msg is None else msg)) log.debug('({ip}) projector_status: {code}: "{message}"'.format(ip=self.ip,
code=status_code,
message=status_message if msg is None else msg))
(status_code, status_message) = self._get_status(self.error_status) (status_code, status_message) = self._get_status(self.error_status)
log.debug('(%s) error_status: %s: %s' % (self.ip, status_code, status_message if msg is None else msg)) log.debug('({ip}) error_status: {code}: "{message}"'.format(ip=self.ip,
code=status_code,
message=status_message if msg is None else msg))
self.changeStatus.emit(self.ip, status, message) self.changeStatus.emit(self.ip, status, message)
@pyqtSlot() @pyqtSlot()
@ -291,27 +297,27 @@ class PJLink1(QTcpSocket):
:param data: Optional data if called from another routine :param data: Optional data if called from another routine
""" """
log.debug('(%s) check_login(data="%s")' % (self.ip, data)) log.debug('({ip}) check_login(data="{data}")'.format(ip=self.ip, data=data))
if data is None: if data is None:
# Reconnected setup? # Reconnected setup?
if not self.waitForReadyRead(2000): if not self.waitForReadyRead(2000):
# Possible timeout issue # Possible timeout issue
log.error('(%s) Socket timeout waiting for login' % self.ip) log.error('({ip}) Socket timeout waiting for login'.format(ip=self.ip))
self.change_status(E_SOCKET_TIMEOUT) self.change_status(E_SOCKET_TIMEOUT)
return return
read = self.readLine(self.maxSize) read = self.readLine(self.maxSize)
dontcare = self.readLine(self.maxSize) # Clean out the trailing \r\n dontcare = self.readLine(self.maxSize) # Clean out the trailing \r\n
if read is None: if read is None:
log.warn('(%s) read is None - socket error?' % self.ip) log.warn('({ip}) read is None - socket error?'.format(ip=self.ip))
return return
elif len(read) < 8: elif len(read) < 8:
log.warn('(%s) Not enough data read)' % self.ip) log.warn('({ip}) Not enough data read)'.format(ip=self.ip))
return return
data = decode(read, 'ascii') data = decode(read, 'ascii')
# Possibility of extraneous data on input when reading. # Possibility of extraneous data on input when reading.
# Clean out extraneous characters in buffer. # Clean out extraneous characters in buffer.
dontcare = self.readLine(self.maxSize) dontcare = self.readLine(self.maxSize)
log.debug('(%s) check_login() read "%s"' % (self.ip, data.strip())) log.debug('({ip}) check_login() read "{data}"'.format(ip=self.ip, data=data.strip()))
# At this point, we should only have the initial login prompt with # At this point, we should only have the initial login prompt with
# possible authentication # possible authentication
# PJLink initial login will be: # PJLink initial login will be:
@ -326,25 +332,25 @@ class PJLink1(QTcpSocket):
else: else:
# Process initial connection # Process initial connection
data_check = data.strip().split(' ') data_check = data.strip().split(' ')
log.debug('(%s) data_check="%s"' % (self.ip, data_check)) log.debug('({ip}) data_check="{data}"'.format(ip=self.ip, data=data_check))
# Check for projector reporting an error # Check for projector reporting an error
if data_check[1].upper() == 'ERRA': if data_check[1].upper() == 'ERRA':
# Authentication error # Authentication error
self.disconnect_from_host() self.disconnect_from_host()
self.change_status(E_AUTHENTICATION) self.change_status(E_AUTHENTICATION)
log.debug('(%s) emitting projectorAuthentication() signal' % self.name) log.debug('({ip}) emitting projectorAuthentication() signal'.format(ip=self.name))
return return
elif data_check[1] == '0' and self.pin is not None: elif data_check[1] == '0' and self.pin is not None:
# Pin set and no authentication needed # Pin set and no authentication needed
self.disconnect_from_host() self.disconnect_from_host()
self.change_status(E_AUTHENTICATION) self.change_status(E_AUTHENTICATION)
log.debug('(%s) emitting projectorNoAuthentication() signal' % self.name) log.debug('({ip}) emitting projectorNoAuthentication() signal'.format(ip=self.name))
self.projectorNoAuthentication.emit(self.name) self.projectorNoAuthentication.emit(self.name)
return return
elif data_check[1] == '1': elif data_check[1] == '1':
# Authenticated login with salt # Authenticated login with salt
log.debug('(%s) Setting hash with salt="%s"' % (self.ip, data_check[2])) log.debug('({ip}) Setting hash with salt="{data}"'.format(ip=self.ip, data=data_check[2]))
log.debug('(%s) pin="%s"' % (self.ip, self.pin)) log.debug('({ip}) pin="{data}"'.format(ip=self.ip, data=self.pin))
salt = qmd5_hash(salt=data_check[2].encode('ascii'), data=self.pin.encode('ascii')) salt = qmd5_hash(salt=data_check[2].encode('ascii'), data=self.pin.encode('ascii'))
else: else:
salt = None salt = None
@ -355,7 +361,7 @@ class PJLink1(QTcpSocket):
self.send_command(cmd='CLSS', salt=salt) self.send_command(cmd='CLSS', salt=salt)
self.waitForReadyRead() self.waitForReadyRead()
if (not self.no_poll) and (self.state() == self.ConnectedState): if (not self.no_poll) and (self.state() == self.ConnectedState):
log.debug('(%s) Starting timer' % self.ip) log.debug('({ip}) Starting timer'.format(ip=self.ip))
self.timer.setInterval(2000) # Set 2 seconds for initial information self.timer.setInterval(2000) # Set 2 seconds for initial information
self.timer.start() self.timer.start()
@ -364,15 +370,15 @@ class PJLink1(QTcpSocket):
""" """
Socket interface to retrieve data. Socket interface to retrieve data.
""" """
log.debug('(%s) get_data(): Reading data' % self.ip) log.debug('({ip}) get_data(): Reading data'.format(ip=self.ip))
if self.state() != self.ConnectedState: if self.state() != self.ConnectedState:
log.debug('(%s) get_data(): Not connected - returning' % self.ip) log.debug('({ip}) get_data(): Not connected - returning'.format(ip=self.ip))
self.send_busy = False self.send_busy = False
return return
read = self.readLine(self.maxSize) read = self.readLine(self.maxSize)
if read == -1: if read == -1:
# No data available # No data available
log.debug('(%s) get_data(): No data available (-1)' % self.ip) log.debug('({ip}) get_data(): No data available (-1)'.format(ip=self.ip))
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
return return
@ -382,11 +388,11 @@ class PJLink1(QTcpSocket):
data = data_in.strip() data = data_in.strip()
if len(data) < 7: if len(data) < 7:
# Not enough data for a packet # Not enough data for a packet
log.debug('(%s) get_data(): Packet length < 7: "%s"' % (self.ip, data)) log.debug('({ip}) get_data(): Packet length < 7: "{data}"'.format(ip=self.ip, data=data))
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
return return
log.debug('(%s) get_data(): Checking new data "%s"' % (self.ip, data)) log.debug('({ip}) get_data(): Checking new data "{data}"'.format(ip=self.ip, data=data))
if data.upper().startswith('PJLINK'): if data.upper().startswith('PJLINK'):
# Reconnected from remote host disconnect ? # Reconnected from remote host disconnect ?
self.check_login(data) self.check_login(data)
@ -394,7 +400,7 @@ class PJLink1(QTcpSocket):
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
return return
elif '=' not in data: elif '=' not in data:
log.warn('(%s) get_data(): Invalid packet received' % self.ip) log.warn('({ip}) get_data(): Invalid packet received'.format(ip=self.ip))
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
return return
@ -402,15 +408,15 @@ class PJLink1(QTcpSocket):
try: try:
(prefix, class_, cmd, data) = (data_split[0][0], data_split[0][1], data_split[0][2:], data_split[1]) (prefix, class_, cmd, data) = (data_split[0][0], data_split[0][1], data_split[0][2:], data_split[1])
except ValueError as e: except ValueError as e:
log.warn('(%s) get_data(): Invalid packet - expected header + command + data' % self.ip) log.warn('({ip}) get_data(): Invalid packet - expected header + command + data'.format(ip=self.ip))
log.warn('(%s) get_data(): Received data: "%s"' % (self.ip, read)) log.warn('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in.strip()))
self.change_status(E_INVALID_DATA) self.change_status(E_INVALID_DATA)
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
return return
if not (self.pjlink_class in PJLINK_VALID_CMD and cmd in PJLINK_VALID_CMD[self.pjlink_class]): if not (self.pjlink_class in PJLINK_VALID_CMD and cmd in PJLINK_VALID_CMD[self.pjlink_class]):
log.warn('(%s) get_data(): Invalid packet - unknown command "%s"' % (self.ip, cmd)) log.warn('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd))
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
return return
@ -424,7 +430,7 @@ class PJLink1(QTcpSocket):
:param err: Error code :param err: Error code
""" """
log.debug('(%s) get_error(err=%s): %s' % (self.ip, err, self.errorString())) log.debug('({ip}) get_error(err={error}): {data}'.format(ip=self.ip, error=err, data=self.errorString()))
if err <= 18: if err <= 18:
# QSocket errors. Redefined in projector.constants so we don't mistake # QSocket errors. Redefined in projector.constants so we don't mistake
# them for system errors # them for system errors
@ -453,32 +459,35 @@ class PJLink1(QTcpSocket):
:param queue: Option to force add to queue rather than sending directly :param queue: Option to force add to queue rather than sending directly
""" """
if self.state() != self.ConnectedState: if self.state() != self.ConnectedState:
log.warn('(%s) send_command(): Not connected - returning' % self.ip) log.warn('({ip}) send_command(): Not connected - returning'.format(ip=self.ip))
self.send_queue = [] self.send_queue = []
return return
self.projectorNetwork.emit(S_NETWORK_SENDING) self.projectorNetwork.emit(S_NETWORK_SENDING)
log.debug('(%s) send_command(): Building cmd="%s" opts="%s" %s' % (self.ip, log.debug('({ip}) send_command(): Building cmd="{command}" opts="{data}"{salt}'.format(ip=self.ip,
cmd, command=cmd,
opts, data=opts,
'' if salt is None else 'with hash')) salt='' if salt is None
if salt is None: else ' with hash'))
out = '%s%s %s%s' % (PJLINK_HEADER, cmd, opts, CR) out = '{salt}{header}{command} {options}{suffix}'.format(salt="" if salt is None else salt,
else: header=PJLINK_HEADER,
out = '%s%s%s %s%s' % (salt, PJLINK_HEADER, cmd, opts, CR) command=cmd,
options=opts,
suffix=CR)
if out in self.send_queue: if out in self.send_queue:
# Already there, so don't add # Already there, so don't add
log.debug('(%s) send_command(out="%s") Already in queue - skipping' % (self.ip, out.strip())) log.debug('({ip}) send_command(out="{data}") Already in queue - skipping'.format(ip=self.ip,
data=out.strip()))
elif not queue and len(self.send_queue) == 0: elif not queue and len(self.send_queue) == 0:
# Nothing waiting to send, so just send it # Nothing waiting to send, so just send it
log.debug('(%s) send_command(out="%s") Sending data' % (self.ip, out.strip())) log.debug('({ip}) send_command(out="{data}") Sending data'.format(ip=self.ip, data=out.strip()))
return self._send_command(data=out) return self._send_command(data=out)
else: else:
log.debug('(%s) send_command(out="%s") adding to queue' % (self.ip, out.strip())) log.debug('({ip}) send_command(out="{data}") adding to queue'.format(ip=self.ip, data=out.strip()))
self.send_queue.append(out) self.send_queue.append(out)
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
log.debug('(%s) send_command(): send_busy is %s' % (self.ip, self.send_busy)) log.debug('({ip}) send_command(): send_busy is {data}'.format(ip=self.ip, data=self.send_busy))
if not self.send_busy: if not self.send_busy:
log.debug('(%s) send_command() calling _send_string()') log.debug('({ip}) send_command() calling _send_string()'.format(ip=self.ip))
self._send_command() self._send_command()
@pyqtSlot() @pyqtSlot()
@ -488,10 +497,10 @@ class PJLink1(QTcpSocket):
:param data: Immediate data to send :param data: Immediate data to send
""" """
log.debug('(%s) _send_string()' % self.ip) log.debug('({ip}) _send_string()'.format(ip=self.ip))
log.debug('(%s) _send_string(): Connection status: %s' % (self.ip, self.state())) log.debug('({ip}) _send_string(): Connection status: {data}'.format(ip=self.ip, data=self.state()))
if self.state() != self.ConnectedState: if self.state() != self.ConnectedState:
log.debug('(%s) _send_string() Not connected - abort' % self.ip) log.debug('({ip}) _send_string() Not connected - abort'.format(ip=self.ip))
self.send_queue = [] self.send_queue = []
self.send_busy = False self.send_busy = False
return return
@ -500,18 +509,18 @@ class PJLink1(QTcpSocket):
return return
if data is not None: if data is not None:
out = data out = data
log.debug('(%s) _send_string(data=%s)' % (self.ip, out.strip())) log.debug('({ip}) _send_string(data="{data}")'.format(ip=self.ip, data=out.strip()))
elif len(self.send_queue) != 0: elif len(self.send_queue) != 0:
out = self.send_queue.pop(0) out = self.send_queue.pop(0)
log.debug('(%s) _send_string(queued data=%s)' % (self.ip, out.strip())) log.debug('({ip}) _send_string(queued data="{data}"%s)'.format(ip=self.ip, data=out.strip()))
else: else:
# No data to send # No data to send
log.debug('(%s) _send_string(): No data to send' % self.ip) log.debug('({ip}) _send_string(): No data to send'.format(ip=self.ip))
self.send_busy = False self.send_busy = False
return return
self.send_busy = True self.send_busy = True
log.debug('(%s) _send_string(): Sending "%s"' % (self.ip, out.strip())) log.debug('({ip}) _send_string(): Sending "{data}"'.format(ip=self.ip, data=out.strip()))
log.debug('(%s) _send_string(): Queue = %s' % (self.ip, self.send_queue)) log.debug('({ip}) _send_string(): Queue = {data}'.format(ip=self.ip, data=self.send_queue))
self.socket_timer.start() self.socket_timer.start()
self.projectorNetwork.emit(S_NETWORK_SENDING) self.projectorNetwork.emit(S_NETWORK_SENDING)
sent = self.write(out.encode('ascii')) sent = self.write(out.encode('ascii'))
@ -528,19 +537,21 @@ class PJLink1(QTcpSocket):
:param cmd: Command to process :param cmd: Command to process
:param data: Data being processed :param data: Data being processed
""" """
log.debug('(%s) Processing command "%s"' % (self.ip, cmd)) log.debug('({ip}) Processing command "{data}"'.format(ip=self.ip, data=cmd))
if data in PJLINK_ERRORS: if data in PJLINK_ERRORS:
# Oops - projector error # Oops - projector error
log.error('({ip}) Projector returned error "{data}"'.format(ip=self.ip, data=data))
if data.upper() == 'ERRA': if data.upper() == 'ERRA':
# Authentication error # Authentication error
self.disconnect_from_host() self.disconnect_from_host()
self.change_status(E_AUTHENTICATION) self.change_status(E_AUTHENTICATION)
log.debug('(%s) emitting projectorAuthentication() signal' % self.ip) log.debug('({ip}) emitting projectorAuthentication() signal'.format(ip=self.ip))
self.projectorAuthentication.emit(self.name) self.projectorAuthentication.emit(self.name)
elif data.upper() == 'ERR1': elif data.upper() == 'ERR1':
# Undefined command # Undefined command
self.change_status(E_UNDEFINED, '%s "%s"' % self.change_status(E_UNDEFINED, '{error} "{data}"'.format(error=translate('OpenLP.PJLink1',
(translate('OpenLP.PJLink1', 'Undefined command:'), cmd)) 'Undefined command:'),
data=cmd))
elif data.upper() == 'ERR2': elif data.upper() == 'ERR2':
# Invalid parameter # Invalid parameter
self.change_status(E_PARAMETER) self.change_status(E_PARAMETER)
@ -555,7 +566,7 @@ class PJLink1(QTcpSocket):
return return
# Command succeeded - no extra information # Command succeeded - no extra information
elif data.upper() == 'OK': elif data.upper() == 'OK':
log.debug('(%s) Command returned OK' % self.ip) log.debug('({ip}) Command returned OK'.format(ip=self.ip))
# A command returned successfully, recheck data # A command returned successfully, recheck data
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
@ -564,7 +575,7 @@ class PJLink1(QTcpSocket):
if cmd in self.PJLINK1_FUNC: if cmd in self.PJLINK1_FUNC:
self.PJLINK1_FUNC[cmd](data) self.PJLINK1_FUNC[cmd](data)
else: else:
log.warn('(%s) Invalid command %s' % (self.ip, cmd)) log.warn('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
self.send_busy = False self.send_busy = False
self.projectorReceivedData.emit() self.projectorReceivedData.emit()
@ -583,7 +594,7 @@ class PJLink1(QTcpSocket):
fill = {'Hours': int(data_dict[0]), 'On': False if data_dict[1] == '0' else True} fill = {'Hours': int(data_dict[0]), 'On': False if data_dict[1] == '0' else True}
except ValueError: except ValueError:
# In case of invalid entry # In case of invalid entry
log.warn('(%s) process_lamp(): Invalid data "%s"' % (self.ip, data)) log.warn('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data))
return return
lamps.append(fill) lamps.append(fill)
data_dict.pop(0) # Remove lamp hours data_dict.pop(0) # Remove lamp hours
@ -610,7 +621,7 @@ class PJLink1(QTcpSocket):
self.send_command('INST') self.send_command('INST')
else: else:
# Log unknown status response # Log unknown status response
log.warn('Unknown power response: %s' % data) log.warn('({ip}) Unknown power response: {data}'.format(ip=self.ip, data=data))
return return
def process_avmt(self, data): def process_avmt(self, data):
@ -635,7 +646,7 @@ class PJLink1(QTcpSocket):
shutter = True shutter = True
mute = True mute = True
else: else:
log.warn('Unknown shutter response: %s' % data) log.warn('({ip}) Unknown shutter response: {data}'.format(ip=self.ip, data=data))
update_icons = shutter != self.shutter update_icons = shutter != self.shutter
update_icons = update_icons or mute != self.mute update_icons = update_icons or mute != self.mute
self.shutter = shutter self.shutter = shutter
@ -652,6 +663,7 @@ class PJLink1(QTcpSocket):
:param data: Currently selected source :param data: Currently selected source
""" """
self.source = data self.source = data
log.info('({ip}) Setting data source to "{data}"'.format(ip=self.ip, data=self.source))
return return
def process_clss(self, data): def process_clss(self, data):
@ -670,7 +682,8 @@ class PJLink1(QTcpSocket):
else: else:
clss = data clss = data
self.pjlink_class = clss self.pjlink_class = clss
log.debug('(%s) Setting pjlink_class for this projector to "%s"' % (self.ip, self.pjlink_class)) log.debug('({ip}) Setting pjlink_class for this projector to "{data}"'.format(ip=self.ip,
data=self.pjlink_class))
return return
def process_name(self, data): def process_name(self, data):
@ -681,6 +694,7 @@ class PJLink1(QTcpSocket):
:param data: Projector name :param data: Projector name
""" """
self.pjlink_name = data self.pjlink_name = data
log.debug('({ip}) Setting projector PJLink name to "{data}"'.format(ip=self.ip, data=self.pjlink_name))
return return
def process_inf1(self, data): def process_inf1(self, data):
@ -691,6 +705,7 @@ class PJLink1(QTcpSocket):
:param data: Projector manufacturer :param data: Projector manufacturer
""" """
self.manufacturer = data self.manufacturer = data
log.debug('({ip}) Setting projector manufacturer data to "{data}"'.format(ip=self.ip, data=self.manufacturer))
return return
def process_inf2(self, data): def process_inf2(self, data):
@ -701,6 +716,7 @@ class PJLink1(QTcpSocket):
:param data: Model name :param data: Model name
""" """
self.model = data self.model = data
log.debug('({ip}) Setting projector model to "{data}"'.format(ip=self.ip, data=self.model))
return return
def process_info(self, data): def process_info(self, data):
@ -711,6 +727,7 @@ class PJLink1(QTcpSocket):
:param data: Projector other info :param data: Projector other info
""" """
self.other_info = data self.other_info = data
log.debug('({ip}) Setting projector other_info to "{data}"'.format(ip=self.ip, data=self.other_info))
return return
def process_inst(self, data): def process_inst(self, data):
@ -727,6 +744,8 @@ class PJLink1(QTcpSocket):
sources.sort() sources.sort()
self.source_available = sources self.source_available = sources
self.projectorUpdateIcons.emit() self.projectorUpdateIcons.emit()
log.debug('({ip}) Setting projector sources_available to "{data}"'.format(ip=self.ip,
data=self.source_available))
return return
def process_erst(self, data): def process_erst(self, data):
@ -776,7 +795,7 @@ class PJLink1(QTcpSocket):
Initiate connection to projector. Initiate connection to projector.
""" """
if self.state() == self.ConnectedState: if self.state() == self.ConnectedState:
log.warn('(%s) connect_to_host(): Already connected - returning' % self.ip) log.warn('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip))
return return
self.change_status(S_CONNECTING) self.change_status(S_CONNECTING)
self.connectToHost(self.ip, self.port if type(self.port) is int else int(self.port)) self.connectToHost(self.ip, self.port if type(self.port) is int else int(self.port))
@ -788,9 +807,9 @@ class PJLink1(QTcpSocket):
""" """
if abort or self.state() != self.ConnectedState: if abort or self.state() != self.ConnectedState:
if abort: if abort:
log.warn('(%s) disconnect_from_host(): Aborting connection' % self.ip) log.warn('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip))
else: else:
log.warn('(%s) disconnect_from_host(): Not connected - returning' % self.ip) log.warn('({ip}) disconnect_from_host(): Not connected - returning'.format(ip=self.ip))
self.reset_information() self.reset_information()
self.disconnectFromHost() self.disconnectFromHost()
try: try:
@ -800,8 +819,8 @@ class PJLink1(QTcpSocket):
if abort: if abort:
self.change_status(E_NOT_CONNECTED) self.change_status(E_NOT_CONNECTED)
else: else:
log.debug('(%s) disconnect_from_host() Current status %s' % (self.ip, log.debug('({ip}) disconnect_from_host() '
self._get_status(self.status_connect)[0])) 'Current status {data}'.format(ip=self.ip, data=self._get_status(self.status_connect)[0]))
if self.status_connect != E_NOT_CONNECTED: if self.status_connect != E_NOT_CONNECTED:
self.change_status(S_NOT_CONNECTED) self.change_status(S_NOT_CONNECTED)
self.reset_information() self.reset_information()
@ -811,60 +830,70 @@ class PJLink1(QTcpSocket):
""" """
Send command to retrieve available source inputs. Send command to retrieve available source inputs.
""" """
log.debug('({ip}) Sending INST command'.format(ip=self.ip))
return self.send_command(cmd='INST') return self.send_command(cmd='INST')
def get_error_status(self): def get_error_status(self):
""" """
Send command to retrieve currently known errors. Send command to retrieve currently known errors.
""" """
log.debug('({ip}) Sending ERST command'.format(ip=self.ip))
return self.send_command(cmd='ERST') return self.send_command(cmd='ERST')
def get_input_source(self): def get_input_source(self):
""" """
Send command to retrieve currently selected source input. Send command to retrieve currently selected source input.
""" """
log.debug('({ip}) Sending INPT command'.format(ip=self.ip))
return self.send_command(cmd='INPT') return self.send_command(cmd='INPT')
def get_lamp_status(self): def get_lamp_status(self):
""" """
Send command to return the lap status. Send command to return the lap status.
""" """
log.debug('({ip}) Sending LAMP command'.format(ip=self.ip))
return self.send_command(cmd='LAMP') return self.send_command(cmd='LAMP')
def get_manufacturer(self): def get_manufacturer(self):
""" """
Send command to retrieve manufacturer name. Send command to retrieve manufacturer name.
""" """
log.debug('({ip}) Sending INF1 command'.format(ip=self.ip))
return self.send_command(cmd='INF1') return self.send_command(cmd='INF1')
def get_model(self): def get_model(self):
""" """
Send command to retrieve the model name. Send command to retrieve the model name.
""" """
log.debug('({ip}) Sending INF2 command'.format(ip=self.ip))
return self.send_command(cmd='INF2') return self.send_command(cmd='INF2')
def get_name(self): def get_name(self):
""" """
Send command to retrieve name as set by end-user (if set). Send command to retrieve name as set by end-user (if set).
""" """
log.debug('({ip}) Sending NAME command'.format(ip=self.ip))
return self.send_command(cmd='NAME') return self.send_command(cmd='NAME')
def get_other_info(self): def get_other_info(self):
""" """
Send command to retrieve extra info set by manufacturer. Send command to retrieve extra info set by manufacturer.
""" """
log.debug('({ip}) Sending INFO command'.format(ip=self.ip))
return self.send_command(cmd='INFO') return self.send_command(cmd='INFO')
def get_power_status(self): def get_power_status(self):
""" """
Send command to retrieve power status. Send command to retrieve power status.
""" """
log.debug('({ip}) Sending POWR command'.format(ip=self.ip))
return self.send_command(cmd='POWR') return self.send_command(cmd='POWR')
def get_shutter_status(self): def get_shutter_status(self):
""" """
Send command to retrieve shutter status. Send command to retrieve shutter status.
""" """
log.debug('({ip}) Sending AVMT command'.format(ip=self.ip))
return self.send_command(cmd='AVMT') return self.send_command(cmd='AVMT')
def set_input_source(self, src=None): def set_input_source(self, src=None):
@ -874,12 +903,12 @@ class PJLink1(QTcpSocket):
:param src: Video source to select in projector :param src: Video source to select in projector
""" """
log.debug('(%s) set_input_source(src=%s)' % (self.ip, src)) log.debug('({ip}) set_input_source(src="{data}")'.format(ip=self.ip, data=src))
if self.source_available is None: if self.source_available is None:
return return
elif src not in self.source_available: elif src not in self.source_available:
return return
log.debug('(%s) Setting input source to %s' % (self.ip, src)) log.debug('({ip}) Setting input source to "{data}"'.format(ip=self.ip, data=src))
self.send_command(cmd='INPT', opts=src) self.send_command(cmd='INPT', opts=src)
self.poll_loop() self.poll_loop()
@ -887,6 +916,7 @@ class PJLink1(QTcpSocket):
""" """
Send command to turn power to on. Send command to turn power to on.
""" """
log.debug('({ip}) Setting POWR to 1 (on)'.format(ip=self.ip))
self.send_command(cmd='POWR', opts='1') self.send_command(cmd='POWR', opts='1')
self.poll_loop() self.poll_loop()
@ -894,6 +924,7 @@ class PJLink1(QTcpSocket):
""" """
Send command to turn power to standby. Send command to turn power to standby.
""" """
log.debug('({ip}) Setting POWR to 0 (standby)'.format(ip=self.ip))
self.send_command(cmd='POWR', opts='0') self.send_command(cmd='POWR', opts='0')
self.poll_loop() self.poll_loop()
@ -901,6 +932,7 @@ class PJLink1(QTcpSocket):
""" """
Send command to set shutter to closed position. Send command to set shutter to closed position.
""" """
log.debug('({ip}) Setting AVMT to 11 (shutter closed)'.format(ip=self.ip))
self.send_command(cmd='AVMT', opts='11') self.send_command(cmd='AVMT', opts='11')
self.poll_loop() self.poll_loop()
@ -908,5 +940,6 @@ class PJLink1(QTcpSocket):
""" """
Send command to set shutter to open position. Send command to set shutter to open position.
""" """
log.debug('({ip}) Setting AVMT to "10" (shutter open)'.format(ip=self.ip))
self.send_command(cmd='AVMT', opts='10') self.send_command(cmd='AVMT', opts='10')
self.poll_loop() self.poll_loop()

View File

@ -107,3 +107,20 @@ class TestPJLink(TestCase):
# THEN: process_inpt method should have been called with 31 # THEN: process_inpt method should have been called with 31
mock_process_inpt.called_with('31', mock_process_inpt.called_with('31',
"process_inpt should have been called with 31") "process_inpt should have been called with 31")
@patch.object(pjlink_test, 'projectorReceivedData')
def projector_process_lamp_test(self, mock_projectorReceivedData):
"""
Test setting lamp on/off and hours
"""
# GIVEN: Test object
pjlink = pjlink_test
# WHEN: Call process_command with lamp data
pjlink.process_command('LAMP', '22222 1')
# THEN: Lamp should have been set with status=ON and hours=22222
self.assertEquals(pjlink.lamp[0]['On'], True,
'Lamp power status should have been set to TRUE')
self.assertEquals(pjlink.lamp[0]['Hours'], 22222,
'Lamp hours should have been set to 22222')