How to Control Your Shelly Plug S LED Light with Python

Hey folks! Theo here. I'm a Python Developer, Product Owner, and a bit of an all-around tech enthusiast. If you're like me, you're fascinated by home automation, energy management, and all things sustainable. That's why I've turned my attention to something incredibly fun: controlling the LED light on my Shelly Plug S using Python.

Why Did I Create This Code?

You might be wondering, "Why would anyone want to control an LED light on a smart plug?" Well, why not? Home automation isn't just about practicality; it's also about having fun and experimenting. Plus, controlling the LED light can be useful. For example, you can change the color to indicate different energy usage levels or simply to match the aesthetic of your room.

And the best part? It's done using Python, a language that I just can't get enough of. The plan was to make the LED light not only switch on and off but also change colors and even blink. Imagine walking into a room and the LED light blinks in your favorite color to welcome you. Cool, right? So let's dive in.

The Prerequisites

Before we jump into the code, you need to have Python installed on your computer. If you haven't yet, you can download it from python.org. You'll also need the requests library for making HTTP calls. You can install it via pip:

pip install requests

Explaining the Code Structure

The script is divided into several functions, each handling a specific interaction with the Shelly Plug S:

  1. get_shelly_status(): Retrieves the status of the Shelly device.

  2. turn_shelly_on(): Turns the Shelly device on.

  3. turn_shelly_off(): Turns the Shelly device off.

  4. set_shelly_led(): Sets the LED color and status.

  5. blink_shelly_led(): Makes the LED blink.

Get Shelly Status

Let's start with the get_shelly_status() function. This function uses the requests.get method to fetch the current status of your Shelly device.

# Fetch the current status of the Shelly device.
def get_shelly_status(ip_address):
    url = f'http://{ip_address}/status'
    try:
        # Make a GET request to the Shelly device's status URL
        response = requests.get(url)
        # Check for successful response
        if response.status_code == 200:
            # Parse the JSON response and return
            return json.loads(response.text)
        else:
            return None
    except Exception as e:
        print(f"An error occurred: {e}")
        return None

Turn Shelly On and Off

Next, we have turn_shelly_on() and turn_shelly_off() functions. Both of these use the requests.get method to send an HTTP GET request to the appropriate relay URL.

# Turn the Shelly device on.
def turn_shelly_on(ip_address):
    url = f'http://{ip_address}/relay/0/on'
    try:
        response = requests.get(url)
        return response.status_code == 200
    except Exception as e:
        print(f"An error occurred: {e}")
        return False
# Turn the Shelly device off.
def turn_shelly_off(ip_address):
    url = f'http://{ip_address}/relay/0/off'
    try:
        response = requests.get(url)
        return response.status_code == 200
    except Exception as e:
        print(f"An error occurred: {e}")
        return False

Set Shelly LED

Now comes the exciting part—set_shelly_led(). This function allows us to set the color and status of the LED. We send a JSON payload via a POST request to adjust the LED settings.

# Set the LED's status and color
def set_shelly_led(ip_address, led_status, led_color=None):
    url = f'http://{ip_address}/settings/led/0'
    payload = {
        'ison': 'true' if led_status else 'false'
    }
    if led_color:
        payload['red'] = led_color.get('red', 0)
        payload['green'] = led_color.get('green', 0)
        payload['blue'] = led_color.get('blue', 0)
    try:
        response = requests.post(url, json=payload)
        return response.status_code == 200
    except Exception as e:
        print(f"An error occurred: {e}")
        return False

Finally, we have blink_shelly_led(), which simply loops through turning the LED on and off to create a blinking effect.

# Make the LED blink
def blink_shelly_led(ip_address, led_color, times=5, interval=1):
    for _ in range(times):
        set_shelly_led(ip_address, True, led_color)
        time.sleep(interval)
        set_shelly_led(ip_address, False)
        time.sleep(interval)

The Complete Code

Here's the complete code including the inline comments.

import requests
import json
import time

def get_shelly_status(ip_address):
    url = f'http://{ip_address}/status'
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return json.loads(response.text)
        else:
            return None
    except Exception as e:
        print(f"An error occurred: {e}")
        return None

def turn_shelly_on(ip_address):
    url = f'http://{ip_address}/relay/0/on'
    try:
        response = requests.get(url)
        return response.status_code == 200
    except Exception as e:
        print(f"An error occurred: {e}")
        return False

def turn_shelly_off(ip_address):
    url = f'http://{ip_address}/relay/0/off'
    try:
        response = requests.get(url)
        return response.status_code == 200
    except Exception as e:
        print(f"An error occurred: {e}")
        return False

def set_shelly_led(ip_address, led_status, led_color=None):
    url = f'http://{ip_address}/settings/led/0'
    payload = {
        'ison': 'true' if led_status else 'false'
    }
    if led_color:
        payload['red'] = led_color.get('red', 0)
        payload['green'] = led_color.get('green', 0)
        payload['blue'] = led_color.get('blue', 0)
    try:
        response = requests.post(url, json=payload)
        return response.status_code == 200
    except Exception as e:
        print(f"An error occurred: {e}")
        return False

def blink_shelly_led(ip_address, led_color, times=5, interval=1):
    for _ in range(times):
        set_shelly_led(ip_address, True, led_color)
        time.sleep(interval)
        set_shelly_led(ip_address, False)
        time.sleep(interval)

if __name__ == "__main__":
    shelly_ip = "192.168.x.x"  # Replace with your Shelly device's IP address

    # Get Shelly status
    status = get_shelly_status(shelly_ip)
    if status:
        print(f"Shelly Status: {status}")

    # Turn Shelly on
    if turn_shelly_on(shelly_ip):
        print("Successfully turned Shelly on")

    # Turn Shelly off
    if turn_shelly_off(shelly_ip):
        print("Successfully turned Shelly off")

# Set LED color to red
    if set_shelly_led(shelly_ip, True, {'red': 255, 'green': 0, 'blue': 0}):
        print("Successfully set LED to red.")

    # Blink LED in blue color
    blink_shelly_led(shelly_ip, {'red': 0, 'green': 0, 'blue': 255}, times=5, interval=1)

And that's it! You've successfully leveled up your home automation game. Have fun experimenting!

Did you find this article valuable?

Support Theo van der Sluijs by becoming a sponsor. Any amount is appreciated!