Skip to content

Instantly share code, notes, and snippets.

@ispiropoulos
Created August 28, 2018 09:16
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save ispiropoulos/90a5f215e71f4dde635e3e3407fb5804 to your computer and use it in GitHub Desktop.
Save ispiropoulos/90a5f215e71f4dde635e3e3407fb5804 to your computer and use it in GitHub Desktop.
Shelly Switch Home Assistant Component
"""
Support for The Shelly Wifi switch.
Save this file inside ".homeassistant/custom_components/switch" (create the folders if not present) and restart HASS.
usage example:
switch:
- platform: shelly
switches:
shelly_switch:
path: /relay/0 (optional, defaults to /relay/0)
host: 10.0.0.219
username: admin
password: admin
Path is optional and defaults to '/relay/0'. If you have the 2-relay Shelly for the second one use /relay/1.
Username & Password are optional. Use only if you have enabled authentication from the shelly web interface.
"""
import logging
import requests
import voluptuous as vol
from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA
from homeassistant.const import (
CONF_HOST, CONF_NAME, CONF_PATH, CONF_USERNAME, CONF_PASSWORD,
CONF_SWITCHES)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
DEFAULT_PATH = "/relay/0"
SWITCH_SCHEMA = vol.Schema({
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_PATH, default=DEFAULT_PATH): cv.string,
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SWITCHES): vol.Schema({cv.slug: SWITCH_SCHEMA}),
})
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Set up Shelly Wifi switches."""
switches = config.get('switches', {})
devices = []
for dev_name, properties in switches.items():
devices.append(
ShellySwitch(
hass,
properties.get(CONF_NAME, dev_name),
properties.get(CONF_HOST, None),
properties.get(CONF_PATH, DEFAULT_PATH),
properties.get(CONF_USERNAME, None),
properties.get(CONF_PASSWORD)))
add_devices_callback(devices)
class ShellySwitch(SwitchDevice):
"""Representation of a Shelly Wifi switch."""
def __init__(self, hass, name, host, path, user, passwd):
"""Initialize the device."""
self._hass = hass
self._name = name
self._state = False
self._url = 'http://{}{}'.format(host, path)
if user is not None:
self._auth = (user, passwd)
else:
self._auth = None
def _switch(self, newstate):
"""Switch on or off."""
_LOGGER.info("Switching to state: %s", newstate)
try:
req = requests.get('{}?turn={}'.format(self._url, newstate),
auth=self._auth, timeout=5)
result = req.json()['ison']
if newstate == 'on':
return result == True
else:
return result == False
except requests.RequestException as error:
_LOGGER.error("Switching failed: " + error)
def _query_state(self):
"""Query switch state."""
_LOGGER.info("Querying state from: %s", self._url)
try:
req = requests.get('{}'.format(self._url),
auth=self._auth, timeout=5)
return req.json()['ison'] == True
except requests.RequestException as error:
_LOGGER.error("State query failed: " + error)
@property
def should_poll(self):
"""Return the polling state."""
return True
@property
def name(self):
"""Return the name of the switch."""
return self._name
@property
def is_on(self):
"""Return true if device is on."""
return self._state
def update(self):
"""Update device state."""
self._state = self._query_state()
def turn_on(self, **kwargs):
"""Turn the device on."""
if self._switch('on'):
self._state = True
def turn_off(self, **kwargs):
"""Turn the device off."""
if self._switch('off'):
self._state = False
@Agith
Copy link

Agith commented Sep 6, 2018

Hi, first of all I wish to thank You for your work! Now a question: is there a way to make a component also for the Shelly2 operating as a roller shutter (the upcoming version 1.3 will support MQTT and have percentage indication for partial opening of the blinds/shades and shutters)???
Again: thanks!
A.

@kolossboss
Copy link

Thanks a lot. Works great

@xbmcnut
Copy link

xbmcnut commented Oct 8, 2018

Great work, thank you! Any way either of the relays could be brought into HA as a light component?

@NicoBijl
Copy link

NicoBijl commented Oct 9, 2018

Nice work !
Could you try to get this into Home Assistant by creating a PR?

@antoinevandenhurk
Copy link

The component is working great. Now i have another Shelly which I want to use as a roller. Is it hard to update the component with the roller function? That would be awesome!

@GabrieleMandalari
Copy link

The component is working great. Now i have another Shelly which I want to use as a roller. Is it hard to update the component with the roller function? That would be awesome!

news about this?

Thanks

@Kbz4
Copy link

Kbz4 commented Nov 19, 2018

any news fr a roller and power meter?
Great component!!
Thanks

@srk23
Copy link

srk23 commented Dec 11, 2018

This works great - many thanks! Is there a way to change the name of the switch from 'shelly_switch' in HA? I'm sure I am missing something very obvious...!

@crsantos
Copy link

crsantos commented Jan 3, 2019

Honest question:

Is this still needed as Shelly now supports MQTT?

@dzacca
Copy link

dzacca commented Jan 15, 2019

Awesome. Worked flawlessly at the first try.
This is exactly what I was looking for as I'm about to replace all my "old" relays with the shelly1's

@qjvtenkroode
Copy link

Works like a charm, just installed my first and integrated it in HA.

This works great - many thanks! Is there a way to change the name of the switch from 'shelly_switch' in HA? I'm sure I am missing something very obvious...!

@srk23 this can be done in two ways, one changes the Entity name: just change the switch name in the config file. For example change 'shelly_switch' to 'living_room'.

switch:
  - platform: shelly
    switches:
      living_room:
        path: /relay/0 (optional, defaults to /relay/0)
        host: 10.0.0.219

This will make the switch Entity have that for a name. The other way would be to add a name would be to add a display name to the Entity, for example:

switch:
  - platform: shelly
    switches:
      shelly_switch:
        name: Living room
        path: /relay/0 (optional, defaults to /relay/0)
        host: 10.0.0.219
```
You're probably looking for the second way.

@sytchi
Copy link

sytchi commented Mar 13, 2019

Great work, thank you! Any way either of the relays could be brought into HA as a light component?

Exactly, it would be nice for me, especially since as I believe most people use it as a light switch

@antoweb
Copy link

antoweb commented Apr 27, 2019

Hi people,
im just reinstalled my raspberry with hassbian and home assistant version 0.92.1. But the shelly wont work. Waths i wrong?

@ghazlewood
Copy link

ghazlewood commented Apr 28, 2019

After upgrading to 0.92 I am getting 'Integration shelly not found when trying to verify its switch platform.' I have updated the configuration to support the new custom_component configuration as required for 0.9 and greater but it seems to be broken now, here's my configuration:

switch:
  - platform: shelly
    switches:
      shelly_switch1: # bin light
        name: Bin Light
        host: <ip address>
        username: shelly
        password: <password>
      shelly_switch2: # corner light
        name: Corner Light
        host: <ip address>
        username: shelly
        password: <password>

@mszpiler
Copy link

I have the same problem with shelly after upgrade to 0.92.1...

@eddsa
Copy link

eddsa commented Apr 28, 2019

Same issue here

@ghazlewood
Copy link

I'm not sure if this was the fix exactly but whilst trying to setup the Plex addon I stumbled on a problem with DNS related to Docker and use the fix in hassio-addons/addon-plex#7 (comment) - after adding this weirdly the problem appears to be solved and both Shelly 1s are appearing as they were before.

@eddsa and @mszpiler could you try the fix linked above and see if it resolve the problem for you both?

@eddsa
Copy link

eddsa commented Apr 30, 2019

Thanks @ghazlewood. In my case it was due to the changes on custom components with 0.92 and later. The manifast.json needs to be added to the custom folder. Moreover the folder structure need to be changed according to the new requirement. Good overview can be found here:
https://developers.home-assistant.io/blog/

@fernmac2
Copy link

fernmac2 commented May 9, 2019

Hello, eddsa could you please specify what must be done exactly? I read the blog but I do not have enough knowledge to find it out.
Thank you

@eddsa
Copy link

eddsa commented May 13, 2019

@fernmac2
There are some Change required, where the rest remains actually the same
**1) Cusomer Component Folder and File Name **
It was "homeassistant/custom_components/switch/shelly.py"
It need to be "homeassistant/custom_components/shelly/switch.py".
It is just a renaming

  1. With 0.92 and later you need also to add the following file, also linked above in the same Folder "homeassistant/custom_components/shelly/"
    2a) Add the file "manifest.json". Just create an empty file and copy the file into the Folder. My text is
    {
    "domain": "shelly",
    "name": "Shelly Cloud",
    "documentation": "https://gist.github.com/ispiropoulos/90a5f215e71f4dde635e3e3407fb5804",
    "dependencies": [],
    "codeowners": [],
    "requirements": []
    }

2b) ad an empty file named "init.py". There is really not text

So your custom folder and content should look like this:
image

@fernmac2
Copy link

fernmac2 commented May 13, 2019 via email

@eddsa
Copy link

eddsa commented May 13, 2019

Hi Everyome, So far I integrated the Shelly 1 as switch. Now I tried with the Shelly 2.5 and was unable to get it running. Has anyone integrated got this script running with a Shelly 2 or Shelly 2.5?

@Gorbac
Copy link

Gorbac commented May 17, 2019

Hi Everyome, So far I integrated the Shelly 1 as switch. Now I tried with the Shelly 2.5 and was unable to get it running. Has anyone integrated got this script running with a Shelly 2 or Shelly 2.5?

Yes. I run a lot of Shelly 1 and 2.5. For the shelly 2.5 use "path: /relay/0" and "path: /relay/1" for each switch.

Great component!

@eddsa
Copy link

eddsa commented May 21, 2019

Thanks @Gorbac

I try that and did not work. I my case the Shelly 2.5 is operated as roller shutter. Is this same on your end? Do you mind copying your relevant configuration for the Shelly 2.5? Thanks for your support.

Regards. Edip

@eddsa
Copy link

eddsa commented May 27, 2019

@Gorbac would really appreciate an answer.

@Gorbac
Copy link

Gorbac commented May 27, 2019

Sorry, I use it as switch

@jonhgaspar
Copy link

have the error:

I have already created the files and continue with errors.

"Setup failed for switch: No setup function defined."

Someone help?

@genem2
Copy link

genem2 commented Aug 7, 2019

Also working great here, thank you for sharing this.
But I did notice this if you're interested: When shutting HomeAssistant (96.5), the log file receives:

2019-08-06 17:52:51 ERROR (MainThread) [homeassistant.core] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
TypeError: stop_shelly() takes 0 positional arguments but 1 was given

@mszpiler
Copy link

@fernmac2
There are some Change required, where the rest remains actually the same
**1) Cusomer Component Folder and File Name **
It was "homeassistant/custom_components/switch/shelly.py"
It need to be "homeassistant/custom_components/shelly/switch.py".
It is just a renaming

  1. With 0.92 and later you need also to add the following file, also linked above in the same Folder "homeassistant/custom_components/shelly/"
    2a) Add the file "manifest.json". Just create an empty file and copy the file into the Folder. My text is
    {
    "domain": "shelly",
    "name": "Shelly Cloud",
    "documentation": "https://gist.github.com/ispiropoulos/90a5f215e71f4dde635e3e3407fb5804",
    "dependencies": [],
    "codeowners": [],
    "requirements": []
    }

2b) ad an empty file named "init.py". There is really not text

So your custom folder and content should look like this:
image

Thank you - it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment