dummylabs / thewatchman

Home Assistant custom integration to keep track of missing entities and actions in your config files
MIT License
476 stars 20 forks source link

Unable to send report via email after upgrading from 0.53 to 0.6 #53

Closed mwolter805 closed 1 year ago

mwolter805 commented 2 years ago

Prior to upgrading to 0.6, I was able to email a report with the service call below.

service: watchman.report
data:
  create_file: false
  send_notification: true
  parse_config: true
  service: notify.smtp_matt
  data:
    title: "Watchman Report"

Now I receive the following error Screen Shot 2022-06-17 at 2 03 55 PM And the following logs

2022-06-17 13:41:14 ERROR (MainThread) [homeassistant.components.automation.watchman_email_alert] While executing automation automation.watchman_email_alert
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/automation/__init__.py", line 521, in async_trigger
await self.action_script.async_run(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1513, in async_run
await asyncio.shield(run.async_run())
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 405, in async_run
await self._async_step(log_exceptions=False)
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 449, in _async_step
self._handle_exception(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 472, in _handle_exception
raise exception
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 447, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 680, in _async_call_service_step
await service_task
File "/usr/src/homeassistant/homeassistant/core.py", line 1627, in async_call
task.result()
File "/usr/src/homeassistant/homeassistant/core.py", line 1664, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/config/custom_components/watchman/__init__.py", line 234, in async_handle_report
await async_report_to_notification(
File "/config/custom_components/watchman/__init__.py", line 416, in async_report_to_notification
data = {} if service_data is None else json.loads(service_data)
File "/usr/local/lib/python3.9/json/__init__.py", line 339, in loads
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict

The only thing that changed in HA was updating watchman and I have verified the email notification service still works properly.

Let me know if more info is needed. Thank you

Pirol62 commented 2 years ago

I'm in the same boat: The script (no matter via developer tools or with automation):

- id: "20040"
  alias: "Execute Watchman monthly"
  trigger:
    - platform: time
      at: "04:00:00"
  condition:
    - condition: template
      value_template: "{{ now().day == 1 }}"
  action:
    - service: watchman.report
      data:
        send_notification: true

The error:

Dieser Fehler wurde von einer benutzerdefinierten Integration verursacht

Logger: homeassistant.helpers.script.websocket_api_script
Source: custom_components/watchman/__init__.py:416
Integration: Watchman (documentation, issues)
First occurred: 08:07:33 (2 occurrences)
Last logged: 08:07:43

websocket_api script: Error executing script. Unexpected error for call_service at pos 1: the JSON object must be str, bytes or bytearray, not dict
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 447, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 680, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1704, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1741, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/config/custom_components/watchman/__init__.py", line 234, in async_handle_report
    await async_report_to_notification(
  File "/config/custom_components/watchman/__init__.py", line 416, in async_report_to_notification
    data = {} if service_data is None else json.loads(service_data)
  File "/usr/local/lib/python3.9/json/__init__.py", line 339, in loads
    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict
mwolter805 commented 1 year ago

Updated to version 0.61 which had the same issue. Instead of using the watchman.report service to generate the email ended up making a template that pulls data from the watchman entities. Screenshot 2023-02-09 at 2 27 08 PM

alias: Watchman - Email Alert
description: ""
trigger:
  - platform: time
    at: "04:00:00"
condition:
  - condition: or
    conditions:
      - condition: numeric_state
        entity_id: sensor.watchman_missing_entities
        above: 0
      - condition: numeric_state
        entity_id: sensor.watchman_missing_services
        above: 0
action:
  - service: watchman.report
    data:
      create_file: true
      parse_config: true
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - service: notify.<NOTIFYICATION_SERVICE>
    data:
        title: "Watchman Report"
        message: "Watchman Report"
        data:
          html: |
            <h1 style="color: #404040; text-align: center;">Watchman Results</h1>
            <h2 style="color: #2e6c80;">Overall:</h2>
            <p>{{states('sensor.watchman_missing_entities') | int(0)}} missing entities.<br />{{states('sensor.watchman_missing_services') | int(0)}} missing services.</p>
            {% if states('sensor.watchman_missing_entities') | int(0) > 0 %}
            <table class="editorDemoTable" style="width: 100%;">
                <thead>
                    <tr style="height: 1em; color: #ffffff; background-color: #303030;">
                    <td style="height: 18px; text-align: center;">Entity ID</td>
                    <td style="height: 18px; text-align: center;">Missing From</td>
                    <td style="height: 18px; text-align: center;">Line #</td>
                    </tr>
                </thead>
                <tbody>
                    {%- for item in state_attr("sensor.watchman_missing_entities", "entities") %}
                    <tr style="height: 18px;">
                        <td>{{ item.id }}</td>
                        <td>{{item.occurrences.split('/')[-1].split(':')[0]}}</td>
                        <td>{{item.occurrences.split('/')[-1].split(':')[1]}}</td>
                    </tr>
                    {%- endfor %}
                </tbody>
            </table>
            {% endif %}
            <br>
            {% if states('sensor.watchman_missing_services') | int(0) > 0 %}
            <table class="editorDemoTable" style="width: 100%;">
                <thead>
                    <tr style="height: 1em; color: #ffffff; background-color: #303030;">
                    <td style="height: 18px; text-align: center;">Service ID</td>
                    <td style="height: 18px; text-align: center;">Missing From</td>
                    <td style="height: 18px; text-align: center;">Line #</td>
                    </tr>
                </thead>
                <tbody>
                    {%- for item in state_attr("sensor.watchman_missing_services", "entities") %}
                    <tr style="height: 18px;">
                        <td>{{ item.id }}</td>
                        <td>{{item.occurrences.split('/')[-1].split(':')[0]}}</td>
                        <td>{{item.occurrences.split('/')[-1].split(':')[1]}}</td>
                    </tr>
                    {%- endfor %}
                </tbody>
            </table>
            {% endif %}

mode: single