Blog / engineering
Seam Connect NoiseAware Integration Guide blog post cover image
| September 24, 2021
Seam Connect NoiseAware Integration Guide

This guide is for Seam Connect customers who are interested in enabling their users (airbnb hosts, homeowners etc.) to grant access to their NoiseAware devices. By using Seam Connect, customers can see all of a host's devices, see noise events, and add, change or remove noise thresholds.

Getting Started

All requests to the Seam API should have the following header:

Authorization: Bearer seam_2kBBb3xo_rCUWph7G1BswPsRU3LKaBY3Y

Where seam_2kBBb3xo_rCUWph7G1BswPsRU3LKaBY3Y is your API key. If you don't have an API contact Seam staff.

To simplify the examples below, we'll use the following modules and utility variables:

import requests

api_key = "YOUR_API_KEY"
auth_headers = { "Authorization": f"Bearer {api_key}" }

Overview

To get access to a host's devices (called "sensors" or "activity zones" by NoiseAware), the Host must be prompted to authorize Seam Connect to connect with their NoiseAware account. You can do this by showing them a URL to a custom webview created for your organization. After the user has authorized the access, which usually involves logging into NoiseAware, the Seam API will pass data to your application and the webview can be closed. You can now query the Seam API for events and devices.

Step by Step

1. Ask Seam Connect for a webview URL

webview = requests.post(
  "https://connect.getseam.com/connect_webviews/create",
  json={ "accepted_providers": ["noiseaware"] },
  headers=auth_headers
).json()["connect_webview"]

webview_id = webview["connect_webview_id"]
webview_url = webview["url"]

2. Display webview URL to user

# In a web application, you could show this in an iframe
# For Android and IOS, use a webview dialog that you can close automatically
print(f"Navigate to this URL: {webview_url}")

3. Wait for user to authorize access

Poll /connect_webviews/get until the status is authorized.

Note: We are introducing a webhook for this soon! The polling API will always remain available.

noiseaware_account_id = None
while True:
  latest_webview = requests.get(
      f"https://connect.getseam.com/v1/connect_webviews/get",
      params={"connect_webview_id": webview_id},
      headers=auth_headers,
  ).json()["connect_webview"]

  if latest_webview["status"] == "authorized":
      noiseaware_account_id = latest_webview["third_party_account_id"]
    break

  time.sleep(0.25)

4. View Devices Associated with Connected Account

devices = requests.get(
  f"https://connect.getseam.com/v1/devices/list",
  params={ "third_party_account_id": noiseaware_account_id },
  headers=auth_headers
).json()["devices"]

print(devices)
# [
#   {
#     device_id: 'fb74aee8-a745-485e-8b55-1ba87a119bcd',
#     device_type: 'noiseaware_activity_zone',
#     workspace_id: 'a553c010-e2ed-44b0-ab26-7b0f7081089c',
#     locations: [
#       {
#         name: "200 Amy Lane",
#         location_id: "00e96aef-4577-46a4-9172-4d375bb34cff"
#       }
#     ],
#     properties: {
#       status: "online",
#       user_image: "https://s3.amazonaws.com/123456789/customer_image.png",
#       noise_thresholds: [{
#         noise_threshold_id: "1407b5bf-3c35-4ddd-9c14-cd7f193cbd4a",
#         time_in_effect: { readable: "3pm to 6pm daily" },
#         level: { value: 70, unit: "NoiseAware Noise Risk Score" }
#       }]
#     },
#     created_at: '2021-09-22T00:33:38.703Z'
#   }
# ]
device_id = devices[0]["device_id"]

5. Add or Remove Noise Threshold

NOT YET SUPPORTED

res = requests.post(
  f"https://connect.getseam.com/devices/noise_detection/noise_thresholds/create",
  json={
    "name": "Party Limit",
    "time_in_effect": { "start_time": "21:00", "end_time": "23:00", "daily": True, "timezone": "local" },
    "level": { "value": 70, "unit": "Noiseaware Noise Risk Score" }
  },
  headers=auth_headers
).json()

assert(res["ok"] == True)

res = requests.post(
  f"https://connect.getseam.com/devices/noise_detection/noise_threshold/remove",
  json={
    "device_id": device_id,
    "noise_threshold_id": "1407b5bf-3c35-4ddd-9c14-cd7f193cbd4a"
  },
  headers=auth_headers
).json()

assert(res["ok"] == True)

6. Poll for Device Events

res = requests.post(
  f"https://connect.getseam.com/devices/events/list",
  json={
    "device_id": device_id,
    "since": "2021-09-22T18:23:07.018Z"
  }
).json().device_events

# [
#   {
#     "device_event_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "type": "NOISE_DETECTED",
#     "device_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "threshold_name": "Party Noise Limit",
#     "created_at": "2021-09-22T18:23:07.018Z",
#   },
#   {
#     "device_event_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "type": "NOISE_QUIETED",
#     "threshold_name": "Party Noise Limit",
#     "device_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "created_at": "2021-09-22T18:23:07.018Z",
#   },
#   {
#     "device_event_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "type": "DEVICE_ONLINE",
#     "device_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "created_at": "2021-09-22T18:23:07.018Z",
#   },
#   {
#     "device_event_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "type": "DEVICE_ONLINE",
#     "device_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "created_at": "2021-09-22T18:23:07.018Z",
#   },
#   {
#     "device_event_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "type": "DEVICE_CREATED",
#     "device_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "device_type": "noiseaware_activity_zone",
#     "created_at": "2021-09-22T18:23:07.018Z",
#   },
#   {
#     "device_event_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "type": "DEVICE_REMOVED",
#     "device_id": "b9366ab9-8ee4-4d63-9214-d424b5d53342",
#     "created_at": "2021-09-22T18:23:07.018Z",
#   }
# ]

The following device_events are available:

| Event Type | Description | Payload | | -------------- | ------------------------------------------------- | ------------------------------- | | NOISE_DETECTED | Noise has exceeded a noise threshold | { threshold_name, device_id } | | NOISE_QUIETED | Noise has dropped below the noise threshold | { threshold_name, device_id } | | DEVICE_ONLINE | Device has come online | { device_id } | | DEVICE_OFFLINE | Device has gone offline (may have been unplugged) | { device_id } |

These events can also be listened to using the webhook below.

| Event Type | Description | | | -------------- | -------------- | --------------- | | DEVICE_CREATED | Device created | { device_id } | | DEVICE_REMOVED | Device removed | { device_id } |

7. Register an events webhook

NOT YET SUPPORTED

res = requests.post(
  f"https://connect.getseam.com/event_webhooks/create",
  json={
    "request_url": "https://mywebsite.com/my-webhook-handler",
    "type": "device_events",
    "device_type": "noiseaware_activity_zone",
    # "events": ["NOISE_DETECTED", "NOISE_QUIETED"] Optional, defaults to all events
    # device_id: Optional, if not specified, all devices will receive webhook
  }
)