{"id":20593339,"url":"https://github.com/objectisadvantag/roomkit-collector","last_synced_at":"2026-03-10T06:04:26.093Z","repository":{"id":89281374,"uuid":"122473269","full_name":"ObjectIsAdvantag/roomkit-collector","owner":"ObjectIsAdvantag","description":"Collects PeopleCount events from Webex Room devices, and computes weighted averages ","archived":false,"fork":false,"pushed_at":"2020-01-23T04:12:47.000Z","size":485,"stargazers_count":16,"open_issues_count":4,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-13T18:43:39.452Z","etag":null,"topics":["cisco","jsxapi","peoplecount","roomdevices","timeseries","xapi"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ObjectIsAdvantag.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}},"created_at":"2018-02-22T12:05:55.000Z","updated_at":"2020-09-06T21:23:15.000Z","dependencies_parsed_at":"2023-03-03T08:00:36.352Z","dependency_job_id":null,"html_url":"https://github.com/ObjectIsAdvantag/roomkit-collector","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ObjectIsAdvantag/roomkit-collector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Froomkit-collector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Froomkit-collector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Froomkit-collector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Froomkit-collector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ObjectIsAdvantag","download_url":"https://codeload.github.com/ObjectIsAdvantag/roomkit-collector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ObjectIsAdvantag%2Froomkit-collector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30326878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T05:25:20.737Z","status":"ssl_error","status_checked_at":"2026-03-10T05:25:17.430Z","response_time":106,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cisco","jsxapi","peoplecount","roomdevices","timeseries","xapi"],"created_at":"2024-11-16T07:48:05.357Z","updated_at":"2026-03-10T06:04:26.072Z","avatar_url":"https://github.com/ObjectIsAdvantag.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PeopleCount Collector for Room Devices [![published](https://static.production.devnetcloud.com/codeexchange/assets/images/devnet-published.svg)](https://developer.cisco.com/codeexchange/github/repo/ObjectIsAdvantag/roomkit-collector)\n\nCollects PeopleCount events from Webex Room Devices, stores them in an in-memory Time Series database to compute weighted averages over flexible time windows, and returns these data through a RESTful API.\n\nBackground: \n- Webex Room Devices fire events every time they notice a change. As participants in meeting roms happen to move their head, it is frequent to see updates to the PeopleCount counter even though no participant entered or left the room. Thus, when queried several times, even in close intervals, the PeopleCount value returned by a Room Kit would be expected to differ.\n- The collector batch utility and 'barycentre' computation help create a stable counter for each device part of a RoomKit deployment. Concretely, PeopleCounter events for each device are collected and stored in an in-memory timeseries database. Moreover, a REST API lets you retreive computed averaged values for a custom period of time.\n\nThis repo contains 3 components:\n1. [a collector batch](collector/collector.js): collects PeopleCount events for a pre-configured list of devices, and stores them as TimeSeries (also recycles all elapsed TimeSeries, aka, out of the observation window),\n2. [a 'barycentre' utility](util/barycentre.js): computes an average value from a Time Series, by weighting each value based on its duration (before next event happens,\n3. [a REST API](server.js): exposes the latest and average weighted value from PeopleCount events fired by a [pre-configured list of devices](devices.json). \n\n\n## Quickstart\n\nTo install and configure the collector, run the instructions below:\n\n```shell\ngit clone https://github.com/ObjectIsAdvantag/roomkit-collector\ncd roomkit-collector\nnpm install\n```\n\nLet's now configure the collector for your Room Devices deployment:\nEdit the [devices.json file](devices.json) with your Room Devices deployment.\n\nHere is an example of a deployment of RoomKits in the DevNet Zone:\n\n```json\n[\n  {\n    \"id\": \"Workbench1\",\n    \"location\": \"Workshop 1\",\n    \"ipAddress\": \"192.68.1.32\",\n    \"username\" : \"integrator\",\n    \"password\" : \"integrator\"\n  },\n  {\n    \"id\": \"Workbench2\",\n    \"location\": \"Workshop 2\",\n    \"ipAddress\": \"192.68.1.33\",\n    \"username\" : \"integrator\",\n    \"password\" : \"integrator\"\n  },\n  {\n    \"id\": \"Workbench3\",\n    \"location\": \"Workshop 3\",\n    \"ipAddress\": \"192.68.1.34\",\n    \"username\" : \"integrator\",\n    \"password\" : \"integrator\"\n  }\n]\n```\n\nNow, we will run the collector in DEBUG mode, and with an observation window of 60 seconds (time series older than 1 minute are erased):\n\n```shell\n# Starts the collector collecting PeopleCount for devices listed in devices.json, and computes averages over 60s periods\nDEBUG=collector*,api*  WINDOW=60 node server.js\n...\n  collector:fine connecting to device: Workbench1 +0ms\n  collector:fine connecting to device: Workbench2 +16ms\n  collector:fine connecting to device: Workbench3 +18ms\n  collector collecting window: 60 seconds +0ms\n\nCollector API started at http://localhost:8080/\n   GET / for healthcheck\n   GET /devices for the list of devices\n   GET /devices/{device} to get the details for the specified device\n   GET /devices/{device}/last for latest PeopleCount value received\n   GET /devices/{device}/average?period=30 for a computed average\n\n  collector:fine connexion successful for device: Workbench1 +334ms\n  collector connected to device: Workbench1 +336ms\n  collector:fine fetched PeopleCount for device: Workbench1 +17ms\n  collector:fine adding count: 0, for device: Workbench1 +1ms\n  collector:fine adding feedback listener to device: Workbench1 +1ms\n...\n```\n\nAll set! \n\nYou can now query the Collector's API (make sure to replace `Workbench1` below by one of the devices identifier configured in your devices.json):\n\n- GET / =\u003e healthcheck\n- GET /devices =\u003e returns the list of devices for which data is  collected\n- GET /devices/Workbench1 =\u003e returns the details for the specified device\n- GET /devices/Workbench1/last =\u003e returns the latest PeopleCount value fired by the 'Workbench1' device\n- GET /devices/Workbench1/max =\u003e returns the max value on the default period (15 seconds)  \n- GET /devices/Workbench1/average?period=60 =\u003e returns an averaged PeopleCount value computed from the PeopleCount events fired by the 'Workbench1' device, over the last 60 seconds\n\nExample:\n\n`GET http://localhost:8080/devices/Workbench1/average?period=60`\n\n```json\n{\n    \"device\": \"Workbench1\",\n    \"peopleCount\": 8.508,\n    \"period\": \"60\",\n    \"unit\": \"seconds\"\n}\n```\n\n_Note that the average weighted value is not rounded by default, in order to maximize your options to use these averages._\n\n\n## Mock service\n\nFor tests purpose, a mock mimics the collector API and returns random data for the same list of devices.\n\n```shell\nDEBUG=collector*,api*  WINDOW=60 node mock.js\n...\nCollector API started at http://localhost:8080/\n   GET / for healthcheck\n   GET /devices for the list of devices\n   GET /devices/{device} to get the details for the specified device\n   GET /devices/{device}/last for latest PeopleCount value received\n   GET /devices/{device}/average?period=30 for a computed average\n\n  api:fine returned mock latest: 7, for device: Workbench1 +0ms\n  api:fine returned mock latest: 4, for device: Workbench1 +2s\n  api:fine returned mock latest: 6, for device: Workbench1 +879ms\n  api:fine returned mock average: -1, for device: Workbench1 +9s\n  api:fine returned mock average: 1, for device: Workbench1 +3s\n...\n```\n\n\n## History\n\nv1.0: release for DevNet Automation Exchange\n\nv0.5: updates for Cisco Live US 2018\n\nv0.4: updates for [DevNet Create](https://devnetcreate.io/) with a [React Map](https://github.com/ObjectIsAdvantag/roomkit-react-map) companion\n\nv0.3: updates for [Cisco Connect Finland](https://www.cisco.com/c/m/fi_fi/training-events/2018/cisco-connect/index.html#~stickynav=2) (Messukeskus)\n\nv0.2: updates for [Cisco Live Melbourne](https://www.ciscolive.com/anz/)\n\nv0.1: created at [BCX18 - Bosch IoT Hackathon Berlin](https://github.com/ObjectIsAdvantag/hackathon-resources/tree/master/bcx18-berlin)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjectisadvantag%2Froomkit-collector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobjectisadvantag%2Froomkit-collector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjectisadvantag%2Froomkit-collector/lists"}