Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Attributes to a sensor device #27

Closed
wcomartin opened this issue Jan 14, 2021 · 14 comments
Closed

Add Attributes to a sensor device #27

wcomartin opened this issue Jan 14, 2021 · 14 comments
Labels
enhancement New feature or request

Comments

@wcomartin
Copy link

Would be really cool to have the ability to add attributes from the scrape to the sensor as well as have multiple sensors

for example if the webpage had a table of data, and you wanted other columns in the table to be attributes.

@danieldotnl danieldotnl transferred this issue from danieldotnl/hass-multiscrape Jun 8, 2021
@kongo09
Copy link

kongo09 commented Jun 8, 2021

Maybe this could be implemented similar to the rest integration https://www.home-assistant.io/integrations/rest/

For example, instead of generating five separate sensor for the same printer

# Dell Printer
multiscrape:
  - resource: !secret printer_status
    scan_interval: 900
    sensor:
      - name: Printer Toner Level Cyan
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(2) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
        unit_of_measurement: "%"
      - name: Printer Toner Level Magenta
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(4) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
        unit_of_measurement: "%"
      - name: Printer Toner Level Yellow
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(6) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
        unit_of_measurement: "%"
      - name: Printer Toner Level Black
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(8) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
        unit_of_measurement: "%"
  - resource: !secret printer_volume
    scan_interval: 900
    sensor:
      - name: Printer Volume
        select: "body > table > tr > td > table:nth-child(4) > tr > td > table > tr > td:nth-child(2) > font"
        value_template: '{{ value }}'
        unit_of_measurement: "pages"

it could be one sensor with a state for the number of pages and four attributes for toner levels. Maybe similar to this:

# Dell Printer
multiscrape:
  - sensor:
      name: Dell Printer
      value:
      - resource: !secret printer_volume
        scan_interval: 900
        name: Printer Volume
        select: "body > table > tr > td > table:nth-child(4) > tr > td > table > tr > td:nth-child(2) > font"
        value_template: '{{ value }}'
        unit_of_measurement: "pages"
      attributes:
      - name: Toner Level Cyan
        resource: !secret printer_status
        scan_interval: 900
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(2) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
      - name: Toner Level Magenta
        ​resource: !secret printer_status
        ​scan_interval: 900
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(4) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
      - name: Toner Level Yellow
        ​resource: !secret printer_status
        ​scan_interval: 900
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(6) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
      - name: Toner Level Black
        ​resource: !secret printer_status
        ​scan_interval: 900
        select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(8) > td:nth-child(1) > b"
        value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'

@DimkaInc
Copy link

DimkaInc commented Jun 8, 2021

how to release read attr paremeter?

multiscrape:
  - resource: !secret pwr_sw_address
    username: !secret pwr_sw_username
    password: !secret pwr_sw_password
    scan_interval: 5
    sensor:
      - name: relay_1
        select: "button[name=relayon1] ~ img"
        attribute: "src"
        value_template: '{{ value.split("light")[1].split(".jpg")[0] }}'

@kongo09
Copy link

kongo09 commented Jun 8, 2021

I realise that my example might be too complicated as it has several calls to different resources for one sensor. But in your example, how would you set state and more than one attribute to one sensor from the one resource?

@kongo09
Copy link

kongo09 commented Jun 10, 2021

What about this:

multiscrape:
  - resource: !secret pwr_sw_address
    username: !secret pwr_sw_username
    password: !secret pwr_sw_password
    scan_interval: 5
    sensor:
      - name: relay_1
        select: "button[name=relayon1] ~ img"
        value_template: '{{ value.split("light")[1].split(".jpg")[0] }}'
        attributes:
          - name: src
            select: "some selection"
            value_template: "some value template"
          - name: brand
            select: "some selection"
            value_template: "some value template"
          - name: model
            select: "some selection"
            value_template: "some value template"

So from one resource you get one or more sensors with states and each sensor can have several attributes with their own selections in addition to the state.

@DimkaInc
Copy link

And how do I get the sensor value then?
my config parsed structure like this:
<td><button name="relayon1" value="on">Open</button><button name="relayoff1" value="off">Close</button><button name="pulse1" value="pluse">Pulse</button> <img src="lightoff.jpg"></td>
and set the sensor value on or off depending on the image name. Do you propose to me to make several different values for one sensor?

@kongo09
Copy link

kongo09 commented Jun 10, 2021

Yes, that would be the idea. You have one main value representing the sensor. But then this sensor also has a number of additional attributes that come along with it.

@DimkaInc
Copy link

Today is not work.

@danieldotnl
Copy link
Owner

What about this:

multiscrape:
  - resource: !secret pwr_sw_address
    username: !secret pwr_sw_username
    password: !secret pwr_sw_password
    scan_interval: 5
    sensor:
      - name: relay_1
        select: "button[name=relayon1] ~ img"
        value_template: '{{ value.split("light")[1].split(".jpg")[0] }}'
        attributes:
          - name: src
            select: "some selection"
            value_template: "some value template"
          - name: brand
            select: "some selection"
            value_template: "some value template"
          - name: model
            select: "some selection"
            value_template: "some value template"

So from one resource you get one or more sensors with states and each sensor can have several attributes with their own selections in addition to the state.

Adding attributes in this way is indeed how I envision it.

@danieldotnl danieldotnl added the enhancement New feature or request label Jun 10, 2021
@danieldotnl
Copy link
Owner

@wcomartin thank you for your patience! Please check pre-release v4.1.0!

PS: And thank you for initiating the Kia Uvo integration :)

@kongo09
Copy link

kongo09 commented Jun 15, 2021

ok, will check, thanks

currently, with the latest 2021.6.4 multiscrape is broken for me. The previously working sensors stopped working. I'll try the pre-release and will report back and if the problem still exists open a separate issue.

@kongo09
Copy link

kongo09 commented Jun 15, 2021

Hm, I'm not entirely sure how the attributes are supposed to work. I tried this:

multiscrape:
  - resource: !secret printer_status
    scan_interval: 900
    sensor:
      - name: Printer Toner Level
        value_template: '{{ value }}'
        select: "body > table > tr > td > table:nth-child(10) > tr > td > table > tr:nth-child(2) > td:nth-child(2) > b"
        attributes:
          - name: Cyan
            select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(2) > td:nth-child(1) > b"
            value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
          - name: Magenta
            select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(4) > td:nth-child(1) > b"
            value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
          - name: Yellow
            select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(6) > td:nth-child(1) > b"
            value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'
          - name: Black
            select: "body > table > tr > td > table:nth-child(6) > tr > td > table > tr:nth-child(8) > td:nth-child(1) > b"
            value_template: '{{ value|regex_findall_index(find="(\d+)\%", index=0, ignorecase=False) }}'

and I get the following error:

2021-06-16 01:15:59 ERROR (MainThread) [homeassistant.components.sensor] Error adding entities for domain sensor with platform multiscrape
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 383, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 588, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 614, in add_to_platform_finish
    await self.async_added_to_hass()
  File "/usr/src/homeassistant/homeassistant/components/rest/entity.py", line 64, in async_added_to_hass
    self._update_from_rest_data()
  File "/config/custom_components/multiscrape/sensor.py", line 178, in _update_from_rest_data
    attr_value = self._scrape(
  File "/config/custom_components/multiscrape/entity.py", line 67, in _scrape
    value = value_template.async_render_with_possible_json_value(value, None)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 543, in async_render_with_possible_json_value
    self._ensure_compiled()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 571, in _ensure_compiled
    assert self.hass is not None, "hass variable not set on template"
AssertionError: hass variable not set on template
2021-06-16 01:15:59 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up multiscrape platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 258, in _async_setup_platform
    await asyncio.gather(*pending)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 383, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 588, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 614, in add_to_platform_finish
    await self.async_added_to_hass()
  File "/usr/src/homeassistant/homeassistant/components/rest/entity.py", line 64, in async_added_to_hass
    self._update_from_rest_data()
  File "/config/custom_components/multiscrape/sensor.py", line 178, in _update_from_rest_data
    attr_value = self._scrape(
  File "/config/custom_components/multiscrape/entity.py", line 67, in _scrape
    value = value_template.async_render_with_possible_json_value(value, None)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 543, in async_render_with_possible_json_value
    self._ensure_compiled()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 571, in _ensure_compiled
    assert self.hass is not None, "hass variable not set on template"
AssertionError: hass variable not set on template

@kongo09
Copy link

kongo09 commented Jun 16, 2021

Thanks, data is arriving well now. But there is still a bug - I'll file a new issue...

@danieldotnl
Copy link
Owner

danieldotnl commented Jun 16, 2021 via email

@wcomartin
Copy link
Author

You guys are awesome!! This is going to make my modem status scraping much simpler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants