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

Looks like it uses openHAB REST API to transmit status changes to OH. Sounds like you want to use REST API to send commands instead.

thx for Reply

Yes that´s Right.

But just using post instead of put, doesn´t Change anything.
Is it possible to send a rest call out of a python script like curl does?

This app would be easy to use for all snips, OH and KNX user.
But i am not able to change the script, that commands to knx also works.
Is that possible, otherwise i have to make a rule for each Status Change.

best regards
Vaillan

No.
You should look at the REST API utility and have a play.

I have no understanding of what your script does, but this
res = requests.put('http://{}:{}/rest/items/{}/state'.format ...
is about sending state updates to OH Item.

This
res = requests.put('http://{}:{}/rest/items/{}/'.format ...
would send a command to OH Item instead. The URL.is different.

i also tried that yesterday.
But i will give it another try, and give Feedback.

best regards
vaillan

Let’s review what you are doing, because i may have misunderstood.
You have some scripts that use REST to send state updates to openHAB Items.
Those same Items are also configured with KNX channels, yes?
But because the update is only a state change, the new information is not sent from OH to KNX - because that is normally triggered by an OH command, not a state change.
So all you want to do is modify your scripts to send REST commands to OH instead of state updates.

you got it.

This script from paule only requires that a OH Item Ends with _light.
And so it is much easier as the other OH integartions with MQTT Manipulation rules.

If it is now possible, to trigger a command out of the rest call, this would be the easiest way to let snips communicate with my knx.

This script is only for turning on Lights, there are serveral more but the logic is the same.

Hope you can help me.

Same