Skip to content

Commit

Permalink
added initial v2 support (#15)
Browse files Browse the repository at this point in the history
* added initial v2 support

* fixed linter errors

* added mode support for v2 and fixed speed handling
  • Loading branch information
hmn authored Nov 23, 2022
1 parent 872a947 commit dd0e81b
Show file tree
Hide file tree
Showing 17 changed files with 455 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"_template": "gh:oncleben31/cookiecutter-homeassistant-custom-component",
"class_name_prefix": "Siku",
"domain_name": "siku",
"friendly_name": "Siku RV Fan integration",
"friendly_name": "Siku Fan",
"github_user": "hmn",
"project_name": "hacs-siku-integration",
"test_suite": "yes",
Expand Down
3 changes: 1 addition & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
{
"image": "ghcr.io/ludeeus/devcontainer/integration:stable",
"name": "Siku RV Fan integration integration development",
"name": "Siku Fan integration development",
"context": "..",
"appPort": ["9123:8123"],
"postCreateCommand": "container install",
Expand All @@ -15,7 +15,6 @@
"settings": {
"files.eol": "\n",
"editor.tabSize": 4,
"terminal.integrated.shell.linux": "/bin/bash",
"python.pythonPath": "/usr/local/python/bin/python",
"python.analysis.autoSearchPaths": false,
"python.linting.pylintEnabled": true,
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pythonenv*
.coverage
venv
.venv
.DS_Store
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Siku RV Fan integration
# Siku Fan integration

[![GitHub Release][releases-shield]][releases]
[![GitHub Activity][commits-shield]][commits]
Expand All @@ -18,11 +18,21 @@

| Platform | Description |
| -------- | ----------- |
| `fan` | Siku RV Fan |
| `fan` | Siku Fan |

Integration for https://www.siku.at/produkte/ wifi fans

Tested on "SIKU RV 50 W Pro WIFI v1"
### Tested on

- "Siku RV 50 W Pro WIFI v1"
- ?

The fan is sold under different brands, for instance :

- Siku RV
- SIKU TwinFresh
- DUKA One
- Oxxify

## Installation

Expand All @@ -32,7 +42,7 @@ Tested on "SIKU RV 50 W Pro WIFI v1"
4. Download _all_ the files from the `custom_components/siku/` directory (folder) in this repository.
5. Place the files you downloaded in the new directory (folder) you created.
6. Restart Home Assistant
7. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Siku RV Fan integration"
7. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Siku Fan integration"

Using your HA configuration directory (folder) as a starting point you should now also have this:

Expand Down
4 changes: 2 additions & 2 deletions custom_components/siku/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""The Siku RV Fan integration."""
"""The Siku Fan integration."""
from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
Expand All @@ -17,7 +17,7 @@


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Siku RV Fan from a config entry."""
"""Set up Siku Fan from a config entry."""

coordinator = SikuDataUpdateCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
Expand Down
58 changes: 24 additions & 34 deletions custom_components/siku/api.py → custom_components/siku/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@
import logging
import socket

from .const import PACKET_POSTFIX
from .const import PACKET_PREFIX
from .const import DIRECTION_ALTERNATING
from .const import DIRECTIONS
from .const import FAN_SPEEDS

LOGGER = logging.getLogger(__name__)

FAN_SPEEDS = ["01", "02", "03"]
# forward = pull air out of the room
# reverse = pull air into the room from outside
# alternating = change directions (used for oscilating option in fan)
DIRECTION_FORWARD = "00"
DIRECTION_ALTERNATING = "01"
DIRECTION_REVERSE = "02"
DIRECTIONS = {
DIRECTION_FORWARD: "forward",
DIRECTION_ALTERNATING: "alternating",
DIRECTION_REVERSE: "reverse",
}
PACKET_PREFIX = bytes.fromhex("6d6f62696c65")
PACKET_POSTFIX = bytes.fromhex("0d0a")

COMMAND_STATUS = "01"
COMMAND_DIRECTION = "06"
COMMAND_SPEED = "04"
Expand All @@ -33,7 +28,7 @@
RESULT_POWER_OFF = "00"


class SikuApi:
class SikuV1Api:
"""Handle requests to the fan controller."""

def __init__(self, host: str, port: int) -> None:
Expand Down Expand Up @@ -102,28 +97,23 @@ async def _send_command(self, command: str) -> list[str]:
# enter the data content of the UDP packet as hex
packet_data = PACKET_PREFIX + packet_command + PACKET_POSTFIX

try:
# initialize a socket, think of it as a cable
# SOCK_DGRAM specifies that this is UDP
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) as s:
s.settimeout(10)

server_address = (self.host, self.port)
LOGGER.debug('sending "%s" to %s', packet_data, server_address)
s.sendto(packet_data, server_address)

# Receive response
data, server = s.recvfrom(4096)
LOGGER.debug('received "%s" from %s', data, server)

hexstring = data.hex()
hexlist = ["".join(x) for x in zip(*[iter(hexstring)] * 2)]
LOGGER.debug("returning hexlist %s", hexlist)
return hexlist
except Exception as ex:
raise Exception(
f"Error sending command to fan controller: {str(ex)}"
) from ex
# initialize a socket, think of it as a cable
# SOCK_DGRAM specifies that this is UDP
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) as s:
s.settimeout(10)

server_address = (self.host, self.port)
LOGGER.debug('sending "%s" to %s', packet_data, server_address)
s.sendto(packet_data, server_address)

# Receive response
data, server = s.recvfrom(4096)
LOGGER.debug('received "%s" from %s', data, server)

hexstring = data.hex()
hexlist = ["".join(x) for x in zip(*[iter(hexstring)] * 2)]
LOGGER.debug("returning hexlist %s", hexlist)
return hexlist

async def _translate_response(self, hexlist: list[str]) -> dict:
"""Translate response from fan controller."""
Expand Down
Loading

0 comments on commit dd0e81b

Please sign in to comment.