ZacheryThomas / homeassistant-smartrent

Home Assistant Custom Component for SmartRent Locks πŸ”, Thermostats 🌑, Sensors πŸ’§ and SwitchesπŸ’‘
MIT License
84 stars 3 forks source link

feature: light switches #4

Closed smalls89 closed 2 years ago

smalls89 commented 2 years ago

Is there anyway to implement light switches?

From what I've gathered, the majority of smart rent installations only have a lock and a thermostat, mine happens to have a couple switches as well.

ZacheryThomas commented 2 years ago

Im sure it would be possible! Unfortunately my installation doesn't have switches πŸ˜…

If I could get the right info theoretically it wouldn't be too hard to add though 🀞. I could probs help you out if you are willing / able to run some python commands.

smalls89 commented 2 years ago

sure, let me know what I need to do

ZacheryThomas commented 2 years ago

In general you are gonna need two python libraries:requests and websockets. If you run the code it wherever you are running homeassistant it should already have those two things though.

So you are gonna have to run two separate scripts and help me interpret the output.

Script 1:

This is to get the general device info related to your particular setup. You should run this and provide the output to me (feel free to change your ID numbers to something random before posting to me for security).

This script will also print out some information you will need in the next step as well. After you run the script it should print out a JSON object that contains a lot of info along with out some ID number for your switch device. You are gonna add that info to the sec script.

SMARTRENT_BASE_URI     = 'https://control.smartrent.com/api/v2/'
SMARTRENT_SESSIONS_URI = SMARTRENT_BASE_URI + 'sessions'
SMARTRENT_HUBS_URI     = SMARTRENT_BASE_URI + 'hubs'
SMARTRENT_HUBS_ID_URI  = SMARTRENT_BASE_URI + 'hubs/{}/devices'

import requests
import json

email = '<YOUR EMAIL HERE>'
password = '<YOUR PASSWORD HERE>'

res = requests.post(SMARTRENT_SESSIONS_URI, json={
    'email': email,
    'password': password
}).json()

token = None
if not res.get('errors'):
    token = res['access_token']

headers={
    'authorization': f'Bearer {token}'
}

hubs = requests.get(
    SMARTRENT_HUBS_URI,
    headers=headers
).json()

for hub in hubs:
    devices = requests.get(
        SMARTRENT_HUBS_ID_URI.format(hub['id']),
        headers=headers
    ).json()

    output = json.dumps(devices, indent=4)
    print(output)

Script 2

This script will track changes in status for a given device. You should be able to get the device ID from the previous step and paste that number where it says device_id = '<DEVICE ID FROM PREV STEP>'

Once you start the script, you can then turn your light switch on and off and see what output is provided.

You can send me the logs from this step as well along with notes about what actions you did.

import json
import asyncio

import requests
import websockets

email = '<YOUR EMAIL HERE>'
password = '<YOUR PASSWORD HERE>'
device_id = '<DEVICE ID FROM PREV STEP>'

SMARTRENT_BASE_URI     = 'https://control.smartrent.com/api/v2/'
SMARTRENT_SESSIONS_URI = SMARTRENT_BASE_URI + "sessions"
JOINER_PAYLOAD = '["null", "null", "devices:{device_id}", "phx_join", {{}}]'
SMARTRENT_WEBSOCKET_URI = (
    "wss://control.smartrent.com/socket/websocket?token={}&vsn=2.0.0"
)

async def main():
    res = requests.post(SMARTRENT_SESSIONS_URI, json={
        'email': email,
        'password': password
    }).json()

    token = None
    if not res.get('errors'):
        token = res['access_token']
    else:
        print('Error occurred when logging in...')
        print(res.get('errors'))
        exit()

    uri = SMARTRENT_WEBSOCKET_URI.format(token)

    async with websockets.connect(uri) as websocket:

        joiner = JOINER_PAYLOAD.format(device_id=device_id)
        print(f"Joining topic for {device_id}...")
        await websocket.send(joiner)

        while True:
            resp = await websocket.recv()

            formatted_resp = json.loads(f"{resp}")[4]

            event_type = formatted_resp.get("type")
            event_name = formatted_resp.get("name")
            event_state = formatted_resp.get("last_read_state")
            if event_type:
                print(f'{event_type:<20}{event_name:<20}{event_state}')
            else:
                print(formatted_resp)

asyncio.run(main())

Do let me know if you have any issues / questions!

smalls89 commented 2 years ago

I didn't have any trouble with this at all, was actually expecting at least one error along the line lol

Hopefully this is what you need for a light switch, and maybe a leak sensor lol

Other topics to touch on, I forgot there is a leak sensor here so I ran that as well. I noticed the included thermostat widget doesn't have a humidity readout, or I haven't found it at least

Switch:

{
        "attributes": [
            {
                "last_read_at": "2022-02-09T04:06:11Z",
                "name": "on",
                "state": "false"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": 1096643,
        "inserted_at": "2020-07-09T23:35:11",
        "name": "Dining Room",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "hub_id": redact,
            "icon": null,
            "id": redact,
            "inserted_at": "2020-07-09T23:24:25.752127",
            "name": "No Room",
            "updated_at": "2020-07-09T23:24:25.752127"
        },
        "show_on_dashboard": true,
        "type": "switch_binary",
        "updated_at": "2022-02-03T22:26:09",
        "valid_config": true,
        "warning": false
}

========== RESTART: C:...\s2.py ========== Joining topic for 1096643... {'response': {}, 'status': 'ok'} OnOff on true OnOff on false OnOff on true OnOff on false

Water leak sensor :

{
        "attributes": [
            {
                "last_read_at": "2022-02-03T04:35:08Z",
                "name": "leak",
                "state": "false"
            }
        ],
        "battery_level": 91,
        "battery_powered": true,
        "icon": null,
        "id": 1096629,
        "inserted_at": "2020-07-09T23:32:47",
        "name": "Water Heater - Leak Sensor",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "hub_id": redact,
            "icon": null,
            "id": redact,
            "inserted_at": "2020-07-09T23:24:25.752127",
            "name": "No Room",
            "updated_at": "2020-07-09T23:24:25.752127"
        },
        "show_on_dashboard": true,
        "type": "sensor_notification",
        "updated_at": "2022-02-10T12:45:30",
        "valid_config": true,
        "warning": false
}

========== RESTART: C:...\s2.py ========== Joining topic for 1096629... {'response': {}, 'status': 'ok'} Notifications leak true Notifications leak false Notifications leak true Notifications leak false

Thermostat JSON:

{
        "attributes": [
            {
                "last_read_at": "2022-02-10T12:28:46Z",
                "name": "mode",
                "state": "heat"
            },
            {
                "last_read_at": "2022-02-09T14:06:52Z",
                "name": "cooling_setpoint",
                "state": "70"
            },
            {
                "last_read_at": "2022-02-09T14:06:51Z",
                "name": "heating_setpoint",
                "state": "70"
            },
            {
                "last_read_at": "2022-02-09T18:10:32Z",
                "name": "fan_mode",
                "state": "auto"
            },
            {
                "last_read_at": "2022-02-10T15:59:28Z",
                "name": "current_humidity",
                "state": "40"
            },
            {
                "last_read_at": "2022-02-10T15:59:26Z",
                "name": "current_temp",
                "state": "72"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": 1096615,
        "inserted_at": "2020-07-09T23:29:20",
        "name": "Thermostat",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "hub_id": redact,
            "icon": null,
            "id": redact,
            "inserted_at": "2020-07-09T23:24:25.752127",
            "name": "No Room",
            "updated_at": "2020-07-09T23:24:25.752127"
        },
        "show_on_dashboard": true,
        "type": "thermostat",
        "updated_at": "2022-02-08T00:19:45",
        "valid_config": true,
        "warning": false
}
ZacheryThomas commented 2 years ago

Thanks so much! This looks great! Lol I def was scared to get my own leak sensor wet so i'm glad you gave me that data πŸ˜…

I'll probably have something cooked up by next week at least for the leak sensor and the switch!

As for the humidity thing, I'm not sure why it doesn't show up in the homeassistant climate widget. I do have support for at least getting that info.

ZacheryThomas commented 2 years ago

So I ended up updating the code to support Leak Sensors and Binary Switches. Let me know if it works for you / if you have any issues!

smalls89 commented 2 years ago

confirmed, all work, being cloud based they are very slow sometimes

I don't get the sensor wet, I just touch 2 leads with something metal, of all the times I've done it, the office has never said anything

saw this was to a smartrent lib listing known working make models, I have the same lock and thermostat light switches: Jasco ZW4008 leak sensor: Alloy SmartHome Leak Sensor ah-nas-ws02z.us << reads like a url but is the part number

ZacheryThomas commented 2 years ago

Great! Glad to hear things are working out (even if it is a bit slow).

Thanks so much for providing all the logs and device info. It was a big help!

AppleTechy commented 2 years ago

Hello, I know this is a closed issue but I was hoping you might be willing to re-open to get support for dimmable light switches.

Here is the output from Script 1: (I did however re-list the specific device's attributes under script 2 for the multi-level switch.

[
    {
        "attributes": [
            {
                "last_read_at": "2022-09-14T04:56:12Z",
                "name": "cooling_setpoint",
                "state": "73"
            },
            {
                "last_read_at": "2022-08-18T20:37:50Z",
                "name": "fan_mode",
                "state": "auto"
            },
            {
                "last_read_at": "2022-09-14T16:12:30Z",
                "name": "current_humidity",
                "state": "56"
            },
            {
                "last_read_at": "2022-09-14T04:53:01Z",
                "name": "operating_state",
                "state": "off"
            },
            {
                "last_read_at": "2022-09-14T04:56:12Z",
                "name": "heating_setpoint",
                "state": "66"
            },
            {
                "last_read_at": "2022-08-07T13:24:20Z",
                "name": "mode",
                "state": "cool"
            },
            {
                "last_read_at": "2022-09-14T16:16:20Z",
                "name": "current_temp",
                "state": "73"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-03-14T17:27:08",
        "name": "Thermostat",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "thermostat",
        "updated_at": "2022-07-19T13:30:32",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "last_read_at": "2022-09-11T22:45:08Z",
                "name": "level",
                "state": "0"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-07-19T14:00:45",
        "name": "Hallway",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "switch_multilevel",
        "updated_at": "2022-07-19T16:32:41",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "last_read_at": "2022-03-14T17:30:20Z",
                "name": "leak",
                "state": "false"
            }
        ],
        "battery_level": 100,
        "battery_powered": true,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-03-14T17:30:03",
        "name": "Washer - Leak Sensor",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "sensor_notification",
        "updated_at": "2022-08-26T11:08:39",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "last_read_at": "2022-03-14T17:31:00Z",
                "name": "leak",
                "state": "false"
            }
        ],
        "battery_level": 100,
        "battery_powered": true,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-03-14T17:30:41",
        "name": "Water Heater - Leak Sensor",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "sensor_notification",
        "updated_at": "2022-09-03T12:44:16",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "last_read_at": "2022-09-14T02:04:44Z",
                "name": "level",
                "state": "0"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-07-19T13:58:31",
        "name": "Kitchen",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "switch_multilevel",
        "updated_at": "2022-07-19T16:22:18",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "name": "access_codes_supported",
                "state": "true"
            },
            {
                "last_read_at": "2022-09-14T16:23:59Z",
                "name": "locked",
                "state": "true"
            },
            {
                "last_read_at": "2022-09-14T16:24:02Z",
                "name": "notifications",
                "state": "ALARM_TYPE_24_LEVEL_1"
            }
        ],
        "battery_level": 77,
        "battery_powered": true,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-03-14T17:22:58",
        "name": "Front Door - Lock",
        "online": true,
        "pending_update": false,
        "primary_lock": true,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "entry_control",
        "updated_at": "2022-09-14T11:00:55",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "last_read_at": "2022-09-14T15:59:24Z",
                "name": "level",
                "state": "28"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-07-19T14:02:45",
        "name": "Bedroom",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "switch_multilevel",
        "updated_at": "2022-07-19T16:28:43",
        "valid_config": true,
        "warning": false
    },
    {
        "attributes": [
            {
                "last_read_at": "2022-09-14T05:51:37Z",
                "name": "level",
                "state": "0"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-07-19T14:04:30",
        "name": "Living Room",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "switch_multilevel",
        "updated_at": "2022-07-19T16:33:52",
        "valid_config": true,
        "warning": false
    }
]

Script 2: The light was initially off. I turned it on and it defaulted to the last known brightness setting (47). I then turned the brightness all the way up. I then turned the light back off.

{'response': {}, 'status': 'ok'}
LevelControl        level               47
LevelControl        level               100
LevelControl        level               0

So from script one it is the last device above:

    {
        "attributes": [
            {
                "last_read_at": "2022-09-14T05:51:37Z",
                "name": "level",
                "state": "0"
            }
        ],
        "battery_level": null,
        "battery_powered": false,
        "icon": null,
        "id": <redacted>,
        "inserted_at": "2022-07-19T14:04:30",
        "name": "Living Room",
        "online": true,
        "pending_update": false,
        "primary_lock": false,
        "room": {
            "deleted_at": null,
            "hub_id": <redacted>,
            "icon": null,
            "id": -1,
            "inserted_at": null,
            "name": "No Room",
            "remote_id": null,
            "remote_marketing_name": null,
            "unit_id": null,
            "updated_at": null
        },
        "show_on_dashboard": true,
        "type": "switch_multilevel",
        "updated_at": "2022-07-19T16:33:52",
        "valid_config": true,
        "warning": false
    }

Though, I have only been running your component for about a day it seems to be working while abate without my lights which I use the most. If you are tracking what types of Locks/Lights/Leak Sensors/ Thermostats seem to be working: Yale Assure Lock SL, HoneyWell Thermostat( TH6320ZW2003), the light switches look to be GE/JASCO but I haven't taken one off the wall yet, Leak Sensors are Dome by ELEXA.

ZacheryThomas commented 2 years ago

@AppleTechy hi! Im down to take a look at adding dimmable switches. I made another issue to track this for now: https://github.com/ZacheryThomas/homeassistant-smartrent/issues/9