Pass Sensor value to Python Script, process it and return back as another Sensor value

Hi!
I need to pass Air Quality parameters like PM2.5 PM10, NO, CO, etc that come from my existing Sensor in HA to Python Script, which calculates air quality index (AQI) and then passes the result to another (new) Sensor in HA.

I have experience of receiving Python script result and creating Sensor based on it, but can’t pass source parameter to Python script.

Here is how Python script looks like:

import aqi
myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, '8.21', algo=aqi.ALGO_EPA)
print(myaqi)

Instead ‘8.21’ I need to pass Sensor value that comes from HA.
and instead of ‘print’ I will input this parameter to HA in configuration.yaml like this with command_line platform:

    command: "python3 /config/python_scripts/py-aqi.py"

Any help is appreciated.
Thank you!

Take a look at the docs here. You can pass values to the python script with adding a data block to your service call and then access the data in the script with data.get().

I’m stuck with Python script even before using data.get().

My configuration:

  - platform: command_line
    name: AQI
    scan_interval: 200
    command_timeout: 30
    command: "python3 /config/python_scripts/py-aqi.py"

My script

import aqi
#pm25 = data.get("sensor.vozdukh_pm2_5")
myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, '2.22', algo=aqi.ALGO_EPA)
print(str(myaqi))

Value of sensor.AQI is unknown.
What can be the problem?
Python function returns normal Int value…

Pass the sensor’s value as an argument to your python script (not to be confused with the python_script integration). See Usage of templating in command

  - platform: command_line
    name: AQI
    scan_interval: 200
    command_timeout: 30
    command: "python3 /config/python_scripts/py-aqi.py {{states('sensor.vozdukh_pn2_5')}}"

In your python script, accept the passed argument using python’s sys runtime service. See Tutorialspoint: Python - Command line arguments

py-aqi.py

import sys
import aqi
pm25 = str(sys.argv[1])
myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, pm25, algo=aqi.ALGO_EPA)
print(str(myaqi))

NOTE
On startup, sensor.aqi might have an initial value of unknown but then should get a correct value when it starts polling.

1 Like

@123 Taras, thanks a lot for your advice, however, AQI sensor remains ‘unknown’ anyway.
I made both script and config as you mentioned.

Have you confirmed the script works by running it from the command line? If it doesn’t work like that then it definitely won’t work when Home Assistant calls it.

Go to the python_scripts directory and run:

python3 ./py-aqi.py 22

I’m sorry, I confused this with the python script integration as Taras pointed out.

I’m using HA under VM, so ‘python3’ cannot be executed via Terminal.
But I’m using another command_line platform python scripts in configuration.yaml and they work like a charm.

How did you install the python-aqi library that’s required by this script?

I used Python_Executor and got this message:

Collecting python-aqi
  Downloading python-aqi-0.6.1.tar.gz (9.0 kB)
Building wheels for collected packages: python-aqi
  Building wheel for python-aqi (setup.py): started
  Building wheel for python-aqi (setup.py): finished with status 'done'
  Created wheel for python-aqi: filename=python_aqi-0.6.1-py3-none-any.whl size=9658 sha256=eb713044c77bf4eab5b1b297461cda2ac2983c2d62d4c09280d144002b9fcadf
  Stored in directory: /root/.cache/pip/wheels/84/94/36/104051f1ca3d29d15c76f6830f128253bb2d8440e99b83aa9b
Successfully built python-aqi
Installing collected packages: python-aqi
Successfully installed python-aqi-0.6.1

When I look into logs now I see the following:

2020-09-08 21:54:53 ERROR (SyncWorker_2) [homeassistant.components.command_line.sensor] Command failed: python3 /config/python_scripts/py-aqi.py 5.5
2020-09-08 21:54:55 ERROR (MainThread) [frontend.js.latest.202007160] http://hassio.local:8123/frontend_latest/chunk.cf565e41b8a8dce0642a.js:133:238 Uncaught TypeError: Cannot read property 'header' of null
2020-09-08 21:54:55 INFO (MainThread) [custom_components.freeathome.pfreeathome] thermostat device ABB700D44BF7/ch0000 current temp is 28.1
2020-09-08 21:55:02 WARNING (SyncWorker_0) [homeassistant.components.python_script] Warning loading script py-aqi.py: Line None: Prints, but never reads 'printed' variable.
2020-09-08 21:55:02 INFO (SyncWorker_0) [homeassistant.components.python_script] Executing py-aqi.py: {}
2020-09-08 21:55:02 ERROR (SyncWorker_0) [homeassistant.components.python_script.py-aqi.py] Error executing script: __import__ not found
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/python_script/__init__.py", line 205, in execute
    exec(compiled.code, restricted_globals)
  File "py-aqi.py", line 1, in <module>
ImportError: __import__ not found

It states that actual parameter of PM2.5 is passed to the script correctly, though it finds error in ‘import’.
I use another Python script where I imported ‘requests’ same way and it works perfectly.
What can be wrong now?

I’m puzzled because that error message appears to be from the python_script integration which runs in a sandboxed environment and disallows importing of any library. Only an external python script, executed from the command line (which is what the command_line sensor does), can import libraries.

Well, nevertheless it imported the ‘python-aqi’ library.
Repeated attempt to install ‘python’aqi’ via python_executor in HA results in message that it’s already installed…
And, as I mentioned, I am having several scripts running with ‘import requests’, that was installed same way.
Any other idea?

I was able to get it to work on my test system.

My test system uses Home Assistant Container so I had to install the python-aqi library within the homeassistant docker container. I used Portainer to login into the container’s command line interface where I ran pip install python-aqi.

In order to make it easier to test, I used an input_number

input_number:
  aqi:
    name: Air Quality
    initial: 5
    max: 10
    min: 1
    step: 1

My command_line sensor refers to input_number.aqi.

  - platform: command_line
    name: aqi
    scan_interval: 200
    command_timeout: 30
    command: "python3 /config/python_scripts/py-aqi.py {{states('input_number.aqi')}}"

py-aqi.py is exactly the same as I posted earlier:

import sys
import aqi
pm25 = str(sys.argv[1])
myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, pm25, algo=aqi.ALGO_EPA)
print(str(myaqi))

After restarting Home Assistant, here’s the result:
Screenshot from 2020-09-08 15-38-13

If I increase the input_number’s value (and wait for the sensor to poll) the sensor reports a new calculated value:
Screenshot from 2020-09-08 15-47-22

So it does work but, due to a difference that’s not apparent, it doesn’t work for you. All I can suggest is that you review and compare the differences (if any) between how I configured it and how you did.

2 Likes

That’s strange…
During manual execution of my script via Python Executor result is:

Traceback (most recent call last):
  File "/share/py-aqi.py", line 2, in <module>
    import aqi
ModuleNotFoundError: No module named 'aqi'

As I mentioned above when I try to install ‘python-aqi’ it says it’s already installed.
How?

UPD:
When I point in Python Executor config the following:

code: /share/py-aqi.py 22
requirements:
  - python-aqi

I receive the result:

Requirement already up-to-date: python-aqi in /data/venv/lib/python3.7/site-packages (0.6.1)
WARNING: You are using pip version 20.0.2; however, version 20.2.3 is available.
You should consider upgrading via the '/data/venv/bin/python3 -m pip install --upgrade pip' command.
72

So it works!
After removing ‘python-aqi’ from requirements of this Add-on (after Hassio reboots), it reverts back to message

ModuleNotFoundError: No module named 'aqi'

When launching the script manually from Python Executor.

Is this some kind of temporary installation of ‘python-aqi’ via Python Executor?
How can I install it permanently?

I don’t know anything about “Python Executor”.

If you installed Home Assistant Supervised in a virtual machine, the python-aqi library must be installed in the homeassistant docker container. If you are installing the library in the host operating system, Home Assistant cannot access it.

Which installation method did you use?

I am using Home assistant VM under VirtualBox (VDI image from HA site). How can I install ‘python-aqi’ manually there?
Thanks!

The way I explained above, in the homeassistant docker container.

Once the library is installed in the homeassistant container, it will be available to Home Assistant. However, containers are temporary and are replaced when you upgrade Home Assistant. That means each time you perform an upgrade, you will have to re-install the python-aqi library.

I use Portainer to manage all the docker containers used by Home Assistant OS (and Home Assistant Supervised). Portainer allows me to open a console into the homeassistant container where I can run pip install python-aqi to install the library.

Screenshot from 2020-09-09 11-25-34

Portainer is available as an Add-on in Supervisor > Add-on Store > Home Assistant Community Add-ons > Portainer.

You could also take a look at appdaemon, there you can import libraries and they are not lost after an update of HA.

I have 0 containers as I’m using Hassio.
Is there smth I’m doing wrong with Portainer?