def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Devices.Shelly.Shelly(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['broker-id'] = "12345" self.device.pluginProps['address'] = "shellies/test-shelly" self.device.pluginProps['resetEnergyOffset'] = 0 self.device.pluginProps['last-input-event-id'] = -1
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Uni_Relay(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-uni-relay" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Plug(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-plug-test" self.device.updateStateOnServer("overpower", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Gas(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-gas-test" self.device.updateStateOnServer("sensor-status", "") self.device.updateStateOnServer("gas-detected", "") self.device.updateStateOnServer("self-test", "") self.device.updateStateOnServer("sensorValue", "")
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_1(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly1-test" self.device.updateStateOnServer("sw-input", False) self.device.updateStateOnServer("longpush", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.pluginProps['last-input-event-id'] = -1
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Motion(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-motion-test" self.device.updateStateOnServer("vibration", "") self.device.updateStateOnServer("lux", "") self.device.updateStateOnServer("active", "") self.device.updateStateOnServer("onOffState", "") self.device.updateStateOnServer("batteryLevel", 0)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_RGBW2_White(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-rgbw2-white-test" self.device.pluginProps['int-temp-units'] = "C->F" self.device.updateStateOnServer("overpower", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("brightnessLevel", 0)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_3EM_Meter(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-3em-meter-test" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("accumEnergyTotal", 0) self.device.updateStateOnServer("power", 0) self.device.updateStateOnServer("total-energy", 0) self.device.updateStateOnServer("total-returned-energy", 0)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Bulb_Duo(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-bulb-duo-test" self.device.updateStateOnServer("overload", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("brightnessLevel", 0) self.device.updateStateOnServer("whiteLevel", 100) self.device.updateStateOnServer("whiteTemperature", 2700)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Flood(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-flood-test" self.device.pluginProps['temp-units'] = "C->F" self.device.pluginProps['temp-offset'] = "2" self.device.pluginProps['temp-decimals'] = "1" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("temperature", 0) self.device.updateStateOnServer("onOffState", False) self.device.updateStateOnServer("batteryLevel", False)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_4_Pro(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly4pro-test" self.device.pluginProps['int-temp-units'] = "C->F" self.device.pluginProps['channel'] = 0 self.device.updateStateOnServer("sw-input", False) self.device.updateStateOnServer("overpower", False) self.device.updateStateOnServer("overtemperature", False) self.device.updateStateOnServer("longpush", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0)
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Dimmer_SL(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-dimmer-sl-test" self.device.pluginProps['last-input-event-id'] = -1 self.device.pluginProps['int-temp-units'] = "C->F" self.device.updateStateOnServer("sw-input", False) self.device.updateStateOnServer("overload", False) self.device.updateStateOnServer("overtemperature", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("brightnessLevel", 0)
def setUp(self): indigo.__init__() self.host_device = IndigoDevice(id=111111, name="Host Device") self.host_shelly = Shelly_1(self.host_device) self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Addon_Detached_Switch(self.device) indigo.activePlugin.shellyDevices[ self.host_shelly.device.id] = self.host_shelly indigo.activePlugin.shellyDevices[self.shelly.device.id] = self.shelly logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.host_device.pluginProps['address'] = "shellies/shelly-addon-test" self.device.pluginProps['host-id'] = "111111" self.device.pluginProps['invert'] = False self.device.states['onOffState'] = False
def setUp(self): indigo.__init__() self.host_device = IndigoDevice(id=111111, name="Host Device") self.host_shelly = Shelly_1(self.host_device) self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Addon(self.device) indigo.activePlugin.shellyDevices[ self.host_shelly.device.id] = self.host_shelly indigo.activePlugin.shellyDevices[self.shelly.device.id] = self.shelly logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.host_device.pluginProps['address'] = "shellies/shelly-addon-test" self.host_device.pluginProps['broker-id'] = "12345" self.host_device.states['ip-address'] = "192.168.1.80" self.host_device.pluginProps['message-type'] = "shellies" self.device.pluginProps['host-id'] = "111111"
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Button1(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-button1-test" self.device.pluginProps['last-input-event-id'] = -1 self.device.states['onOffState'] = False
def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Door_Window(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-dw-test" self.device.pluginProps['useCase'] = "door" self.device.pluginProps['temp-units'] = "C->F" self.device.pluginProps['temp-offset'] = "2" self.device.pluginProps['temp-decimals'] = "1" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("temperature", 0) self.device.updateStateOnServer("status", False) self.device.updateStateOnServer("vibration", False) self.device.updateStateOnServer("lux", 0) self.device.updateStateOnServer("tilt", 0) self.device.updateStateOnServer("batteryLevel", 0)
def setUp(self): indigo.__init__() self.host_device = IndigoDevice(id=111111, name="Host Device") self.host_shelly = Shelly_1(self.host_device) self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Addon_DS1820(self.device) indigo.activePlugin.shellyDevices[ self.host_shelly.device.id] = self.host_shelly indigo.activePlugin.shellyDevices[self.shelly.device.id] = self.shelly logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.host_device.pluginProps['address'] = "shellies/shelly-addon-test" self.device.pluginProps['host-id'] = "111111" self.device.pluginProps['probe-number'] = 0 self.device.pluginProps['temp-units'] = "C->F" self.device.pluginProps['temp-offset'] = "2" self.device.pluginProps['temp-decimals'] = "1" self.device.states['temperature'] = 0
class Test_Shelly_2_5_Relay(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_2_5_Relay(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly25relay-test" self.device.pluginProps['last-input-event-id'] = -1 self.device.pluginProps['int-temp-units'] = "C->F" self.device.pluginProps['channel'] = 0 self.device.updateStateOnServer("sw-input", False) self.device.updateStateOnServer("overpower", False) self.device.updateStateOnServer("overtemperature", False) self.device.updateStateOnServer("longpush", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("temperature-status", "Normal") def test_getSubscriptions_no_address(self): """Test getting subscriptions with no address defined.""" self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions_channel_1(self): """Test getting subscriptions with a defined address on channel 1.""" topics = [ "shellies/announce", "shellies/shelly25relay-test/online", "shellies/shelly25relay-test/relay/0", "shellies/shelly25relay-test/input/0", "shellies/shelly25relay-test/longpush/0", "shellies/shelly25relay-test/relay/0/power", "shellies/shelly25relay-test/relay/0/overpower_value", "shellies/shelly25relay-test/relay/0/energy", "shellies/shelly25relay-test/temperature", "shellies/shelly25relay-test/overtemperature", "shellies/shelly25relay-test/input_event/0", "shellies/shelly25relay-test/temperature_status" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_getSubscriptions_channel_2(self): """Test getting subscriptions with a defined address on channel 2.""" self.device.pluginProps['channel'] = 1 topics = [ "shellies/announce", "shellies/shelly25relay-test/online", "shellies/shelly25relay-test/relay/1", "shellies/shelly25relay-test/input/1", "shellies/shelly25relay-test/longpush/1", "shellies/shelly25relay-test/relay/1/power", "shellies/shelly25relay-test/relay/1/overpower_value", "shellies/shelly25relay-test/relay/1/energy", "shellies/shelly25relay-test/temperature", "shellies/shelly25relay-test/overtemperature", "shellies/shelly25relay-test/input_event/1", "shellies/shelly25relay-test/temperature_status" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_channel_1(self): self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage("shellies/shelly25relay-test/relay/0", "on") self.assertTrue(self.shelly.isOn()) def test_channel_2(self): self.device.pluginProps['channel'] = 1 self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage("shellies/shelly25relay-test/relay/1", "on") self.assertTrue(self.shelly.isOn()) def test_handleMessage_relay_on(self): """Test getting a relay on message.""" self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage("shellies/shelly25relay-test/relay/0", "on") self.assertTrue(self.shelly.isOn()) self.assertFalse(self.shelly.device.states['overpower']) def test_handleMessage_relay_off(self): """Test getting a relay off message.""" self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.handleMessage("shellies/shelly25relay-test/relay/0", "off") self.assertTrue(self.shelly.isOff()) self.assertFalse(self.shelly.device.states['overpower']) def test_handleMessage_relay_overpower(self): """Test getting a relay overpower message.""" self.assertFalse(self.shelly.device.states['overpower']) self.shelly.handleMessage("shellies/shelly25relay-test/relay/0", "overpower") self.assertTrue(self.shelly.device.states['overpower']) def test_handleMessage_relay_overpower_value(self): """Test getting a relay overpower message.""" self.shelly.handleMessage( "shellies/shelly25relay-test/relay/0/overpower_value", "100.12") self.assertEqual("100.12", self.shelly.device.states['overpower-value']) self.assertEqual( "100.12 W", self.shelly.device.states_meta['overpower-value']['uiValue']) def test_handleMessage_switch_on(self): """Test getting a switch on message.""" self.assertFalse(self.shelly.device.states['sw-input']) self.shelly.handleMessage("shellies/shelly25relay-test/input/0", "1") self.assertTrue(self.shelly.device.states['sw-input']) def test_handleMessage_switch_off(self): """Test getting a switch off message.""" self.shelly.device.states['sw-input'] = True self.assertTrue(self.shelly.device.states['sw-input']) self.shelly.handleMessage("shellies/shelly25relay-test/input/0", "0") self.assertFalse(self.shelly.device.states['sw-input']) def test_handleMessage_longpush_on(self): """Test getting a longpush on message.""" self.assertFalse(self.shelly.device.states['longpush']) self.shelly.handleMessage("shellies/shelly25relay-test/longpush/0", "1") self.assertTrue(self.shelly.device.states['longpush']) def test_handleMessage_longpush_off(self): """Test getting a longpush off message.""" self.shelly.device.states['longpush'] = True self.assertTrue(self.shelly.device.states['longpush']) self.shelly.handleMessage("shellies/shelly25relay-test/longpush/0", "0") self.assertFalse(self.shelly.device.states['longpush']) def test_handleMessage_power(self): self.shelly.handleMessage("shellies/shelly25relay-test/relay/0/power", "0") self.assertEqual("0", self.shelly.device.states['curEnergyLevel']) self.assertEqual( "0 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) self.shelly.handleMessage("shellies/shelly25relay-test/relay/0/power", "101.123") self.assertEqual("101.123", self.shelly.device.states['curEnergyLevel']) self.assertEqual( "101.123 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) def test_handleMessage_energy(self): self.shelly.handleMessage("shellies/shelly25relay-test/relay/0/energy", "0") self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) self.shelly.handleMessage("shellies/shelly25relay-test/relay/0/energy", "50") self.assertAlmostEqual(0.0008, self.shelly.device.states['accumEnergyTotal'], 4) def test_handleMessage_temperature(self): self.shelly.handleMessage("shellies/shelly25relay-test/temperature", "50") self.assertEqual(122, self.shelly.device.states['internal-temperature']) def test_handleMessage_overtemperature(self): self.assertFalse(self.device.states['overtemperature']) self.shelly.handleMessage( "shellies/shelly25relay-test/overtemperature", "1") self.assertTrue(self.device.states['overtemperature']) self.shelly.handleMessage( "shellies/shelly25relay-test/overtemperature", "0") self.assertFalse(self.device.states['overtemperature']) def test_handleMessage_announce(self): announcement = '{"id": "shelly25relay-test", "mac": "aa:bb:cc:ee", "ip": "192.168.1.101", "fw_ver": "0.1.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:ee", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.101", self.shelly.getIpAddress()) self.assertEqual("0.1.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly25relay-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly25relay-test/online", "false") self.assertFalse(self.shelly.device.states['online']) def test_handleMessage_temperature_status(self): self.shelly.handleMessage( "shellies/shelly25relay-test/temperature_status", "High") self.assertEqual("High", self.shelly.device.states['temperature-status']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) turnOn = IndigoAction(indigo.kDeviceAction.TurnOn) self.shelly.handleAction(turnOn) self.assertTrue(self.shelly.isOn()) publish.assert_called_with( "shellies/shelly25relay-test/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) turnOff = IndigoAction(indigo.kDeviceAction.TurnOff) self.shelly.handleAction(turnOff) self.assertTrue(self.shelly.isOff()) publish.assert_called_with( "shellies/shelly25relay-test/relay/0/command", "off") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly25relay-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_off_to_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOn()) publish.assert_called_with( "shellies/shelly25relay-test/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_on_to_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOff()) publish.assert_called_with( "shellies/shelly25relay-test/relay/0/command", "off") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_reset_energy(self, publish): self.shelly.updateEnergy(30) self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) resetEnergy = IndigoAction(indigo.kUniversalAction.EnergyReset) self.shelly.handleAction(resetEnergy) self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_update_energy(self, publish): updateEnergy = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(updateEnergy) publish.assert_called_with("shellies/shelly25relay-test/command", "update") def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_2_5_Relay.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_2_5_Relay.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_2_5_Relay.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors) @patch('Devices.Shelly.Shelly.processInputEvent') def test_input_event_is_processed(self, processInputEvent): """Test that an input_event message is processed""" self.shelly.handleMessage("shellies/shelly25relay-test/input_event/0", '{"event": "S", "event_cnt": 1}') processInputEvent.assert_called_with('{"event": "S", "event_cnt": 1}')
class Test_Shelly_Button1(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Gas(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-gas-test" self.device.updateStateOnServer("sensor-status", "") self.device.updateStateOnServer("gas-detected", "") self.device.updateStateOnServer("self-test", "") self.device.updateStateOnServer("sensorValue", "") def test_getSubscriptions(self): subscriptions = [ "shellies/announce", "shellies/shelly-gas-test/online", "shellies/shelly-gas-test/sensor/operation", "shellies/shelly-gas-test/sensor/gas", "shellies/shelly-gas-test/sensor/self_test", "shellies/shelly-gas-test/sensor/concentration" ] self.assertListEqual(subscriptions, self.shelly.getSubscriptions()) def test_updateStateImage_on_mild(self): self.device.states['gas-detected'] = "mild" self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.SensorTripped, self.device.image) def test_updateStateImage_on_heavy(self): self.device.states['gas-detected'] = "heavy" self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.SensorTripped, self.device.image) def test_updateStateImage_off(self): self.device.states['gas-detected'] = "" self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.SensorOn, self.device.image) def test_handleMessage_online_true(self): self.device.states['online'] = False self.shelly.handleMessage("shellies/shelly-gas-test/online", "true") self.assertTrue(self.device.states['online']) def test_handleMessage_online_false(self): self.device.states['online'] = True self.shelly.handleMessage("shellies/shelly-gas-test/online", "false") self.assertFalse(self.device.states['online']) def test_handleMessage_operation(self): self.shelly.handleMessage("shellies/shelly-gas-test/sensor/operation", "normal") self.assertEqual("normal", self.device.states['sensor-status']) def test_handleMessage_gas(self): self.shelly.handleMessage("shellies/shelly-gas-test/sensor/gas", "mild") self.assertEqual("mild", self.device.states['gas-detected']) def test_handleMessage_self_test(self): self.shelly.handleMessage("shellies/shelly-gas-test/sensor/self_test", "completed") self.assertEqual("completed", self.device.states['self-test']) def test_handleMessage_concentration(self): self.shelly.handleMessage("shellies/shelly-gas-test/sensor/concentration", "102") self.assertEqual(102, self.device.states['sensorValue']) self.assertEqual("102 ppm", self.device.states_meta['sensorValue']['uiValue']) def test_handleMessage_concentration_string(self): self.assertRaises(ValueError, self.shelly.handleMessage("shellies/shelly-gas-test/sensor/concentration", "102a")) @patch('Devices.Shelly.Shelly.publish') def test_sendStatusRequestCommand(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly-gas-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handlePluginAction_self_test(self, publish): self_test = PluginAction("gas-self-test") self.shelly.handlePluginAction(self_test) publish.assert_called_with("shellies/shelly-gas-test/sensor/start_self_test", "start") @patch('Devices.Shelly.Shelly.publish') def test_handlePluginAction_mute_alarm(self, publish): mute = PluginAction("gas-mute-alarm") self.shelly.handlePluginAction(mute) publish.assert_called_with("shellies/shelly-gas-test/sensor/mute", "mute") @patch('Devices.Shelly.Shelly.publish') def test_handlePluginAction_unmute_alarm(self, publish): unmute = PluginAction("gas-unmute-alarm") self.shelly.handlePluginAction(unmute) publish.assert_called_with("shellies/shelly-gas-test/sensor/unmute", "unmute")
class Test_Shelly_EM_Meter(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_EM_Meter(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-em-meter-test" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("accumEnergyTotal", 0) self.device.updateStateOnServer("power", 0) self.device.updateStateOnServer("total-energy", 0) self.device.updateStateOnServer("total-returned-energy", 0) def test_getSubscriptions_no_address(self): """Test getting subscriptions with no address defined.""" self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): """Test getting subscriptions with a defined address.""" topics = [ "shellies/announce", "shellies/shelly-em-meter-test/online", "shellies/shelly-em-meter-test/emeter/0/energy", "shellies/shelly-em-meter-test/emeter/0/returned_energy", "shellies/shelly-em-meter-test/emeter/0/power", "shellies/shelly-em-meter-test/emeter/0/reactive_power", "shellies/shelly-em-meter-test/emeter/0/voltage", "shellies/shelly-em-meter-test/emeter/0/total", "shellies/shelly-em-meter-test/emeter/0/total_returned" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_power(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/power", "0") self.assertEqual(0, self.shelly.device.states['curEnergyLevel']) self.assertEqual( "0.00 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/power", "101.123") self.assertEqual(101.123, self.shelly.device.states['curEnergyLevel']) self.assertEqual( "101.12 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) def test_handleMessage_power_invalid(self): self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/power", "Aa")) def test_handleMessage_reactive_power(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/reactive_power", "0") self.assertEqual(0, self.shelly.device.states['power-reactive']) self.assertEqual( "0.00 W", self.shelly.device.states_meta['power-reactive']['uiValue']) self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/reactive_power", "50.632") self.assertEqual(50.632, self.shelly.device.states['power-reactive']) self.assertEqual( "50.63 W", self.shelly.device.states_meta['power-reactive']['uiValue']) def test_handleMessage_reactive_power_invalid(self): self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/reactive_power", "Aa")) def test_handleMessage_energy(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "0") self.assertAlmostEqual(0.0000, self.shelly.device.states['energy-consumed'], 4) self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "50") self.assertAlmostEqual(0.0008, self.shelly.device.states['energy-consumed'], 4) def test_handleMessage_energy_invalid(self): self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "Aa")) def test_handleMessage_returned_energy(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "0") self.assertAlmostEqual(0.0000, self.shelly.device.states['energy-returned'], 4) self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "50") self.assertAlmostEqual(0.0008, self.shelly.device.states['energy-returned'], 4) def test_handleMessage_returned_energy_invalid(self): self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "Aa")) def test_handleMessage_total(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/total", "5") self.assertAlmostEqual(5.0, self.shelly.device.states['total-energy'], 1) def test_handleMessage_total_returned(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/total_returned", "6") self.assertAlmostEqual( 6.0, self.shelly.device.states['total-returned-energy'], 1) def test_handleMessage_voltage(self): self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/voltage", "120.12") self.assertAlmostEqual(120.12, self.shelly.device.states['voltage'], 2) self.assertEqual("120.1 V", self.shelly.device.states_meta['voltage']['uiValue']) self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/voltage", "122.87") self.assertAlmostEqual(122.87, self.shelly.device.states['voltage'], 2) self.assertEqual("122.9 V", self.shelly.device.states_meta['voltage']['uiValue']) def test_handleMessage_voltage_invalid(self): self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/voltage", "Aa")) def test_handleMessage_announce(self): announcement = '{"id": "shelly-em-meter-test", "mac": "aa:bb:cc:ee", "ip": "192.168.1.101", "fw_ver": "0.1.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:ee", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.101", self.shelly.getIpAddress()) self.assertEqual("0.1.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-em-meter-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-em-meter-test/online", "false") self.assertFalse(self.shelly.device.states['online']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly-em-meter-test/command", "update") def test_handleAction_reset_energy(self): self.shelly.updateEnergy(30) self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) resetEnergy = IndigoAction(indigo.kUniversalAction.EnergyReset) self.shelly.handleAction(resetEnergy) self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_update_energy(self, publish): updateEnergy = IndigoAction(indigo.kUniversalAction.EnergyUpdate) self.shelly.handleAction(updateEnergy) publish.assert_called_with("shellies/shelly-em-meter-test/command", "update") def test_updateEnergy_net_positive(self): self.shelly.device.pluginProps['energy-display'] = "net" self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "20") self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "50") # net of 30 consumed self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "0.0005 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) def test_updateEnergy_net_negative(self): self.shelly.device.pluginProps['energy-display'] = "net" self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "50") self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "20") # net of 30 returned self.assertAlmostEqual(-0.0005, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "-0.0005 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) def test_updateEnergy_consumed(self): self.shelly.device.pluginProps['energy-display'] = "consumed" self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "50") self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "20") # 50 returned, 20 consumed self.assertAlmostEqual(0.0003, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "0.0003 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) def test_updateEnergy_returned(self): self.shelly.device.pluginProps['energy-display'] = "returned" self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/returned_energy", "50") self.shelly.handleMessage( "shellies/shelly-em-meter-test/emeter/0/energy", "20") # 50 returned, 20 consumed self.assertAlmostEqual(-0.0008, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "-0.0008 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) def test_buildEnergyUIValue_4_decimals(self): self.assertEqual("0.0080 kWh", self.shelly.buildEnergyUIValue(0.008)) def test_buildEnergyUIValue_3_decimals(self): self.assertEqual("0.123 kWh", self.shelly.buildEnergyUIValue(0.1234)) def test_buildEnergyUIValue_2_decimals(self): self.assertEqual("1.28 kWh", self.shelly.buildEnergyUIValue(1.28344)) def test_buildEnergyUIValue_1_decimal(self): self.assertEqual("12.2 kWh", self.shelly.buildEnergyUIValue(12.23982)) def test_updateStateImage_on(self): self.shelly.device.states['online'] = True self.shelly.updateStateImage() self.assertEquals(indigo.kStateImageSel.EnergyMeterOn, self.shelly.device.image) def test_updateStateImage_off(self): self.shelly.device.states['online'] = False self.shelly.updateStateImage() self.assertEquals(indigo.kStateImageSel.EnergyMeterOff, self.shelly.device.image) def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_EM_Meter.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_EM_Meter.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_EM_Meter.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors)
class Test_Shelly_Plug(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Plug(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-plug-test" self.device.updateStateOnServer("overpower", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) def test_getSubscriptions_no_address(self): """Test getting subscriptions with no address defined.""" self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): """Test getting subscriptions with a defined address.""" topics = [ "shellies/announce", "shellies/shelly-plug-test/online", "shellies/shelly-plug-test/relay/0", "shellies/shelly-plug-test/relay/0/power", "shellies/shelly-plug-test/relay/0/overpower_value", "shellies/shelly-plug-test/relay/0/energy" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_relay_on(self): """Test getting a relay on message.""" self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage("shellies/shelly-plug-test/relay/0", "on") self.assertTrue(self.shelly.isOn()) self.assertFalse(self.shelly.device.states['overpower']) def test_handleMessage_relay_off(self): """Test getting a relay off message.""" self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.handleMessage("shellies/shelly-plug-test/relay/0", "off") self.assertTrue(self.shelly.isOff()) self.assertFalse(self.shelly.device.states['overpower']) def test_handleMessage_relay_overpower(self): """Test getting a relay overpower message.""" self.assertFalse(self.shelly.device.states['overpower']) self.shelly.handleMessage("shellies/shelly-plug-test/relay/0", "overpower") self.assertTrue(self.shelly.device.states['overpower']) def test_handleMessage_relay_overpower_value(self): """Test getting a relay overpower message.""" self.shelly.handleMessage( "shellies/shelly-plug-test/relay/0/overpower_value", "100.12") self.assertEqual("100.12", self.shelly.device.states['overpower-value']) self.assertEqual( "100.12 W", self.shelly.device.states_meta['overpower-value']['uiValue']) def test_handleMessage_power(self): self.shelly.handleMessage("shellies/shelly-plug-test/relay/0/power", "0") self.assertEqual("0", self.shelly.device.states['curEnergyLevel']) self.assertEqual( "0 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) self.shelly.handleMessage("shellies/shelly-plug-test/relay/0/power", "101.123") self.assertEqual("101.123", self.shelly.device.states['curEnergyLevel']) self.assertEqual( "101.123 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) def test_handleMessage_energy(self): self.shelly.handleMessage("shellies/shelly-plug-test/relay/0/energy", "0") self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) self.shelly.handleMessage("shellies/shelly-plug-test/relay/0/energy", "50") self.assertAlmostEqual(0.0008, self.shelly.device.states['accumEnergyTotal'], 4) def test_handleMessage_energy_invalid(self): self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-plug-test/relay/0/energy", "0A")) def test_handleMessage_announce(self): announcement = '{"id": "shelly-plug-test", "mac": "aa:bb:cc:ee", "ip": "192.168.1.101", "fw_ver": "0.1.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:ee", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.101", self.shelly.getIpAddress()) self.assertEqual("0.1.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-plug-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-plug-test/online", "false") self.assertFalse(self.shelly.device.states['online']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) turnOn = IndigoAction(indigo.kDeviceAction.TurnOn) self.shelly.handleAction(turnOn) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly-plug-test/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) turnOff = IndigoAction(indigo.kDeviceAction.TurnOff) self.shelly.handleAction(turnOff) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly-plug-test/relay/0/command", "off") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly-plug-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_off_to_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly-plug-test/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_on_to_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly-plug-test/relay/0/command", "off") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_reset_energy(self, publish): self.shelly.updateEnergy(30) self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) resetEnergy = IndigoAction(indigo.kUniversalAction.EnergyReset) self.shelly.handleAction(resetEnergy) self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_update_energy(self, publish): updateEnergy = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(updateEnergy) publish.assert_called_with("shellies/shelly-plug-test/command", "update") def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_Plug.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_Plug.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_Plug.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors)
class Test_Shelly_RGBW2_White(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_RGBW2_White(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-rgbw2-white-test" self.device.pluginProps['int-temp-units'] = "C->F" self.device.updateStateOnServer("overpower", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("brightnessLevel", 0) def test_getSubscriptions_no_address(self): """Test getting subscriptions with no address defined.""" self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): """Test getting subscriptions with a defined address.""" topics = [ "shellies/announce", "shellies/shelly-rgbw2-white-test/online", "shellies/shelly-rgbw2-white-test/white/0/status" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_getSubscriptions_channel_1(self): """Test getting subscriptions with a defined address on channel 1.""" self.shelly.device.pluginProps['channel'] = 1 topics = [ "shellies/announce", "shellies/shelly-rgbw2-white-test/online", "shellies/shelly-rgbw2-white-test/white/1/status" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_status_invalid(self): """Test getting invalid status data.""" self.assertRaises(ValueError, self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", '{"ison": true, "mo')) def test_handleMessage_invalid_mode(self): """Test getting a message for the wrong mode.""" self.assertFalse(self.shelly.isOn()) payload = { "ison": True, "mode": "color", "brightness": 100, "power": 25, "overpower": False } self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", json.dumps(payload)) self.assertFalse(self.shelly.isOn()) def test_handleMessage_light_on(self): """Test getting a light on message.""" self.assertTrue(self.shelly.isOff()) payload = { "ison": True, "mode": "white", "brightness": 100, "power": 25, "overpower": False } self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", json.dumps(payload)) self.assertTrue(self.shelly.isOn()) self.assertFalse(self.shelly.device.states['overpower']) self.assertEqual(100, self.shelly.device.states['brightnessLevel']) def test_handleMessage_light_off(self): """Test getting a light off message.""" self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) payload = { "ison": False, "mode": "white", "brightness": 0, "power": 25, "overpower": False } self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", json.dumps(payload)) self.assertTrue(self.shelly.isOff()) self.assertFalse(self.shelly.device.states['overpower']) def test_handleMessage_overpower(self): """Test getting a relay overpower message.""" self.assertFalse(self.shelly.device.states['overpower']) payload = { "ison": False, "mode": "white", "brightness": 100, "power": 25, "overpower": True } self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", json.dumps(payload)) self.assertTrue(self.shelly.device.states['overpower']) def test_handleMessage_power(self): payload = { "ison": False, "mode": "white", "brightness": 100, "power": 0, "overpower": False } self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", json.dumps(payload)) self.assertEqual(0, self.shelly.device.states['curEnergyLevel']) self.assertEqual("0 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) payload = { "ison": True, "mode": "white", "brightness": 100, "power": 101.123, "overpower": False } self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/white/0/status", json.dumps(payload)) self.assertEqual(101.123, self.shelly.device.states['curEnergyLevel']) self.assertEqual("101.123 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) def test_handleMessage_announce(self): announcement = '{"id": "shelly-rgbw2-white-test", "mac": "aa:bb:cc:ee", "ip": "192.168.1.101", "fw_ver": "0.1.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:ee", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.101", self.shelly.getIpAddress()) self.assertEqual("0.1.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-rgbw2-white-test/online", "false") self.assertFalse(self.shelly.device.states['online']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) turnOn = IndigoAction(indigo.kDeviceAction.TurnOn) self.shelly.handleAction(turnOn) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 100})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) turnOff = IndigoAction(indigo.kDeviceAction.TurnOff) self.shelly.handleAction(turnOff) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "off", "brightness": 0})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly-rgbw2-white-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_off_to_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 100})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_on_to_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "off", "brightness": 0})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_setBrightness(self, publish): self.assertEqual(0, self.shelly.device.states['brightnessLevel']) setBrightness = IndigoAction(indigo.kDeviceAction.SetBrightness, actionValue=50) self.shelly.handleAction(setBrightness) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 50})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_brightenBy(self, publish): self.assertEqual(0, self.shelly.device.states['brightnessLevel']) brightenBy = IndigoAction(indigo.kDeviceAction.BrightenBy, actionValue=25) self.shelly.handleAction(brightenBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(25, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 25})) self.shelly.handleAction(brightenBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 50})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_brightenBy_more_than_100(self, publish): self.shelly.device.updateStateOnServer('brightnessLevel', 90) brightenBy = IndigoAction(indigo.kDeviceAction.BrightenBy, actionValue=25) self.shelly.handleAction(brightenBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(100, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 100})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_dimBy(self, publish): self.shelly.device.updateStateOnServer('brightnessLevel', 100) dimBy = IndigoAction(indigo.kDeviceAction.DimBy, actionValue=25) self.shelly.handleAction(dimBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(75, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 75})) self.shelly.handleAction(dimBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "on", "brightness": 50})) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_dimBy_less_than_0(self, publish): self.shelly.device.updateStateOnServer('brightnessLevel', 10) dimBy = IndigoAction(indigo.kDeviceAction.DimBy, actionValue=25) self.shelly.handleAction(dimBy) self.assertTrue(self.shelly.isOff()) self.assertEqual(0, self.shelly.device.states['brightnessLevel']) publish.assert_called_with("shellies/shelly-rgbw2-white-test/white/0/set", json.dumps({"turn": "off", "brightness": 0})) def test_apply_brightness_off(self): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.applyBrightness(0) self.assertTrue(self.shelly.isOff()) self.assertEqual(0, self.shelly.device.brightness) def test_apply_brightness_on(self): self.assertTrue(self.shelly.isOff()) self.shelly.applyBrightness(50) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.brightness) self.shelly.applyBrightness(100) self.assertTrue(self.shelly.isOn()) self.assertEqual(100, self.shelly.device.brightness) def test_update_state_image_on(self): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.assertEqual(indigo.kStateImageSel.DimmerOn, self.shelly.device.image) def test_update_state_image_off(self): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) self.assertEqual(indigo.kStateImageSel.DimmerOff, self.shelly.device.image) def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_RGBW2_White.validateConfigUI(values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_RGBW2_White.validateConfigUI(values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_RGBW2_White.validateConfigUI(values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors)
class Test_Shelly_Uni_Relay(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Uni_Relay(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-uni-relay" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) def test_getSubscriptions_no_address(self): self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): topics = [ "shellies/announce", "shellies/shelly-uni-relay/online", "shellies/shelly-uni-relay/info", "shellies/shelly-uni-relay/relay/0", "shellies/shelly-uni-relay/ext_temperatures", "shellies/shelly-uni-relay/ext_humidities" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_relay_on(self): self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage("shellies/shelly-uni-relay/relay/0", "on") self.assertTrue(self.shelly.isOn()) def test_handleMessage_relay_off(self): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.handleMessage("shellies/shelly-uni-relay/relay/0", "off") self.assertTrue(self.shelly.isOff()) def test_handleMessage_announce(self): announcement = '{"id": "shelly-uni-relay", "mac": "aa:bb:cc:dd", "ip": "192.168.1.100", "fw_ver": "0.0.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:dd", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.100", self.shelly.getIpAddress()) self.assertEqual("0.0.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.shelly.device.states['online'] = False self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-uni-relay/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-uni-relay/online", "false") self.assertFalse(self.shelly.device.states['online']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) turnOn = IndigoAction(indigo.kDeviceAction.TurnOn) self.shelly.handleAction(turnOn) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly-uni-relay/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) turnOff = IndigoAction(indigo.kDeviceAction.TurnOff) self.shelly.handleAction(turnOff) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly-uni-relay/relay/0/command", "off") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly-uni-relay/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_off_to_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly-uni-relay/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_on_to_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly-uni-relay/relay/0/command", "off") def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_Uni_Relay.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_Uni_Relay.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_Uni_Relay.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors) def test_handleMessage_info(self): payload = '{"adcs": [{"voltage": 12.13}]}' self.shelly.handleMessage("shellies/shelly-uni-relay/info", payload) self.assertEqual(12.13, self.device.states['voltage'])
class Test_Shelly_Bulb_Duo(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Bulb_Duo(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-bulb-duo-test" self.device.updateStateOnServer("overload", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("curEnergyLevel", 0) self.device.updateStateOnServer("brightnessLevel", 0) self.device.updateStateOnServer("whiteLevel", 100) self.device.updateStateOnServer("whiteTemperature", 2700) def test_getSubscriptions_no_address(self): """Test getting subscriptions with no address defined.""" self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): """Test getting subscriptions with a defined address.""" topics = [ "shellies/announce", "shellies/shelly-bulb-duo-test/online", "shellies/shelly-bulb-duo-test/light/0/status", "shellies/shelly-bulb-duo-test/light/0/power", "shellies/shelly-bulb-duo-test/light/0/energy" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_status_invalid(self): """Test getting invalid status data.""" self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/light/0/status", '{"ison": true, "mo')) def test_handleMessage_light_on(self): """Test getting a light on message.""" self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/light/0/status", '{"ison": true, "white": 100, "temp": 5000, "brightness": 100}') self.assertTrue(self.shelly.isOn()) self.assertFalse(self.shelly.device.states['overload']) self.assertEqual(100, self.shelly.device.states['brightnessLevel']) def test_handleMessage_light_off(self): """Test getting a light off message.""" self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/light/0/status", '{"ison": false, "white": 100, "temp": 5000, "brightness": 100}') self.assertTrue(self.shelly.isOff()) self.assertFalse(self.shelly.device.states['overload']) self.assertEqual(0, self.shelly.device.states['brightnessLevel']) def test_handleMessage_overpower(self): """Test getting a relay overpower message.""" self.assertFalse(self.shelly.device.states['overload']) self.shelly.handleMessage("shellies/shelly-bulb-duo-test/overload", "1") self.assertTrue(self.shelly.device.states['overload']) def test_handleMessage_power(self): self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/relay/0/power", "0") self.assertEqual("0", self.shelly.device.states['curEnergyLevel']) self.assertEqual( "0 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/relay/0/power", "101.123") self.assertEqual("101.123", self.shelly.device.states['curEnergyLevel']) self.assertEqual( "101.123 W", self.shelly.device.states_meta['curEnergyLevel']['uiValue']) def test_handleMessage_energy(self): self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/relay/0/energy", "0") self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) self.shelly.handleMessage( "shellies/shelly-bulb-duo-test/relay/0/energy", "50") self.assertAlmostEqual(0.0008, self.shelly.device.states['accumEnergyTotal'], 4) def test_handleMessage_announce(self): announcement = '{"id": "shelly-bulb-duo-test", "mac": "aa:bb:cc:ee", "ip": "192.168.1.101", "fw_ver": "0.1.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:ee", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.101", self.shelly.getIpAddress()) self.assertEqual("0.1.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-bulb-duo-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-bulb-duo-test/online", "false") self.assertFalse(self.shelly.device.states['online']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) turnOn = IndigoAction(indigo.kDeviceAction.TurnOn) self.shelly.handleAction(turnOn) self.assertTrue(self.shelly.isOn()) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 100}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) turnOff = IndigoAction(indigo.kDeviceAction.TurnOff) self.shelly.handleAction(turnOff) self.assertTrue(self.shelly.isOff()) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "off", "temp": 2700, "brightness": 0}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly-bulb-duo-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_off_to_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOn()) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 100}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_on_to_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOff()) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "off", "temp": 2700, "brightness": 0}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_reset_energy(self, publish): self.shelly.updateEnergy(30) self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) resetEnergy = IndigoAction(indigo.kUniversalAction.EnergyReset) self.shelly.handleAction(resetEnergy) self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_update_energy(self, publish): updateEnergy = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(updateEnergy) publish.assert_called_with("shellies/shelly-bulb-duo-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_setBrightness(self, publish): self.assertEqual(0, self.shelly.device.states['brightnessLevel']) setBrightness = IndigoAction(indigo.kDeviceAction.SetBrightness, actionValue=50) self.shelly.handleAction(setBrightness) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 50}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_brightenBy(self, publish): self.assertEqual(0, self.shelly.device.states['brightnessLevel']) brightenBy = IndigoAction(indigo.kDeviceAction.BrightenBy, actionValue=25) self.shelly.handleAction(brightenBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(25, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 25}') self.shelly.handleAction(brightenBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 50}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_brightenBy_more_than_100(self, publish): self.shelly.device.updateStateOnServer('brightnessLevel', 90) brightenBy = IndigoAction(indigo.kDeviceAction.BrightenBy, actionValue=25) self.shelly.handleAction(brightenBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(100, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 100}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_dimBy(self, publish): self.shelly.device.updateStateOnServer('brightnessLevel', 100) dimBy = IndigoAction(indigo.kDeviceAction.DimBy, actionValue=25) self.shelly.handleAction(dimBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(75, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 75}') self.shelly.handleAction(dimBy) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 2700, "brightness": 50}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_dimBy_less_than_0(self, publish): self.shelly.device.updateStateOnServer('brightnessLevel', 10) dimBy = IndigoAction(indigo.kDeviceAction.DimBy, actionValue=25) self.shelly.handleAction(dimBy) self.assertTrue(self.shelly.isOff()) self.assertEqual(0, self.shelly.device.states['brightnessLevel']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "off", "temp": 2700, "brightness": 0}') @patch('Devices.Shelly.Shelly.publish') def test_handleAction_setColorLevels(self, publish): self.shelly.turnOn() self.shelly.device.updateStateOnServer('brightnessLevel', 100) self.shelly.device.updateStateOnServer('whiteLevel', 10) self.shelly.device.updateStateOnServer('whiteTemperature', 10) setColorLevels = IndigoAction(indigo.kDeviceAction.SetColorLevels, actionValue={ 'whiteLevel': 50, 'whiteTemperature': 6500 }) self.shelly.handleAction(setColorLevels) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.states['whiteLevel']) self.assertEqual(6500, self.shelly.device.states['whiteTemperature']) publish.assert_called_with( "shellies/shelly-bulb-duo-test/light/0/set", '{"turn": "on", "temp": 6500, "brightness": 100}') def test_apply_brightness_off(self): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.applyBrightness(0) self.assertTrue(self.shelly.isOff()) self.assertEqual(0, self.shelly.device.brightness) def test_apply_brightness_on(self): self.assertTrue(self.shelly.isOff()) self.shelly.applyBrightness(50) self.assertTrue(self.shelly.isOn()) self.assertEqual(50, self.shelly.device.brightness) self.shelly.applyBrightness(100) self.assertTrue(self.shelly.isOn()) self.assertEqual(100, self.shelly.device.brightness) def test_update_state_image_on(self): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.assertEqual(indigo.kStateImageSel.DimmerOn, self.shelly.device.image) def test_update_state_image_off(self): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) self.assertEqual(indigo.kStateImageSel.DimmerOff, self.shelly.device.image) def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_Bulb_Duo.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_Bulb_Duo.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_Bulb_Duo.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors)
class Test_Shelly_1(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_1(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly1-test" self.device.updateStateOnServer("sw-input", False) self.device.updateStateOnServer("longpush", False) self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.pluginProps['last-input-event-id'] = -1 def test_getSubscriptions_no_address(self): self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): topics = [ "shellies/announce", "shellies/shelly1-test/online", "shellies/shelly1-test/relay/0", "shellies/shelly1-test/input/0", "shellies/shelly1-test/longpush/0", "shellies/shelly1-test/input_event/0", "shellies/shelly1-test/ext_temperatures", "shellies/shelly1-test/ext_humidities" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_relay_on(self): self.assertTrue(self.shelly.isOff()) self.shelly.handleMessage("shellies/shelly1-test/relay/0", "on") self.assertTrue(self.shelly.isOn()) def test_handleMessage_relay_off(self): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) self.shelly.handleMessage("shellies/shelly1-test/relay/0", "off") self.assertTrue(self.shelly.isOff()) def test_handleMessage_switch_on(self): self.assertFalse(self.shelly.device.states['sw-input']) self.shelly.handleMessage("shellies/shelly1-test/input/0", "1") self.assertTrue(self.shelly.device.states['sw-input']) def test_handleMessage_switch_off(self): self.shelly.device.states['sw-input'] = True self.assertTrue(self.shelly.device.states['sw-input']) self.shelly.handleMessage("shellies/shelly1-test/input/0", "0") self.assertFalse(self.shelly.device.states['sw-input']) def test_handleMessage_longpush_on(self): self.assertFalse(self.shelly.device.states['longpush']) self.shelly.handleMessage("shellies/shelly1-test/longpush/0", "1") self.assertTrue(self.shelly.device.states['longpush']) def test_handleMessage_longpush_off(self): self.shelly.device.states['longpush'] = True self.assertTrue(self.shelly.device.states['longpush']) self.shelly.handleMessage("shellies/shelly1-test/longpush/0", "0") self.assertFalse(self.shelly.device.states['longpush']) def test_handleMessage_announce(self): announcement = '{"id": "shelly1-test", "mac": "aa:bb:cc:dd", "ip": "192.168.1.100", "fw_ver": "0.0.0", "new_fw": false}' self.shelly.handleMessage("shellies/announce", announcement) self.assertEqual("aa:bb:cc:dd", self.shelly.device.states['mac-address']) self.assertEqual("192.168.1.100", self.shelly.getIpAddress()) self.assertEqual("0.0.0", self.shelly.getFirmware()) self.assertFalse(self.shelly.updateAvailable()) def test_handleMessage_online_true(self): self.shelly.device.states['online'] = False self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly1-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly1-test/online", "false") self.assertFalse(self.shelly.device.states['online']) @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) turnOn = IndigoAction(indigo.kDeviceAction.TurnOn) self.shelly.handleAction(turnOn) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly1-test/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_turn_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) turnOff = IndigoAction(indigo.kDeviceAction.TurnOff) self.shelly.handleAction(turnOff) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly1-test/relay/0/command", "off") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_status_request(self, publish): statusRequest = IndigoAction(indigo.kDeviceAction.RequestStatus) self.shelly.handleAction(statusRequest) publish.assert_called_with("shellies/shelly1-test/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_off_to_on(self, publish): self.shelly.turnOff() self.assertTrue(self.shelly.isOff()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOn()) publish.assert_called_with("shellies/shelly1-test/relay/0/command", "on") @patch('Devices.Shelly.Shelly.publish') def test_handleAction_toggle_on_to_off(self, publish): self.shelly.turnOn() self.assertTrue(self.shelly.isOn()) toggle = IndigoAction(indigo.kDeviceAction.Toggle) self.shelly.handleAction(toggle) self.assertTrue(self.shelly.isOff()) publish.assert_called_with("shellies/shelly1-test/relay/0/command", "off") def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True } isValid, valuesDict, errors = Shelly_1.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type" } isValid, valuesDict, errors = Shelly_1.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "" } isValid, valuesDict, errors = Shelly_1.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors) @patch('Devices.Shelly.Shelly.processInputEvent') def test_input_event_is_processed(self, processInputEvent): """Test that an input_event message is processed""" self.shelly.handleMessage("shellies/shelly1-test/input_event/0", '{"event": "S", "event_cnt": 1}') processInputEvent.assert_called_with('{"event": "S", "event_cnt": 1}')
class Test_Shelly_Motion(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Motion(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-motion-test" self.device.updateStateOnServer("vibration", "") self.device.updateStateOnServer("lux", "") self.device.updateStateOnServer("active", "") self.device.updateStateOnServer("onOffState", "") self.device.updateStateOnServer("batteryLevel", 0) def test_getSubscriptions(self): subscriptions = [ "shellies/announce", "shellies/shelly-motion-test/online", "shellies/shelly-motion-test/status" ] self.assertListEqual(subscriptions, self.shelly.getSubscriptions()) def test_updateStateImage_on_motion(self): self.device.states['onOffState'] = True self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.MotionSensorTripped, self.device.image) def test_updateStateImage_on_inactivity(self): self.device.states['onOffState'] = False self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.MotionSensor, self.device.image) def test_handleMessage_online_true(self): self.device.states['online'] = False self.shelly.handleMessage("shellies/shelly-motion-test/online", "true") self.assertTrue(self.device.states['online']) def test_handleMessage_online_false(self): self.device.states['online'] = True self.shelly.handleMessage("shellies/shelly-motion-test/online", "false") self.assertFalse(self.device.states['online']) def test_handleMessage_motion_detected(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"motion": true}') self.assertTrue(self.device.states['onOffState']) def test_handleMessage_motion_undetected(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"motion": false}') self.assertFalse(self.device.states['onOffState']) def test_handleMessage_active_true(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"active": true}') self.assertTrue(self.device.states['active']) def test_handleMessage_active_false(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"active": false}') self.assertFalse(self.device.states['active']) def test_handleMessage_vibration_true(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"vibration": true}') self.assertTrue(self.device.states['vibration']) def test_handleMessage_vibration_false(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"vibration": false}') self.assertFalse(self.device.states['vibration']) def test_handleMessage_lux(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"lux": 88}') self.assertEqual(88, self.device.states['lux']) def test_handleMessage_battery_level(self): self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"bat": 68}') self.assertEqual(68, self.device.states['batteryLevel']) def test_handleMessage_invalid_json(self): self.assertRaises(ValueError, self.shelly.handleMessage("shellies/shelly-motion-test/status", '{"bat": 6]'))
class Test_Shelly(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Devices.Shelly.Shelly(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['broker-id'] = "12345" self.device.pluginProps['address'] = "shellies/test-shelly" self.device.pluginProps['resetEnergyOffset'] = 0 self.device.pluginProps['last-input-event-id'] = -1 @patch('Devices.Shelly.Shelly.getSubscriptions', return_value=["test/one", "test/two"]) def test_subscribe(self, getSubscriptions): """Test subscribing to a topic.""" self.shelly.subscribe() subscriptions = [{ 'topic': "test/one", 'qos': 0 }, { 'topic': "test/two", 'qos': 0 }] self.assertListEqual( subscriptions, self.shelly.getMQTT().getBrokerSubscriptions(12345)) @patch('Devices.Shelly.Shelly.getSubscriptions', return_value=["test/one", "test/two"]) def test_subscribe_with_connector_fix(self, getSubscriptions): """Test subscribing to a topic.""" indigo.activePlugin.pluginPrefs['connector-fix'] = True self.shelly.subscribe() subscriptions = [{ 'topic': "0:test/one", 'qos': 0 }, { 'topic': "0:test/two", 'qos': 0 }] self.assertListEqual( subscriptions, self.shelly.getMQTT().getBrokerSubscriptions(12345)) def test_publish(self): """Test publishing a payload to a topic.""" self.shelly.publish("some/topic", {'the': 'payload'}) expected = [{ 'topic': 'some/topic', 'retain': 0, 'qos': 0, 'payload': { 'the': 'payload' } }] self.assertListEqual(expected, self.shelly.getMQTT().getMessagesOut(12345)) def test_getSubscriptions(self): self.assertEqual(0, len(self.shelly.getSubscriptions())) def test_getIpAddress(self): self.device.states['ip-address'] = "192.168.1.100" self.assertEqual("192.168.1.100", self.shelly.getIpAddress()) def test_getAddress(self): self.device.pluginProps['address'] = "some/address" self.assertEqual("some/address", self.shelly.getAddress()) def test_updateAvailable_has_update(self): self.device.states['has-firmware-update'] = True self.assertTrue(self.shelly.updateAvailable()) def test_updateAvailable_no_update(self): self.device.states['has-firmware-update'] = False self.assertFalse(self.shelly.updateAvailable()) def test_updateAvailable_no_info(self): self.assertFalse('has-firmware-update' in self.device.states.keys()) self.assertFalse(self.shelly.updateAvailable()) def test_getFirmware(self): self.device.states['firmware-version'] = "abc.123.d@qwerty" self.assertEqual("abc.123.d@qwerty", self.shelly.getFirmware()) def test_getFirmware_no_info(self): self.assertFalse('firmware-version' in self.device.states.keys()) self.assertIsNone(self.shelly.getFirmware()) def test_getMQTT_enabled(self): indigo.server.plugins[ "com.flyingdiver.indigoplugin.mqtt"].enabled = True self.assertIsNotNone(self.shelly.getMQTT()) self.assertTrue(self.shelly.getMQTT().isEnabled()) def test_getMQTT_disabled(self): indigo.server.plugins[ "com.flyingdiver.indigoplugin.mqtt"].enabled = False self.assertIsNone(self.shelly.getMQTT()) def test_getBrokerId_valid(self): self.assertEquals(12345, self.shelly.getBrokerId()) def test_getBrokerId_empty(self): self.device.pluginProps['broker-id'] = None self.assertIsNone(self.shelly.getBrokerId()) self.device.pluginProps['broker-id'] = "" self.assertIsNone(self.shelly.getBrokerId()) def test_getMessageType(self): self.device.pluginProps["message-type"] = "some-type" self.assertEquals("some-type", self.shelly.getMessageType()) def test_getMessageType_empty(self): self.assertEquals("", self.shelly.getMessageType()) def test_getAnnounceMessageType_same(self): self.device.pluginProps[ 'announce-message-type-same-as-message-type'] = True self.assertIsNone(self.shelly.getAnnounceMessageType()) def test_getAnnounceMessageType_different(self): self.device.pluginProps['message-type'] = "some-type" self.device.pluginProps['announce-message-type'] = "some-other-type" self.device.pluginProps[ 'announce-message-type-same-as-message-type'] = False self.assertEquals("some-type", self.shelly.getMessageType()) self.assertEquals("some-other-type", self.shelly.getAnnounceMessageType()) def test_getMessageTypes(self): self.device.pluginProps['message-type'] = "some-type" self.assertListEqual(["some-type"], self.shelly.getMessageTypes()) self.device.pluginProps['announce-message-type'] = "some-other-type" self.device.pluginProps[ 'announce-message-type-same-as-message-type'] = True self.assertListEqual(["some-type"], self.shelly.getMessageTypes()) self.device.pluginProps[ 'announce-message-type-same-as-message-type'] = False self.assertListEqual(["some-type", "some-other-type"], self.shelly.getMessageTypes()) del self.device.pluginProps['message-type'] self.assertListEqual(["some-other-type"], self.shelly.getMessageTypes()) @patch('Devices.Shelly.Shelly.publish') def test_sendStatusRequestCommand(self, publish): self.shelly.sendStatusRequestCommand() publish.assert_called_with("shellies/test-shelly/command", "update") @patch('Devices.Shelly.Shelly.publish') def test_announce(self, publish): self.shelly.announce() publish.assert_called_with("shellies/test-shelly/command", "announce") @patch('Devices.Shelly.Shelly.publish') def test_sendUpdateFirmwareCommand(self, publish): self.shelly.sendUpdateFirmwareCommand() publish.assert_called_with("shellies/test-shelly/command", "update_fw") def test_setTemperature(self): self.device.pluginProps['temp-units'] = "F" self.shelly.setTemperature(75) self.assertEqual(75, self.device.states['temperature']) self.assertEqual("75.0 °F", self.device.states_meta['temperature']['uiValue']) self.assertEquals( 1, self.device.states_meta['temperature']['decimalPlaces']) def test_setTemperature_custom(self): self.device.pluginProps['units'] = "C->F" self.device.pluginProps['offset'] = "1.2345" self.device.pluginProps['decimals'] = 3 self.shelly.setTemperature(100, state="temp", unitsProps="units", decimalsProps="decimals", offsetProps="offset") self.assertEqual(213.2345, self.device.states['temp']) self.assertEqual("213.234 °F", self.device.states_meta['temp']['uiValue']) self.assertEquals(3, self.device.states_meta['temp']['decimalPlaces']) def test_setTemperature_with_valid_offset(self): self.device.pluginProps['temp-units'] = "F" self.device.pluginProps['temp-offset'] = "1.25" self.shelly.setTemperature(75) self.assertEqual(76.25, self.device.states['temperature']) self.assertEqual("76.2 °F", self.device.states_meta['temperature']['uiValue']) self.assertEquals( 1, self.device.states_meta['temperature']['decimalPlaces']) def test_setTemperature_with_invalid_offset(self): self.device.pluginProps['temp-units'] = "F" self.device.pluginProps['temp-offset'] = "a" self.assertRaises(ValueError, self.shelly.setTemperature(75)) def test_setTemperature_F(self): self.device.pluginProps['temp-units'] = "F" self.shelly.setTemperature(50) self.assertEqual(50.0, self.device.states['temperature']) self.assertEqual("50.0 °F", self.device.states_meta['temperature']['uiValue']) self.assertEquals( 1, self.device.states_meta['temperature']['decimalPlaces']) def test_setTemperature_C_to_F(self): self.device.pluginProps['temp-units'] = "C->F" self.shelly.setTemperature(0) self.assertEqual(32.0, self.device.states['temperature']) self.assertEqual("32.0 °F", self.device.states_meta['temperature']['uiValue']) self.assertEquals( 1, self.device.states_meta['temperature']['decimalPlaces']) def test_setTemperature_C(self): self.device.pluginProps['temp-units'] = "C" self.shelly.setTemperature(10) self.assertEqual(10.0, self.device.states['temperature']) self.assertEqual("10.0 °C", self.device.states_meta['temperature']['uiValue']) self.assertEquals( 1, self.device.states_meta['temperature']['decimalPlaces']) def test_setTemperature_F_to_C(self): self.device.pluginProps['temp-units'] = "F->C" self.shelly.setTemperature(212) self.assertEqual(100.0, self.device.states['temperature']) self.assertEqual("100.0 °C", self.device.states_meta['temperature']['uiValue']) self.assertEquals( 1, self.device.states_meta['temperature']['decimalPlaces']) def test_convertCtoF(self): """Convert from celsius to fahrenheit.""" self.assertEqual(32, self.shelly.convertCtoF(0)) self.assertEqual(122, self.shelly.convertCtoF(50)) self.assertEqual(77, self.shelly.convertCtoF(25)) self.assertAlmostEqual(82.4, self.shelly.convertCtoF(28), 4) def test_convertFtoC(self): """Convert from fahrenheit to celsius.""" self.assertEqual(0, self.shelly.convertFtoC(32)) self.assertEqual(50, self.shelly.convertFtoC(122)) self.assertEqual(25, self.shelly.convertFtoC(77)) self.assertAlmostEqual(28, self.shelly.convertFtoC(82.4), 4) def test_pasrseAnnouncement_no_firmware_updated(self): """Parse an announcement message that indicates no firmware change.""" self.device.pluginProps['address'] = "shellies/test-shelly" announcement = '{"id": "test-shelly", "mac": "aa:bb:cc:dd", "ip": "192.168.1.100", "fw_ver": "0.0.0", "new_fw": false}' self.shelly.parseAnnouncement(announcement) self.assertEqual("aa:bb:cc:dd", self.device.states['mac-address']) self.assertEqual("192.168.1.100", self.device.states['ip-address']) self.assertEqual("0.0.0", self.device.states['firmware-version']) self.assertFalse(self.device.states['has-firmware-update']) def test_parseAnnouncement_with_firmware_updated(self): """Parse an announcement message that indicates firmware has changed.""" self.device.pluginProps['address'] = "shellies/test-shelly" announcement = '{"id": "test-shelly", "mac": "aa:bb:cc:dd:ff", "ip": "192.168.1.101", "fw_ver": "0.0.0", "new_fw": true}' self.shelly.parseAnnouncement(announcement) self.assertEqual("aa:bb:cc:dd:ff", self.device.states['mac-address']) self.assertEqual("192.168.1.101", self.device.states['ip-address']) self.assertEqual("0.0.0", self.device.states['firmware-version']) self.assertTrue(self.device.states['has-firmware-update']) def test_parseAnnouncement_invalid_device_data(self): """Parse an announcement message for the wrong device.""" self.device.pluginProps['address'] = "shellies/test-shelly" announcement = '{"identifier": "test-shelly", "mac": "aa:bb:cc:dd", "ip": "192.168.1.100", "fw_ver": "0.0.0", "new_fw": false}' self.shelly.parseAnnouncement(announcement) self.assertDictEqual({}, self.device.states) announcement = '{"identifier": "test-shelly"}' self.shelly.parseAnnouncement(announcement) self.assertFalse('mac-address' in self.device.states.keys()) self.assertFalse('ip-address' in self.device.states.keys()) self.assertFalse('firmware-version' in self.device.states.keys()) self.assertFalse('has-firmware-update' in self.device.states.keys()) def test_parseAnnouncement_invalid_announcement_for_device(self): """Parse an invalid announcement message.""" self.device.pluginProps['address'] = "shellies/test-shelly" self.device.updateStateOnServer('mac-address', '1') self.device.updateStateOnServer('ip-address', '2') self.device.updateStateOnServer('firmware-version', '3') self.device.updateStateOnServer('has-firmware-update', False) self.assertEqual("1", self.device.states['mac-address']) self.assertEqual("2", self.device.states['ip-address']) self.assertEqual("3", self.device.states['firmware-version']) self.assertFalse(self.device.states['has-firmware-update']) announcement = '{"id": "test-invalid-shelly", "mac": "aa:bb:cc:dd:ff", "ip": "192.168.1.101", "fw_ver": "0.0.0", "new_fw": true}' self.shelly.parseAnnouncement(announcement) self.assertEqual("1", self.device.states['mac-address']) self.assertEqual("2", self.device.states['ip-address']) self.assertEqual("3", self.device.states['firmware-version']) self.assertFalse(self.device.states['has-firmware-update']) def test_updateEnergy_4_decimals(self): self.shelly.updateEnergy(50) self.assertAlmostEqual(0.0008, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "0.0008 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) self.assertEqual( 4, self.shelly.device.states_meta['accumEnergyTotal'] ['decimalPlaces']) def test_updateEnergy_3_decimals(self): self.shelly.updateEnergy(5000) self.assertAlmostEqual(0.0833, self.shelly.device.states['accumEnergyTotal'], 3) self.assertEqual( "0.083 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) self.assertEqual( 4, self.shelly.device.states_meta['accumEnergyTotal'] ['decimalPlaces']) def test_updateEnergy_2_decimals(self): self.shelly.updateEnergy(500000) self.assertAlmostEqual(8.3333, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "8.33 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) self.assertEqual( 4, self.shelly.device.states_meta['accumEnergyTotal'] ['decimalPlaces']) def test_updateEnergy_1_decimal(self): self.shelly.updateEnergy(5000000) self.assertAlmostEqual(83.3333, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "83.3 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) self.assertEqual( 4, self.shelly.device.states_meta['accumEnergyTotal'] ['decimalPlaces']) def test_updateEnergy_after_reset(self): """Test updating energy after it has been reset.""" self.shelly.updateEnergy(30) self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "0.0005 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) self.shelly.resetEnergy() self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) self.shelly.updateEnergy(60) self.assertAlmostEqual(0.0005, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "0.0005 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) def test_resetEnergy(self): """Test resetting the energy data.""" self.shelly.updateEnergy(15) self.assertAlmostEqual(0.00025, self.shelly.device.states['accumEnergyTotal'], 4) self.assertEqual( "0.0003 kWh", self.shelly.device.states_meta['accumEnergyTotal']['uiValue']) self.shelly.resetEnergy() self.assertAlmostEqual(0.0000, self.shelly.device.states['accumEnergyTotal'], 4) def test_turnOn(self): """Test turning the device on in Indigo.""" self.device.states['onOffState'] = False self.shelly.turnOn() self.assertTrue(self.device.states['onOffState']) def test_turnOff(self): """Test turning the device off in Indigo.""" self.device.states['onOffState'] = True self.shelly.turnOff() self.assertFalse(self.device.states['onOffState']) def test_isOn(self): """Test determining if the device is on.""" self.device.states['onOffState'] = True self.assertTrue(self.shelly.isOn()) self.device.states['onOffState'] = False self.assertFalse(self.shelly.isOn()) def test_isOff(self): """Test determining of the device is off.""" self.device.states['onOffState'] = False self.assertTrue(self.shelly.isOff()) self.device.states['onOffState'] = True self.assertFalse(self.shelly.isOff()) def test_getChannel_default(self): """Test getting the default channel.""" self.assertEqual(0, self.shelly.getChannel()) def test_getChannel_custom(self): """Test getting a defined channel.""" self.device.pluginProps['channel'] = 1 self.assertEqual(1, self.shelly.getChannel()) def test_isAddon(self): """Test determining of the device is an addon.""" self.assertFalse(self.shelly.isAddon()) def test_updateStateImage_on(self): """Test setting the state icon when the device is on.""" self.device.states['onOffState'] = True self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.PowerOn, self.device.image) def test_updateStateImage_off(self): """Test setting the state icon when the device is off.""" self.device.states['onOffState'] = False self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.PowerOff, self.device.image) def test_isMuted(self): """Test getting whether the device is set to be muted.""" self.assertFalse(self.shelly.isMuted()) self.device.pluginProps['muted'] = True self.assertTrue(self.shelly.isMuted()) def test_getMutedLoggingMethods(self): """Test getting the log levels to mute when the device is muted.""" self.assertListEqual(["debug", "info"], self.shelly.getMutedLoggingMethods()) def test_get_last_input_event_id(self): """Test getting the last input event id""" self.assertEqual(-1, self.shelly.getLastInputEventId()) self.device.pluginProps['last-input-event-id'] = "5" self.assertEqual(5, self.shelly.getLastInputEventId()) def test_get_last_input_event_id_default_to_negative_one(self): """Test getting the last input event id when there is no value""" del self.device.pluginProps['last-input-event-id'] self.assertFalse( 'last-input-event-id' in self.device.pluginProps.keys()) self.assertEqual(-1, self.shelly.getLastInputEventId()) def test_process_input_event_invalid_event_type_returns_None(self): """Test processing an event message with an invalid event type""" message = '{"event": null, "event_cnt": 0}' self.assertIsNone(self.shelly.processInputEvent(message)) def test_process_input_event_invalid_event_count_returns_None(self): """Test processing an event message with an invalid event count""" message = '{"event": "", "event_cnt": null}' self.assertIsNone(self.shelly.processInputEvent(message)) def test_process_input_event_new_event_id_stored(self): """Test processing an event message stores the new event id""" message = '{"event": "S", "event_cnt": 1}' self.shelly.processInputEvent(message) self.assertEqual(1, self.shelly.getLastInputEventId()) def test_process_input_event_duplicate_event_not_processed(self): """Test processing an event message that has been previously processed is not reprocessed""" message = '{"event": "S", "event_cnt": 1}' self.shelly.processInputEvent(message) self.assertEqual(1, self.shelly.getLastInputEventId()) # Duplicate message processed... self.shelly.processInputEvent(message) self.assertEqual(1, self.shelly.getLastInputEventId()) def test_process_input_event_trigger_executed(self): """Test processing an event message and a trigger was executed""" trigger_S = IndigoTrigger("input-event-s", {'device-id': self.device.id}) trigger_S_other = IndigoTrigger("input-event-s", {'device-id': self.device.id + 1}) trigger_L = IndigoTrigger("input-event-l", {'device-id': self.device.id}) indigo.activePlugin.triggers['1'] = trigger_S indigo.activePlugin.triggers['2'] = trigger_L indigo.activePlugin.triggers['3'] = trigger_S_other message = '{"event": "S", "event_cnt": 1}' self.shelly.processInputEvent(message) self.assertTrue(trigger_S.executed) self.assertFalse(trigger_L.executed) self.assertFalse(trigger_S_other.executed) def test_process_temperature_status_normal_event_trigger_executed(self): """Test that a normal temperature status fires executes a trigger""" trigger = IndigoTrigger("abnormal-temperature-status-any", {}) indigo.activePlugin.triggers['1'] = trigger self.shelly.processTemperatureStatus("Normal") self.assertFalse(trigger.executed) def test_process_temperature_status_abnormal_event_trigger_executed(self): """Test that an abnormal temperature status fires executes a trigger""" trigger = IndigoTrigger("abnormal-temperature-status-any", {}) indigo.activePlugin.triggers['1'] = trigger self.shelly.processTemperatureStatus("High") self.assertTrue(trigger.executed) def test_process_temperature_sensors_creates_correct_list(self): """Test that the list of sensors is properly created""" payload = '{"0":{"hwID":"2885186e38190123","tC":20.5}, "1":{"hwID":"2885186e38190456","tC":21.5}, "2":{"hwID":"2885186e38190789","tC":22.5}}' self.shelly.processTemperatureSensors(payload) expected = [{ "channel": 0, "id": "2885186e38190123" }, { "channel": 1, "id": "2885186e38190456" }, { "channel": 2, "id": "2885186e38190789" }] self.assertItemsEqual(expected, self.shelly.temperature_sensors) def test_process_temperature_sensors_ignores_invalid_sensors(self): """Test that the list of sensors is properly created""" payload = '{"0":{"hwID":"2885186e38190123","tC":20.5}, "1":{"hwID":"000000000000000","tC":999}, "2":{"hwID":"2885186e38190789","tC":22.5}}' self.shelly.processTemperatureSensors(payload) expected = [{ "channel": 0, "id": "2885186e38190123" }, { "channel": 2, "id": "2885186e38190789" }] self.assertItemsEqual(expected, self.shelly.temperature_sensors) def test_process_temperature_sensors_removes_old_sensors(self): """Test that old sensors are no longer included""" payload = '{"0":{"hwID":"2885186e38190123","tC":20.5}, "1":{"hwID":"2885186e38190456","tC":21.5}, "2":{"hwID":"2885186e38190789","tC":22.5}}' self.shelly.processTemperatureSensors(payload) payload = '{"0":{"hwID":"2885186e38190456","tC":20.5}, "1":{"hwID":"00000000000000","tC":999}, "2":{"hwID":"2885186e38190789","tC":22.5}}' self.shelly.processTemperatureSensors(payload) expected = [{ "channel": 0, "id": "2885186e38190456" }, { "channel": 2, "id": "2885186e38190789" }] self.assertItemsEqual(expected, self.shelly.temperature_sensors) def test_process_humidity_sensors_creates_correct_list(self): """Test that the list of sensors is properly created""" payload = '{"0":{"hwID":"2885186e38190123","hum":20.5}, "1":{"hwID":"2885186e38190456","hum":21.5}}' self.shelly.processHumiditySensors(payload) expected = [{ "channel": 0, "id": "2885186e38190123" }, { "channel": 1, "id": "2885186e38190456" }] self.assertItemsEqual(expected, self.shelly.humidity_sensors) def test_process_humidity_sensors_ignores_invalid_sensors(self): """Test that the list of sensors is properly created""" payload = '{"0":{"hwID":"2885186e38190123","hum":20.5}, "1":{"hwID":"000000000000000","hum":999}}' self.shelly.processHumiditySensors(payload) expected = [{"channel": 0, "id": "2885186e38190123"}] self.assertItemsEqual(expected, self.shelly.humidity_sensors) def test_process_humidity_sensors_removes_old_sensors(self): """Test that old sensors are no longer included""" payload = '{"0":{"hwID":"2885186e38190123","hum":20.5}, "1":{"hwID":"2885186e38190456","hum":21.5}}' self.shelly.processHumiditySensors(payload) payload = '{"0":{"hwID":"2885186e38190456","hum":20.5}}' self.shelly.processHumiditySensors(payload) expected = [{"channel": 0, "id": "2885186e38190456"}] self.assertItemsEqual(expected, self.shelly.humidity_sensors) def test_handleMessage_temperature_sensors(self): """Test that temperature sensor messages are processed""" topic = 'shellies/test-shelly/ext_temperatures' payload = '{"0":{"hwID":"2885186e38190123","tC":20.5}, "1":{"hwID":"2885186e38190456","tC":21.5}}' self.shelly.handleMessage(topic, payload) expected = [{ "channel": 0, "id": "2885186e38190123" }, { "channel": 1, "id": "2885186e38190456" }] self.assertItemsEqual(expected, self.shelly.temperature_sensors) def test_handleMessage_humidity_sensors(self): """Test that humidity sensor messages are processed""" topic = 'shellies/test-shelly/ext_humidities' payload = '{"0":{"hwID":"2885186e38190456","hum":20.5}}' self.shelly.handleMessage(topic, payload) expected = [{"channel": 0, "id": "2885186e38190456"}] self.assertItemsEqual(expected, self.shelly.humidity_sensors) def test_updateBatteryLevel(self): """Test updating the battery level sets the state.""" self.shelly.updateBatteryLevel(52) self.assertEqual(52, self.shelly.device.states['batteryLevel']) self.assertEqual( "52%", self.shelly.device.states_meta['batteryLevel']['uiValue']) def test_updateBatteryLevel_triggers_low_battery(self): """Test that a low battery level trigger is fired.""" trigger_any = IndigoTrigger("low-battery-any", {}) trigger_device = IndigoTrigger("low-battery-device", {'device-id': self.device.id}) indigo.activePlugin.triggers['1'] = trigger_any indigo.activePlugin.triggers['2'] = trigger_device self.shelly.updateBatteryLevel(10) self.assertTrue(trigger_any.executed) self.assertTrue(trigger_device.executed) def test_updateBatteryLevel_only_triggers_on_change(self): """Test that a low battery level trigger only fires when the battery level changes.""" trigger_any = IndigoTrigger("low-battery-any", {}) trigger_device = IndigoTrigger("low-battery-device", {'device-id': self.device.id}) indigo.activePlugin.triggers['1'] = trigger_any indigo.activePlugin.triggers['2'] = trigger_device self.shelly.updateBatteryLevel(10) self.shelly.updateBatteryLevel(10) self.assertEqual(trigger_any.execution_count, 1) self.assertEqual(trigger_device.execution_count, 1)
class Test_Shelly_Door_Window(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_Door_Window(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler(logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-dw-test" self.device.pluginProps['useCase'] = "door" self.device.pluginProps['temp-units'] = "C->F" self.device.pluginProps['temp-offset'] = "2" self.device.pluginProps['temp-decimals'] = "1" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("temperature", 0) self.device.updateStateOnServer("status", False) self.device.updateStateOnServer("vibration", False) self.device.updateStateOnServer("lux", 0) self.device.updateStateOnServer("tilt", 0) self.device.updateStateOnServer("batteryLevel", 0) def test_getSubscriptions_no_address(self): """Test getting subscriptions with no address defined.""" self.device.pluginProps['address'] = None self.assertListEqual([], self.shelly.getSubscriptions()) def test_getSubscriptions(self): """Test getting subscriptions with a defined address.""" topics = [ "shellies/announce", "shellies/shelly-dw-test/online", "shellies/shelly-dw-test/sensor/state", "shellies/shelly-dw-test/sensor/lux", "shellies/shelly-dw-test/sensor/tilt", "shellies/shelly-dw-test/sensor/vibration", "shellies/shelly-dw-test/sensor/temperature", "shellies/shelly-dw-test/sensor/battery" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_temperature(self): self.shelly.handleMessage("shellies/shelly-dw-test/sensor/temperature", "50") self.assertEqual(124, self.shelly.device.states['temperature']) self.assertEqual("124.0 °F", self.shelly.device.states_meta['temperature']['uiValue']) def test_handleMessage_temperature_invalid(self): self.assertRaises(ValueError, self.shelly.handleMessage("shellies/shelly-dw-test/sensor/temperature", "A")) def test_handleMessage_online_true(self): self.shelly.device.states['online'] = False self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-dw-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-dw-test/online", "false") self.assertFalse(self.shelly.device.states['online']) def test_handleMessage_state_open(self): self.shelly.device.states['onOffState'] = True self.shelly.handleMessage("shellies/shelly-dw-test/sensor/state", "open") self.assertEqual(False, self.shelly.device.states['onOffState']) self.assertEqual("open", self.shelly.device.states_meta['onOffState']['uiValue']) def test_handleMessage_state_closed(self): self.shelly.device.states['onOffState'] = False self.shelly.handleMessage("shellies/shelly-dw-test/sensor/state", "close") self.assertEqual(True, self.shelly.device.states['onOffState']) self.assertEqual("close", self.shelly.device.states_meta['onOffState']['uiValue']) def test_handleMessage_lux(self): self.shelly.handleMessage("shellies/shelly-dw-test/sensor/lux", "55") self.assertEqual("55", self.shelly.device.states['lux']) def test_handleMessage_tilt(self): self.shelly.handleMessage("shellies/shelly-dw-test/sensor/tilt", "60") self.assertEqual("60", self.shelly.device.states['tilt']) self.assertEqual("60°", self.shelly.device.states_meta['tilt']['uiValue']) def test_handleMessage_vibration(self): self.assertFalse(self.shelly.device.states['vibration']) self.shelly.handleMessage("shellies/shelly-dw-test/sensor/vibration", "1") self.assertTrue(self.shelly.device.states['vibration']) self.shelly.handleMessage("shellies/shelly-dw-test/sensor/vibration", "0") self.assertFalse(self.shelly.device.states['vibration']) def test_handleMessage_battery(self): self.shelly.handleMessage("shellies/shelly-dw-test/sensor/battery", "94") self.assertEqual("94", self.shelly.device.states['batteryLevel']) def test_update_state_image_door_open(self): self.device.pluginProps['useCase'] = "door" self.shelly.device.states['onOffState'] = False self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.DoorSensorOpened, self.shelly.device.image) def test_update_state_image_door_close(self): self.device.pluginProps['useCase'] = "door" self.shelly.device.states['onOffState'] = True self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.DoorSensorClosed, self.shelly.device.image) def test_update_state_image_window_open(self): self.device.pluginProps['useCase'] = "window" self.shelly.device.states['onOffState'] = False self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.WindowSensorOpened, self.shelly.device.image) def test_update_state_image_window_close(self): self.device.pluginProps['useCase'] = "window" self.shelly.device.states['onOffState'] = True self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.WindowSensorClosed, self.shelly.device.image) def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True, "temp-offset": "" } isValid, valuesDict, errors = Shelly_Door_Window.validateConfigUI(values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type", "temp-offset": "" } isValid, valuesDict, errors = Shelly_Door_Window.validateConfigUI(values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "", "temp-offset": "a" } isValid, valuesDict, errors = Shelly_Door_Window.validateConfigUI(values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors) self.assertTrue("temp-offset" in errors)
class Test_Shelly_HT(unittest.TestCase): def setUp(self): indigo.__init__() self.device = IndigoDevice(id=123456, name="New Device") self.shelly = Shelly_HT(self.device) logging.getLogger('Plugin.ShellyMQTT').addHandler( logging.NullHandler()) self.device.pluginProps['address'] = "shellies/shelly-ht-test" self.device.pluginProps['temp-units'] = "C->F" self.device.pluginProps['temp-offset'] = "2" self.device.pluginProps['temp-decimals'] = "1" self.device.pluginProps['humidity-offset'] = "4" self.device.pluginProps['humidity-decimals'] = "0" self.device.updateStateOnServer("ip-address", None) self.device.updateStateOnServer("mac-address", None) self.device.updateStateOnServer("online", False) self.device.updateStateOnServer("temperature", 0) self.device.updateStateOnServer("humidity", 0) self.device.updateStateOnServer("batteryLevel", 0) def test_getSubscriptions(self): """Test getting subscriptions with a defined address.""" topics = [ "shellies/announce", "shellies/shelly-ht-test/online", "shellies/shelly-ht-test/sensor/temperature", "shellies/shelly-ht-test/sensor/humidity", "shellies/shelly-ht-test/sensor/battery" ] self.assertListEqual(topics, self.shelly.getSubscriptions()) def test_handleMessage_online_true(self): self.shelly.device.states['online'] = False self.assertFalse(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-ht-test/online", "true") self.assertTrue(self.shelly.device.states['online']) def test_handleMessage_online_false(self): self.shelly.device.states['online'] = True self.assertTrue(self.shelly.device.states['online']) self.shelly.handleMessage("shellies/shelly-ht-test/online", "false") self.assertFalse(self.shelly.device.states['online']) def test_handleMessage_temperature(self): self.shelly.handleMessage("shellies/shelly-ht-test/sensor/temperature", "43") self.assertAlmostEqual(111.4, self.shelly.device.states['temperature']) self.assertEqual( "111.4 °F", self.shelly.device.states_meta['temperature']['uiValue']) def test_handleMessage_humidity(self): self.shelly.handleMessage("shellies/shelly-ht-test/sensor/humidity", "60") self.assertAlmostEqual(64, self.shelly.device.states['humidity']) self.assertEqual("64%", self.shelly.device.states_meta['humidity']['uiValue']) def test_handleMessage_humidity_with_invalid_offset(self): self.device.pluginProps['humidity-offset'] = "4a" self.assertRaises( ValueError, self.shelly.handleMessage( "shellies/shelly-ht-test/sensor/humidity", "60")) def test_handleMessage_battery(self): self.shelly.handleMessage("shellies/shelly-ht-test/sensor/battery", "94") self.assertEqual("94", self.shelly.device.states['batteryLevel']) def test_update_state_image_on(self): self.shelly.device.states['online'] = True self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.TemperatureSensorOn, self.shelly.device.image) def test_update_state_image_off(self): self.shelly.device.states['online'] = False self.shelly.updateStateImage() self.assertEqual(indigo.kStateImageSel.TemperatureSensor, self.shelly.device.image) def test_validateConfigUI(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": True, "temp-offset": "", "humidity-offset": "" } isValid, valuesDict, errors = Shelly_HT.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_announce_message_type(self): values = { "broker-id": "12345", "address": "some/address", "message-type": "a-type", "announce-message-type-same-as-message-type": False, "announce-message-type": "another-type", "temp-offset": "", "humidity-offset": "" } isValid, valuesDict, errors = Shelly_HT.validateConfigUI( values, None, None) self.assertTrue(isValid) def test_validateConfigUI_invalid(self): values = { "broker-id": "", "address": "", "message-type": "", "announce-message-type-same-as-message-type": False, "announce-message-type": "", "temp-offset": "a", "humidity-offset": "b" } isValid, valuesDict, errors = Shelly_HT.validateConfigUI( values, None, None) self.assertFalse(isValid) self.assertTrue("broker-id" in errors) self.assertTrue("address" in errors) self.assertTrue("message-type" in errors) self.assertTrue("announce-message-type" in errors) self.assertTrue("temp-offset" in errors) self.assertTrue("humidity-offset" in errors)