def test_mqtt_load_persistence(self): """Test load persistence file for MQTTGateway.""" sensor = self._add_sensor(1) sensor.children[1] = ChildSensor( 1, self.gateway.const.Presentation.S_HUM) sensor.children[1].values[self.gateway.const.SetReq.V_HUM] = '20' with tempfile.TemporaryDirectory() as temp_dir: self.gateway.persistence_file = os.path.join(temp_dir, 'file.json') # pylint: disable=protected-access self.gateway._save_sensors() del self.gateway.sensors[1] self.assertNotIn(1, self.gateway.sensors) self.gateway._safe_load_sensors() self.assertEqual( self.gateway.sensors[1].children[1].id, sensor.children[1].id) self.assertEqual( self.gateway.sensors[1].children[1].type, sensor.children[1].type) self.assertEqual( self.gateway.sensors[1].children[1].values, sensor.children[1].values) calls = [ mock.call('/1/1/1/+/+', self.gateway.recv, 0), mock.call('/1/1/2/+/+', self.gateway.recv, 0), mock.call('/1/+/4/+/+', self.gateway.recv, 0)] self.mock_sub.assert_has_calls(calls)
def test_req_novalue(self): """Test req message for sensor with no value.""" sensor = self._add_sensor(1) sensor.children[1] = ChildSensor( 1, self.gateway.const.Presentation.S_POWER) ret = self.gateway.logic('1;1;2;0;24;\n') self.assertEqual(ret, None)
def test_start_stop_gateway(self): """Test start and stop of MQTT gateway.""" self.assertFalse(self.gateway.is_alive()) sensor = self._add_sensor(1) sensor.children[1] = ChildSensor(1, self.gateway.const.Presentation.S_HUM) sensor.children[1].values[self.gateway.const.SetReq.V_HUM] = '20' self.gateway.recv('/1/1/2/0/1', '', 0) self.gateway.recv('/1/1/1/0/1', '30', 0) self.gateway.recv('/1/1/2/0/1', '', 0) self.gateway.start() self.assertTrue(self.gateway.is_alive()) calls = [ mock.call('/+/+/0/+/+', self.gateway.recv, 0), mock.call('/+/+/3/+/+', self.gateway.recv, 0) ] self.mock_sub.assert_has_calls(calls) time.sleep(0.05) calls = [ mock.call('/1/1/1/0/1', '20', 0, True), mock.call('/1/1/1/0/1', '30', 0, True) ] self.mock_pub.assert_has_calls(calls) self.gateway.stop() self.gateway.join(timeout=0.5) self.assertFalse(self.gateway.is_alive())
def test_req_zerovalue(self): """Test req message in case where value exists but is zero.""" sensor = self._add_sensor(1) sensor.children[1] = ChildSensor( 1, self.gateway.const.Presentation.S_POWER) sensor.set_child_value(1, self.gateway.const.SetReq.V_VAR1, 0) ret = self.gateway.logic('1;1;2;0;24;\n') self.assertEqual(ret, '1;1;1;0;24;0\n')
def test_set_and_reboot(self): """Test set message with reboot attribute true.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) sensor.reboot = True ret = self.gateway.logic('1;0;1;0;23;43\n') self.assertEqual(ret, '1;255;3;0;13;\n')
def test_set_humidity_level(self): """Test set humidity level.""" sensor = self._add_sensor(1) sensor.children[1] = ChildSensor(1, self.gateway.const.Presentation.S_HUM) self.gateway.logic('1;1;1;0;1;75\n') self.assertEqual( sensor.children[1].values[self.gateway.const.SetReq.V_HUM], '75')
def test_set_light_level(self): """Test set of light level.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) self.gateway.logic('1;0;1;0;23;43\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_LIGHT_LEVEL], '43')
def test_recv_wrong_prefix(self): """Test recv method with wrong topic prefix.""" sensor = self._add_sensor(1) sensor.children[1] = ChildSensor( 1, self.gateway.const.Presentation.S_HUM) sensor.children[1].values[self.gateway.const.SetReq.V_HUM] = '20' self.gateway.recv('wrong/1/1/2/0/1', '', 0) ret = self.gateway.handle_queue() self.assertEqual(ret, None)
def test_set_child_value_bad_ack(self): """Test Gateway method set_child_value with bad ack.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT) self.gateway.set_child_value( 1, 0, self.gateway.const.SetReq.V_LIGHT, 1, ack='one') ret = self.gateway.handle_queue() self.assertEqual(ret, None)
def test_set_child_no_children(self): """Test Gateway method set_child_value without child in children.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT) self.gateway.set_child_value( 1, 0, self.gateway.const.SetReq.V_LIGHT, 1, children={}) ret = self.gateway.handle_queue() self.assertEqual(ret, None)
def test_set_with_new_state(self): """Test set message with populated new_state.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) self.gateway.logic('1;0;1;0;23;43\n') self.gateway.logic('1;255;3;0;22;\n') self.gateway.logic('1;0;1;0;23;57\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_LIGHT_LEVEL], sensor.new_state[0].values[ self.gateway.const.SetReq.V_LIGHT_LEVEL])
def test_recv(self): """Test recv method.""" sensor = self._add_sensor(1) sensor.children[1] = ChildSensor( 1, self.gateway.const.Presentation.S_HUM) sensor.children[1].values[self.gateway.const.SetReq.V_HUM] = '20' self.gateway.recv('/1/1/2/0/1', '', 0) ret = self.gateway.handle_queue() self.assertEqual(ret, '1;1;1;0;1;20\n') self.gateway.recv('/1/1/2/0/1', '', 1) ret = self.gateway.handle_queue() self.assertEqual(ret, '1;1;1;1;1;20\n')
def test_set_child_value_value_type(self): """Test Gateway method set_child_value with string value type.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT) self.gateway.set_child_value(1, 0, 2, 1) ret = self.gateway.handle_queue() self.assertEqual(ret, '1;0;1;0;2;1\n') child_values = dict(sensor.children[0].values) self.gateway.set_child_value(1, 0, '2', 1) ret = self.gateway.handle_queue() self.assertEqual(child_values, sensor.children[0].values) self.assertEqual(ret, '1;0;1;0;2;1\n')
def test_nested_prefix(self): """Test recv method with nested topic prefix.""" self._setup('test/test-in', 'test/test-out') sensor = self._add_sensor(1) sensor.children[1] = ChildSensor(1, self.gateway.const.Presentation.S_HUM) sensor.children[1].values[self.gateway.const.SetReq.V_HUM] = '20' self.gateway.recv('test/test-in/1/1/2/0/1', '', 0) ret = self.gateway.handle_queue() self.assertEqual(ret, '1;1;1;0;1;20\n') self.gateway.recv('test/test-in/1/1/2/0/1', '', 1) ret = self.gateway.handle_queue() self.assertEqual(ret, '1;1;1;1;1;20\n')
def test_set_forecast(self): """Test set of V_FORECAST.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_BARO) self.gateway.logic('1;0;1;0;5;sunny\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_FORECAST], 'sunny') self.gateway.logic('1;0;1;0;5;rainy\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_FORECAST], 'rainy')
def test_set_child_value(self): """Test Gateway method set_child_value.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT) self.gateway.set_child_value(1, 0, self.gateway.const.SetReq.V_LIGHT, '1') ret = self.gateway.handle_queue() self.assertEqual(ret, '1;0;1;0;2;1\n') # test integer value self.gateway.set_child_value(1, 0, self.gateway.const.SetReq.V_LIGHT, 0) ret = self.gateway.handle_queue() self.assertEqual(ret, '1;0;1;0;2;0\n')
def test_child_validate(self): """Test child validate method.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) sensor.children[0].values[ self.gateway.const.SetReq.V_LIGHT_LEVEL] = '43' sensor.children[0].validate(self.gateway.protocol_version) self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_LIGHT_LEVEL], '43') sensor.children[0].values[self.gateway.const.SetReq.V_TRIPPED] = '1' with self.assertRaises(vol.Invalid): sensor.children[0].validate(self.gateway.protocol_version)
def _test_persistence(self, filename): """Test persistence.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL, 'test') sensor.children[0].values[ self.gateway.const.SetReq.V_LIGHT_LEVEL] = '43' self.gateway.sensors[ 1].type = self.gateway.const.Presentation.S_ARDUINO_NODE self.gateway.sensors[1].sketch_name = 'testsketch' self.gateway.sensors[1].sketch_version = '1.0' self.gateway.sensors[1].battery_level = 78 self.gateway.sensors[1].protocol_version = '1.4.1' with tempfile.TemporaryDirectory() as temp_dir: self.gateway.persistence_file = os.path.join(temp_dir, filename) self.gateway.persistence_bak = os.path.join( temp_dir, '{}.bak'.format(filename)) # pylint: disable=protected-access self.gateway._save_sensors() del self.gateway.sensors[1] self.assertNotIn(1, self.gateway.sensors) self.gateway._safe_load_sensors() self.assertEqual( self.gateway.sensors[1].sketch_name, sensor.sketch_name) self.assertEqual(self.gateway.sensors[1].sketch_version, sensor.sketch_version) self.assertEqual( self.gateway.sensors[1].battery_level, sensor.battery_level) self.assertEqual(self.gateway.sensors[1].type, sensor.type) self.assertEqual(self.gateway.sensors[1].protocol_version, sensor.protocol_version) self.assertEqual( self.gateway.sensors[1].children[0].id, sensor.children[0].id) self.assertEqual( self.gateway.sensors[1].children[0].type, sensor.children[0].type) self.assertEqual( self.gateway.sensors[1].children[0].description, sensor.children[0].description) self.assertEqual( self.gateway.sensors[1].children[0].values, sensor.children[0].values) self.gateway._save_sensors() del self.gateway.sensors[1] self.assertNotIn(1, self.gateway.sensors) self.gateway._safe_load_sensors() self.assertIn(1, self.gateway.sensors)
def _test_persistence_upgrade(self, filename, mock_save_json): """Test that all attributes are present after persistence upgrade.""" # pylint: disable=protected-access mock_save_json.side_effect = self._save_json_upgrade sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) del self.gateway.sensors[1].__dict__['new_state'] self.assertNotIn('new_state', self.gateway.sensors[1].__dict__) del self.gateway.sensors[1].__dict__['queue'] self.assertNotIn('queue', self.gateway.sensors[1].__dict__) del self.gateway.sensors[1].__dict__['reboot'] self.assertNotIn('reboot', self.gateway.sensors[1].__dict__) del self.gateway.sensors[1].__dict__['_battery_level'] self.assertNotIn('_battery_level', self.gateway.sensors[1].__dict__) self.gateway.sensors[1].__dict__['battery_level'] = 58 del self.gateway.sensors[1].__dict__['_protocol_version'] self.assertNotIn('_protocol_version', self.gateway.sensors[1].__dict__) self.gateway.sensors[1].__dict__[ 'protocol_version'] = self.gateway.protocol_version del self.gateway.sensors[1].children[0].__dict__['description'] self.assertNotIn( 'description', self.gateway.sensors[1].children[0].__dict__) with tempfile.TemporaryDirectory() as temp_dir: self.gateway.persistence_file = os.path.join(temp_dir, filename) self.gateway.persistence_bak = os.path.join( temp_dir, '{}.bak'.format(filename)) self.gateway._save_sensors() del self.gateway.sensors[1] self.assertNotIn(1, self.gateway.sensors) self.gateway._safe_load_sensors() self.assertEqual(self.gateway.sensors[1].battery_level, 58) self.assertEqual( self.gateway.sensors[1].protocol_version, self.gateway.protocol_version) self.assertEqual(self.gateway.sensors[1].new_state, {}) self.assertEqual(self.gateway.sensors[1].queue, deque()) self.assertEqual(self.gateway.sensors[1].reboot, False) self.assertEqual( self.gateway.sensors[1].children[0].description, '') self.assertEqual( self.gateway.sensors[1].children[0].id, sensor.children[0].id) self.assertEqual( self.gateway.sensors[1].children[0].type, sensor.children[0].type)
def test_set_position(self): """Test set of V_POSITION.""" sensor = self._add_sensor(1) sensor.protocol_version = '2.0' sensor.children[0] = ChildSensor(0, self.gateway.const.Presentation.S_GPS) self.gateway.logic('1;0;1;0;49;10.0,10.0,10.0\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_POSITION], '10.0,10.0,10.0') self.gateway.logic('1;0;1;0;49;bad,format\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_POSITION], '10.0,10.0,10.0') self.gateway.logic('1;0;1;0;41;bad,bad,bad\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_POSITION], '10.0,10.0,10.0')
def test_set_rgbw(self): """Test set of V_RGBW.""" sensor = self._add_sensor(1) sensor.protocol_version = '1.5' sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_RGBW_LIGHT) self.gateway.logic('1;0;1;0;41;ffffffff\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_RGBW], 'ffffffff') self.gateway.logic('1;0;1;0;41;ffffffff00\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_RGBW], 'ffffffff') self.gateway.logic('1;0;1;0;41;nothexxx\n') self.assertEqual( sensor.children[0].values[self.gateway.const.SetReq.V_RGBW], 'ffffffff')
def test_callback(self, mock_save_sensors): """Test gateway callback function.""" self.gateway.event_callback = self._callback self.gateway.persistence = True self.gateway.test_callback_message = None sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) self.gateway.logic('1;0;1;0;23;43\n') self.assertIsNotNone(self.gateway.test_callback_message) self.assertEqual(self.gateway, self.gateway.test_callback_message.gateway) self.assertEqual(1, self.gateway.test_callback_message.node_id) self.assertEqual(0, self.gateway.test_callback_message.child_id) self.assertEqual(1, self.gateway.test_callback_message.type) self.assertEqual(0, self.gateway.test_callback_message.ack) self.assertEqual(23, self.gateway.test_callback_message.sub_type) self.assertEqual('43', self.gateway.test_callback_message.payload) assert mock_save_sensors.called
def test_heartbeat(self): """Test heartbeat message.""" sensor = self._add_sensor(1) sensor.children[0] = ChildSensor( 0, self.gateway.const.Presentation.S_LIGHT_LEVEL) self.gateway.logic('1;0;1;0;23;43\n') ret = self.gateway.handle_queue() self.assertEqual(ret, None) # heartbeat self.gateway.logic('1;255;3;0;22;\n') ret = self.gateway.handle_queue() # nothing has changed self.assertEqual(ret, None) # change from controller side self.gateway.set_child_value(1, 0, self.gateway.const.SetReq.V_LIGHT_LEVEL, '57') ret = self.gateway.handle_queue() # no heartbeat self.assertEqual(ret, None) # heartbeat comes in self.gateway.logic('1;255;3;0;22;\n') ret = self.gateway.handle_queue() # instance responds with new values self.assertEqual(ret, '1;0;1;0;23;57\n') # request from node self.gateway.logic('1;0;2;0;23;\n') ret = self.gateway.handle_queue() # no heartbeat self.assertEqual(ret, None) # heartbeat self.gateway.logic('1;255;3;0;22;\n') ret = self.gateway.handle_queue() # instance responds to request with current value self.assertEqual(ret, '1;0;1;0;23;57\n') # heartbeat self.gateway.logic('1;255;3;0;22;\n') ret = self.gateway.handle_queue() # nothing has changed self.assertEqual(ret, None)