Allow the creation of RESTful Switch even when receiving a HTTP bad request from the API configured in the state_resource or the resource fields

Hi all,

I would like to propose changing the REstful Switch behavior when facing an HTTP bad request during its loading process.

Proposed change:

Current behavior:

Precondition: State providing API used in the RESTfull Switch is in an error state (404, 409, etc) and Home Assistant is rebooted

  • An error is included in the log
  • The switch entity is not created

Proposed behavior:

Precondition: State providing API used in the RESTfull Switch is in an error state (404, 409, etc) and Home Assistant is rebooted

  • An error is included in the log
  • The switch entity is created

Possible code changes:

File: https://github.com/home-assistant/core/blob/43b5dcff7631124e4509b6c951f3875ef7be905c/homeassistant/components/rest/switch.py
Current Code - Line 105:

        req = await switch.get_device_state(hass)
        if req.status >= HTTP_BAD_REQUEST:
            _LOGGER.error("Got non-ok response from resource: %s", req.status)
        else:
            async_add_entities([switch])

Proposed Code:
Current Code - Line 105:

        req = await switch.get_device_state(hass)
        if req.status >= HTTP_BAD_REQUEST:
            _LOGGER.error("Got non-ok response from resource: %s", req.status)     
        async_add_entities([switch])

Reason for prosing this

Right now I am trying to create a RESTful switch to control a plugging called PSU Control. I manage to get the switch up and running (configuration.yaml extract bellow) however I need to have the printer connected to octoprint when I restart Home Assistant because the Octoprint state API return 409 (details bellow)

switch:
  # Ender 3 Control
  
  # Ender 3 - PSU Control - Power Control
  - platform: rest
    resource: http://ender3.local/api/plugin/psucontrol
    state_resource: http://ender3.local/api/printer
    name: "Ender 3 - Power"
    body_on: '{"command": "turnPSUOn"}'
    body_off: '{"command": "turnPSUOff"}'
    is_on_template: "{{ value_json.state.flags.operational }}"
    headers:
      Content-Type: application/json
      X-Api-Key: 234844E83675497EBB4593AD4D8086C0
    verify_ssl: false

**API response when the printer is not connected **
Response code 404 or 409

{
  "error":"Printer is not operational"
}

**API response when the printer is connected **

{
  "sd":{
    "ready":false
  },
  "state":{
    "error":"",
    "flags":{
      "cancelling":false,
      "closedOrError":false,
      "error":false,
      "finishing":false,
      "operational":true,
      "paused":false,
      "pausing":false,
      "printing":false,
      "ready":true,
      "resuming":false,
      "sdReady":false
    },
    "text":"Operational"
  },
  "temperature":{
    
  }
}

Another use case that support this change is:

  • A user has REST devices connected to his network using WIFI;
  • The user creates RESTfull switches using the Wifi connected REST API
  • User wifi network is down
  • User restart Home Assistant while the wifi is down

In this case all RESTfull switches would disappear, and wouldn’t be recreated until the user restart his Home Assistant server after restoring Wifi. If the RESTfull swiches were created even with the wifi connected REST devices down, when the wifi was restored those switches would restart working.

What do you all think about this? Is there a deeper reason for not creating the RESTfull Switches? when getting an error from the API?

Let me know if you think it is a good idea, that I can take a stab in making this code change, it may take a while as I have no idea how to set up a Home Assistant development environment (I am reading the documentation right now)

Hi @gmlupatelli, I’d even go further than “just” the behavior change at switch creation time: I think RESTful switches should be able to deal with any http error at any time and provide a clean behavior.

Here’s my use-case:
My mac office computer has a little webhook server running, allowing me to request some state and even execute scripts from the HA REST platform. The office computer is running most of the time, but not always (it’s often in standby/sleep where it doesn’t answer HA’s rest requests).

The current behavior is such that the rest platform logs a lot of errors whenever the mac doesn’t answer because it is in standby (I guess if I were to restart HA during those times, the switch would disappear - which makes it related to your feature request).

However, I’d like HA to just make the switch unavailable but don’t log errors and don’t remove it when it gets != 200 responses from the rest server. This should also include any tcp errors like timeout, connection refused, host not found,…

Making error hebavior configurable would allow backwards compatibility if required.

Best regards,
Mike