Using an input_number for scan_interval

I am trying to using an input_number so that I can vary the scan_interval time when I am refreshing the Maps from my Xiaomi when using Valetudo
I have tried to copy the bottom example using an input_number as a delay.

But I am getting an error when running it through the Configuration validation

My code:

input_number:

  mapdelay:
    name: mapdelay
    initial: 3600
    min: 1
    max: 3600
    step: 1
    icon: mdi:timer

sensor:
  - platform: rest
    resource: http://192.168.x.x/api/remote/map?drawRobot=true&drawCharger=true&scale=5&border=0&doCropping=true&drawPath=true
    name: RosiesMap
    value_template: '{{ value_json.mapsrc }}'
    scan_interval: '00:00:{{ states.input_number.mapdelay.state | int }}'

The error:

Invalid config for [sensor]: offset 00:00:{{ states.input_number.mapdelay.state | int }} should be format ‘HH:MM’ or ‘HH:MM:SS’ for dictionary value @ data[‘scan_interval’]. Got None. (See /config/configuration.yaml, line 61). Please check the docs at Sensor - Home Assistant

So I am a bit stuck, has anyone used an input_number before on a scan_interval or is it not possible?

Right, think I may have found part of the problem.
I have a decimal point and a zero after the number, probably need to figure out how to get rid of that?

Templates can’t be used in that location. What you are trying to do is impossible without a component change.

Also, that attribute doesn’t even exist for the rest sensor… not sure how you even got the idea to use that.

documentation:

available attributes for setup:

resource
(string)(Required)The resource or endpoint that contains the value.

Default value: string

method
(string)(Optional)The method of the request.

Default value: GET

name
(string)(Optional)Name of the REST sensor.

Default value: REST Sensor

value_template
(template)(Optional)Defines a template to extract the value.

payload
(string)(Optional)The payload to send with a POST request. Depends on the service, but usually formed as JSON.

verify_ssl
(boolean)(Optional)Verify the certification of the endpoint.

Default value: true

unit_of_measurement
(string)(Optional)Defines the units of measurement of the sensor, if any.

authentication
(string)(Optional)Type of the HTTP authentication. basic or digest.

username
(string)(Optional)The username for accessing the REST endpoint.

password
(string)(Optional)The password for accessing the REST endpoint.

headers
(list | string)(Optional)The headers for the requests.

json_attributes
(list | string)A list of keys to extract values from a JSON dictionary result and then set as sensor attributes.

force_update
(boolean)Sends update events even if the value hasn’t changed. Useful if you want to have meaningful value graphs in history.

Default value: false

notice how scan_interval doesn’t exist in the documentation?

Well it seems to be working fine if hard coded.

If i have scan_interval: 30 it updates the image location every 30 seconds and if i use scan_interval: 3600 it updates once an hour. I can confirm that by the time stamp on the images on my Vacuum.

It’s possible that the sensor base class has a scan_interval attribute/setup variable. But the fact still remains, templates can only exist in spots that allow templating.

And if scan_interval truely is an acceptable attribute, then it should be in the documentation… that’s misleading if it’s not.

image

At the min the scan_interval is set at 3600

Is there any other way of turning the rest sensor on / off?
Really I only want it to run once when HA starts up.
Then when my Vacuum is running turn the rest sensor back on again and have the scan_interval running at say 2 seconds so I have real time maps displayed.

I have tried putting the sensor in an automation but that didn’t work.

The problem is, you can’t change scan interval live. From my experience, it appears as if the scan interval is only built into the configuration and cannot be set during execution.

You may be able to do this in a python script. Meaning, create the sensor for a duration and then destroy it after it’s done.

Side question, why don’t you want it updating every 2 seconds all the time? Then it will know immediately when it’s on, or do you have a separate sensor for on/off?

I am using the standard Xiaomi platform on HA to control the Vacuum, so I can see from there if it’s running or not.

I am using Valetudo for the live maps as I could’t get dust cloud working with my Vacuum.
With Valetudo what you do is send a request like:

192.168.1.x/api/remote/map

You then get back something like:

{“scale”:4,“border”:8,“doCropping”:true,“drawPath”:true,“mapsrc”:"/maps/2018-08-29_15-57-24.png",“drawCharger”:true,“charger”:[516,588],“drawRobot”:true,“robot”:[516,573],“robotAngle”:270}

I am using:

value_template: '{{ value_json.mapsrc }}'

So I am just left with:

/maps/2018-08-29_15-57-24.png

Then I am using a generic camera to view the images:

camera:
  - platform: generic
    name: Vacuum Map
    still_image_url: http://192.168.x.x{{states.sensor.rosiesmap.state | string }}
    content_type: image/png
    framerate: 1

I didn’t want it running all the time as I don’t want to be writing to the flash on the Vacuum all the time from a wear point of view.

Couldn’t you just stop the image creation process in Valetudo when the vacuum is off? I mean you could build valetudo into home assistant as a custom component and handle the on/off there.

If your vacuum is already rooted and you know what you’re doing just download the latest valetudo binary from the releases page and scp it to /usr/local/bin/ . Then grab the valetudo.conf from the deployment folder put it inside /etc/init/ run service valetudo start and you’re good. Don’t forget to chmod +x the binary.

I think it would mean SSH’ing into the Vacuum to turn on an off the webserver every time I wanted to clean so I could get the maps.
it would be possible to fork the github and change it so it self updated the maps in the folder only when cleaning. But I wouldn’t know where to start.

Perhaps AppDaemon could be used instead to do the rest process?
Or would it behave the same as normal yaml and have the rest sensor polling the vacuum all the time?

I don’t know the answer to that.

Have you created a component before? The valetudo interface for the phone looked like it had a start/stop button. My assumption would be that the api has those methods as well.

Making a new component that has a start/stop service would suit your needs I think.

scan_interval is undocumented but valid for a RESTful sensor. However, you’re right, templates are not allowed there. And scan_interval is not an attribute of the sensor itself, so you can’t even force a change there.

My recommendation would be to write either a “shell_command” or a “python_script” that, when run, will fetch the resource and store the data in a sensor.

Then make two automations… both of them call your new script. One of them has a time trigger of every 3600 seconds. The other, a time trigger of every 30 seconds. Use automation.turn_off and automation.turn_on to turn on the 30 second trigger automation whenever you need the more frequent updating.

1 Like

Thanks @petro and @swiftlyfalling for the help so far.

I like the idea of the python_script I have never used python before but I am guessing a python_script is just normal python?

I am trying to piece together this Python Rest example and Python Scripts I have not tried this yet, but am I going in the right direction?

I am ok with the automation side of it I think, it’s more the python bit.

configuration.yaml

input_text:

  rosiesurl:
    name: rosiesurl
    icon: mdi:clipboard-text

camera:

  - platform: generic
    name: Vacuum Map
    still_image_url: http://192.168.x.x{{states.sensor.rosiesurl.state | string }}
    content_type: image/png
    framerate: 1

test_script.py

# importing the requests library
import requests
 
# api-endpoint
URL = "http://192.168.x.x/api/remote/map"
 
# sending get request and saving the response as response object
r = requests.get(url = URL)
 
# extracting data in json format
data = r.json()
 
# extracting the second half of the map URL 
imageurl = data['results'][0]['mapsrc']
 
# passing the output back to HASS
hass.services.call('entity_id:rosieurl', imageurl)

I don’t actually know if I need the [‘results’][0] part of imageurl = data[‘results’][0][‘mapsrc’] though?

:slight_smile:

A yea, that’s where I read about it :slight_smile:

Touche! That seems like a great spot for it! /s

Well… this is where it gets… a bit harder.

Yes, a python script is MOSTLY just normal python. However, it is a crippled python (in order to keep your script from doing “bad things”, I presume).

So, among many other things… you can’t use “import”. At all. Which will make this task difficult.

However, on the positive side… you can use a shell_script (instead of a python script) and that shell script can be in any language you want (including python), and it’ll have none of the crippled aspects of python_script… but… it’ll also not have access to any of the “easy to use” stuff that HASS Includes in its python libraries. It’s completely standalone. So… to set a sensor, for instance, you’re going to have to call Home Assistant’s REST API.

I can’t offer any input on what pieces of the json returned by the request you need because I have not seen the data nor do I know exactly what you’re trying to do. But… if you run this as a shell_command, that last line (hass.service.call…) will need to be the place where you call the Home Assistant REST API instead.

1 Like