forked from openlp/openlp
PJlink class 2 updates C
This commit is contained in:
parent
5c161eb541
commit
cb5c0f82a3
@ -621,5 +621,5 @@ from .imagemanager import ImageManager
|
||||
from .renderer import Renderer
|
||||
from .mediamanageritem import MediaManagerItem
|
||||
from .projector.db import ProjectorDB, Projector
|
||||
from .projector.pjlink1 import PJLink1
|
||||
from .projector.pjlink1 import PJLink
|
||||
from .projector.constants import PJLINK_PORT, ERROR_MSG, ERROR_STRING
|
||||
|
@ -150,11 +150,15 @@ class Projector(CommonBase, Base):
|
||||
name: Column(String(20))
|
||||
location: Column(String(30))
|
||||
notes: Column(String(200))
|
||||
pjlink_name: Column(String(128)) # From projector (future)
|
||||
manufacturer: Column(String(128)) # From projector (future)
|
||||
model: Column(String(128)) # From projector (future)
|
||||
other: Column(String(128)) # From projector (future)
|
||||
sources: Column(String(128)) # From projector (future)
|
||||
pjlink_name: Column(String(128)) # From projector
|
||||
manufacturer: Column(String(128)) # From projector
|
||||
model: Column(String(128)) # From projector
|
||||
other: Column(String(128)) # From projector
|
||||
sources: Column(String(128)) # From projector
|
||||
serial_no: Column(String(30)) # From projector (Class 2)
|
||||
sw_version: Column(String(30)) # From projector (Class 2)
|
||||
model_filter: Column(String(30)) # From projector (Class 2)
|
||||
model_lamp: Column(String(30)) # From projector (Class 2)
|
||||
|
||||
ProjectorSource relates
|
||||
"""
|
||||
@ -164,20 +168,25 @@ class Projector(CommonBase, Base):
|
||||
"""
|
||||
return '< Projector(id="{data}", ip="{ip}", port="{port}", pin="{pin}", name="{name}", ' \
|
||||
'location="{location}", notes="{notes}", pjlink_name="{pjlink_name}", ' \
|
||||
'manufacturer="{manufacturer}", model="{model}", other="{other}", ' \
|
||||
'sources="{sources}", source_list="{source_list}") >'.format(data=self.id,
|
||||
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)
|
||||
'manufacturer="{manufacturer}", model="{model}", serial_no="{serial}", other="{other}", ' \
|
||||
'sources="{sources}", source_list="{source_list}", model_filter="{mfilter}", ' \
|
||||
'model_lamp="{mlamp}", sw_version="{sw_ver}") >'.format(data=self.id,
|
||||
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,
|
||||
serial=self.serial_no,
|
||||
mfilter=self.model_filter,
|
||||
mlamp=self.model_lamp,
|
||||
sw_ver=self.sw_version)
|
||||
ip = Column(String(100))
|
||||
port = Column(String(8))
|
||||
pin = Column(String(20))
|
||||
@ -189,6 +198,10 @@ class Projector(CommonBase, Base):
|
||||
model = Column(String(128))
|
||||
other = Column(String(128))
|
||||
sources = Column(String(128))
|
||||
serial_no = Column(String(30))
|
||||
sw_version = Column(String(30))
|
||||
model_filter = Column(String(30))
|
||||
model_lamp = Column(String(30))
|
||||
source_list = relationship('ProjectorSource',
|
||||
order_by='ProjectorSource.code',
|
||||
backref='projector',
|
||||
@ -359,6 +372,10 @@ class ProjectorDB(Manager):
|
||||
old_projector.model = projector.model
|
||||
old_projector.other = projector.other
|
||||
old_projector.sources = projector.sources
|
||||
old_projector.serial_no = projector.serial_no
|
||||
old_projector.sw_version = projector.sw_version
|
||||
old_projector.model_filter = projector.model_filter
|
||||
old_projector.model_lamp = projector.model_lamp
|
||||
return self.save_object(old_projector)
|
||||
|
||||
def delete_projector(self, projector):
|
||||
|
@ -42,7 +42,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
log.debug('pjlink1 loaded')
|
||||
|
||||
__all__ = ['PJLink1']
|
||||
__all__ = ['PJLink']
|
||||
|
||||
from codecs import decode
|
||||
|
||||
@ -68,7 +68,7 @@ PJLINK_HEADER = '{prefix}{{linkclass}}'.format(prefix=PJLINK_PREFIX)
|
||||
PJLINK_SUFFIX = CR
|
||||
|
||||
|
||||
class PJLink1(QtNetwork.QTcpSocket):
|
||||
class PJLink(QtNetwork.QTcpSocket):
|
||||
"""
|
||||
Socket service for connecting to a PJLink-capable projector.
|
||||
"""
|
||||
@ -129,7 +129,7 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
self.pin = pin
|
||||
super(PJLink1, self).__init__()
|
||||
super(PJLink, self).__init__()
|
||||
self.dbid = None
|
||||
self.location = None
|
||||
self.notes = None
|
||||
@ -162,7 +162,7 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
# Socket timer for some possible brain-dead projectors or network cable pulled
|
||||
self.socket_timer = None
|
||||
# Map command to function
|
||||
self.pjlink1_functions = {
|
||||
self.pjlink_functions = {
|
||||
'AVMT': self.process_avmt,
|
||||
'CLSS': self.process_clss,
|
||||
'ERST': self.process_erst,
|
||||
@ -286,7 +286,7 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
elif status in STATUS_STRING:
|
||||
return STATUS_STRING[status], ERROR_MSG[status]
|
||||
else:
|
||||
return status, translate('OpenLP.PJLink1', 'Unknown status')
|
||||
return status, translate('OpenLP.PJLink', 'Unknown status')
|
||||
|
||||
def change_status(self, status, msg=None):
|
||||
"""
|
||||
@ -296,7 +296,7 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
:param status: Status code
|
||||
:param msg: Optional message
|
||||
"""
|
||||
message = translate('OpenLP.PJLink1', 'No message') if msg is None else msg
|
||||
message = translate('OpenLP.PJLink', 'No message') if msg is None else msg
|
||||
(code, message) = self._get_status(status)
|
||||
if msg is not None:
|
||||
message = msg
|
||||
@ -576,7 +576,7 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
if sent == -1:
|
||||
# Network error?
|
||||
self.change_status(E_NETWORK,
|
||||
translate('OpenLP.PJLink1', 'Error while sending data to projector'))
|
||||
translate('OpenLP.PJLink', 'Error while sending data to projector'))
|
||||
|
||||
def process_command(self, cmd, data):
|
||||
"""
|
||||
@ -625,8 +625,9 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
|
||||
if cmd in self.pjlink1_functions:
|
||||
self.pjlink1_functions[cmd](data)
|
||||
if cmd in self.pjlink_functions:
|
||||
log.debug('({ip}) Calling function for {cmd}'.format(ip=self.ip, cmd=cmd))
|
||||
self.pjlink_functions[cmd](data)
|
||||
else:
|
||||
log.warning('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
|
||||
self.send_busy = False
|
||||
@ -662,6 +663,7 @@ class PJLink1(QtNetwork.QTcpSocket):
|
||||
|
||||
:param data: Power status
|
||||
"""
|
||||
log.debug('({ip}: Processing POWR command'.format(ip=self.ip))
|
||||
if data in PJLINK_POWR_STATUS:
|
||||
power = PJLINK_POWR_STATUS[data]
|
||||
update_icons = self.power != power
|
||||
|
@ -38,7 +38,7 @@ from openlp.core.lib.projector.constants import ERROR_MSG, ERROR_STRING, E_AUTHE
|
||||
E_NETWORK, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, STATUS_STRING, S_CONNECTED, S_CONNECTING, S_COOLDOWN, \
|
||||
S_INITIALIZE, S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP
|
||||
from openlp.core.lib.projector.db import ProjectorDB
|
||||
from openlp.core.lib.projector.pjlink1 import PJLink1
|
||||
from openlp.core.lib.projector.pjlink1 import PJLink
|
||||
from openlp.core.ui.projector.editform import ProjectorEditForm
|
||||
from openlp.core.ui.projector.sourceselectform import SourceSelectTabs, SourceSelectSingle
|
||||
|
||||
@ -690,19 +690,19 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, UiProjecto
|
||||
Helper app to build a projector instance
|
||||
|
||||
:param projector: Dict of projector database information
|
||||
:returns: PJLink1() instance
|
||||
:returns: PJLink() instance
|
||||
"""
|
||||
log.debug('_add_projector()')
|
||||
return PJLink1(dbid=projector.id,
|
||||
ip=projector.ip,
|
||||
port=int(projector.port),
|
||||
name=projector.name,
|
||||
location=projector.location,
|
||||
notes=projector.notes,
|
||||
pin=None if projector.pin == '' else projector.pin,
|
||||
poll_time=self.poll_time,
|
||||
socket_timeout=self.socket_timeout
|
||||
)
|
||||
return PJLink(dbid=projector.id,
|
||||
ip=projector.ip,
|
||||
port=int(projector.port),
|
||||
name=projector.name,
|
||||
location=projector.location,
|
||||
notes=projector.notes,
|
||||
pin=None if projector.pin == '' else projector.pin,
|
||||
poll_time=self.poll_time,
|
||||
socket_timeout=self.socket_timeout
|
||||
)
|
||||
|
||||
def add_projector(self, projector, start=False):
|
||||
"""
|
||||
@ -961,7 +961,7 @@ class ProjectorItem(QtCore.QObject):
|
||||
"""
|
||||
Initialization for ProjectorItem instance
|
||||
|
||||
:param link: PJLink1 instance for QListWidgetItem
|
||||
:param link: PJLink instance for QListWidgetItem
|
||||
"""
|
||||
self.link = link
|
||||
self.thread = None
|
||||
|
@ -29,7 +29,6 @@ class TestProjectorConstants(TestCase):
|
||||
"""
|
||||
Test specific functions in the projector constants module.
|
||||
"""
|
||||
@skip('Waiting for merge of ~alisonken1/openlp/pjlink2-resource-data')
|
||||
def build_pjlink_video_label_test(self):
|
||||
"""
|
||||
Test building PJLINK_DEFAULT_CODES dictionary
|
||||
|
@ -25,13 +25,13 @@ Package to test the openlp.core.lib.projector.pjlink1 package.
|
||||
from unittest import TestCase
|
||||
from unittest.mock import call, patch, MagicMock
|
||||
|
||||
from openlp.core.lib.projector.pjlink1 import PJLink1
|
||||
from openlp.core.lib.projector.pjlink1 import PJLink
|
||||
from openlp.core.lib.projector.constants import E_PARAMETER, ERROR_STRING, S_OFF, S_STANDBY, S_ON, \
|
||||
PJLINK_POWR_STATUS, S_CONNECTED
|
||||
|
||||
from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST_HASH
|
||||
|
||||
pjlink_test = PJLink1(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
|
||||
pjlink_test = PJLink(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
|
||||
|
||||
|
||||
class TestPJLink(TestCase):
|
||||
@ -164,23 +164,36 @@ class TestPJLink(TestCase):
|
||||
'Lamp 3 hours should have been set to 33333')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorReceivedData')
|
||||
def test_projector_process_power_on(self, mock_projectorReceivedData):
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
@patch.object(pjlink_test, 'send_command')
|
||||
@patch.object(pjlink_test, 'change_status')
|
||||
def test_projector_process_power_on(self, mock_change_status,
|
||||
mock_send_command,
|
||||
mock_UpdateIcons,
|
||||
mock_ReceivedData):
|
||||
"""
|
||||
Test status power to ON
|
||||
"""
|
||||
# GIVEN: Test object and preset
|
||||
pjlink = pjlink_test
|
||||
pjlink.power = S_STANDBY
|
||||
pjlink.socket_timer = MagicMock()
|
||||
|
||||
# WHEN: Call process_command with turn power on command
|
||||
pjlink.process_command('POWR', PJLINK_POWR_STATUS[S_ON])
|
||||
|
||||
# THEN: Power should be set to ON
|
||||
self.assertEquals(pjlink.power, S_ON, 'Power should have been set to ON')
|
||||
mock_send_command.assert_called_once_with('INST')
|
||||
self.assertEquals(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorReceivedData')
|
||||
def test_projector_process_power_off(self, mock_projectorReceivedData):
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
@patch.object(pjlink_test, 'send_command')
|
||||
@patch.object(pjlink_test, 'change_status')
|
||||
def test_projector_process_power_off(self, mock_change_status,
|
||||
mock_send_command,
|
||||
mock_UpdateIcons,
|
||||
mock_ReceivedData):
|
||||
"""
|
||||
Test status power to STANDBY
|
||||
"""
|
||||
@ -193,6 +206,8 @@ class TestPJLink(TestCase):
|
||||
|
||||
# THEN: Power should be set to STANDBY
|
||||
self.assertEquals(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY')
|
||||
self.assertEquals(mock_send_command.called, False, 'send_command should not have been called')
|
||||
self.assertEquals(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called')
|
||||
|
||||
@patch.object(pjlink_test, 'projectorUpdateIcons')
|
||||
def test_projector_process_avmt_closed_unmuted(self, mock_projectorReceivedData):
|
||||
@ -372,7 +387,7 @@ class TestPJLink(TestCase):
|
||||
@patch.object(pjlink_test, '_not_implemented')
|
||||
def not_implemented_test(self, mock_not_implemented):
|
||||
"""
|
||||
Test pjlink1._not_implemented method being called
|
||||
Test PJLink._not_implemented method being called
|
||||
"""
|
||||
# GIVEN: test object
|
||||
pjlink = pjlink_test
|
||||
@ -381,13 +396,13 @@ class TestPJLink(TestCase):
|
||||
# WHEN: A future command is called that is not implemented yet
|
||||
pjlink.process_command(test_cmd, "Garbage data for test only")
|
||||
|
||||
# THEN: pjlink1.__not_implemented should have been called with test_cmd
|
||||
# THEN: PJLink.__not_implemented should have been called with test_cmd
|
||||
mock_not_implemented.assert_called_with(test_cmd)
|
||||
|
||||
@patch.object(pjlink_test, 'disconnect_from_host')
|
||||
def socket_abort_test(self, mock_disconnect):
|
||||
"""
|
||||
Test PJLink1.socket_abort calls disconnect_from_host
|
||||
Test PJLink.socket_abort calls disconnect_from_host
|
||||
"""
|
||||
# GIVEN: Test object
|
||||
pjlink = pjlink_test
|
||||
@ -400,7 +415,7 @@ class TestPJLink(TestCase):
|
||||
|
||||
def poll_loop_not_connected_test(self):
|
||||
"""
|
||||
Test PJLink1.poll_loop not connected return
|
||||
Test PJLink.poll_loop not connected return
|
||||
"""
|
||||
# GIVEN: Test object and mocks
|
||||
pjlink = pjlink_test
|
||||
@ -409,7 +424,7 @@ class TestPJLink(TestCase):
|
||||
pjlink.state.return_value = False
|
||||
pjlink.ConnectedState = True
|
||||
|
||||
# WHEN: PJLink1.poll_loop called
|
||||
# WHEN: PJLink.poll_loop called
|
||||
pjlink.poll_loop()
|
||||
|
||||
# THEN: poll_loop should exit without calling any other method
|
||||
@ -418,7 +433,7 @@ class TestPJLink(TestCase):
|
||||
@patch.object(pjlink_test, 'send_command')
|
||||
def poll_loop_start_test(self, mock_send_command):
|
||||
"""
|
||||
Test PJLink1.poll_loop makes correct calls
|
||||
Test PJLink.poll_loop makes correct calls
|
||||
"""
|
||||
# GIVEN: test object and test data
|
||||
pjlink = pjlink_test
|
||||
@ -450,7 +465,7 @@ class TestPJLink(TestCase):
|
||||
call('NAME', queue=True),
|
||||
]
|
||||
|
||||
# WHEN: PJLink1.poll_loop is called
|
||||
# WHEN: PJLink.poll_loop is called
|
||||
pjlink.poll_loop()
|
||||
|
||||
# THEN: proper calls were made to retrieve projector data
|
||||
|
@ -26,13 +26,15 @@ record functions.
|
||||
PREREQUISITE: add_record() and get_all() functions validated.
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.lib.projector.db import Manufacturer, Model, Projector, ProjectorDB, ProjectorSource, Source
|
||||
from openlp.core.lib.projector.constants import PJLINK_PORT
|
||||
|
||||
from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
|
||||
from tests.resources.projector.data import TEST_DB_PJLINK1, TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
|
||||
from tests.utils.constants import TEST_RESOURCES_PATH
|
||||
|
||||
|
||||
def compare_data(one, two):
|
||||
@ -45,7 +47,11 @@ def compare_data(one, two):
|
||||
one.port == two.port and \
|
||||
one.name == two.name and \
|
||||
one.location == two.location and \
|
||||
one.notes == two.notes
|
||||
one.notes == two.notes and \
|
||||
one.sw_version == two.sw_version and \
|
||||
one.serial_no == two.serial_no and \
|
||||
one.model_filter == two.model_filter and \
|
||||
one.model_lamp == two.model_lamp
|
||||
|
||||
|
||||
def compare_source(one, two):
|
||||
@ -168,6 +174,10 @@ class TestProjectorDB(TestCase):
|
||||
record.name = TEST3_DATA['name']
|
||||
record.location = TEST3_DATA['location']
|
||||
record.notes = TEST3_DATA['notes']
|
||||
record.sw_version = TEST3_DATA['sw_version']
|
||||
record.serial_no = TEST3_DATA['serial_no']
|
||||
record.model_filter = TEST3_DATA['model_filter']
|
||||
record.model_lamp = TEST3_DATA['model_lamp']
|
||||
updated = self.projector.update_projector(record)
|
||||
self.assertTrue(updated, 'Save updated record should have returned True')
|
||||
record = self.projector.get_projector_by_ip(TEST3_DATA['ip'])
|
||||
@ -246,7 +256,8 @@ class TestProjectorDB(TestCase):
|
||||
projector = Projector()
|
||||
|
||||
# WHEN: projector() is populated
|
||||
# NOTE: projector.pin, projector.other, projector.sources should all return None
|
||||
# NOTE: projector.[pin, other, sources, sw_version, serial_no, sw_version, model_lamp, model_filter]
|
||||
# should all return None.
|
||||
# projector.source_list should return an empty list
|
||||
projector.id = 0
|
||||
projector.ip = '127.0.0.1'
|
||||
@ -262,8 +273,9 @@ class TestProjectorDB(TestCase):
|
||||
self.assertEqual(str(projector),
|
||||
'< Projector(id="0", ip="127.0.0.1", port="4352", pin="None", name="Test One", '
|
||||
'location="Somewhere over the rainbow", notes="Not again", pjlink_name="TEST", '
|
||||
'manufacturer="IN YOUR DREAMS", model="OpenLP", other="None", sources="None", '
|
||||
'source_list="[]") >',
|
||||
'manufacturer="IN YOUR DREAMS", model="OpenLP", serial_no="None", other="None", '
|
||||
'sources="None", source_list="[]", model_filter="None", model_lamp="None", '
|
||||
'sw_version="None") >',
|
||||
'Projector.__repr__() should have returned a proper representation string')
|
||||
|
||||
def test_projectorsource_repr(self):
|
||||
|
@ -27,6 +27,8 @@ import os
|
||||
from tempfile import gettempdir
|
||||
|
||||
# Test data
|
||||
TEST_DB_PJLINK1 = 'projector_pjlink1.sqlite'
|
||||
|
||||
TEST_DB = os.path.join(gettempdir(), 'openlp-test-projectordb.sql')
|
||||
|
||||
TEST_SALT = '498e4a67'
|
||||
@ -44,21 +46,33 @@ TEST1_DATA = dict(ip='111.111.111.111',
|
||||
pin='1111',
|
||||
name='___TEST_ONE___',
|
||||
location='location one',
|
||||
notes='notes one')
|
||||
notes='notes one',
|
||||
serial_no='Serial Number 1',
|
||||
sw_version='Version 1',
|
||||
model_filter='Filter type 1',
|
||||
model_lamp='Lamp type 1')
|
||||
|
||||
TEST2_DATA = dict(ip='222.222.222.222',
|
||||
port='2222',
|
||||
pin='2222',
|
||||
name='___TEST_TWO___',
|
||||
location='location two',
|
||||
notes='notes two')
|
||||
notes='notes one',
|
||||
serial_no='Serial Number 2',
|
||||
sw_version='Version 2',
|
||||
model_filter='Filter type 2',
|
||||
model_lamp='Lamp type 2')
|
||||
|
||||
TEST3_DATA = dict(ip='333.333.333.333',
|
||||
port='3333',
|
||||
pin='3333',
|
||||
name='___TEST_THREE___',
|
||||
location='location three',
|
||||
notes='notes three')
|
||||
notes='notes one',
|
||||
serial_no='Serial Number 3',
|
||||
sw_version='Version 3',
|
||||
model_filter='Filter type 3',
|
||||
model_lamp='Lamp type 3')
|
||||
|
||||
TEST_VIDEO_CODES = {
|
||||
'11': 'RGB 1',
|
||||
|
Loading…
Reference in New Issue
Block a user