{"id":19322199,"url":"https://github.com/fomtarro/vts-heartrate","last_synced_at":"2025-08-24T18:39:53.035Z","repository":{"id":37078601,"uuid":"425377650","full_name":"FomTarro/vts-heartrate","owner":"FomTarro","description":"Heartrate Monitor Plugin for VTube Studio","archived":false,"fork":false,"pushed_at":"2025-02-10T00:55:22.000Z","size":71402,"stargazers_count":7,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-22T19:44:56.128Z","etag":null,"topics":["csharp","heartbeat","unity","vtube-studio","vtuber"],"latest_commit_sha":null,"homepage":"https://www.skeletom.net/projects/vts-heartrate","language":"C#","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/FomTarro.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}},"created_at":"2021-11-07T00:16:57.000Z","updated_at":"2025-02-10T00:54:52.000Z","dependencies_parsed_at":"2025-04-22T19:52:54.444Z","dependency_job_id":null,"html_url":"https://github.com/FomTarro/vts-heartrate","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/FomTarro/vts-heartrate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FomTarro%2Fvts-heartrate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FomTarro%2Fvts-heartrate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FomTarro%2Fvts-heartrate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FomTarro%2Fvts-heartrate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FomTarro","download_url":"https://codeload.github.com/FomTarro/vts-heartrate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FomTarro%2Fvts-heartrate/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269809501,"owners_count":24478552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"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":["csharp","heartbeat","unity","vtube-studio","vtuber"],"created_at":"2024-11-10T01:40:30.950Z","updated_at":"2025-08-11T00:11:54.086Z","avatar_url":"https://github.com/FomTarro.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"![We finally have a logo!](img/banner_logo.png)\n\n# VTS-Heartrate\nA VTube Studio plugin that allows for connectivity between heart rate monitors (HRM) and VTube Studio!\n\n![Pulsoid Verified Badge](https://pulsoid.net/s/github-badge)\n \n[Download the latest version here!](https://skeletom-ch.itch.io/vts-heartrate) Or, in the [release section](https://github.com/FomTarro/vts-heartrate/releases) of this repo.\n\n![Working Example](img/akari_gif_2.gif)\n \n# Features\n\n💓 Support for \u003cb\u003emany heart rate monitors\u003c/b\u003e with [pulsoid.net](#pulsoid), [hyperate.io](#hyperate), [ANT+](#ant) and even [Fitbit](#fitbit)!  \n\n💓 Configurable \u003cb\u003emodel tinting\u003c/b\u003e that scales with pulse!\n\n💓 Automatic \u003cb\u003eexpression and hotkey triggering\u003c/b\u003e at desired heartrate thresholds!\n\n💓 Custom \u003cb\u003etracking parameters\u003c/b\u003e for pulse and breath!\n\n💓 Support for \u003cb\u003eLive2D Items\u003c/b\u003e!\n\n💓 NEW! Dynamically control \u003cb\u003e[VTube Studio VFX](https://github.com/DenchiSoft/VTubeStudio/wiki/Visual-Effects)\u003c/b\u003e with your heartbeat! \n\n💓 NEW! \u003cb\u003ePlugin API\u003c/b\u003e so that you can build your own apps that consume or write heartrate data!\n\n# Table of Contents\n* [About](#about)\n* [Usage](#usage)\n    * [Heartrate Input Methods](#heartrate-input-methods)\n        * [Test Slider](#test-slider)\n        * [Read from File](#read-from-file)\n        * [API WebSocket](#api-websocket)\n        * [Pulsoid](#pulsoid)\n        * [ANT+](#ant)\n        * [HypeRate](#hyperate)\n        * [Fitbit](#fitbit)\n    * [Outputs](#outputs)\n        * [Art Mesh Tinting](#art-mesh-tinting)\n        * [Automatic Expression Triggering](#automatic-expression-triggering)\n        * [Automatic Hotkey Triggering](#automatic-hotkey-triggering)\n        * [Custom Tracking Parameters](#custom-tracking-parameters)\n        * [Live2D Items](#live2d-items)\n        * [VFX Configs](#vfx-configs)\n        * [Stream Widget](#stream-widget)\n    * [Profiles](#profiles)\n* [API](#api)\n    * [Data API](#data-api)\n    * [Events API](#event-api)\n    * [Input API](#input-api)\n        * [Authenticating Your Plugin](#authenticating-your-plugin)\n        * [Writing Heartrate Data](#writing-heartrate-data)\n    * [Errors](#errors)\n* [FAQ](#faq)\n    * [\"What devices are supported?\"](#q-what-devices-are-supported)\n* [Roadmap](#roadmap)\n\n\n# About\nThis plugin is developed by Tom \"Skeletom\" Farro. If you need to contact him, the best way to do so is via [Twitter](https://www.twitter.com/FomTarro).\n\nIf you're more of an email-oriented person, you can contact his support email: [tom@skeletom.net](mailto:tom@skeletom.net).\n\n# Usage\nGetting up and running is relatively straightforward. The plugin will automatically connect to VTube Studio on launch. From there, do the following steps:\n\n* Input an estimated \u003cb\u003eminimum\u003c/b\u003e and \u003cb\u003emaximum\u003c/b\u003e heartrate.\n* Select a desired heartrate \u003cb\u003einput method\u003c/b\u003e. You can connect over bluetooth using your phone and [pulsoid.net](https://www.pulsoid.net) or [hyperate.io](https://www.hyperate.io/), connect directly to your PC with an [ANT+](https://www.thisisant.com/consumer/ant-101/what-is-ant) USB dongle, or even use your [Fitbit](#fitbit) with a special companion app.\n* Add [\u003cb\u003eArt Mesh Tint modules\u003c/b\u003e](#art-mesh-tinting) and configure them to parts of your model!\n* Add [\u003cb\u003eExpression and Hotkey Trigger modules\u003c/b\u003e](#automatic-expression-triggering) and configure them to activate model functions automatically!\n* Hook up [\u003cb\u003eCustom Tracking Parameters\u003c/b\u003e](#custom-tracking-parameters), to your model for things like breathing speed!\n\nA comprehensive [video tutorial](https://www.youtube.com/watch?v=tV1kK0uSjFE) has also been provided as reference.\n\n\n## Heartrate Input Methods\nIn the interest of being widely accessible, this plugin features a wide set of possible input methods, which you may freely switch between at any time.\n \n### Test Slider\nThe slider is primarily useful for quick testing of different heartrate values. The slider range is from 0 to 255.\n \n### Read from File\nThis input method allows you to read heartrate data from an external file.\nThe file must simply contain the \u003cb\u003enumeric heartrate value\u003c/b\u003e in \u003cb\u003eplain text\u003c/b\u003e. File path must be absolute. Useful if you have another program that can output heartrate data.\n \n### API WebSocket\nThis input method allows you to read heartrate data from the \u003cb\u003eInput API\u003c/b\u003e. For more information about the API, consult the [API Documentation](#API).\n\n### Pulsoid\n![Pulsoid Verified Badge](https://pulsoid.net/s/github-badge)\n\n[\u003cb\u003ePulsoid\u003c/b\u003e](https://www.pulsoid.net) is a free third-party app for Android/iOS which allows for easy, reliable connectivity to a wide set of heartrate monitors via the Bluetooth of your mobile device. \n\nOnce you have a Pulsoid account, you can use this input method to collect heartrate data from the service.\n \nBy clicking the \u003cb\u003e'Login' button\u003c/b\u003e in the plugin, you will be asked to grant this plugin permission to connect to your account. You will then be given an \u003cb\u003e'Authentication Token'\u003c/b\u003e which you must paste into the plugin.\n \n### ANT+\n[\u003cb\u003eANT+\u003c/b\u003e](https://www.thisisant.com/consumer/ant-101/what-is-ant) is a low-power protocol supported by many sport and fitness sensors.\n\nThis input method allows for direct connection to your ANT+ device, provided that you have a \u003cb\u003eUSB receiver\u003c/b\u003e plugged in.\n\nBy clicking the \u003cb\u003e'Refresh' button\u003c/b\u003e, this plugin will begin a continuous scan for devices that output heartrate data.\nThen, simply select one from the dropdown and click the \u003cb\u003e'Connect' button\u003c/b\u003e.\n\nPlease note that this plugin is not an officially licensed or certified affiliate of the ANT+ Brand.\n\n### HypeRate\n[\u003cb\u003eHypeRate\u003c/b\u003e](https://www.hyperate.io/) is a free third-party app for Android/iOS which allows for easy, reliable connectivity to a wide set of heartrate monitors via the Bluetooth of your mobile device. \n\nOnce you have a HypeRate account, you can use this input method to collect heartrate data from the service.\n\n### Fitbit\n\n**⚠ IMPORTANT! ⚠**: As of October 2023, [Pulsoid](#pulsoid) and [HypeRate](#hyperate) now natively support Fitbit devices through their app! As such, it is **highly recommended** to use one of these input methods for this plugin, and connect your Fitbit device through that instead.\n\n[\u003cb\u003eFitbit\u003c/b\u003e](https://www.fitbit.com) is wearable fitness device brand, with an app for Android/iOS.\n\nIn order to use your Fitbit with vts-heartrate, you will need to download a special companion app onto the Fitbit device itself. \n\nTo do this, select your watch model from the dropdown. Then scan the \u003cb\u003e'Download the Companion App' QR code\u003c/b\u003e with your phone, which will take you to the Fitbit App Gallery listing for the companion app version that is compatible with your model. Follow the prompts on your phone to install this companion app via the Fitbit phone app.\n\nOn the phone app, beneath the \u003cb\u003e'Install' button\u003c/b\u003e, there will be sections labelled as \u003cb\u003e'Permissions'\u003c/b\u003e and \u003cb\u003e'Settings'\u003c/b\u003e. Make sure to grant all requested permissions. Then navigate to \u003cb\u003e'Settings'\u003c/b\u003e, where you will be prompted for \u003cb\u003eYour Local IP\u003c/b\u003e, which is provided to you by the vts-heartrate PC app. Upon entering that information, your Fitbit watch should finally begin sending heartrate data to vts-heartrate after a short delay.\n\nIf you ever need to return to the \u003cb\u003e'Settings'\u003c/b\u003e menu again, in order to update \u003cb\u003eYour Local IP\u003c/b\u003e, simply scan the \u003cb\u003e'Download the Companion App' QR code\u003c/b\u003e again.\n\nThis setup also requires that your phone is on the same network as the PC running vts-heartrate, because your phone is actually the device relaying information between the Fitbit and the PC.\n\nA list of [compatible Fitbit models can be found in the FAQ at the bottom of this README](#q-what-devices-are-supported).\n\n## Outputs\n \n### Art Mesh Tinting\nThis output will gradually tint the matched \u003cb\u003eArt Meshes\u003c/b\u003e the desired color, based on your current heartrate. For example, you can use this to make your model's face flushed for workouts, or run cold during horror games.\n \n\u003cb\u003eArt Meshes\u003c/b\u003e are matched as long as their names or tags contain \u003cb\u003eany\u003c/b\u003e of the provided list of text to match. For example, providing the text '\u003cb\u003ehead,mouth,neck\u003c/b\u003e' will match Art Meshes with names like '\u003cb\u003eforehead\u003c/b\u003e', '\u003cb\u003eoutermouth2\u003c/b\u003e', and '\u003cb\u003eleftneckside1\u003c/b\u003e'.\nText to match must be \u003cb\u003ecomma separated\u003c/b\u003e and should \u003cb\u003enot contain spaces\u003c/b\u003e.\n \nIf you are unsure of what your Art Meshes are named, a great web-tool was developed by \u003cb\u003eHawkbar\u003c/b\u003e called [\u003cb\u003eVTubeStudioTagger\u003c/b\u003e](https://hawk.bar/VTubeStudioTagger/), which offers an intuitive way to discover the names of your model's Art Meshes.\n \nAdditionally, as of version 1.3.0, you can select specific Art Meshes by clicking the \u003cb\u003e'Select Art Meshes in VTube Studio' button\u003c/b\u003e, which will open a prompt in VTube Studio.\n\n![Working Example](img/color_setup_2.png)\n\n### Automatic Expression Triggering\nThis output will cause an \u003cb\u003eExpression\u003c/b\u003e to \u003cb\u003eactivate or deactivate\u003c/b\u003e when the current heartrate is \u003cb\u003eabove or below a given threshold\u003c/b\u003e, based on the selected behavior settings.\n\nFor example, the configuration in the provided image will cause the `angry` Expression to automatically activate when the heartrate exceeds 120 BPM, and will deactivate when the heartrate falls back beneath 120 BPM.\n\n![Working Example](img/expression_trigger_2.png)\n\n### Automatic Hotkey Triggering\nThis output will cause a \u003cb\u003eHotkey\u003c/b\u003e to be triggered when the current heartrate is \u003cb\u003eabove or below a given threshold\u003c/b\u003e, based on the selected behavior settings.\n \nFor example, the configuration in the provided image will cause the `panic` Item Scene to automatically toggle when the heartrate exceeds 120 BPM, and will toggle again when the heartrate falls back beneath 120 BPM.\n\n![Working Example](img/hotkey_trigger_2.png)\n\n### Custom Tracking Parameters\nThis plugin outputs \u003cb\u003efifteen custom tracking parameters\u003c/b\u003e for use. They are as follows:\n \n* `VTS_Heartrate_Linear`: A value that scales from 0.0 to 1.0 as your heartrate moves across the expected range.\n* `VTS_Heartrate_Pulse`: A value that bounces back and forth between 0.0 and 1.0 with a frequency exactly matching your heartrate.\n* `VTS_Heartrate_Breath`: A value that bounces back and forth between 0.0 and 1.0 with a frequency slower than `VTS_Heartrate_Pulse`, suitable for controlling your model's `ParamBreath` output parameter.\n\nThe following parameters are primarily suited for controlling Live2D props, but you may also find them useful of your model:\n\n* `VTS_Heartrate_BPM`: A value that represents the actual current BPM from 0 to 255, rather than a normalized value from 0.0 to 1.0.\n* `VTS_Heartrate_BPM_Ones`: A value from 0 to 9 that represents the first digit of the current BPM. For example, with a heartrate of 95, this parameter would be 5.\n* `VTS_Heartrate_BPM_Tens`: A value from 0 to 9 that represents the second digit of the current BPM. For example, with a heartrate of 95, this parameter would be 9.\n* `VTS_Heartrate_BPM_Hundreds`: A value from 0 to 9 that represents the third digit of the current BPM. For example, with a heartrate of 95, this parameter would be 0.\n* `VTS_Heartrate_Repeat_1`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every heartbeat.\n* `VTS_Heartrate_Repeat_5`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every 5 heartbeats.\n* `VTS_Heartrate_Repeat_10`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every 10 heartbeats.\n* `VTS_Heartrate_Repeat_20`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every 20 heartbeats.\n* `VTS_Heartrate_Repeat_30`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every 30 heartbeats.\n* `VTS_Heartrate_Repeat_60`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every 60 heartbeats.\n* `VTS_Heartrate_Repeat_120`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with every 120 heartbeats.\n* `VTS_Heartrate_Repeat_Breath`: A value that scales linearly from 0.0 to 1.0 and resets back to 0.0 with the frequency of the `VTS_Heartrate_Breath` parameter.\n\n\nFor more information on how to integrate these tracking parameters into your model, please refer to the [Official VTube Studio documentation](https://github.com/DenchiSoft/VTubeStudio/wiki/Plugins#what-are-custom-parameters).\n \n![Custom Parameter setup](img/parameter_setup.png)\n\n### Live2D Items\nThere are several \u003cb\u003eLive2D Item assets\u003c/b\u003e available which are \u003cb\u003ealready configured\u003c/b\u003e to take advantage of the above custom parameters. You can find them at the [7M|C Shop](https://7mcproductions.com/asset-shop/). These assets packs are:\n\n* [Scared Emote Kit](https://7mcproductions.com/product/scared-emotion-toggle-kit/)\n* [Exercise Emote Kit](https://7mcproductions.com/product/exercise-emotions-toggle-kit/)\n* [Excited Emote Kit](https://7mcproductions.com/product/excited-emotions-toggle-kit/)\n* [Heart Rate Starter Kit](https://7mcproductions.com/product/heart-rate-starter-kit/)\n\nThese packs include things such as sweat drips, EKG monitors, steamy breath puffs and more.\n\nOf course, if you're up the the task, you can also \u003cb\u003emake your own Live2D Items\u003c/b\u003e using these custom parameters, as well. You can find the complete guide to making Live2D Items in the [VTube Studio Manual](https://github.com/DenchiSoft/VTubeStudio/wiki/Live2D-Items).\n\n### VFX Configs\n\nVTube Studio offers a ton of cool [\u003cb\u003epost-processing rendering effects\u003c/b\u003e](https://github.com/DenchiSoft/VTubeStudio/wiki/Visual-Effects), called \"visual effects\" or \"\u003cb\u003eVFX\u003c/b\u003e\" for short.\n\nYou can make the intensity of these effects scale with your heartrate using \u003cb\u003eCustom Tracking Parameters\u003c/b\u003e! Simply \u003cb\u003eselect the desired tracking parameter\u003c/b\u003e that you want to use to \u003cb\u003econtrol a given config value\u003c/b\u003e of the effect. You can then additionally \u003cb\u003emodify the config value\u003c/b\u003e using the slider to \u003cb\u003eincrease\u003c/b\u003e or \u003cb\u003edecrease\u003c/b\u003e its maximum intensity.\n\nThere is a \u003cb\u003elot of customizability\u003c/b\u003e with this feature, so it is recommended that you \u003cb\u003eplay around with different values\u003c/b\u003e and see how they look.\n\nFor example, the configuration in the provided image will cause the `analog_glitch` effect to have a pulsating intensity driven by the `VTS_Heartrate_Pulse` parameter, which is then multiplied by `0.50` to dampen the minimum and maximum strength of the overall effect. It will also cause the `scanline_jitter` aspect of the effect to have an intensity driven by `VTS_Heartrate_Linear` parameter, multiplied by `0.65` for the same reason. \n\nIn this way, you can enjoy having dynamic VFX that scale with your heartrate, while still being able to limit how intense they get, even at your highest heartrate values.\n\n![VFX Config example](img/vfx_config.png)\n\n### Stream Widget\n\nYou can use the \u003cb\u003eStream Widget\u003c/b\u003e as a [Browser Source in OBS](https://obsproject.com/kb/browser-source), or as a [Web Item in VTube Studio](https://github.com/DenchiSoft/VTubeStudio/wiki/Web-Items). It prints your heartrate in real time, and the backing image does a pulsing animation at the corresponding speed.\n\nThe widget will automatically attempt to connect to vts-heartrate when it loads, so if you open the widget before launching vts-heartrate, simply refresh the widget to connect.\n\nYou can get the URL for the widget from a button within vts-heartrate.\n\n![Stream Widget](img/widget.gif)\n\n## Profiles\nAs of version 1.2.0, vts-heartrate supports \u003cb\u003eprofiles\u003c/b\u003e.\n\nProfiles allow you to have \u003cb\u003emultiple output configurations\u003c/b\u003e for the same model. For example, you may want one profile where you go blue in the face for Horror Games, and another profile where you flush red and activate a sweating expression for Workouts.\n\nYou can even \u003cb\u003ecopy profile configurations\u003c/b\u003e from one profile to another, even across models. This is useful if you have multiple variations of the same base model, such as different outfits.\n\nWhen a model is loaded in VTube Studio, a \u003cb\u003eDEFAULT\u003c/b\u003e profile is automatically loaded along with it. User-created profiles \u003cb\u003emust be loaded manually\u003c/b\u003e.\n\n\n# API\nAs of version 1.2.0, vts-heartrate features its own \u003cb\u003ePlugin API\u003c/b\u003e, so that you can build your own apps that consume or write heartrate data! That's right, this VTube Studio plugin now supports plugins of its own.\n \nThere are three underlying API endpoints, all accessible via WebSocket: the [Data API](#Data-API), the [Events API](#Events-API), and the [Input API](#Input-API).\n \n## Data API\n \nThe \u003cb\u003eData API\u003c/b\u003e is a read-only endpoint accessible at `ws://localhost:\u003cyour chosen port\u003e/data`. Upon connecting to this endpoint, your WebSocket will receive a message containing current heartrate and output parameter data once per frame (60 times per second).\n \nThe message structure is as follows:\n```\n{\n    apiVersion: \"1.0\",\n    messageType: \"DataResponse\",\n    timestamp: 1656382245785\n    data: {\n        heartrate: 103,\n        parameters: {\n            vts_heartrate_bpm: 103,\n            vts_heartrate_bpm_hundreds: 1,\n            vts_heartrate_bpm_ones: 3,\n            vts_heartrate_bpm_tens: 0,\n            vts_heartrate_breath: 0.29349666833877563,\n            vts_heartrate_linear: 1,\n            vts_heartrate_pulse: 0.994240403175354,\n            vts_heartrate_repeat_1: 0.27418050169944763,\n            vts_heartrate_repeat_5: 0.07212083041667938,\n            vts_heartrate_repeat_10: 0.3203545808792114,\n            vts_heartrate_repeat_20: 0.12136854976415634,\n            vts_heartrate_repeat_30: 0.4221900999546051,\n            vts_heartrate_repeat_60: 0.714303731918335,\n            vts_heartrate_repeat_120: 0.932239294052124,\n            vts_heartrate_repeat_breath: 0.29349666833877563\n        },\n        tints: [\n            {\n                baseColor: { r: 255, g: 128, b: 128, a: 255 },\n                currentColor: { r: 255, g: 200, b: 200, a: 255 },\n                matchers: ['head', 'face']\n            },\n            {\n                baseColor: { r: 255, g: 128, b: 128, a: 255 },\n                currentColor: { r: 255, g: 200, b: 200, a: 255 },\n                matchers: ['mouth', 'neck']\n            }\n        ]\n    }\n}\n```\nFor more information about the output parameters, consult the [Custom Tracking Parameter Documentation](#Custom-Tracking-Parameters) and [Art Mesh Tinting Documentation](#Art-Mesh-Tinting).\n \n## Event API\n \nThe \u003cb\u003eEvent API\u003c/b\u003e is a read-only endpoint accessible at `ws://localhost:\u003cyour chosen port\u003e/events`. Upon connecting to this endpoint, your WebSocket will receive a message containing event information every time an [Expression Trigger](#Automatic-Expression-Triggering) or [Hotkey Trigger](#Automatic-Hotkey-Triggering) is triggered.\n \nFor \u003cb\u003eExpressions\u003c/b\u003e, the message structure is as follows:\n```\n{\n    apiVersion: \"1.0\",\n    messageType: \"ExpressionEventResponse\",\n    timestamp: 1656382245785\n    data: {\n        threshold: 120,\n        heartrate: 121,\n        expression: \"angry.exp3.json\",\n        behavior: 2,\n        activated: true\n    }\n}\n```\n \nThe complete list of possible `behavior` values is as follows:\n```\nUNKNOWN = -1,    \nACTIVATE_ABOVE_DEACTIVATE_BELOW = 0,\nDEACTIVATE_ABOVE_ACTIVATE_BELOW = 1,\nACTIVATE_ABOVE = 2,\nDEACTIVATE_ABOVE = 3,\nACTIVATE_BELOW = 4,\nDEACTIVATE_BELOW = 5,\n```\n \nFor \u003cb\u003eHotkeys\u003c/b\u003e, the message structure is as follows:\n```\n{\n    apiVersion: \"1.0\",\n    messageType: \"HotkeyEventResponse\",\n    timestamp: 1656382245785\n    data: {\n        threshold: 120,\n        heartrate: 121,\n        hotkey: \"Blush\",\n        behavior: 1\n    }\n}\n```\n \nThe complete list of possible `behavior` values is as follows:\n```\nUNKNOWN = -1,    \nACTIVATE_ABOVE_ACTIVATE_BELOW = 0,\nACTIVATE_ABOVE = 1,\nACTIVATE_BELOW = 2,\n```\n \n## Input API\n \nThe \u003cb\u003eInput API\u003c/b\u003e is a read and write endpoint accessible at `ws://localhost:\u003cyour chosen port\u003e/input`. Upon connecting to this endpoint, your WebSocket will be able to write heartrate data for use with the [API WebSocket](#API-WebSocket) input method.\n \n### Authenticating Your Plugin\n \nFirst, you will need to authenticate your client before you are granted write permission. In order to authenticate, you must first \u003cb\u003erequest a token\u003c/b\u003e by sending a message with the following structure:\n```\n{\n    messageType: \"AuthenticationRequest\",\n    data: {\n        pluginName: \"My Heartrate Plugin\",\n        pluginAuthor: \"Skeletom\",\n        pluginAbout: \"A plugin for connecting a third-party service.\"\n    }\n}\n```\n \nThe user will then be prompted to either Approve or Deny access to this plugin. If the request is approved, the API server will then respond with a message containing a token.\n \nYou only need to do this step if your plugin has not already been granted a token. If it has a token already, you can skip to the next step.\n \nThe message structure is as follows:\n```\n{\n    apiVersion: \"1.0\",\n    messageType: \"AuthenticationResponse\",\n    timestamp: 1656382245785\n    data: {\n        pluginName: \"My Heartrate Plugin\",\n        pluginAuthor: \"Skeletom\",\n        token: \"e404d80b-c160-4af4-a0b9-9c0159f3010e\",\n        authenticated: false\n    }\n}\n```\n \nIt is strongly recommended that you save this token so that your plugin may use it again in the future. Finally, you must now submit an authentication request using the token, by sending a message with the following structure:\n```\n{\n    messageType: \"AuthenticationRequest\",\n    data: {\n        pluginName: \"My Heartrate Plugin\",\n        pluginAuthor: \"Skeletom\",\n        token: \"e404d80b-c160-4af4-a0b9-9c0159f3010e\"\n    }\n}\n```\n \nAssuming you have provided a token that the user has granted access for, the API Server will finally respond with a message indicating that your plugin is fully authenticated, and that you may begin writing heartwrate data.\n \nThe message structure is as follows:\n```\n{\n    apiVersion: \"1.0\",\n    messageType: \"AuthenticationResponse\",\n    timestamp: 1656382245785\n    data: {\n        pluginName: \"My Heartrate Plugin\",\n        pluginAuthor: \"Skeletom\",\n        token: \"e404d80b-c160-4af4-a0b9-9c0159f3010e\",\n        authenticated: true\n    }\n}\n```\n \n### Writing Heartrate Data\n \nOnce your plugin is fully authenticated, you can write heartrate data sending a message with the following structure:\n```\n{\n    messageType: \"InputRequest\",\n    data: {\n        heartrate: 78\n    }\n}\n```\nUpon successfully writing data, the API Server will echo your message back to you as an `InputResponse`, to confirm that it has been received.\n \n## Errors\n \nIn the event that something goes wrong, such as the API Server receiving a message it cannot parse, or a message from an unauthenticated client, your WebSocket will receive an error message.\n \nThe message structure is as follows:\n```\n{\n    apiVersion: \"1.0\",\n    messageType: \"ErrorResponse\",\n    timestamp: 1656382245785\n    data: {\n        errorCode: 403,\n        message: \"This client is not authenticated!\"\n    }\n}\n```\n \nThe complete list of possible `errorCode` values is as follows (they are HTTP status codes):\n```\nOK = 200,\nBAD_REQUEST = 400,\nFORBIDDEN = 403,\nSERVER_ERROR = 500,\n```\n\n# FAQ\n## Q: \"What devices are supported?\"\nA: This plugin supports any device that is supported by \n\n* [Pulsoid (compatibility list)](https://www.blog.pulsoid.net/monitors?from=faq)\n* [HypeRate (compatibility list)](https://www.hyperate.io/supported-devices)\n* [ANT+ with a USB Receiver](https://www.thisisant.com/directory/)\n* The following Fitbit devices:\n    * Versa 3\n    * Sense\n    * Ionic\n    * Versa 2\n    * Versa Lite\n    * Versa\n\nUnfortunately, Fitbit has not provided a way to develop or install third-party apps on their latest models (Versa 4 and later), so the latest devices cannot be supported at this time.\n\n# Roadmap\n \nPlanned features include the following:\n* Localization into additional languages\n* More device integrations (I take requests!)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffomtarro%2Fvts-heartrate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffomtarro%2Fvts-heartrate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffomtarro%2Fvts-heartrate/lists"}