Control KNX over OH with Snips

Hi Guys,

i want to control my OH KNX Items with Snips.
To use MQTT is a Workaround for me, hard to expand and maintain.

Now i found a Snips App from Paule https://gitlab.com/faupau/snips-lichtsteuerung-openhab-skill

This could be easy to expand and i possibly don´t need so much rules.
It is working great, but changes only my OH Items state and triggers not the item channel.

So the items change in OH but not on KNX, which is possibe with curl on the snips CLI.
I am not the Rest best :rofl: is there a possibility to change the python script and change also the channel state, or do i have to make a rule for each item?

Here is the script for switching on:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import configparser
from hermes_python.hermes import Hermes
from hermes_python.ffi.utils import MqttOptions
from hermes_python.ontology import *
import requests
import io
import json

translation_table = {           #translation table to replace german umlauts
    "ä": "ae",
    "ö": "oe",
    "ü": "ue",
    "Ü": "Ue",
    "Ö": "Oe",
    "Ä": "Ae"
}

CONFIGURATION_ENCODING_FORMAT = "utf-8"
CONFIG_INI = "config.ini"

class SnipsConfigParser(configparser.SafeConfigParser):
    def to_dict(self):
        return {section : {option_name : option for option_name, option in self.items(section)} for section in self.sections()}

def read_configuration_file(configuration_file):
    try:
        with io.open(configuration_file, encoding=CONFIGURATION_ENCODING_FORMAT) as f:
            conf_parser = SnipsConfigParser()
            conf_parser.readfp(f)
            return conf_parser.to_dict()
    except (IOError, configparser.Error) as e:
        return dict()

def subscribe_intent_callback(hermes, intentMessage):
    conf = read_configuration_file(CONFIG_INI)
    action_wrapper(hermes, intentMessage, conf)


def action_wrapper(hermes, intentMessage, conf):
    openhab_port = conf['global'].get("openhab_server_port")                #getting openhab port from config.ini
    openhab_server = conf['global'].get("openhab_server_url")               #getting openhab server ip from config.ini
    room = intentMessage.slots.deviceLocation.first().value                 #gets room slot
    room_without = room.translate(str.maketrans(translation_table))         #replaces german umlauts
    room_item = room_without
    room_item += "_light"
    response = requests.get('http://{}:{}/rest/items/{}'.format(openhab_server, openhab_port, room_item))
    response_string = json.loads(response.text)
    item_type = response_string.get('type')
    if item_type == 'Switch':
        command = "ON"
    elif item_type == 'Dimmer':
        command = "100"
    elif item_type == 'Color':
        command = "0, 0, 100"
    res = requests.put('http://{}:{}/rest/items/{}/state'.format(openhab_server, openhab_port, room_item), command) #sending command to openhab
    if res.status_code == 202:
        result_sentence = "Schalte das Licht in {} ein".format(str(room))
    else:
        result_sentence = "Das Eitem {} gibt es nicht. Bitte erstelle in Openhab ein Eitem mit dem Namen: {} unterstrich leiht!"
    current_session_id = intentMessage.session_id
    hermes.publish_end_session(current_session_id, result_sentence)

if __name__ == "__main__":
    conf = read_configuration_file(CONFIG_INI)
    mqtt_server = conf['global'].get("mqtt_server")
    mqtt_opts = MqttOptions()
    with Hermes("{}:1883".format(mqtt_server)) as h:
        h.subscribe_intent("Paule:LampenAnSchalten", subscribe_intent_callback) \
.start()

i hope anyone of the python/rest specialists could help me, because i think this can be the best way to control KNX Items with snips.
otherwise i have to make a rule for each state Change.

thx for help
Vaillan

Hi @vaillan,

I am no Python expert myself but I still think I can help you. If you want to trigger your item channels you need to send a command to your items and not just update their state: https://www.openhab.org/docs/configuration/rules-dsl.html#manipulating-item-states

According to the OpenHAB REST API you have to send a POST request instead of a PUT request. And according to the documentation of the Requests library (https://2.python-requests.org/en/master/user/quickstart/#make-a-request) you just need to change

res = requests.put('http://{}:{}/rest/items/{}/state'.format(openhab_server, openhab_port, room_item), command) #sending command to openhab

to

res = requests.post('http://{}:{}/rest/items/{}'.format(openhab_server, openhab_port, room_item), command) #sending command to openhab

Another OpenHAB app you can check out comes from Alpha200. It uses semantic tagging, like HABot and the other voice assisstants Alexa, Siri and Google: https://github.com/Alpha200/snips-openhab