@homebridge-plugins/homebridge-eufy-security 4.7.1 → 5.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORS +4 -0
- package/CODE_OF_CONDUCT.md +30 -0
- package/CONTRIBUTING.md +77 -0
- package/README.md +152 -49
- package/SECURITY.md +30 -0
- package/config.schema.json +92 -3
- package/dist/account/ownership.js +290 -0
- package/dist/account/ownership.js.map +1 -0
- package/dist/account/persistence.js +274 -0
- package/dist/account/persistence.js.map +1 -0
- package/dist/account/temporary-authentication.js +348 -0
- package/dist/account/temporary-authentication.js.map +1 -0
- package/dist/configuration.js +167 -0
- package/dist/configuration.js.map +1 -0
- package/dist/device/member-evidence.js +66 -0
- package/dist/device/member-evidence.js.map +1 -0
- package/dist/device/member-trust.js +114 -0
- package/dist/device/member-trust.js.map +1 -0
- package/dist/device/snapshot.js +190 -0
- package/dist/device/snapshot.js.map +1 -0
- package/dist/diagnostics.js +2218 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/homekit/adapter.js +2 -0
- package/dist/homekit/adapter.js.map +1 -0
- package/dist/homekit/adapters/battery.js +208 -0
- package/dist/homekit/adapters/battery.js.map +1 -0
- package/dist/homekit/adapters/camera-controls.js +527 -0
- package/dist/homekit/adapters/camera-controls.js.map +1 -0
- package/dist/homekit/adapters/camera-streaming.js +1515 -0
- package/dist/homekit/adapters/camera-streaming.js.map +1 -0
- package/dist/homekit/adapters/contact.js +138 -0
- package/dist/homekit/adapters/contact.js.map +1 -0
- package/dist/homekit/adapters/doorbell.js +57 -0
- package/dist/homekit/adapters/doorbell.js.map +1 -0
- package/dist/homekit/adapters/information.js +55 -0
- package/dist/homekit/adapters/information.js.map +1 -0
- package/dist/homekit/adapters/lock.js +489 -0
- package/dist/homekit/adapters/lock.js.map +1 -0
- package/dist/homekit/adapters/motion.js +100 -0
- package/dist/homekit/adapters/motion.js.map +1 -0
- package/dist/homekit/adapters/registry.js +26 -0
- package/dist/homekit/adapters/registry.js.map +1 -0
- package/dist/homekit/adapters/security-system.js +425 -0
- package/dist/homekit/adapters/security-system.js.map +1 -0
- package/dist/homekit/adapters/siren.js +136 -0
- package/dist/homekit/adapters/siren.js.map +1 -0
- package/dist/homekit/adapters/smart-light.js +662 -0
- package/dist/homekit/adapters/smart-light.js.map +1 -0
- package/dist/homekit/coverage-matrix.js +119 -0
- package/dist/homekit/coverage-matrix.js.map +1 -0
- package/dist/homekit/device-control.js +175 -0
- package/dist/homekit/device-control.js.map +1 -0
- package/dist/homekit/reconciler.js +319 -0
- package/dist/homekit/reconciler.js.map +1 -0
- package/dist/homekit/representation.js +23 -0
- package/dist/homekit/representation.js.map +1 -0
- package/dist/index.js +4 -9
- package/dist/index.js.map +1 -1
- package/dist/media/contracts.js +2 -0
- package/dist/media/contracts.js.map +1 -0
- package/dist/media/last-successful-image.js +208 -0
- package/dist/media/last-successful-image.js.map +1 -0
- package/dist/media/live-stream.js +1003 -0
- package/dist/media/live-stream.js.map +1 -0
- package/dist/media/recording.js +560 -0
- package/dist/media/recording.js.map +1 -0
- package/dist/media/session-budget.js +39 -0
- package/dist/media/session-budget.js.map +1 -0
- package/dist/media/snapshot.js +406 -0
- package/dist/media/snapshot.js.map +1 -0
- package/dist/media/station-live-sessions.js +101 -0
- package/dist/media/station-live-sessions.js.map +1 -0
- package/dist/platform.js +97 -769
- package/dist/platform.js.map +1 -1
- package/dist/runtime/channel.js +375 -0
- package/dist/runtime/channel.js.map +1 -0
- package/dist/runtime/owner.js +682 -0
- package/dist/runtime/owner.js.map +1 -0
- package/dist/runtime/sdk-client.js +211 -0
- package/dist/runtime/sdk-client.js.map +1 -0
- package/dist/runtime/tracker.js +211 -0
- package/dist/runtime/tracker.js.map +1 -0
- package/dist/settings.js +1 -43
- package/dist/settings.js.map +1 -1
- package/dist/storage.js +59 -0
- package/dist/storage.js.map +1 -0
- package/dist/ui/dashboard.js +181 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/device-image.js +22 -0
- package/dist/ui/device-image.js.map +1 -0
- package/dist/ui/runtime-channel-client.js +305 -0
- package/dist/ui/runtime-channel-client.js.map +1 -0
- package/dist/ui/server.js +259 -0
- package/dist/ui/server.js.map +1 -0
- package/homebridge-ui/public/app.css +1902 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T1250.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2070.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2080.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2081.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2103.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2117.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2118.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2119.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T211A.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2120.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2123.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2128.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2130.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2132.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2150.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2181.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2182.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2190.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2192.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2193.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2194.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2210.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2250.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2251.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2252.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2253.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2254.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2255.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2256.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2257.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2258.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2259.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2261.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2262.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2266.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2267.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2268.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2270.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2272.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2273.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2276.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2277.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2278.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2280.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2292.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2320.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2351.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2352.webp +0 -0
- package/homebridge-ui/public/assets/devices/clean/clean-T2353.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L00.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L01.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L02.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L04.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L10.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L20.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L30.webp +0 -0
- package/homebridge-ui/public/assets/devices/life/life-T8L40.webp +0 -0
- package/homebridge-ui/public/assets/devices/mower/mower-T2801.webp +0 -0
- package/homebridge-ui/public/assets/devices/mower/mower-T280B.webp +0 -0
- package/homebridge-ui/public/assets/devices/mower/mower-T2880.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T7400.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T7401.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8001.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8002.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8010.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8021.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8023.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8025.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8030.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8110.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8111.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8112.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8113.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8114.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8122.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8123.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8124.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8130.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8131.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8134.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8140.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8141.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8150.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8151.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8152.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8153.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8160.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8161.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8162.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8170.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8171.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8172.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8173.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8200.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8200X.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8201.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8203.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8210.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8213.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8214.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8222.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8400.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8401.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8410.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8411.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8414.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8416.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8417.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8419.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8419N.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8420.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8420X.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8422.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8423.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8424.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8425.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8441.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8442.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8452.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T84A0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T84A1.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8500.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8502.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8503.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8504.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8506.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8510.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8510P.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8520.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8520P.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8530.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8531.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T85D0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T85L0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T85P0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T85V0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8600.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T86P2.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8790.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T87B0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T87B2.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8900.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8910.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8920.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8960.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8B0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8E00.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8N00.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T8W11C.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T90F0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T90M0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T90R0.webp +0 -0
- package/homebridge-ui/public/assets/devices/security/security-T90S0.webp +0 -0
- package/homebridge-ui/public/assets/icons/inventory.svg +1 -1
- package/homebridge-ui/public/assets/icons/troubleshoot.svg +1 -0
- package/homebridge-ui/public/assets/icons/warning.svg +1 -1
- package/homebridge-ui/public/assets/logo-dark.svg +10 -0
- package/homebridge-ui/public/assets/logo.svg +10 -0
- package/homebridge-ui/public/i18n/en.json +218 -0
- package/homebridge-ui/public/i18n/fr.json +218 -0
- package/homebridge-ui/public/index.html +377 -28
- package/homebridge-ui/public/js/app.js +1065 -0
- package/homebridge-ui/public/js/dashboard.js +385 -0
- package/homebridge-ui/public/js/legacy-settings.js +37 -0
- package/homebridge-ui/public/js/profile-wizard.js +68 -0
- package/homebridge-ui/server.js +2 -1393
- package/i18n/runtime/en.json +100 -0
- package/media/Snapshot-Unavailable.jpg +0 -0
- package/media/Snapshot-black.jpg +0 -0
- package/media/camera-disabled.jpg +0 -0
- package/media/camera-offline.jpg +0 -0
- package/package.json +29 -24
- package/.claude/CLAUDE.md +0 -175
- package/.claude/PRD.md +0 -241
- package/.claude/docs/debug-recording-lessons.md +0 -91
- package/.claude/docs/hksv-recording-fix.md +0 -160
- package/.claude/skills/architect/SKILL.md +0 -76
- package/.claude/skills/developer/SKILL.md +0 -59
- package/.claude/skills/new-device-support/SKILL.md +0 -212
- package/.claude/skills/new-device-support/check-device.mjs +0 -363
- package/.claude/skills/new-device-support/map-properties.mjs +0 -450
- package/.claude/skills/new-device-support/verify-device.mjs +0 -272
- package/.claude/skills/planner/SKILL.md +0 -100
- package/.claude/skills/qa/SKILL.md +0 -79
- package/.claude/skills/support/SKILL.md +0 -175
- package/.prettierignore +0 -7
- package/.prettierrc.json +0 -7
- package/FUNDING.yml +0 -1
- package/dist/accessories/AutoSyncStationAccessory.js +0 -157
- package/dist/accessories/AutoSyncStationAccessory.js.map +0 -1
- package/dist/accessories/BaseAccessory.js +0 -261
- package/dist/accessories/BaseAccessory.js.map +0 -1
- package/dist/accessories/CameraAccessory.js +0 -431
- package/dist/accessories/CameraAccessory.js.map +0 -1
- package/dist/accessories/Device.js +0 -65
- package/dist/accessories/Device.js.map +0 -1
- package/dist/accessories/EntrySensorAccessory.js +0 -48
- package/dist/accessories/EntrySensorAccessory.js.map +0 -1
- package/dist/accessories/LockAccessory.js +0 -142
- package/dist/accessories/LockAccessory.js.map +0 -1
- package/dist/accessories/MotionSensorAccessory.js +0 -48
- package/dist/accessories/MotionSensorAccessory.js.map +0 -1
- package/dist/accessories/SmartDropAccessory.js +0 -141
- package/dist/accessories/SmartDropAccessory.js.map +0 -1
- package/dist/accessories/StationAccessory.js +0 -373
- package/dist/accessories/StationAccessory.js.map +0 -1
- package/dist/config.js +0 -26
- package/dist/config.js.map +0 -1
- package/dist/controller/DebugRecordingManager.js +0 -402
- package/dist/controller/DebugRecordingManager.js.map +0 -1
- package/dist/controller/LocalLivestreamManager.js +0 -371
- package/dist/controller/LocalLivestreamManager.js.map +0 -1
- package/dist/controller/recordingDelegate.js +0 -252
- package/dist/controller/recordingDelegate.js.map +0 -1
- package/dist/controller/snapshotDelegate.js +0 -348
- package/dist/controller/snapshotDelegate.js.map +0 -1
- package/dist/controller/streamingDelegate.js +0 -389
- package/dist/controller/streamingDelegate.js.map +0 -1
- package/dist/interfaces.js +0 -2
- package/dist/interfaces.js.map +0 -1
- package/dist/media/Snapshot-Unavailable.png +0 -0
- package/dist/media/Snapshot-Unavailable.xcf +0 -0
- package/dist/media/Snapshot-black.png +0 -0
- package/dist/media/camera-disabled.png +0 -0
- package/dist/media/camera-offline.png +0 -0
- package/dist/media/media/Snapshot-Unavailable.png +0 -0
- package/dist/media/media/Snapshot-Unavailable.xcf +0 -0
- package/dist/media/media/Snapshot-black.png +0 -0
- package/dist/media/media/camera-disabled.png +0 -0
- package/dist/media/media/camera-offline.png +0 -0
- package/dist/utils/Talkback.js +0 -162
- package/dist/utils/Talkback.js.map +0 -1
- package/dist/utils/accessoriesStore.js +0 -207
- package/dist/utils/accessoriesStore.js.map +0 -1
- package/dist/utils/configTypes.js +0 -36
- package/dist/utils/configTypes.js.map +0 -1
- package/dist/utils/ffmpeg.js +0 -1111
- package/dist/utils/ffmpeg.js.map +0 -1
- package/dist/utils/interfaces.js +0 -8
- package/dist/utils/interfaces.js.map +0 -1
- package/dist/utils/utils.js +0 -224
- package/dist/utils/utils.js.map +0 -1
- package/dist/version.js +0 -2
- package/dist/version.js.map +0 -1
- package/homebridge-eufy-security.png +0 -0
- package/homebridge-ui/diagnosticsCrypto.js +0 -112
- package/homebridge-ui/public/app.js +0 -237
- package/homebridge-ui/public/assets/devices/4g_lte_cam_s330_large.png +0 -0
- package/homebridge-ui/public/assets/devices/4g_lte_starlight_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/BATTERY_DOORBELL_C30.png +0 -0
- package/homebridge-ui/public/assets/devices/BATTERY_DOORBELL_C31.png +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell1080p_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell2k_large.png +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell2kdual_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell_e340_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufy-security-client.png +0 -0
- package/homebridge-ui/public/assets/devices/eufyCamS4_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2c_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2cpro_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2pro_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam3_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam3c_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam3pro_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufycam_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycame330_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/flood_freeze_sensor_e20_t90F0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/floodlight2_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlight2pro_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlight_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlightcame340_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/garage_camera_t8452_large.png +0 -0
- package/homebridge-ui/public/assets/devices/homebase2_large.png +0 -0
- package/homebridge-ui/public/assets/devices/homebase3_large.png +0 -0
- package/homebridge-ui/public/assets/devices/homebase_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/homebasemini_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamC210_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamC220_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamC220_t8419N_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamE30_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamc120_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcammini_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamp24_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcams350_large.png +0 -0
- package/homebridge-ui/public/assets/devices/keypad_large.png +0 -0
- package/homebridge-ui/public/assets/devices/minibase_chime_T8023_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/motionsensor_large.png +0 -0
- package/homebridge-ui/public/assets/devices/nvr_s4_max_T8N00_large.png +0 -0
- package/homebridge-ui/public/assets/devices/pir_sensor_e20_large.png +0 -0
- package/homebridge-ui/public/assets/devices/poe_bullet_ptz_cam_s4_T8E00_large.png +0 -0
- package/homebridge-ui/public/assets/devices/sensor_large.png +0 -0
- package/homebridge-ui/public/assets/devices/siren_sensor_e20_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartdrop_t8790_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8500_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8500_wifibridge_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8503_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8504_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8510P_t8520P_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t85D0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t85L0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t85P0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t85V0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8502_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8506_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8520_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_t8510_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_t8510_wifibridge_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_video_t8530_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_video_t8531_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlockwifibridge_t8021_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartsafe_s10_t7400_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartsafe_s12_t7401_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smarttrack_card_t87B2_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smarttrack_link_t87B0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smoke_alarm_e10_t90S0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocamc210_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocamc35_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocame20_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocame30_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocame40_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocame42_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocaml20_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocams220_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocams340_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocams40_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/soloindoorcamc24_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solooutdoorcamc22_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solooutdoorcamc24_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/unknown.png +0 -0
- package/homebridge-ui/public/assets/devices/walllight_s100_large.png +0 -0
- package/homebridge-ui/public/assets/devices/walllight_s120_large.png +0 -0
- package/homebridge-ui/public/assets/devices/water_freeze_sensor_t8920_large.png +0 -0
- package/homebridge-ui/public/assets/devices/wireddoorbell1080p_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/wireddoorbell2k_large.png +0 -0
- package/homebridge-ui/public/assets/devices/wireddoorbelldual_large.jpg +0 -0
- package/homebridge-ui/public/assets/icons/attach.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_0.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_1.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_2.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_3.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_4.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_5.svg +0 -1
- package/homebridge-ui/public/assets/icons/battery_6.svg +0 -1
- package/homebridge-ui/public/assets/icons/copy.svg +0 -1
- package/homebridge-ui/public/assets/icons/delete.svg +0 -1
- package/homebridge-ui/public/assets/icons/download.svg +0 -1
- package/homebridge-ui/public/assets/icons/info.svg +0 -1
- package/homebridge-ui/public/assets/icons/refresh.svg +0 -1
- package/homebridge-ui/public/assets/icons/satellite_alt.svg +0 -1
- package/homebridge-ui/public/assets/icons/solar_power.svg +0 -1
- package/homebridge-ui/public/components/device-card.js +0 -174
- package/homebridge-ui/public/components/guard-modes.js +0 -88
- package/homebridge-ui/public/components/number-input.js +0 -121
- package/homebridge-ui/public/components/select.js +0 -73
- package/homebridge-ui/public/components/toggle.js +0 -68
- package/homebridge-ui/public/services/api.js +0 -250
- package/homebridge-ui/public/services/config.js +0 -144
- package/homebridge-ui/public/style.css +0 -818
- package/homebridge-ui/public/utils/countries.js +0 -73
- package/homebridge-ui/public/utils/device-images.js +0 -102
- package/homebridge-ui/public/utils/helpers.js +0 -115
- package/homebridge-ui/public/views/dashboard.js +0 -226
- package/homebridge-ui/public/views/device-detail.js +0 -626
- package/homebridge-ui/public/views/diagnostics.js +0 -402
- package/homebridge-ui/public/views/login.js +0 -650
- package/homebridge-ui/public/views/recordings.js +0 -319
- package/homebridge-ui/public/views/settings.js +0 -197
- package/homebridge-ui/public/views/unsupported-detail.js +0 -296
- package/media/Snapshot-Unavailable.png +0 -0
- package/media/Snapshot-Unavailable.xcf +0 -0
- package/media/Snapshot-black.png +0 -0
- package/media/camera-disabled.png +0 -0
- package/media/camera-offline.png +0 -0
- package/scripts/decrypt-diagnostics.mjs +0 -257
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* map-properties.mjs
|
|
4
|
-
*
|
|
5
|
-
* Maps raw device param_type numbers from a device properties JSON dump
|
|
6
|
-
* to the corresponding property constants in eufy-security-client.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* node map-properties.mjs <raw-properties.json> [--closest]
|
|
10
|
-
* cat raw.json | node map-properties.mjs [--closest]
|
|
11
|
-
*
|
|
12
|
-
* The input JSON should be the rawProperties object from a device dump,
|
|
13
|
-
* e.g. { "1101": { "value": 100 }, "1013": { "value": 1 }, ... }
|
|
14
|
-
* or an array of { "param_type": 1101, "param_value": "..." } objects.
|
|
15
|
-
*
|
|
16
|
-
* Options:
|
|
17
|
-
* --closest Find the closest existing devices by Jaccard similarity
|
|
18
|
-
* on resolved PropertyName overlap. Useful to identify which
|
|
19
|
-
* existing device to base the DeviceProperties block on.
|
|
20
|
-
*
|
|
21
|
-
* Output: a table mapping each param_type to its CommandType/ParamType enum name
|
|
22
|
-
* and all property constants that use that key.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { readFileSync } from "fs";
|
|
26
|
-
import { join, dirname } from "path";
|
|
27
|
-
import { fileURLToPath } from "url";
|
|
28
|
-
|
|
29
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
30
|
-
|
|
31
|
-
// Paths relative to this script's location
|
|
32
|
-
// eufy-security-client is a sibling repo at the same level as homebridge-eufy-security
|
|
33
|
-
const CLIENT_ROOT = join(__dirname, "..", "..", "..", "..", "eufy-security-client");
|
|
34
|
-
const TYPES_HTTP = join(CLIENT_ROOT, "src", "http", "types.ts");
|
|
35
|
-
const TYPES_P2P = join(CLIENT_ROOT, "src", "p2p", "types.ts");
|
|
36
|
-
|
|
37
|
-
// ── Step 1: Parse enum values from source ──────────────────────────────────
|
|
38
|
-
|
|
39
|
-
function parseEnum(source, enumName) {
|
|
40
|
-
const map = new Map(); // number → enum member name
|
|
41
|
-
const re = new RegExp(`enum\\s+${enumName}\\s*\\{([\\s\\S]*?)\\}`, "m");
|
|
42
|
-
const match = source.match(re);
|
|
43
|
-
if (!match) return map;
|
|
44
|
-
|
|
45
|
-
const body = match[1];
|
|
46
|
-
for (const line of body.split("\n")) {
|
|
47
|
-
const m = line.match(/^\s*(\w+)\s*=\s*(\d+)/);
|
|
48
|
-
if (m) {
|
|
49
|
-
map.set(Number(m[2]), `${enumName}.${m[1]}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return map;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const httpSource = readFileSync(TYPES_HTTP, "utf-8");
|
|
56
|
-
const p2pSource = readFileSync(TYPES_P2P, "utf-8");
|
|
57
|
-
|
|
58
|
-
const paramTypeMap = parseEnum(httpSource, "ParamType");
|
|
59
|
-
const commandTypeMap = parseEnum(p2pSource, "CommandType");
|
|
60
|
-
const trackerCommandTypeMap = parseEnum(p2pSource, "TrackerCommandType");
|
|
61
|
-
|
|
62
|
-
// Merge all enum maps (CommandType takes precedence as it's most commonly used)
|
|
63
|
-
const allEnums = new Map();
|
|
64
|
-
for (const [k, v] of paramTypeMap) allEnums.set(k, v);
|
|
65
|
-
for (const [k, v] of trackerCommandTypeMap) allEnums.set(k, v);
|
|
66
|
-
for (const [k, v] of commandTypeMap) allEnums.set(k, v);
|
|
67
|
-
|
|
68
|
-
// ── Step 2: Parse property constants and their keys ────────────────────────
|
|
69
|
-
|
|
70
|
-
// Match property constant definitions and extract their key field
|
|
71
|
-
// Handles both direct keys and spread patterns
|
|
72
|
-
function parsePropertyConstants(source) {
|
|
73
|
-
const props = []; // { constName, key, keyRaw, propertyName }
|
|
74
|
-
|
|
75
|
-
// Find each "export const XxxProperty" block
|
|
76
|
-
const constRegex = /export\s+const\s+(\w+Property)\s*:\s*\w+\s*=\s*\{([\s\S]*?)\};/g;
|
|
77
|
-
let m;
|
|
78
|
-
while ((m = constRegex.exec(source)) !== null) {
|
|
79
|
-
const constName = m[1];
|
|
80
|
-
const body = m[2];
|
|
81
|
-
|
|
82
|
-
// Extract key field
|
|
83
|
-
let key = null;
|
|
84
|
-
let keyRaw = null;
|
|
85
|
-
const keyMatch = body.match(/key:\s*(.+?)(?:,|\n)/);
|
|
86
|
-
if (keyMatch) {
|
|
87
|
-
keyRaw = keyMatch[1].trim();
|
|
88
|
-
// Resolve to numeric if it's an enum reference
|
|
89
|
-
if (keyRaw.startsWith('"') || keyRaw.startsWith("'")) {
|
|
90
|
-
key = keyRaw.replace(/['"]/g, ""); // string key
|
|
91
|
-
} else {
|
|
92
|
-
// It's an enum reference like CommandType.CMD_GET_BATTERY
|
|
93
|
-
const parts = keyRaw.split(".");
|
|
94
|
-
if (parts.length === 2) {
|
|
95
|
-
const enumName = parts[0];
|
|
96
|
-
let enumMap;
|
|
97
|
-
if (enumName === "CommandType") enumMap = commandTypeMap;
|
|
98
|
-
else if (enumName === "ParamType") enumMap = paramTypeMap;
|
|
99
|
-
else if (enumName === "TrackerCommandType") enumMap = trackerCommandTypeMap;
|
|
100
|
-
|
|
101
|
-
if (enumMap) {
|
|
102
|
-
for (const [num, fullName] of enumMap) {
|
|
103
|
-
if (fullName === keyRaw) {
|
|
104
|
-
key = num;
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Extract PropertyName
|
|
114
|
-
let propertyName = null;
|
|
115
|
-
const nameMatch = body.match(/name:\s*(PropertyName\.\w+)/);
|
|
116
|
-
if (nameMatch) {
|
|
117
|
-
propertyName = nameMatch[1];
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Handle spread: ...SomeOtherProperty (inherits key if not overridden)
|
|
121
|
-
let spreadFrom = null;
|
|
122
|
-
const spreadMatch = body.match(/\.\.\.(\w+Property)/);
|
|
123
|
-
if (spreadMatch) {
|
|
124
|
-
spreadFrom = spreadMatch[1];
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
props.push({ constName, key, keyRaw, propertyName, spreadFrom });
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Resolve spreads: inherit missing fields from parent property
|
|
131
|
-
const byName = new Map(props.map((p) => [p.constName, p]));
|
|
132
|
-
for (const prop of props) {
|
|
133
|
-
if (prop.spreadFrom) {
|
|
134
|
-
const parent = byName.get(prop.spreadFrom);
|
|
135
|
-
if (parent) {
|
|
136
|
-
if (prop.key === null) {
|
|
137
|
-
prop.key = parent.key;
|
|
138
|
-
if (!prop.keyRaw) prop.keyRaw = `(spread from ${prop.spreadFrom}) ${parent.keyRaw}`;
|
|
139
|
-
}
|
|
140
|
-
// Always inherit propertyName from parent when missing, even if key is overridden
|
|
141
|
-
if (!prop.propertyName) prop.propertyName = parent.propertyName;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return props;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const allProps = parsePropertyConstants(httpSource);
|
|
150
|
-
|
|
151
|
-
// Build lookup: numeric key → list of property constants
|
|
152
|
-
const keyToProps = new Map(); // key (number|string) → [{ constName, propertyName }]
|
|
153
|
-
for (const p of allProps) {
|
|
154
|
-
if (p.key === null) continue;
|
|
155
|
-
const k = p.key;
|
|
156
|
-
if (!keyToProps.has(k)) keyToProps.set(k, []);
|
|
157
|
-
keyToProps.get(k).push({ constName: p.constName, propertyName: p.propertyName });
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// ── Step 3: Parse DeviceProperties blocks to see which constants are used ──
|
|
161
|
-
|
|
162
|
-
function parseDevicePropertiesUsage(source) {
|
|
163
|
-
// Find all [DeviceType.XXX]: { ... } blocks inside DeviceProperties
|
|
164
|
-
const usage = new Map(); // constName → Set of DeviceType names that use it
|
|
165
|
-
const dpRegex = /\[DeviceType\.(\w+)\]\s*:\s*\{([\s\S]*?)\}/g;
|
|
166
|
-
// Only search within the DeviceProperties section
|
|
167
|
-
const dpStart = source.indexOf("export const DeviceProperties");
|
|
168
|
-
const dpEnd = source.indexOf("export const StationProperties");
|
|
169
|
-
if (dpStart === -1) return usage;
|
|
170
|
-
|
|
171
|
-
const dpSection = source.slice(dpStart, dpEnd === -1 ? undefined : dpEnd);
|
|
172
|
-
let m;
|
|
173
|
-
while ((m = dpRegex.exec(dpSection)) !== null) {
|
|
174
|
-
const deviceType = m[1];
|
|
175
|
-
const body = m[2];
|
|
176
|
-
// Find all property constant references
|
|
177
|
-
const refRegex = /:\s*(\w+Property)/g;
|
|
178
|
-
let rm;
|
|
179
|
-
while ((rm = refRegex.exec(body)) !== null) {
|
|
180
|
-
const constName = rm[1];
|
|
181
|
-
if (!usage.has(constName)) usage.set(constName, new Set());
|
|
182
|
-
usage.get(constName).add(deviceType);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return usage;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const propUsage = parseDevicePropertiesUsage(httpSource);
|
|
189
|
-
|
|
190
|
-
// ── Step 4: Read and parse input JSON ──────────────────────────────────────
|
|
191
|
-
|
|
192
|
-
let inputData;
|
|
193
|
-
const inputFile = process.argv.slice(2).find((a) => !a.startsWith("-"));
|
|
194
|
-
if (inputFile) {
|
|
195
|
-
inputData = readFileSync(inputFile, "utf-8");
|
|
196
|
-
} else {
|
|
197
|
-
// Read from stdin
|
|
198
|
-
inputData = readFileSync("/dev/stdin", "utf-8");
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
let rawParamTypes; // Set of numeric param_type values
|
|
202
|
-
try {
|
|
203
|
-
const parsed = JSON.parse(inputData);
|
|
204
|
-
|
|
205
|
-
if (Array.isArray(parsed)) {
|
|
206
|
-
// Array of { param_type: number, ... }
|
|
207
|
-
rawParamTypes = new Set(parsed.map((item) => Number(item.param_type)));
|
|
208
|
-
} else if (typeof parsed === "object") {
|
|
209
|
-
// Check if it's a full device dump with rawProperties nested
|
|
210
|
-
if (parsed.rawProperties && typeof parsed.rawProperties === "object") {
|
|
211
|
-
rawParamTypes = new Set(Object.keys(parsed.rawProperties).map(Number));
|
|
212
|
-
} else {
|
|
213
|
-
// Direct { "1101": ..., "1013": ... } format
|
|
214
|
-
rawParamTypes = new Set(Object.keys(parsed).map(Number));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
} catch {
|
|
218
|
-
console.error("Error: Could not parse input JSON. Provide either:");
|
|
219
|
-
console.error(' - A raw properties object: { "1101": {...}, "1013": {...}, ... }');
|
|
220
|
-
console.error(' - An array: [{ "param_type": 1101, ... }, ...]');
|
|
221
|
-
console.error(" - A device dump with rawProperties key");
|
|
222
|
-
process.exit(1);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Filter out NaN (from string keys in the input)
|
|
226
|
-
rawParamTypes = new Set([...rawParamTypes].filter((n) => !isNaN(n)));
|
|
227
|
-
|
|
228
|
-
// ── Step 5: Output results ─────────────────────────────────────────────────
|
|
229
|
-
|
|
230
|
-
const COL1 = 12; // param_type
|
|
231
|
-
const COL2 = 48; // enum name
|
|
232
|
-
const COL3 = 50; // property constants
|
|
233
|
-
// COL4 reserved for future use
|
|
234
|
-
|
|
235
|
-
const header = [
|
|
236
|
-
"param_type".padEnd(COL1),
|
|
237
|
-
"Enum Name".padEnd(COL2),
|
|
238
|
-
"Property Constant(s)".padEnd(COL3),
|
|
239
|
-
"Used by DeviceTypes",
|
|
240
|
-
].join(" | ");
|
|
241
|
-
|
|
242
|
-
console.log("=".repeat(header.length));
|
|
243
|
-
console.log("Device Raw Properties → Property Constants Mapping");
|
|
244
|
-
console.log(`Total raw param_types: ${rawParamTypes.size}`);
|
|
245
|
-
console.log("=".repeat(header.length));
|
|
246
|
-
console.log();
|
|
247
|
-
console.log(header);
|
|
248
|
-
console.log("-".repeat(header.length));
|
|
249
|
-
|
|
250
|
-
const matched = [];
|
|
251
|
-
const unmatched = [];
|
|
252
|
-
|
|
253
|
-
for (const paramType of [...rawParamTypes].sort((a, b) => a - b)) {
|
|
254
|
-
const enumName = allEnums.get(paramType) || "???";
|
|
255
|
-
const props = keyToProps.get(paramType);
|
|
256
|
-
|
|
257
|
-
if (props && props.length > 0) {
|
|
258
|
-
const constNames = props.map((p) => p.constName);
|
|
259
|
-
const propertyNames = [...new Set(props.map((p) => p.propertyName).filter(Boolean))];
|
|
260
|
-
const usedBy = new Set();
|
|
261
|
-
for (const cn of constNames) {
|
|
262
|
-
const devices = propUsage.get(cn);
|
|
263
|
-
if (devices) devices.forEach((d) => usedBy.add(d));
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
matched.push({
|
|
267
|
-
paramType,
|
|
268
|
-
enumName,
|
|
269
|
-
constNames,
|
|
270
|
-
propertyNames,
|
|
271
|
-
usedBy: [...usedBy],
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
console.log(
|
|
275
|
-
[
|
|
276
|
-
String(paramType).padEnd(COL1),
|
|
277
|
-
enumName.padEnd(COL2),
|
|
278
|
-
constNames.join(", ").padEnd(COL3),
|
|
279
|
-
[...usedBy].slice(0, 5).join(", ") + (usedBy.size > 5 ? "..." : ""),
|
|
280
|
-
].join(" | ")
|
|
281
|
-
);
|
|
282
|
-
} else {
|
|
283
|
-
unmatched.push({ paramType, enumName });
|
|
284
|
-
console.log(
|
|
285
|
-
[
|
|
286
|
-
String(paramType).padEnd(COL1),
|
|
287
|
-
enumName.padEnd(COL2),
|
|
288
|
-
"(no property constant found)".padEnd(COL3),
|
|
289
|
-
"",
|
|
290
|
-
].join(" | ")
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
console.log();
|
|
296
|
-
console.log("=".repeat(80));
|
|
297
|
-
console.log(`MATCHED: ${matched.length} / ${rawParamTypes.size} param_types have property constants`);
|
|
298
|
-
console.log(`UNMATCHED: ${unmatched.length} param_types have no known property constant`);
|
|
299
|
-
console.log("=".repeat(80));
|
|
300
|
-
|
|
301
|
-
if (unmatched.length > 0) {
|
|
302
|
-
console.log();
|
|
303
|
-
console.log("Unmatched param_types (may need new property constants or may be internal):");
|
|
304
|
-
for (const u of unmatched) {
|
|
305
|
-
console.log(` ${u.paramType} → ${u.enumName}`);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// ── Step 6: Companion custom properties ─────────────────────────────────────
|
|
310
|
-
// Some param_type-based properties require a companion custom (runtime) property
|
|
311
|
-
// that never appears in raw device data. Define those pairings here so the
|
|
312
|
-
// suggested block always includes both.
|
|
313
|
-
|
|
314
|
-
const COMPANION_PROPERTIES = new Map([
|
|
315
|
-
// DeviceRTSPStream (CMD_NAS_SWITCH) → DeviceRTSPStreamUrl (custom_rtspStreamUrl)
|
|
316
|
-
["PropertyName.DeviceRTSPStream", {
|
|
317
|
-
propertyName: "PropertyName.DeviceRTSPStreamUrl",
|
|
318
|
-
constName: "DeviceRTSPStreamUrlProperty",
|
|
319
|
-
reason: "RTSP URL is set at runtime by the station — must accompany DeviceRTSPStream",
|
|
320
|
-
}],
|
|
321
|
-
// DeviceWifiRSSI → DeviceWifiSignalLevel (custom_wifiSignalLevel)
|
|
322
|
-
["PropertyName.DeviceWifiRSSI", {
|
|
323
|
-
propertyName: "PropertyName.DeviceWifiSignalLevel",
|
|
324
|
-
constName: "DeviceWifiSignalLevelProperty",
|
|
325
|
-
reason: "WiFi signal level is derived at runtime from RSSI",
|
|
326
|
-
}],
|
|
327
|
-
// DeviceCellularRSSI → DeviceCellularSignalLevel (custom_cellularSignalLevel)
|
|
328
|
-
["PropertyName.DeviceCellularRSSI", {
|
|
329
|
-
propertyName: "PropertyName.DeviceCellularSignalLevel",
|
|
330
|
-
constName: "DeviceCellularSignalLevelProperty",
|
|
331
|
-
reason: "Cellular signal level is derived at runtime from RSSI",
|
|
332
|
-
}],
|
|
333
|
-
]);
|
|
334
|
-
|
|
335
|
-
// Output a suggested PropertyName list for use in DeviceProperties block
|
|
336
|
-
console.log();
|
|
337
|
-
console.log("=".repeat(80));
|
|
338
|
-
console.log("SUGGESTED DeviceProperties block entries:");
|
|
339
|
-
console.log("=".repeat(80));
|
|
340
|
-
const seen = new Set();
|
|
341
|
-
const companionsAdded = [];
|
|
342
|
-
for (const m of matched) {
|
|
343
|
-
// Use original props lookup to get correct constName → propertyName mapping
|
|
344
|
-
// (the deduplicated m.propertyNames array loses the index association with m.constNames)
|
|
345
|
-
const propsForKey = keyToProps.get(m.paramType) || [];
|
|
346
|
-
for (const prop of propsForKey) {
|
|
347
|
-
const pn = prop.propertyName;
|
|
348
|
-
const cn = prop.constName;
|
|
349
|
-
if (pn && !seen.has(pn)) {
|
|
350
|
-
seen.add(pn);
|
|
351
|
-
console.log(` [${pn}]: ${cn},`);
|
|
352
|
-
|
|
353
|
-
// Check if this property has a required companion
|
|
354
|
-
const companion = COMPANION_PROPERTIES.get(pn);
|
|
355
|
-
if (companion && !seen.has(companion.propertyName)) {
|
|
356
|
-
seen.add(companion.propertyName);
|
|
357
|
-
console.log(` [${companion.propertyName}]: ${companion.constName}, // ⚠ companion (custom/runtime)`);
|
|
358
|
-
companionsAdded.push(companion);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (companionsAdded.length > 0) {
|
|
365
|
-
console.log();
|
|
366
|
-
console.log("=".repeat(80));
|
|
367
|
-
console.log("⚠ COMPANION PROPERTIES (custom/runtime — not in raw device data):");
|
|
368
|
-
console.log("=".repeat(80));
|
|
369
|
-
for (const c of companionsAdded) {
|
|
370
|
-
console.log(` ${c.constName}: ${c.reason}`);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// ── Step 7: Closest device detection (--closest flag) ───────────────────────
|
|
375
|
-
|
|
376
|
-
if (process.argv.includes("--closest")) {
|
|
377
|
-
// Collect the set of PropertyName values from the matched raw properties
|
|
378
|
-
const targetPropNames = new Set();
|
|
379
|
-
for (const m of matched) {
|
|
380
|
-
for (const pn of m.propertyNames) {
|
|
381
|
-
if (pn) targetPropNames.add(pn);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if (targetPropNames.size === 0) {
|
|
386
|
-
console.log("\nCannot compute closest device — no PropertyName matches found.");
|
|
387
|
-
} else {
|
|
388
|
-
// Parse DeviceProperties blocks to get property sets per device type
|
|
389
|
-
const dpStart = httpSource.indexOf("export const DeviceProperties");
|
|
390
|
-
const dpEnd = httpSource.indexOf("export const StationProperties");
|
|
391
|
-
if (dpStart !== -1) {
|
|
392
|
-
const dpSection = httpSource.slice(dpStart, dpEnd === -1 ? undefined : dpEnd);
|
|
393
|
-
|
|
394
|
-
const devicePropSets = new Map(); // DeviceType name → Set of PropertyName references
|
|
395
|
-
const blockRegex = /\[DeviceType\.(\w+)\]\s*:\s*\{([\s\S]*?)\}/g;
|
|
396
|
-
let bm;
|
|
397
|
-
while ((bm = blockRegex.exec(dpSection)) !== null) {
|
|
398
|
-
const dt = bm[1];
|
|
399
|
-
const body = bm[2];
|
|
400
|
-
const props = new Set();
|
|
401
|
-
// Extract property constants used, then resolve to PropertyName
|
|
402
|
-
const refRegex = /:\s*(\w+Property)/g;
|
|
403
|
-
let rm;
|
|
404
|
-
while ((rm = refRegex.exec(body)) !== null) {
|
|
405
|
-
const constName = rm[1];
|
|
406
|
-
const prop = allProps.find((p) => p.constName === constName);
|
|
407
|
-
if (prop && prop.propertyName) props.add(prop.propertyName);
|
|
408
|
-
}
|
|
409
|
-
devicePropSets.set(dt, props);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Jaccard similarity
|
|
413
|
-
const similarities = [];
|
|
414
|
-
for (const [dt, props] of devicePropSets) {
|
|
415
|
-
const intersection = new Set([...targetPropNames].filter((p) => props.has(p)));
|
|
416
|
-
const union = new Set([...targetPropNames, ...props]);
|
|
417
|
-
const jaccard = union.size > 0 ? intersection.size / union.size : 0;
|
|
418
|
-
if (jaccard > 0.2) {
|
|
419
|
-
similarities.push({
|
|
420
|
-
device: dt,
|
|
421
|
-
jaccard: Math.round(jaccard * 100),
|
|
422
|
-
shared: intersection.size,
|
|
423
|
-
targetOnly: [...targetPropNames].filter((p) => !props.has(p)).length,
|
|
424
|
-
otherOnly: [...props].filter((p) => !targetPropNames.has(p)).length,
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
similarities.sort((a, b) => b.jaccard - a.jaccard);
|
|
430
|
-
const top = similarities.slice(0, 8);
|
|
431
|
-
|
|
432
|
-
console.log();
|
|
433
|
-
console.log("=".repeat(80));
|
|
434
|
-
console.log("CLOSEST EXISTING DEVICES (by property overlap with raw data)");
|
|
435
|
-
console.log("=".repeat(80));
|
|
436
|
-
if (top.length === 0) {
|
|
437
|
-
console.log(" No devices with >20% property overlap found.");
|
|
438
|
-
} else {
|
|
439
|
-
console.log(" " + "Device".padEnd(38) + "Similarity Shared Target-only Other-only");
|
|
440
|
-
for (const d of top) {
|
|
441
|
-
console.log(
|
|
442
|
-
` ${d.device.padEnd(38)} ${String(d.jaccard + "%").padEnd(11)} ${String(d.shared).padEnd(7)} ${String(d.targetOnly).padEnd(12)} ${d.otherOnly}`
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
console.log();
|
|
446
|
-
console.log(` Recommended base: ${top[0].device} (${top[0].jaccard}% overlap)`);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|