Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
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", "")
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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)
Exemplo n.º 7
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)
Exemplo n.º 8
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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
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)
Exemplo n.º 13
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
Exemplo n.º 14
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(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"
Exemplo n.º 15
0
    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)
Exemplo n.º 17
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}')
Exemplo n.º 19
0
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")
Exemplo n.º 20
0
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)
Exemplo n.º 21
0
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)
Exemplo n.º 22
0
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)
Exemplo n.º 23
0
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)
Exemplo n.º 25
0
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}')
Exemplo n.º 26
0
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]'))
Exemplo n.º 27
0
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)
Exemplo n.º 29
0
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)