{"id":51536707,"url":"https://github.com/imaznation/cradlewise-bridge","last_synced_at":"2026-07-09T09:01:35.221Z","repository":{"id":355997294,"uuid":"1213747513","full_name":"imaznation/cradlewise-bridge","owner":"imaznation","description":"Unofficial read-only interoperability library for Cradlewise smart cribs: REST state, Janus WebRTC video/audio feed, continuous recording, adaptive audio spike detection.","archived":false,"fork":false,"pushed_at":"2026-05-06T06:43:47.000Z","size":73,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T08:12:24.252Z","etag":null,"topics":["aiortc","baby-monitor","cradlewise","home-automation","interoperability","janus","python","reverse-engineering","smart-home","webrtc"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imaznation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-17T18:06:51.000Z","updated_at":"2026-05-06T06:43:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/imaznation/cradlewise-bridge","commit_stats":null,"previous_names":["imaznation/cradlewise-bridge"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/imaznation/cradlewise-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imaznation%2Fcradlewise-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imaznation%2Fcradlewise-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imaznation%2Fcradlewise-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imaznation%2Fcradlewise-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imaznation","download_url":"https://codeload.github.com/imaznation/cradlewise-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imaznation%2Fcradlewise-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35293217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aiortc","baby-monitor","cradlewise","home-automation","interoperability","janus","python","reverse-engineering","smart-home","webrtc"],"created_at":"2026-07-09T09:01:33.473Z","updated_at":"2026-07-09T09:01:35.213Z","avatar_url":"https://github.com/imaznation.png","language":"Python","funding_links":["https://buymeacoffee.com/imaznation"],"categories":[],"sub_categories":[],"readme":"# cradlewise-bridge\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-support-yellow?logo=buy-me-a-coffee)](https://buymeacoffee.com/imaznation)\n\nAn unofficial interoperability library for [Cradlewise](https://cradlewise.com/)\nsmart cribs. Uses your own Cradlewise credentials to subscribe to the live\nvideo and audio feed your crib already publishes to Cradlewise's cloud, so\nyou can integrate it into your own monitoring, home automation, or analytics\npipeline.\n\n**Status:** works, alpha, single maintainer. Not affiliated with Cradlewise Inc.\n\n## What this does\n\n* **REST state polling.** Read the full device shadow (temperature, baby\n  presence, sleep state, bouncing, music, light, etc.) for each crib on\n  your account. Builds on [`pycradlewise`](https://github.com/jlamendo/pycradlewise)\n  for authentication.\n* **Live WebRTC video + audio.** Connect to Cradlewise's Janus gateway,\n  authenticate with HMAC-signed WebSocket headers, and subscribe to your\n  crib's H.264 video + Opus audio streams via [`aiortc`](https://github.com/aiortc/aiortc).\n* **Continuous recording.** Decimate video to a configurable FPS (default 2),\n  write 5-minute MP4 segments, index them in SQLite, and purge after 48h\n  (configurable).\n* **Adaptive audio spike detection.** Exponential-moving-average ambient\n  baseline + multiplier threshold + deferred post-spike capture — saves\n  10-second WAV snippets centered on crying/fussing/loud events.\n* **Multi-crib.** Connect to every crib on your account concurrently with\n  independent reconnect loops.\n* **Read-only by design.** No control commands ever leave this library.\n  Bouncing, music, lighting, 2-way audio — all out of scope.\n\n## Install\n\n```bash\npip install -e .\n# or\npip install -r requirements.txt\n```\n\nRequires Python 3.10+. Depends on `pycradlewise`, `aiortc`, `aiohttp`,\n`boto3`, `numpy`, `Pillow`, `imageio[ffmpeg]`.\n\n## Quickstart\n\n```python\nimport asyncio, os\nfrom cradlewise_bridge import CradlewiseBridge, CribConfig\nfrom pycradlewise import CradlewiseAuth, CradlewiseClient, get_app_config\n\nasync def main():\n    email, password = os.environ[\"CRADLEWISE_EMAIL\"], os.environ[\"CRADLEWISE_PASSWORD\"]\n\n    # One-time discovery to map cradle_id -\u003e device_id\n    app = await get_app_config()\n    auth = CradlewiseAuth(email, password, app_config=app)\n    await auth.authenticate()\n    cradles = await CradlewiseClient(auth).discover_cradles()\n\n    bridge = CradlewiseBridge(\n        email=email,\n        password=password,\n        cribs=[\n            CribConfig(name=(c.baby_name or cid[:8]).lower(),\n                       cradle_id=cid, device_id=c.device_id)\n            for cid, c in cradles.items()\n        ],\n    )\n\n    async def on_spike(crib, wav):  print(f\"[{crib}] cry: {wav}\")\n    async def on_segment(crib, mp4): print(f\"[{crib}] saved: {mp4}\")\n    bridge.on_audio_spike = on_spike\n    bridge.on_segment_flushed = on_segment\n\n    await bridge.run()\n\nasyncio.run(main())\n```\n\nSee `examples/` for four runnable scripts:\n\n| Script                             | What it does                                   |\n|------------------------------------|------------------------------------------------|\n| `state_polling.py`                 | Print the device-shadow state (no video)       |\n| `connect_and_snapshot.py`          | Connect, grab 10 frames, save one as JPG       |\n| `detect_audio_spikes.py`           | Save WAVs whenever crying / loud sounds occur  |\n| `record_continuously.py`           | Full 48h rolling recording with auto-reconnect |\n\n## Design notes\n\n* The only piece that required real reverse engineering is the Janus\n  gateway layer — WebSocket HMAC signing, videoroom handshake, trickle\n  ICE injection into the SDP. It's documented in full in\n  [`PROTOCOL.md`](./PROTOCOL.md).\n* Everything above that layer (segment recording, adaptive cry detection,\n  multi-crib supervision) is standard engineering with no Cradlewise-specific\n  surprises. You can freely ignore those modules and just use\n  `janus.py` + `rest.py` if you have your own media pipeline.\n* `pycradlewise` does all the Cognito / SigV4 auth work; we don't reimplement\n  it. Credit where due.\n\n## How is this different from pycradlewise?\n\n`pycradlewise` is a REST-and-MQTT client — it reads the device shadow and\nexposes typed properties. It does **not** give you access to the video or\naudio stream. `cradlewise-bridge` adds:\n\n* The Janus video-room activation call (AWS SigV4 REST endpoint).\n* The Janus WebSocket client with HMAC-signed upgrade headers.\n* The videoroom subscribe flow and trickle ICE handling.\n* WebRTC peer connection via aiortc to actually receive the media.\n* The recording and audio-analysis pipeline on top.\n\nIt depends on `pycradlewise` for authentication and shadow access.\n\n## Legal \u0026 ethical framing\n\nThis project exists so owners of Cradlewise cribs can monitor their own\ndevices using their own credentials. It is not affiliated with, endorsed by,\nor supported by Cradlewise Inc.\n\n**What this code does and doesn't do**\n\n* **Uses your own account.** The library authenticates as you, using\n  credentials you provide. It does not bypass authentication, impersonate\n  other users, or access anyone else's cribs.\n* **Read-only by design.** It subscribes to the video/audio stream and\n  reads REST state. It never sends control commands (bouncing, music,\n  lights, 2-way audio). The documented API exists — this project just\n  consumes it from a non-mobile client.\n* **No credentials, tokens, or device identifiers are included.** The\n  signing scheme and protocol framing are documented as algorithms; the\n  runtime config (API base, region, room secrets) is fetched from\n  Cradlewise's own endpoints using your credentials, exactly as the\n  official mobile app does.\n\n**Legal basis (U.S., not legal advice)**\n\n* Reverse engineering a product you own for *interoperability* is\n  expressly permitted under 17 U.S.C. §1201(f) (DMCA interoperability\n  exception) and has been broadly upheld for personal and research use\n  (*Sega v. Accolade*, *Sony v. Connectix*).\n* The Computer Fraud and Abuse Act (CFAA) targets *unauthorized* access.\n  Authenticating to an account you own and accessing your own devices is\n  authorized access by definition.\n* Publishing protocol documentation derived from clean-room observation\n  of your own authenticated sessions is protected speech; no trade\n  secrets are misappropriated (public network traffic from a product\n  you own is not a trade secret).\n\n**Terms of Service caveat**\n\nCradlewise's Terms of Service may prohibit use of unofficial clients.\nUsing this library could result in account termination at Cradlewise's\ndiscretion. That's a risk you accept by using it. If you don't want that\nrisk, don't use this library.\n\n**Trademarks**\n\n\"Cradlewise\" is a trademark of Cradlewise Inc. It is used here\nnominatively — only to identify the product this library interoperates\nwith — and implies no endorsement.\n\n**No warranty, not for safety-critical use**\n\nThis is an independent personal-use tool provided as-is under the MIT\nlicense. **Do not rely on it for safety-critical monitoring of an infant.**\nUse the official Cradlewise app and follow their safety guidance. The\nauthors assume no responsibility for any harm, financial loss, or account\ntermination arising from use of this software.\n\n## Contributing\n\nIssues and PRs welcome. Scope I'll accept:\n\n* Bug fixes in the Janus / WebRTC flow.\n* Better reconnect logic and error taxonomy.\n* Additional examples (HomeAssistant bridge, Frigate sidecar, etc.).\n* Protocol documentation improvements.\n\nScope I'll decline:\n\n* Anything that sends control commands to a crib.\n* Anything that ships credentials, tokens, or per-account identifiers.\n* Anything that makes the library usable as a mass-scraping tool.\n\n## Credits\n\n* [`pycradlewise`](https://github.com/jlamendo/pycradlewise) by Jon Lamendola —\n  AWS Cognito SRP auth, AWS IoT MQTT, device shadow access.\n* [`aiortc`](https://github.com/aiortc/aiortc) by Jeremy Lainé — the WebRTC\n  stack that makes Python WebRTC actually work.\n* [Janus Gateway](https://janus.conf.meetecho.com/) — the server side of the\n  media pipeline (not affiliated with this project, just used by Cradlewise).\n\n## Support\n\nIf this project helped you get more out of your Cradlewise, consider buying me a coffee!\n\n[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-support-yellow?logo=buy-me-a-coffee\u0026style=for-the-badge)](https://buymeacoffee.com/imaznation)\n\n## License\n\nMIT. See [`LICENSE`](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimaznation%2Fcradlewise-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimaznation%2Fcradlewise-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimaznation%2Fcradlewise-bridge/lists"}