Control OpenHAB2 with Telegram and simple python script

you can start the script as a service like mosquitto

Thanks for your hint. Tried it by creating a file “TelegramMenu.service” with

[Unit]
Description=Start TelegramMenu
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/python /etc/openhab2/scripts/TelegramMenu.py
Restart=on-abort

[Install]
WantedBy=multi-user.target

and received the following error after starting the service:

[16:45:13] openhabian@openhabnew:/etc/systemd/system$ sudo systemctl status telegramMenu.service
● telegramMenu.service - Start TelegramMenu
   Loaded: loaded (/etc/systemd/system/telegramMenu.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sun 2018-08-26 16:45:13 CEST; 6s ago
  Process: 19196 ExecStart=/usr/bin/python /etc/openhab2/scripts/TelegramMenu.py (code=exited, status=1/FAILURE)
 Main PID: 19196 (code=exited, status=1/FAILURE)

Aug 26 16:45:13 openhabnew systemd[1]: Started Start TelegramMenu.
Aug 26 16:45:13 openhabnew python[19196]: Traceback (most recent call last):
Aug 26 16:45:13 openhabnew python[19196]:   File "/etc/openhab2/scripts/TelegramMenu.py", line 4, in <module>
Aug 26 16:45:13 openhabnew python[19196]:     import telebot
Aug 26 16:45:13 openhabnew python[19196]: ImportError: No module named telebot
Aug 26 16:45:13 openhabnew systemd[1]: telegramMenu.service: Main process exited, code=exited, status=1/FAILURE
Aug 26 16:45:13 openhabnew systemd[1]: telegramMenu.service: Unit entered failed state.
Aug 26 16:45:13 openhabnew systemd[1]: telegramMenu.service: Failed with result 'exit-code'.

The script works when I start it from the command line. What is wrong?

I’m guessing permissions/user/group, I will try this method on my setup. I guess you have added your own take on what the bot returns as information ?

VS code flags up many errors with the .rules, but it does work as the author states

gTemperature.members.forEach[ item | 
            if (item.state != NULL &&
                item.state != UNDEF &&
               // item.name != "Temperature" &&
               // item.name != "RFTemp" &&
                item.name != "FF_Bathroom_Extractor_Temperature") 
                {
                TempCount += 1
                if (AvgTemp = null) {AvgTemp = item.state} else {AvgTemp += item.state}
                if (MaxTemp = null) {MaxTemp = item.state; MaxTempSensorName = item.label} else if (MaxTemp < item.state) {MaxTemp = item.state; MaxTempSensorName = item.label}
                if (MinTemp = null) {MinTemp = item.state; MinTempSensorName = item.label} else if (MinTemp > item.state) {MinTemp = item.state; MinTempSensorName = item.label}
            }
        ]
Cannot refer to the non-final variable TempCount inside a lambda expression

Type mismatch: cannot convert from BigDecimal to Number

Type mismatch: cannot convert from DecimalType to boolean

Type mismatch: cannot convert from State to DecimalType

Type mismatch: cannot convert from State to Number

is VS code wrong or is its prefered method something different

I tried to launch it like mosquito too with the same issue than you, It didn’t work. So I have to launch it manually after reboot. This is one of the pending things to improve, but I haven’t had time to debug it

Where do you see that errors? I don’t have them

Anyway I edited original post to remove the details on how to compose the answer message as It is quite distractful

See attached, I have been searching for solutions, which there logical, but are they necessary ?

It works for me. Anyway this is my very own code for getting the list of current temperatures, it is just a use case, the purpose was only to show how to trigger a rule from telegram menu, this part of code I should have wrote just a “telegramSend(myBot, ‘Hello World’)”

By the way, how do you manage to have rule files problem advisor? I have the latest version of VS Add-on and It shows nothing…

I like the way your code cycles the gtemperatures Group and generates a status like feedback, very nice.

I am on ubuntu with I guess the latest, July 2018 v1.26 of VS code, openHAB 0.4.0 extension

the python code always responds from /menu with the icons,

on icon use it usually works with the correct response from openhab,

maybe a few uses here and there,

then comes python comes back with

2018-08-25 23:55:07,812 (util.py:65 PollingThread) ERROR - TeleBot: "ConnectionError occurred, args=(ProtocolError('Connection 
             aborted.', error(24, 'Too many open files')),)
23:36 < chod> Traceback (most recent call last):
23:36 < chod>  File "/usr/local/lib/python2.7/dist-packages/telebot/util.py", line 59, in run
23:36 < chod>    task(*args, **kwargs)
23:36 < chod>  File "/usr/local/lib/python2.7/dist-packages/telebot/__init__.py", line 277, in __retrieve_updates
23:36 < chod>    updates = self.get_updates(offset=(self.last_update_id + 1), timeout=timeout)
23:36 < chod>  File "/usr/local/lib/python2.7/dist-packages/telebot/__init__.py", line 247, in get_updates
23:36 < chod>    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates)
23:36 < chod>  File "/usr/local/lib/python2.7/dist-packages/telebot/apihelper.py", line 180, in get_updates
23:36 < chod>    return _make_request(token, method_url, params=payload)
23:36 < chod>  File "/usr/local/lib/python2.7/dist-packages/telebot/apihelper.py", line 54, in _make_request
23:36 < chod>    timeout=(connect_timeout, read_timeout), proxies=proxy)
23:36 < chod>  File "/home/chod/.local/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
23:36 < chod>    resp = self.send(prep, **send_kwargs)
23:36 < chod>  File "/home/chod/.local/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
23:36 < chod>    r = adapter.send(request, **kwargs)
23:36 < chod>  File "/home/chod/.local/lib/python2.7/site-packages/requests/adapters.py", line 415, in send
23:36 < chod>    raise ConnectionError(err, request=request)
23:36 < chod> ConnectionError: ('Connection aborted.', error(24, 'Too many open files'))
23:36 < chod> "
23:36 < chod> ^CTraceback (most recent call last):
23:36 < chod>  File "telegrammenu.py", line 53, in <module>
23:36 < chod> NameError: name 'sys' is not defined

As no one said this explicitly:

  1. With openHAB2, there is no state UNDEF but only NULL
  2. Cannot refer to the non-final variable TempCount inside a lambda expression is: you try to use the var TempCount within the lambda expression (everything between [ and ]), but TempCount is non-final, so you can’t do this. To get rid of this error, you have to do the var definition outside the rule (at the top of the rules-file)
  3. if (AvgTemp = null) -> this is wrong. = is “set the var or val on the left side to the value on the right side”, but you want to compare the left and the right side, so you have to use == instead.
    Even more, as you do the comparison to null, you have to use ===.
  4. it’s better to explicitly cast the type to Number

The rule part would be smarter if doing it this way:

gTemperature.members.filter[m|m.state instanceof Number].forEach[ item | 
    val Number temp = item.state as Number
    if (AvgTemp === null) 
        AvgTemp = temp
    else 
        AvgTemp += temp
    if (MaxTemp === null) MaxTemp = -273  // smallest possible temperarture ;)
    if (MaxTemp < temp) {
        MaxTemp = temp
        MaxTempSensorName = item.label
    }
    if (MinTemp === null) MinTemp = 1000 // at least, a higher temperature would be very unusual
    if (MinTemp > temp) {
        MinTemp = temp
        MinTempSensorName = item.label
    }
]
AvgTemp = AvgTemp / gTemperature.members.filter[m|m.state instanceof Number].size //get rid of TempCount

don’t include items in the group, which should not be taken into account (FF_Bathroom_Extractor_Temperature), otherwise you will need to count the items which are taken into account

3 Likes

That’s a very clever approach!

Regarding 2. Can’t be the var declared outside the lambda expression (i.e. before the gTemperature for each) instead of at the top of the rules-file?
3. Do you know why NULL is working for me (not null)? I can use both with the same result (null with === and NULL with ==)

The reason why I exclude items from the group by name is because I wan’t them to be in the temperatures group as I have many other things where all temp sensors are included (persistence, graphs, sitemap temperatures group, etc), only for this silly max, min and average what to exclude this couple of sensors that would have abnormal values compared with the rest. I could create an additional group where all but them was included, but I don’t think it worth it just for this silly rule.

By the way, I’m using VS Code v1.26.1, openHAB extension v 0.4.0 connecting to a RaspPi with OpenHAB v2.3 but I never saw “problems” within VS Code as @Chod does. Is there anything else special that have to be installed or configured to have such a code review recommendations? for python I does receive them (even though some are false, as the imports are working fine)

No, because then it’s non-final. The var simply isn’t defined in the lambda if not defined as global.

Well, it’s part of the allowed state list for Number. But if using vars it would be better to use null instead.

Exclude by name:

Well, then you will have to define the counter as a global var.

In question of code verification in VSCode: Did you setup the plugin correctly? Warning here: Code completion/verification is very slow, as soon as the amount of code grows. So it’s possible to get warnings for Code which is already correct or no warnings for incorrect code. You simply have to wait for VSCode to get ready :wink:

Is there any plan to include something like this in the Telegram action? Is this possible? Would this be useful? Is it even a good idea?

It feels like this could be an addition to the sendTelegram and sendTelegram commands already implemented.

I don’t think it is possible for an action (output only). This requires to actually polling the bot, so I guess it would need to be build as a binding. Maybe someday somebody can refactor the code and make it happen…

I think you are right.
I looked at the action yesterday and the custom keyboard should be relativly easy to implemented.
The problem would be: How to recognize what button is pressed.

I never build something for openhab. What would be an simple(!) maybe similar binding to look at?
Because I have no second raspberry, I have to come up with another development environment to develop and test drive everything? Are there any recommendations how other people are setting things up?

I don’t know Java so haven’t develop anything for OpenHAB yet and can’t tell what binding to look at as template, but for the other questions, you will know that button is pressed because in the button definition you specify a tag (callback_data) that is returned when the button is pressed, then whenever your binding polls Telegram API it will receive and event containing it so you will trigger a channel

Regarding the dev environment, the best setup I can recommend you is a virtual machine, so you can setup snapshots and tests things over and over

Hi @Dixon, I wrote a telegram-python-script too, but I didn’t want to post it here as I didn’t want to hijack your thread. That’s why I started another one:

Maybe you are interested to have a look at it.
Cheers,
Jochen

1 Like

Hey together,

i’m trying to set up this script but getting an error when I one of the menu buttons

I use mosquito from OH2 and the Mqtt broker is connected

2018-12-05 19:03:42.737 [INFO ] [penhab.io.transport.mqtt.MqttService] - MQTT Service initialization completed.
2018-12-05 19:03:42.742 [INFO ] [t.mqtt.internal.MqttBrokerConnection] - Starting MQTT broker connection 'broker'

So anyone have a hint for me ?

Cheers Ronny

For this issue and many other command line execs from openhab (e.g. to control my Broadlink RM) I finally added openhab user to sudoers group:

sudo visudo

And then place this line at the END of the file:

openhab ALL=(ALL) NOPASSWD:ALL

Save and exit (CTRL+X - Y - ENTER).

This should be enough. In my installation notes I see I also did:

Add openhab to sudo group

sudo usermod -aG sudo openhab

But I’m not sure this last step is necessary.

what would the best way of launching this and re launching when it bails with too many open files , or have (as usual) done something wrong