seahaven-door-unlock-api/README.md
Adam Moussa 839b92ffe3
Add lockdown mode and CI/CD pipeline (#3)
* Add lockdown profile toggle endpoints with T58W linekey support

Add a new Lambda handler that toggles Elements lockdown profiles
(Bohemia and Ronkonkoma) via the Elements API, with status
verification before and after each toggle. Returns Yealink XML
to control linekey LEDs (green=inactive, red=locked down).

Also brings both Lambda handlers into compliance with system
standards: Node 22.x runtime, arm64 architecture, 60-day log
retention, and kebab-case function names.

* Add lockdown poller Lambda and fix lockdown handler responses

- Add VPC-connected poller Lambda that monitors lockdown status via
  Elements API every 15 seconds (4 polls per 1-min EventBridge schedule)
- Handle Elements API rate limits (429) with retry-after support
- Fix lockdown handler to use TextScreen XML instead of Execute XML
  (Execute shows globe icon on T58W, TextScreen renders properly)
- Fix Elements API status parsing to be case-insensitive
- Trust toggle action instead of re-checking status (eventual consistency)
- Configure push_xml.server = any in T58W template for Push XML support
- Clear action_url.setup_completed (poller replaces boot-time check)
- Update README with lockdown architecture and known LED limitation

Note: T58W line key LED color does not change to reflect lockdown
status. Execute LED commands are transient on the T58W - the phone's
XML Browser key type immediately overrides them.

* Add buildspec for CodePipeline CI/CD

* Update README with CI/CD pipeline details
2026-05-01 18:52:37 -04:00

3.7 KiB

Sea Haven Door Unlock API

AWS Lambda middleware that allows Yealink desk phones to unlock the front door and manage lockdown profiles via LenelS2 Elements.

Yealink T54W/T58W → HTTPS GET → API Gateway → Lambda → LenelS2 Elements API

Architecture

  • API Gateway (HTTP API) — GET /unlock, GET /lockdown, GET /lockdown/status with throttling (5 burst / 2 sustained req/sec)
  • Unlock Lambda — validates a shared auth token, calls the Elements TemporaryUnlock command
  • Lockdown Lambda — toggles lockdown profiles (start/stop) and checks status, returns Yealink XML TextScreen responses
  • Lockdown Poller Lambda — VPC-connected, polls Elements API every 15 seconds for lockdown status (runs 4x per 1-minute EventBridge schedule)
  • SSM Parameter Store — stores the Elements API key, auth token, door ID, and phone IPs
  • Secrets Manager — stores the Yealink phone admin password
  • Custom Domain — doorunlock.seahaven.com via Route 53 + ACM wildcard cert

Lockdown Profiles

Two lockdown profiles are configured:

Profile Elements ID Line Key
Bohemia - Whole Building 4b4a3e6b-c903-4cce-8cd6-288612bf0542 3
Ronkonkoma - Whole Building ff9876bc-c54f-472e-aef9-d2bffd4b7cf7 4

Pressing the line key toggles the lockdown on/off and displays the current status on the phone screen.

Known limitation: Line key LED color does not currently change to reflect lockdown status. The T58W's XML Browser key type (17) does not support persistent LED color changes via Push XML or Execute commands — LED commands are transient and immediately overridden by the phone's key type management.

SSM Parameters

Parameter Type Description
/seahaven/door-unlock/elements-api-key SecureString LenelS2 Elements API key
/seahaven/door-unlock/auth-token SecureString Shared secret embedded in the Yealink DSS key URL
/seahaven/door-unlock/door-id String Elements device ID for the front door reader
/seahaven/door-unlock/phone-ips String Comma-separated phone IPs for lockdown poller

Secrets Manager

Secret Description
door-unlock-api/phone-password Yealink phone admin password for Push XML

CI/CD

Pushes to main trigger an AWS CodePipeline (V2) that runs cdk deploy via CodeBuild.

Resource Name
Pipeline seahaven-door-unlock-api-pipeline
CodeBuild project seahaven-door-unlock-api-build
Artifact bucket seahaven-door-unlock-api-pipeline-artifacts

The CodeBuild role assumes CDK bootstrap roles for deployment — no separate CloudFormation stage.

Manual Deployment

npm install
npx cdk deploy

Phone Configuration

Configure DSS keys on the Yealink T54W/T58W (via phone web UI or 3CX):

  • Key 2 — Unlock Door

    • Type: URL
    • Value: https://doorunlock.seahaven.com/unlock?token=<auth-token>
  • Keys 3-4 — Lockdown Toggle

    • Type: XML Browser (17)
    • Value: https://doorunlock.seahaven.com/lockdown?token=<auth-token>&profile=bohemia|ronkonkoma

3CX Provisioning Templates

Custom 3CX templates are included with door unlock and lockdown URLs hardcoded.

Template Model Key 2 Keys 3-4 Display
yealinkT54W-door-unlock.ph.xml T54W Unlock Door Managed by 3CX BLF Dim after 5 min, never sleep
yealinkT54W-door-unlock-with-sp.ph.xml T54W Unlock Door Shared Parking SP1-3 Dim after 5 min, never sleep
yealinkT58W-door-unlock.ph.xml T58W Unlock Door Lockdown Toggle (Bohemia/Ronkonkoma) Default T58W display settings