Integrating custom IoT-Devices

Hey there!

I’m currently starting getting into Home Assistant and also trying to integrate custom built devices. This is where I’m really struggling, as I’m an experienced python-developer but am missing a good documentation (the documentation available seems more like a collection of drafts, not helping in any way for really understanding what’s going on). Is there any book you can recommend?

I do have a device (a custom doorbell named thallo) which outputs sound. Via a http-request I’m able to read the current volume (http://thallo:8080/volume/) and also set it (http://thallo:8080/volume/50). Now: How do I integrate this into Homeassistant?

What I did try was creating a media_player.py component (as it has volume controls). See my code below (inside of the configuration-folder: thallo/media_player.py):

import logging

import requests
import voluptuous as vol

from homeassistant.components.media_player import PLATFORM_SCHEMA, MediaPlayerEntity
from homeassistant.components.media_player.const import (
    SUPPORT_VOLUME_SET,
)
from homeassistant.const import (
    CONF_HOST,
    CONF_NAME,
    CONF_PORT,
)
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = "Thallo"
DEFAULT_PORT = 8080
DEFAULT_TIMEOUT = 10
DOMAIN = "thallo"

SUPPORT_THALLO = (
    SUPPORT_VOLUME_SET
)


PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_HOST): cv.string,
        vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
        vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
    }
)

class Thallo:
    
    def __init__(self, host, port):
        self.host = host
        self.port = port
        
    @property
    def _base_url(self):
        port = f':{self.port}' if self.port else ''
        return f'http://{self.host}{port}'
        
    def _request(self, method, path, params=None):
        url = f'{self._base_url}{path}'
        try:
            if method == 'GET':
                response = requests.get(url, timeout=DEFAULT_TIMEOUT)
            elif method == 'POST':
                response = requests.put(url, params, timeout=DEFAULT_TIMEOUT)
            elif method == 'PUT':
                response = requests.put(url, params, timeout=DEFAULT_TIMEOUT)
            elif method == 'DELETE':
                response = requests.delete(url, timeout=DEFAULT_TIMEOUT)
        
            return response.json()
        except requests.exceptions.HTTPError:
            return {'player_state': 'error'}
        except requests.exceptions.RequestException:
            return {'player_state': 'offline'}
        
    def set_volume(self, level):
        return self._request('GET', f'/volume/{level}')
        
    def get_volume(self):
        return self._request('GET', f'/volume/')

def setup_platform(hass, config, add_entities, discovery_info=None):
    add_entities([ThalloDevice(config.get(CONF_NAME), config.get(CONF_HOST), config.get(CONF_PORT))])

class ThalloDevice(MediaPlayerEntity):
    def __init__(self, name, host, port):
        self._name = name
        self._host = host
        self._port = port
        
        self.client = Thallo(self._host, self._port)
        
        self.current_volume = None
        self.update(self.client.get_volume())
        
    def update(self, state_hash):
        self.current_volume = state_hash.get('volume', 0)
        
    @property
    def name(self):
        return self._name
        
    @property
    def volume_level(self):
        return self.current_volume / 100.0
        
    @property
    def supported_features(self):
        return SUPPORT_THALLO
        
    def set_volume_level(self, volume):
        response = self.client.set_volume(int(volume * 100))
        self.update(response)

I adapted this script from the iTunes-integration. If I’m now trying to add it up to my config-file, I only get an error (Platform thallo not found):

media_player:
  - platform: thallo
    host: thallo
    port: 8080

Do you have any pointers to helping me out in this situation? Thanks in advance!

I actually solved the problem by stumbling across one extra information: The integration has to be placed inside of the folder custom_components/thallo. Now everything sort of runs. But there is still a lot to clarify. The question is the same: Does anyone know of any resources to be able to thoroughly learn about the development of addons?

Sincere greetings and thanks for your help!

Not sure what you mean by “drafts,” but there is quite a lot of documentation here: https://developers.home-assistant.io/