Skip to content

Commit e309303

Browse files
committed
Allow to rollback to non-persistant connections
Sometimes, we need to rollback to old non-persistant connections to allow other software to connect to the MAX! cube to pair new devices or perform other operations not yet supported.
1 parent 89efe6e commit e309303

File tree

4 files changed

+42
-3
lines changed

4 files changed

+42
-3
lines changed

maxcube/commander.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Commander(object):
2626
def __init__(self, host: str, port: int):
2727
self.__host: str = host
2828
self.__port: int = port
29+
self.use_persistent_connection = True
2930
self.__connection: Connection = None
3031
self.__unsolicited_messages: List[Message] = []
3132

@@ -54,6 +55,8 @@ def update(self) -> List[Message]:
5455
self.__connect(deadline)
5556
else:
5657
self.__connect(deadline)
58+
if not self.use_persistent_connection:
59+
self.disconnect()
5760
return self.get_unsolicited_messages()
5861

5962
def send_radio_msg(self, hex_radio_msg: str) -> bool:
@@ -101,6 +104,10 @@ def __call(self, msg: Message, deadline: Deadline) -> Message:
101104
else:
102105
raise
103106

107+
finally:
108+
if not self.use_persistent_connection:
109+
self.disconnect()
110+
104111
def __is_connected(self) -> bool:
105112
return self.__connection is not None
106113

maxcube/cube.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ def __init__(self, host: str, port: int = DEFAULT_PORT):
4444
self.update()
4545
self.log()
4646

47+
@property
48+
def use_persistent_connection(self) -> bool:
49+
return self.__commander.use_persistent_connection
50+
51+
@use_persistent_connection.setter
52+
def use_persistent_connection(self, value: bool) -> None:
53+
self.__commander.use_persistent_connection = value
54+
4755
def disconnect(self):
4856
self.__commander.disconnect()
4957

tests/test_commander.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
S_CMD_SUCCESS = Message('S', '00,0,31')
1515
S_CMD_ERROR = Message('S', '100,1,31')
1616
S_CMD_THROTTLE_ERROR = Message('S', '100,1,0')
17+
Q_CMD = Message('q')
1718

1819
TEST_TIMEOUT = Timeout('test', 1.0)
1920

@@ -35,16 +36,17 @@ def testDisconnectIsNoopIfAlreadyDisconnected(self, ClassMock):
3536
self.connection.recv.assert_not_called()
3637
self.connection.close.assert_not_called()
3738

38-
def testUpdateOpensNewConnectionIfDisconnected(self, ClassMock):
39+
def testUpdateOpensNewNonPersistantConnectionAndClosesIt(self, ClassMock):
3940
messages = [Message('H'), Message('L')]
4041
self.init(ClassMock)
42+
self.commander.use_persistent_connection = False
4143
self.connection.recv.side_effect = messages
4244

4345
self.assertEqual(messages, self.commander.update())
4446

45-
self.connection.send.assert_not_called()
47+
self.connection.send.assert_called_once_with(Q_CMD)
4648
self.assertEqual(2, self.connection.recv.call_count)
47-
self.connection.close.assert_not_called()
49+
self.connection.close.assert_called_once()
4850

4951
def testUpdateSendsCommandAfterAfterTimeout(self, ClassMock):
5052
messages = [Message('H'), None]
@@ -78,6 +80,21 @@ def testSendRadioMsgAutoconnects(self, ClassMock = None):
7880
self.assertEqual(2, self.connection.recv.call_count)
7981
self.connection.close.assert_not_called()
8082

83+
def testSendRadioMsgOpensNewNonPersistentConnectionAndClosesIt(self, ClassMock = None):
84+
self.init(ClassMock)
85+
self.commander.use_persistent_connection = False
86+
self.connection.recv.side_effect = [
87+
L_CMD_SUCCESS, # connection preambule
88+
S_CMD_SUCCESS
89+
]
90+
91+
self.assertTrue(self.commander.send_radio_msg(S_CMD_HEX))
92+
self.connection.send.assert_has_calls([
93+
call(S_CMD), call(Q_CMD)
94+
])
95+
self.assertEqual(2, self.connection.recv.call_count)
96+
self.connection.close.assert_called_once()
97+
8198
def testSendRadioMsgReusesConnection(self, ClassMock):
8299
self.testSendRadioMsgAutoconnects()
83100

tests/test_cube.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ def test_disconnect(self, ClassMock):
154154
self.cube.disconnect()
155155
self.commander.disconnect.assert_called_once()
156156

157+
def test_use_persistent_connection(self, ClassMock):
158+
self.init(ClassMock, INIT_RESPONSE_1)
159+
self.commander.use_persistent_connection = True
160+
self.assertTrue(self.cube.use_persistent_connection)
161+
self.cube.use_persistent_connection = False
162+
self.assertFalse(self.commander.use_persistent_connection)
163+
157164
def test_is_thermostat(self, _):
158165
device = MaxDevice()
159166
device.type = MAX_CUBE

0 commit comments

Comments
 (0)