jbergler / hass-ttlock

Home Assistant integration for TTLock locks
68 stars 13 forks source link

auto_lock_seconds set to -1 even though lock is relocking after 5 seconds #67

Open jbergler opened 1 year ago

jbergler commented 1 year ago

"Can you double check that you've setup the webhook correctly, and if you're still not seeing the "Last Operator" and "Last Trigger" sensors updating please open an issue with some logs."

This happend to me too and I did not set up the webhook correctly.

Step 5 and 6: Once the integration is working you should receive a system notification with the webhook url This will go away when the webhook receives data Go back to the url from the first step and set the 'Callback URL' for your application

Webhook has been setup correctly. "Last Operator" and "Last Trigger" sensors are updating just fine... the coordinator.py has
auto_lock_seconds: int = -1 on line 41 that I have change from -1 to 5 seconds thinking that it would enable the auto-lock... so the lock status would automatically change to locked after 5 seconds but that was not case...

Originally posted by @ronluna in https://github.com/jbergler/hass-ttlock/issues/1#issuecomment-1693990934

jbergler commented 1 year ago

@ronluna can you enable debug logging for the integration and then reload it from the UI. The logs would then have the raw data coming back from the TTLock api which will help confirm if we can do anything about this or if this is a bug in ttlocks software.

ronluna commented 1 year ago

Apologies for the late reply.

There is nothing interesting in the logs: 2023-09-15 11:50:28.150 DEBUG (MainThread) [custom_components.ttlock.coordinator] Finished fetching ttlock data in 20.060 seconds (success: True) 2023-09-15 12:01:06.876 DEBUG (MainThread) [custom_components.ttlock.api] [6b2a] Sending request to https://euapi.ttlock.com/v3/lock/unlock with args={'lockId': XXXXXXX} 2023-09-15 12:01:16.680 DEBUG (MainThread) [custom_components.ttlock.api] [6b2a] Received response: status=200: body={'errcode': 0, 'errmsg': 'none error message or means yes', 'description': '表示成功或是'}

image Screen Shot 2023-09-15 at 12 04 01 PM image
jbergler commented 1 year ago

No worries, I'm also reasonably busy at the moment so sorry I didn't get back to you for a month.

The lock doesn't generate a "locked" event when it's configured to auto-lock, so the way the auto-lock works in the integration is to parse that auto lock value from the lock and store it in that variable. If the field has any value in the API response then your local changes will get overridden.

What I'd need to make progress on this is the debug logs from when the lock is initially discovered by the integration (the request to /lock/detail) so that I can try and reconstruct the state the lock has in memory.

It would also help if you could share the info from the 'download diagnostics' button in your screenshot.

ronluna commented 1 year ago

Thanks for replying though, Here it is:

{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.10.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.5",
    "docker": true,
    "arch": "x86_64",
    "timezone": "America/New_York",
    "os_name": "Linux",
    "os_version": "6.1.56",
    "supervisor": "2023.10.0",
    "host_os": "Home Assistant OS 11.0",
    "docker_version": "24.0.6",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "fpl": {
      "version": "1.0.0",
      "requirements": [
        "integrationhelper"
      ]
    },
    "hacs": {
      "version": "1.33.0",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "ttlock": {
      "version": "v0.5.4",
      "requirements": [
        "pydantic"
      ]
    },
  "integration_manifest": {
    "domain": "ttlock",
    "name": "TTLock",
    "after_dependencies": [
      "cloud"
    ],
    "codeowners": [
      "@jbergler"
    ],
    "config_flow": true,
    "dependencies": [
      "application_credentials",
      "persistent_notification",
      "webhook"
    ],
    "documentation": "https://github.com/jbergler/hass-ttlock",
    "homekit": {},
    "iot_class": "cloud_polling",
    "issue_tracker": "https://github.com/jbergler/hass-ttlock/issues",
    "requirements": [
      "pydantic"
    ],
    "ssdp": [],
    "version": "v0.5.4",
    "zeroconf": [],
    "is_built_in": false
  },
  "data": {
    "config_entry": {
      "entry_id": "d9cc93f60d437aee25280baa0508d145",
      "version": 1,
      "domain": "ttlock",
      "title": "CtrlableAccessControlCloud",
      "data": {
        "auth_implementation": "ttlock_0fd1ea0822dd41efad9ef38ac7bd6549",
        "token": "**REDACTED**",
        "webhook_id": "ce307c29eb2a368e607897490581ea13419ccd0fb7831d68eb922cd4c46c25a7",
        "webhook_status": true
      },
      "options": {},
      "pref_disable_new_entities": false,
      "pref_disable_polling": false,
      "source": "user",
      "unique_id": null,
      "disabled_by": null
    },
    "locks": [
      {
        "unique_id": "ttlock-1487174",
        "device": {
          "name": "Front Office",
          "mac": "D7:97:81:B6:E0:6F",
          "model": "SN149-BL01_PV53",
          "battery_level": 100,
          "hardware_version": "1.6",
          "firmware_version": "4.3.1.190115",
          "features": 316647,
          "locked": false,
          "action_pending": false,
          "last_user": null,
          "last_reason": null,
          "auto_lock_seconds": -1,
          "passage_mode_config": {
            "__type": "<class 'custom_components.ttlock.models.PassageModeConfig'>",
            "repr": "PassageModeConfig(enabled=<OnOff.off: 2>, start_minute=0, end_minute=0, all_day=<OnOff.unknown: 0>, week_days=[], auto_unlock=<OnOff.off: 2>)"
          }
        },
        "entities": [
          {
            "entity_id": "lock.front_office",
            "state": "unlocked",
            "attributes": {
              "friendly_name": "Front Office",
              "supported_features": 0
            },
            "last_changed": "2023-10-16T13:14:44.558687+00:00",
            "last_updated": "2023-10-16T13:14:44.558687+00:00",
            "context": {
              "id": "01HCW9ZRYENAAPSYC5PX8QXJHV",
              "parent_id": null,
              "user_id": null
            }
          },
          {
            "entity_id": "sensor.front_office_battery",
            "state": "100",
            "attributes": {
              "unit_of_measurement": "%",
              "device_class": "battery",
              "friendly_name": "Front Office Battery"
            },
            "last_changed": "2023-10-16T12:43:39.370090+00:00",
            "last_updated": "2023-10-16T12:43:39.370090+00:00",
            "context": {
              "id": "01HCW86VFAS44BGTXQ7DWYVH2M",
              "parent_id": null,
              "user_id": null
            }
          },
          {
            "entity_id": "sensor.front_office_last_operator",
            "state": "Unknown",
            "attributes": {
              "friendly_name": "Front Office Last Operator"
            },
            "last_changed": "2023-10-16T12:43:39.372797+00:00",
            "last_updated": "2023-10-16T12:43:39.372797+00:00",
            "context": {
              "id": "01HCW86VFCSW35WAW3B9CBJY1A",
              "parent_id": null,
              "user_id": null
            }
          },
          {
            "entity_id": "sensor.front_office_last_trigger",
            "state": "Unknown",
            "attributes": {
              "friendly_name": "Front Office Last Trigger"
            },
            "last_changed": "2023-10-16T12:43:39.375151+00:00",
            "last_updated": "2023-10-16T12:43:39.375151+00:00",
            "context": {
              "id": "01HCW86VFF8PX8WPQ1Q7PWWYAK",
              "parent_id": null,
              "user_id": null
            }
          },
          {
            "entity_id": "binary_sensor.front_office_passage_mode",
            "state": "off",
            "attributes": {
              "friendly_name": "Front Office Passage Mode"
            },
            "last_changed": "2023-10-16T12:43:39.404813+00:00",
            "last_updated": "2023-10-16T12:43:39.404813+00:00",
            "context": {
              "id": "01HCW86VGCS1XGRWD0Y3PTPSNJ",
              "parent_id": null,
              "user_id": null
            }
          }
        ]
      }
    ]
  }
}
jbergler commented 1 year ago

It's definitely parsing -1 in whatever it gets back from the API. Are you able to turn on debugging for the integration, reload it so it fetches the data fresh from the API and then share the data for response from /lock/detail for that lock?

jbergler commented 1 year ago

Yes, that's really helpful. (I deleted your comment since it included some sensitive data which I forgot to warn you about)

What we're looking for is a value for the field autoLockTime in the response, but it's not there.

Sending request to https://euapi.ttlock.com/v3/lock/detail with args={'lockId': 1487174}
{
  "date": 1564092731000,
  "lockAlias": "Front Office",
  "lockSound": 0,
  "modelNum": "SN149-BL01_PV53",
  "lockMac": "D7:97:81:B6:E0:6F",
  "privacyLock": 0,
  "deletePwd": "",
  "featureValue": "4D4E7",
  "adminPwd": "<removed>"",
  "soundVolume": 5,
  "hasGateway": 1,
  "wirelessKeypadFeatureValue": "0",
  "lockKey": "<removed>",
  "isFrozen": 2,
  "lockName": "BL01_6fe0b6",
  "resetButton": 0,
  "firmwareRevision": "4.3.1.190115",
  "tamperAlert": 0,
  "specialValue": 316647,
  "displayPasscode": 0,
  "noKeyPwd": "3229973",
  "passageMode": 2,
  "passageModeAutoUnlock": 2,
  "timezoneRawOffset": -14400000,
  "lockId": 1487174,
  "electricQuantity": 100,
  "lockFlagPos": 0,
  "lockUpdateDate": 1692985066000,
  "keyboardPwdVersion": 4,
  "aesKeyStr": "<removed>",
  "hardwareRevision": "1.6",
  "openDirection": 0,
  "lockVersion": {
    "groupId": 10,
    "protocolVersion": 3,
    "protocolType": 5,
    "orgId": 38,
    "scene": 2
  },
  "sensitivity": -1
}

I will try and reach out to TTLock, but I don't know if they will respond, in the meantime I don't know if there is much we can do.

jbergler commented 1 year ago

@ronluna In the meantime, the only idea I have is that maybe you configured the lock and the config didn't sync to TTLock's cloud.

If you have your API credentials, you could try directly changing the auto lock time using this endpoint: https://euopen.ttlock.com/document/doc?urlName=cloud%2Flock%2FsetAutoLockTimeEn.html That may result in the data being available in the cloud?

It might also be possible to do this via the app when you're not within bluetooth range of the lock.

ronluna commented 1 year ago

Hello @jbergler , Thanks for taking the time in looking into this. I've tried your suggestions but when seding the curl command to set the autlock time the request returns the following:

Get access token request:

curl --location -g --request POST 'https://euapi.ttlock.com/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'clientId=xxxxxxxxxxxxxxxx' \
--data-urlencode 'clientSecret=xxxxxxxxxxxxxxxxxxxx' \
--data-urlencode 'username=xxxx@xxxxxx.com' \
--data-urlencode 'password=xxxxxxxxxxxxxxxx'    

set autolock time request:

curl --location -g --request POST 'https://euapi.ttlock.com/v3/lock/setAutoLockTime' \
--data-urlencode 'clientId=xxxxxxxxxxxxxxxxx' \
--data-urlencode 'accessToken=xxxxxxxxxxxxxxxx' \
--data-urlencode 'lockId=1487174' \
--data-urlencode 'seconds=10' \
--data-urlencode 'type=2' \
--data-urlencode 'date=1697859458053'

response:

{"errcode":1,"errmsg":"failed or means no","description":"表示失败或否"}

When I access the ttlock and go into the lock settings there are no options to set turn on an autolock anywhere in the app... Please keep in mind this lock it operates as mortise lock. When access is granted the lock for a short moment gears with the handle so when the handle is turn the door can be opened, if the handle is not turned within that perior of time the lock releases the internal gears and the handle is free again and won't allow the door to open. so the only way this lock can operate is in autolock mode by default.

wondering if there is a way to simply force the autolock internally in the ttlock integration for this type of locks since it seems like this locks won't accept the autolock settins?

jbergler commented 1 year ago

That is interesting, but I don't really understand why the lock doesn't report this :| My lock has a very similar behavior, except I can configure in the app if it should leave the gears engaged or should release the gears.

It doesn't seem quite right to assume that a missing field implies certain behavior so I'm reluctant to change the default in the integration.

jbergler commented 1 year ago

Random idea, if you set type=1 in your setAutoLockTimeRequest it won't actually make any changes to the lock, but maybe it will record the value in the cloud and start reporting it in the api?

ronluna commented 1 year ago

Just tried with type=1 but it returned the same error:

` {"errcode":0,"errmsg":"none error message or means yes","description":"表示成功或是"}

`

Maybe this autolock feature addon side is optional and only for rare cases like this ?

jbergler commented 1 year ago

Alright, well if you want to patch it locally you can make the change here and it should work https://github.com/jbergler/hass-ttlock/blob/develop/custom_components/ttlock/models.py#L67C10-L67C10

ronluna commented 1 year ago

Wondering if it's normal for the webhook to return ERR_INVALID_RESPONSE when invoking the webhook url generated by the addon?

https://hass_external_url:port/api/webhook/the_wedhook_id_generated_by_the_addon

also seeing this in the logs:

` 2023-10-21 09:31:22.894 DEBUG (MainThread) [custom_components.ttlock.api] [98f7] Sending request to https://euapi.ttlock.com/v3/lock/unlock with args={'lockId': 1487144} 2023-10-21 09:31:52.920 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140169347279040] Cannot connect to host euapi.ttlock.com:443 ssl:default [None]

` Not sure if this could affect the autolock behavior?

I just noticed the following: If the lock is unlock using the addon the lock will unlock but will remain in the unlock or unknown state... If I unlock it again using the official ttlock the lock will unlock and autolock again but this time it will update the state of the lock of the addon correctly.

` 2023-10-21 10:27:58.903 DEBUG (MainThread) [custom_components.ttlock.coordinator] Manually updated ttlock data 2023-10-21 10:27:58.903 DEBUG (MainThread) [custom_components.ttlock.coordinator] Lock ttlock-1487174 received id=1487174 mac='D7:97:81:B6:E0:6F' battery_level=100 server_ts=datetime.datetime(2023, 10, 21, 10, 27, 58, 236000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York')) lock_ts=datetime.datetime(2023, 10, 21, 10, 26, 2, tzinfo=zoneinfo.ZoneInfo(key='America/New_York')) event=Event(EventDescription(action=<Action.unlock: 3>, description='unlock by gateway')) user='xxxx@xxxxxx.com' success=True 2023-10-21 10:27:58.904 DEBUG (MainThread) [custom_components.ttlock.coordinator] Manually updated ttlock data 2023-10-21 10:27:58.922 DEBUG (MainThread) [custom_components.ttlock.coordinator] Assuming lock auto locked after 5 seconds 2023-10-21 10:27:58.922 DEBUG (MainThread) [custom_components.ttlock.coordinator] Manually updated ttlock data 2023-10-21 10:27:58.923 DEBUG (MainThread) [custom_components.ttlock.coordinator] Assuming lock auto locked after 5 seconds 2023-10-21 10:27:58.924 DEBUG (MainThread) [custom_components.ttlock.coordinator] Manually updated ttlock data 2023-10-21 10:27:58.925 DEBUG (MainThread) [custom_components.ttlock.coordinator] Assuming lock auto locked after 5 seconds 2023-10-21 10:27:58.925 DEBUG (MainThread) [custom_components.ttlock.coordinator] Manually updated ttlock data 2023-10-21 10:27:58.926 DEBUG (MainThread) [custom_components.ttlock.coordinator] Assuming lock auto locked after 5 seconds 2023-10-21 10:27:58.926 DEBUG (MainThread) [custom_components.ttlock.coordinator] Manually updated ttlock data

`

ronluna commented 1 year ago

by the way. It seems like it finally started working correctly after unlocking the lock using the official ttlock app . Will continue testing and share the results...

Thanks for the help and sharing this great addon.

ronluna commented 11 months ago

I just noticed, something new... The cloud account has two and there two locks physically installed on site. They work just fine with the native ttlock app locally or remotely. With the addon things behave a little different, the addon can unlock both locks but the auto_lock feature seems is only working on one of the two locks. On the other lock the addon keeps it under the unlock status.

Wondering if you could share some light and why that might be? maybe the auto_lock feature is only supported for the first lock on the ttlock cloud account ?