<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.vibhub.io/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jasx</id>
	<title>VibHub Wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.vibhub.io/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jasx"/>
	<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php/Special:Contributions/Jasx"/>
	<updated>2026-05-23T23:27:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=CE&amp;diff=48</id>
		<title>CE</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=CE&amp;diff=48"/>
		<updated>2026-03-31T14:35:36Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;Todo: CE Declaration of conformity.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Todo: CE Declaration of conformity.&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Product_Comparison&amp;diff=47</id>
		<title>Product Comparison</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Product_Comparison&amp;diff=47"/>
		<updated>2026-03-26T21:09:42Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;There are currently two available VibHub dev kits. {| class=&amp;quot;wikitable&amp;quot; |+ !Feature !VibHub Micro !VibHub Classic 4xAA |- |Release Year |2026 |2020 |- |USB Outputs |2x USB-A |4x USB-A |- |Wireless Protocol |WiFi 2.4GHz |WiFi 2.4Ghz |- |Input Port |USB-C |USB Micro |- |Microcontroller |ESP32-S3 |ESP32 |- |Battery |Built in 1500mAh lithium |External 4x AA batteries |- |Size |77x45x20mm (3.03x1.77x0.79 in) |80x106x28mm (3.15x4.17x1.10 in) |- |Weight (Incl Batteries) |68g (2...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are currently two available VibHub dev kits.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Feature&lt;br /&gt;
!VibHub Micro&lt;br /&gt;
!VibHub Classic 4xAA&lt;br /&gt;
|-&lt;br /&gt;
|Release Year&lt;br /&gt;
|2026&lt;br /&gt;
|2020&lt;br /&gt;
|-&lt;br /&gt;
|USB Outputs&lt;br /&gt;
|2x USB-A&lt;br /&gt;
|4x USB-A&lt;br /&gt;
|-&lt;br /&gt;
|Wireless Protocol&lt;br /&gt;
|WiFi 2.4GHz&lt;br /&gt;
|WiFi 2.4Ghz&lt;br /&gt;
|-&lt;br /&gt;
|Input Port&lt;br /&gt;
|USB-C&lt;br /&gt;
|USB Micro&lt;br /&gt;
|-&lt;br /&gt;
|Microcontroller&lt;br /&gt;
|ESP32-S3&lt;br /&gt;
|ESP32&lt;br /&gt;
|-&lt;br /&gt;
|Battery&lt;br /&gt;
|Built in 1500mAh lithium&lt;br /&gt;
|External 4x AA batteries&lt;br /&gt;
|-&lt;br /&gt;
|Size&lt;br /&gt;
|77x45x20mm (3.03x1.77x0.79 in)&lt;br /&gt;
|80x106x28mm (3.15x4.17x1.10 in)&lt;br /&gt;
|-&lt;br /&gt;
|Weight (Incl Batteries)&lt;br /&gt;
|68g (2.4oz)&lt;br /&gt;
|222g (7.8oz)&lt;br /&gt;
|-&lt;br /&gt;
|Max PWM Resolution&lt;br /&gt;
|12 bit&lt;br /&gt;
|8 bit&lt;br /&gt;
|-&lt;br /&gt;
|Capabilities&lt;br /&gt;
|PWM, Programs, Battery Status, Serial Control&lt;br /&gt;
|PWM, Programs&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Wago_Adapter&amp;diff=46</id>
		<title>Wago Adapter</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Wago_Adapter&amp;diff=46"/>
		<updated>2026-03-26T20:54:43Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Wago adapter.jpg|thumb|The Wago Adapter is a cheap way to turn most dumb 5V vibrators into smart ones.]]&lt;br /&gt;
The VibHub Wago adapter is a little bare circuit adapter that lets you convert most dumb 5V vibrators into smart ones by cutting and stripping the cable.&lt;br /&gt;
&lt;br /&gt;
=== Basic Use ===&lt;br /&gt;
First off you need a vibrator that&#039;s capable. Check the [[Compatible toys|Compatible Toys]] page for more info!&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we&#039;ll be using a common 2-in-one vibrator from AliExpress. At the time of writing, these sell for like $4 per pair, so they&#039;re almost cheap enough to be considered disposable. A cheap egg vibrator is a good starting point in case you don&#039;t know what you&#039;re doing. But connecting a simple wire-remote device to a VibHub is very easy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Before you begin, &#039;&#039;&#039;please note that the process is destructive&#039;&#039;&#039;, as you&#039;ll be cutting the cord! Don&#039;t convert a vibrator if you want to restore it at a later date!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you can do one vibrator per adapter, don&#039;t cram multiple cords in there!&lt;br /&gt;
[[File:ExampleProduct.jpg|thumb|Example of a cheap vibrator that can be used.]]&lt;br /&gt;
[[File:Step00.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Cut the cord. You want a lead connected directly to the vibrator!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step01.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Split and strip a bit at the end of the cord to expose some copper. 5mm (0.2&amp;quot;) is enough.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step02.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Press down on the &amp;quot;button&amp;quot; on top and slide the cable in. If you give it a gentle tug after, and it doesn&#039;t release, you&#039;re good!&lt;br /&gt;
&#039;&#039;Note: The polarity of the wires doesn&#039;t matter, you can attach them in any order!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step03.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 4:&#039;&#039;&#039; Repeat with the other wire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step04.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 5:&#039;&#039;&#039; Do the same with the other vibrator if you wish, but that&#039;s it! &#039;&#039;&#039;You&#039;re done!&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Wago_Adapter&amp;diff=45</id>
		<title>Wago Adapter</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Wago_Adapter&amp;diff=45"/>
		<updated>2026-03-26T20:54:01Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Wago adapter.jpg|thumb|The Wago Adapter is a cheap way to turn most dumb 5V vibrators into smart ones.]]&lt;br /&gt;
The VibHub Wago adapter is a little bare circuit adapter that lets you convert most dumb 5V vibrators into smart ones by cutting and stripping the cable.&lt;br /&gt;
&lt;br /&gt;
=== Basic Use ===&lt;br /&gt;
First off you need a vibrator that&#039;s capable. Check the [[Compatible toys|Compatible Toys]] page for more info!&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we&#039;ll be using a common 2-in-one vibrator from AliExpress. At the time of writing, these sell for like $4 per pair, so they&#039;re almost cheap enough to be considered disposable. A cheap egg vibrator is a good starting point in case you don&#039;t know what you&#039;re doing. But connecting a simple wire-remote device to a VibHub is very easy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Before you begin, &#039;&#039;&#039;please note that the process is destructive&#039;&#039;&#039;, as you&#039;ll be cutting the cord! Don&#039;t convert a vibrator if you want to restore it at a later date!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you can do one vibrator per adapter, don&#039;t cram multiple cords in there!&lt;br /&gt;
[[File:ExampleProduct.jpg|thumb|Example of a cheap vibrator that can be used.]]&lt;br /&gt;
[[File:Step00.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Cut the cord. You want a lead connected directly to the vibrator!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step01.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Split and strip a bit at the end of the cord to expose some copper. 5mm (0.2&amp;quot;) is enough.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step02.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Press down on the &amp;quot;button&amp;quot; on top and slide the cable in. If you give it a gentle tug after and it doesn&#039;t release, you&#039;re good!&lt;br /&gt;
&#039;&#039;Note: The polarity of the wires doesn&#039;t matter, you can attach them in any order!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Step03.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 4:&#039;&#039;&#039; Repeat with the other wire.&lt;br /&gt;
&lt;br /&gt;
[[File:Step04.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 5:&#039;&#039;&#039; Do the same with the other vibrator if you wish, but that&#039;s it! &#039;&#039;&#039;You&#039;re done!&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Wago_Adapter&amp;diff=44</id>
		<title>Wago Adapter</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Wago_Adapter&amp;diff=44"/>
		<updated>2026-03-26T20:53:30Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;The Wago Adapter is a cheap way to turn most dumb 5V vibrators into smart ones. The VibHub Wago adapter is a little bare circuit adapter that lets you convert most dumb 5V vibrators into smart ones by cutting and stripping the cable.  === Basic Use === First off you need a vibrator that&amp;#039;s capable. Check the Compatible Toys page for more info!  In this tutorial, we&amp;#039;ll be using a common 2-in-one vibrator from AliExpress....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Wago adapter.jpg|thumb|The Wago Adapter is a cheap way to turn most dumb 5V vibrators into smart ones.]]&lt;br /&gt;
The VibHub Wago adapter is a little bare circuit adapter that lets you convert most dumb 5V vibrators into smart ones by cutting and stripping the cable.&lt;br /&gt;
&lt;br /&gt;
=== Basic Use ===&lt;br /&gt;
First off you need a vibrator that&#039;s capable. Check the [[Compatible toys|Compatible Toys]] page for more info!&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we&#039;ll be using a common 2-in-one vibrator from AliExpress. At the time of writing, these sell for like $4 per pair, so they&#039;re almost cheap enough to be considered disposable. A cheap egg vibrator is a good starting point in case you don&#039;t know what you&#039;re doing. But connecting a simple wire-remote device to a VibHub is very easy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Before you begin, &#039;&#039;&#039;please note that the process is destructive&#039;&#039;&#039;, as you&#039;ll be cutting the cord! Don&#039;t convert a vibrator if you want to restore it at a later date!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you can do one vibrator per adapter, don&#039;t cram multiple cords in there!&lt;br /&gt;
[[File:ExampleProduct.jpg|thumb|Example of a cheap vibrator that can be used.]]&lt;br /&gt;
[[File:Step00.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 1:&#039;&#039;&#039; Cut the cord. You want a lead connected directly to the vibrator!&lt;br /&gt;
[[File:Step01.jpg|frameless]]&lt;br /&gt;
&#039;&#039;&#039;Step 2:&#039;&#039;&#039; Split and strip a bit at the end of the cord to expose some copper. 5mm (0.2&amp;quot;) is enough.&lt;br /&gt;
[[File:Step02.jpg|frameless]]&lt;br /&gt;
&#039;&#039;&#039;Step 3:&#039;&#039;&#039; Press down on the &amp;quot;button&amp;quot; on top and slide the cable in. If you give it a gentle tug after and it doesn&#039;t release, you&#039;re good!&lt;br /&gt;
&#039;&#039;Note: The polarity of the wires doesn&#039;t matter, you can attach them in any order!&#039;&#039;&lt;br /&gt;
[[File:Step03.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 4:&#039;&#039;&#039; Repeat with the other wire.&lt;br /&gt;
&lt;br /&gt;
[[File:Step04.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Step 5:&#039;&#039;&#039; Do the same with the other vibrator if you wish, but that&#039;s it! &#039;&#039;&#039;You&#039;re done!&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Step04.jpg&amp;diff=43</id>
		<title>File:Step04.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Step04.jpg&amp;diff=43"/>
		<updated>2026-03-26T20:52:23Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wago&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Step03.jpg&amp;diff=42</id>
		<title>File:Step03.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Step03.jpg&amp;diff=42"/>
		<updated>2026-03-26T20:51:43Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Connect the other one&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Step02.jpg&amp;diff=41</id>
		<title>File:Step02.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Step02.jpg&amp;diff=41"/>
		<updated>2026-03-26T20:49:58Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Connect the wago&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Step01.jpg&amp;diff=40</id>
		<title>File:Step01.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Step01.jpg&amp;diff=40"/>
		<updated>2026-03-26T20:48:38Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Strip the jacket with a scissor&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Step00.jpg&amp;diff=39</id>
		<title>File:Step00.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Step00.jpg&amp;diff=39"/>
		<updated>2026-03-26T20:47:28Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Cut the cord&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:ExampleProduct.jpg&amp;diff=38</id>
		<title>File:ExampleProduct.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:ExampleProduct.jpg&amp;diff=38"/>
		<updated>2026-03-26T20:42:11Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Example of a vibrator that can be converted with the Wago connector.&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Wago_adapter.jpg&amp;diff=37</id>
		<title>File:Wago adapter.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Wago_adapter.jpg&amp;diff=37"/>
		<updated>2026-03-26T20:37:27Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VibHub Wago Adapter&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=36</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=36"/>
		<updated>2026-03-26T20:31:57Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;User Resources&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[[Product Comparison|VibHub Product Comparison]]&lt;br /&gt;
|See which kinds of VibHubs are available, and what their hardware specs are.&lt;br /&gt;
|-&lt;br /&gt;
|[[User Manual]]&lt;br /&gt;
|Learn how to use your VibHub!&lt;br /&gt;
|-&lt;br /&gt;
|[[Compatible toys|Toy Compatibility]]&lt;br /&gt;
|See what kind of toys you can use.&lt;br /&gt;
|-&lt;br /&gt;
|[[Wago Adapter|Using the VibHub Wago Adapter]]&lt;br /&gt;
|A fast snap adapter that lets you turn most 5V vibrators into smart ones.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Developer Resources ==&lt;br /&gt;
Welcome to the VibHub wiki! Before we start, let&#039;s go over some terms:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Term&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|[[Firmware|Device]]&lt;br /&gt;
|This is the physical hardware VibHub, and also refers to the firmware.&lt;br /&gt;
|-&lt;br /&gt;
|[[App]]&lt;br /&gt;
|The code that sends vibration instructions to the Device. This is likely what you&#039;re here for! See the API documentation below!&lt;br /&gt;
|-&lt;br /&gt;
|[[Server]]&lt;br /&gt;
|This is the server that relays messages between the Device and the App. You can host your own!&lt;br /&gt;
|-&lt;br /&gt;
|deviceID&lt;br /&gt;
|A unique ID for each Device that allows the App to communicate with it&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Source Code ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Server VibHub Server]&lt;br /&gt;
|Host your own VibHub server!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Browser VibHub Browser]&lt;br /&gt;
|Official JS client library. See [[VibHub-Browser]] for documentation.&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/SL-XOBJ/blob/master/xobj_core/classes/jas%20VibHub.lsl XOBJ SL Library]&lt;br /&gt;
|Second Life library built on the XOBJ framework&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-SocketDemo Browser Example]&lt;br /&gt;
|Example browser app that lets you run VibHub locally with just a few lines of code!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== API ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!API Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[[REST]]&lt;br /&gt;
|Lets you send vibration programs to a device through simple HTTP requests.&lt;br /&gt;
|-&lt;br /&gt;
|[[Web Sockets]]&lt;br /&gt;
|Much faster than REST requests, recommended if your platform supports it!&lt;br /&gt;
|-&lt;br /&gt;
|[[Tasks|Tasks Reference]]&lt;br /&gt;
|Tasks that your device can handle.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=REST&amp;diff=35</id>
		<title>REST</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=REST&amp;diff=35"/>
		<updated>2026-03-26T14:57:22Z</updated>

		<summary type="html">&lt;p&gt;Jasx: /* vib */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The REST API allows you to send a set of tween instructions to a device. This is a good option if you want to send fewer requests that execute a program of pulses, turning on and off etc, or your platform can&#039;t do websockets.&lt;br /&gt;
&lt;br /&gt;
To send a program to a device, simply send a GET request to: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://vibhub.io/api?id=&amp;lt;/nowiki&amp;gt;&amp;lt;device_id&amp;gt;&amp;amp;type=&amp;lt;type&amp;gt;&amp;amp;data=&amp;lt;json_data_here&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(HTTP is also accepted but should only be used if your app can&#039;t use SSL)&lt;br /&gt;
&lt;br /&gt;
Query params explained:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string&lt;br /&gt;
|The deviceID you want to run the program on&lt;br /&gt;
|-&lt;br /&gt;
|type&lt;br /&gt;
|string&lt;br /&gt;
|The task to send. See Tasks below.&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|varies&lt;br /&gt;
|Depends on the type, see below.&lt;br /&gt;
|}&lt;br /&gt;
Don&#039;t forget to URL encode.&lt;br /&gt;
&lt;br /&gt;
= Types =&lt;br /&gt;
&lt;br /&gt;
=== vib ===&lt;br /&gt;
The &amp;quot;vib&amp;quot; task expects data to be a URL encoded array of objects with the following params:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Required&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|stages&lt;br /&gt;
|N/A&lt;br /&gt;
|Yes&lt;br /&gt;
|Array&lt;br /&gt;
|An array of stage objects to be tweened beetween. See below for stage objects&lt;br /&gt;
|-&lt;br /&gt;
|repeats&lt;br /&gt;
|0&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|Nr times the animation should repeat. 0 plays it once, 1 plays it twice etc. Use -1 for infinity&lt;br /&gt;
|-&lt;br /&gt;
|port&lt;br /&gt;
|0&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|Bitwise combination of ports to run the program on. 0x1 is the first port, 0x2 second and so forth. 0 or negative values will target ALL ports. Most devices handle this as a 16bit signed int, so you can use up to 15 ports on a device.&lt;br /&gt;
|-&lt;br /&gt;
|highres&lt;br /&gt;
|false&lt;br /&gt;
|No&lt;br /&gt;
|boolean&lt;br /&gt;
|When set, we will use all supported bits in the program. Check the &amp;quot;h&amp;quot; response in whois for max nr of bits the device supports.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Stages ===&lt;br /&gt;
The stage is an object containing tweening information for that stage of the program. It has the following properties:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|i&lt;br /&gt;
|0&lt;br /&gt;
|integer/obj/boolean&lt;br /&gt;
|A value between 0 and 255. Higher value = faster vibrations. Or false to use the previous value. Or a RandObject (see below).&lt;br /&gt;
|-&lt;br /&gt;
|d&lt;br /&gt;
|0&lt;br /&gt;
|integer/obj&lt;br /&gt;
|Time in milliseconds to reach specified intensity. 0 = instant. Or a RandObject (see below).&lt;br /&gt;
|-&lt;br /&gt;
|e&lt;br /&gt;
|&amp;quot;Linear.None&amp;quot;&lt;br /&gt;
|string&lt;br /&gt;
|A string denoting the tween.js easing type. See this example for the supported types.&lt;br /&gt;
|-&lt;br /&gt;
|r&lt;br /&gt;
|0&lt;br /&gt;
|integer/object&lt;br /&gt;
|Repeats. 0 = play this stage once, 1 = play this stage twice and so forth. Or a RandObject (see below)&lt;br /&gt;
|-&lt;br /&gt;
|y&lt;br /&gt;
|false&lt;br /&gt;
|boolean/truthy/falsy value&lt;br /&gt;
|Go back and forth. Requires repeats to work. Repeats of 1 goes back and forth once, repeats of 3 goes back and forth twice etc. An even number such as 2 will go forth, back, forth, and then start at forth on the next stage.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RandObject ===&lt;br /&gt;
A RandObject can be used in certain places of a vib call. It&#039;ll generate a random value. This value will be randomized at the start of each program loop, but not program stage loop.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|min&lt;br /&gt;
|0&lt;br /&gt;
|integer&lt;br /&gt;
|Min value to randomize&lt;br /&gt;
|-&lt;br /&gt;
|max&lt;br /&gt;
|varying&lt;br /&gt;
|integer&lt;br /&gt;
|Max value to randomize. The default value for this depends on the stage param you put it in. i=255, d=10000, r=9&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|0&lt;br /&gt;
|integer&lt;br /&gt;
|Adds an offset to the randomly generated value. Useful in yoyo type steps where you always want an odd number of repeats (combine with multi of 2).&lt;br /&gt;
|-&lt;br /&gt;
|multi&lt;br /&gt;
|1&lt;br /&gt;
|integer&lt;br /&gt;
|Multiplies the random value by this. Useful together with offset to generate pulses going up and down n times&lt;br /&gt;
|}&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;min&amp;quot;:0, &amp;quot;max&amp;quot;:3, &amp;quot;offset&amp;quot;:1, &amp;quot;multi&amp;quot;:2}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is useful in repeats with yoyo, as it always generates an odd number. In practice, the above line means &amp;quot;generate 1-4 pulses.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Run a program on device id &amp;quot;JasTestBullet&amp;quot;. The program resets the vibration level to 0, then goes up to 50% and down again 3 times, then resets back to 0.&lt;br /&gt;
Request:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GET &amp;lt;nowiki&amp;gt;https://vibhub.io/api/?id=JasTestBullet&amp;amp;type=vib&amp;amp;data=&amp;lt;/nowiki&amp;gt;[{&amp;quot;stages&amp;quot;:[{&amp;quot;i&amp;quot;:0,&amp;quot;d&amp;quot;:0},{&amp;quot;i&amp;quot;:50,&amp;quot;d&amp;quot;:500,&amp;quot;r&amp;quot;:5,&amp;quot;y&amp;quot;:1},{&amp;quot;i&amp;quot;:0,&amp;quot;d&amp;quot;:0}]}]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;message&amp;quot;:&amp;quot;OK&amp;quot;,&amp;quot;success&amp;quot;:true}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== whois ==&lt;br /&gt;
Lets you get meta information about a connected device:&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Request:&lt;br /&gt;
&amp;lt;code&amp;gt;GET &amp;lt;nowiki&amp;gt;https://vibhub.io/api/?id=JasTestBullet&amp;amp;type=whois&amp;amp;data=&amp;lt;/nowiki&amp;gt;[]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{&amp;quot;message&amp;quot;:{&amp;quot;numPorts&amp;quot;:4,&amp;quot;version&amp;quot;:&amp;quot;0.3.0&amp;quot;,&amp;quot;hwversion&amp;quot;:&amp;quot;esp32&amp;quot;,&amp;quot;custom&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;capabilities&amp;quot;:{&amp;quot;p&amp;quot;:true,&amp;quot;ps&amp;quot;:true,&amp;quot;vib&amp;quot;:&amp;quot;true&amp;quot;}},&amp;quot;success&amp;quot;:true}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Compatible_toys&amp;diff=34</id>
		<title>Compatible toys</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Compatible_toys&amp;diff=34"/>
		<updated>2026-02-04T15:00:45Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In general, you can use any toy that&#039;s directly &#039;&#039;&#039;powered&#039;&#039;&#039; with USB. If the device is &#039;&#039;&#039;charged&#039;&#039;&#039; with USB, it&#039;s incompatible unless you manually rebuild it.&lt;br /&gt;
&lt;br /&gt;
Also note that if the toy has a remote on the cable, then it&#039;s not going to work unless the remote is analog. However, most cheap toys with a remote can be reworked into a VibHub capable toy with a pair of scissors (note that this is a one way conversion).&lt;br /&gt;
&lt;br /&gt;
== Toys that work directly ==&lt;br /&gt;
[[File:Direct pink.jpg|frameless]][[File:Direct black.jpg|frameless]]&lt;br /&gt;
These are toys that are &#039;&#039;&#039;powered&#039;&#039;&#039; directly with USB. They&#039;re a bit of rarity these days. But if you can find one, it&#039;s by far the easiest option.&lt;br /&gt;
&lt;br /&gt;
== Toys that are easy to use with the screw adapter ==&lt;br /&gt;
Using the VibHub Screw Adapter or VibHub Wago Adapter, these devices are budget friendly options. Note that in order to use these with the adapter, you have to manually cut off the wire, strip the end, and screw it in place into the VibHub adapter. This obviously ruins the use of the original remote control, but these toys are super cheap anyhow.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Eggs cut.jpg|frameless]][[File:Egg remote.jpg|frameless]][[File:Tripple cut.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
These devices are super cheap (usually a few dollars), and can be turned into a VibHub toy by cutting the power cord at the base of the remote, stripping away some cord, and using the VibHub Screw/Wago Adapter.  &lt;br /&gt;
You can find them everywhere on sites like Amazon &amp;amp; AliExpress. Just search for &#039;&#039;usb vibrating egg&#039;&#039; or similar.&lt;br /&gt;
&lt;br /&gt;
== Toys that can be used, but require significant rework ==&lt;br /&gt;
&lt;br /&gt;
[[File:Doable.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
Some vibrators with a built in battery &#039;&#039;and are USB-chargeable&#039;&#039; can be reworked into VibHub toys. However, this process involves opening the toy case up, taking out the existing circuitry, and soldering the charge port directly to the vibrator motor. This requires significantly more work, but if you&#039;re comfortable around a soldering iron and basic circuitry, you&#039;ll have an easy time doing so.&lt;br /&gt;
== Toys that are NOT compatible  ==&lt;br /&gt;
[[File:Incompatible voltage.jpg|left|frameless]]&lt;br /&gt;
[[File:Already wireless.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
Toys that don&#039;t rely on 5V (or thereabouts), or that are already wireless cannot be used.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: Technically you can rework an already wireless toy by taking out the existing circuitry and soldering the motor to the charge port, but doing so is a destructive process, and using a simple toy listed above with the screw adapter is going to be much cheaper and easier.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Already_wireless.jpg&amp;diff=33</id>
		<title>File:Already wireless.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Already_wireless.jpg&amp;diff=33"/>
		<updated>2026-02-04T14:58:47Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Toys that are already wireless cannot be used&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Incompatible_voltage.jpg&amp;diff=32</id>
		<title>File:Incompatible voltage.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Incompatible_voltage.jpg&amp;diff=32"/>
		<updated>2026-02-04T14:58:13Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Not powered with 5V&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Doable.jpg&amp;diff=31</id>
		<title>File:Doable.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Doable.jpg&amp;diff=31"/>
		<updated>2026-02-04T14:55:38Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Can be reworked, but requires soldering&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Compatible_toys&amp;diff=30</id>
		<title>Compatible toys</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Compatible_toys&amp;diff=30"/>
		<updated>2026-02-04T14:52:56Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;In general, you can use any toy that&amp;#039;s directly &amp;#039;&amp;#039;&amp;#039;powered&amp;#039;&amp;#039;&amp;#039; with USB. If the device is &amp;#039;&amp;#039;&amp;#039;charged&amp;#039;&amp;#039;&amp;#039; with USB, it&amp;#039;s incompatible unless you manually rebuild it.  Also note that if the toy has a remote on the cable, then it&amp;#039;s not going to work unless the remote is analog. However, most cheap toys with a remote can be reworked into a VibHub capable toy with a pair of scissors (note that this is a one way conversion).  == Toys that work directly == File:Direct pink.jpg|...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In general, you can use any toy that&#039;s directly &#039;&#039;&#039;powered&#039;&#039;&#039; with USB. If the device is &#039;&#039;&#039;charged&#039;&#039;&#039; with USB, it&#039;s incompatible unless you manually rebuild it.&lt;br /&gt;
&lt;br /&gt;
Also note that if the toy has a remote on the cable, then it&#039;s not going to work unless the remote is analog. However, most cheap toys with a remote can be reworked into a VibHub capable toy with a pair of scissors (note that this is a one way conversion).&lt;br /&gt;
&lt;br /&gt;
== Toys that work directly ==&lt;br /&gt;
[[File:Direct pink.jpg|frameless]][[File:Direct black.jpg|frameless]]&lt;br /&gt;
These are toys that are &#039;&#039;&#039;powered&#039;&#039;&#039; directly with USB. They&#039;re a bit of rarity these days. But if you can find one, it&#039;s by far the easiest option.&lt;br /&gt;
&lt;br /&gt;
== Toys that are easy to use with the screw adapter ==&lt;br /&gt;
Using the VibHub Screw Adapter or VibHub Wago Adapter, these devices are budget friendly options. Note that in order to use these with the adapter, you have to manually cut off the wire, strip the end, and screw it in place into the VibHub adapter. This obviously ruins the use of the original remote control, but these toys are super cheap anyhow.&lt;br /&gt;
[[File:Eggs cut.jpg|frameless]][[File:Egg remote.jpg|frameless]][[File:Tripple cut.jpg|frameless]]&lt;br /&gt;
&lt;br /&gt;
These devices are super cheap (usually a few dollars), and can be turned into a VibHub toy by cutting the power cord at the base of the remote, stripping away some cord, and using the VibHub Screw/Wago Adapter.  &lt;br /&gt;
You can find them everywhere on sites like Amazon &amp;amp; AliExpress. Just search for &#039;&#039;usb vibrating egg&#039;&#039; or similar.&lt;br /&gt;
&lt;br /&gt;
== Toys that can be used, but require significant rework ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Toys that are NOT compatible  ==&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Tripple_cut.jpg&amp;diff=29</id>
		<title>File:Tripple cut.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Tripple_cut.jpg&amp;diff=29"/>
		<updated>2026-02-04T14:43:25Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Cheap device that gives you 3 toys&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Egg_remote.jpg&amp;diff=28</id>
		<title>File:Egg remote.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Egg_remote.jpg&amp;diff=28"/>
		<updated>2026-02-04T14:42:53Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Cut and attach to adapter&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Eggs_cut.jpg&amp;diff=27</id>
		<title>File:Eggs cut.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Eggs_cut.jpg&amp;diff=27"/>
		<updated>2026-02-04T14:42:15Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These toys can be cut and wired into the screw adapter&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Direct_black.jpg&amp;diff=26</id>
		<title>File:Direct black.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Direct_black.jpg&amp;diff=26"/>
		<updated>2026-02-04T14:35:41Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Works directly with VibHub&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=File:Direct_pink.jpg&amp;diff=25</id>
		<title>File:Direct pink.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=File:Direct_pink.jpg&amp;diff=25"/>
		<updated>2026-02-04T14:34:57Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Works directly with VibHub&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=24</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=24"/>
		<updated>2026-02-04T12:47:46Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you&#039;re a user rather than a dev, you may be interested in a [[User Manual]]!&lt;br /&gt;
&lt;br /&gt;
Or maybe you&#039;re looking for help finding [[compatible toys]]?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Welcome to the VibHub wiki! Before we start, let&#039;s go over some terms:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Term&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|[[Firmware|Device]]&lt;br /&gt;
|This is the physical hardware VibHub, and also refers to the firmware.&lt;br /&gt;
|-&lt;br /&gt;
|[[App]]&lt;br /&gt;
|The code that sends vibration instructions to the Device. This is likely what you&#039;re here for! See the API documentation below!&lt;br /&gt;
|-&lt;br /&gt;
|[[Server]]&lt;br /&gt;
|This is the server that relays messages between the Device and the App. You can host your own!&lt;br /&gt;
|-&lt;br /&gt;
|deviceID&lt;br /&gt;
|A unique ID for each Device that allows the App to communicate with it&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Source Code ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Server VibHub Server]&lt;br /&gt;
|Host your own VibHub server!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Browser VibHub Browser]&lt;br /&gt;
|Official JS client library. See [[VibHub-Browser]] for documentation.&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/SL-XOBJ/blob/master/xobj_core/classes/jas%20VibHub.lsl XOBJ SL Library]&lt;br /&gt;
|Second Life library built on the XOBJ framework&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-SocketDemo Browser Example]&lt;br /&gt;
|Example browser app that lets you run VibHub locally with just a few lines of code!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!API Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[[REST]]&lt;br /&gt;
|Lets you send vibration programs to a device through simple HTTP requests.&lt;br /&gt;
|-&lt;br /&gt;
|[[Web Sockets]]&lt;br /&gt;
|Much faster than REST requests, recommended if your platform supports it!&lt;br /&gt;
|-&lt;br /&gt;
|[[Tasks|Tasks Reference]]&lt;br /&gt;
|Tasks that your device can handle.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=User_Manual&amp;diff=23</id>
		<title>User Manual</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=User_Manual&amp;diff=23"/>
		<updated>2026-02-04T12:23:15Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VibHub is an open source, open hardware vibrator controller. It allows you to turn any non-battery-driven USB vibrator into a smart internet capable one, supporting 2 ports for the VibHub micro, and 4 ports for the classic 4xAA version. This manual is focused on the newer VibHub Micro version, but a lot of what&#039;s written here is also true for the older 4x AA version.&lt;br /&gt;
&lt;br /&gt;
=== WARNING ===&lt;br /&gt;
&lt;br /&gt;
* The VibHub USB output ports are ONLY for powering motors or similar simple devices such as lights. &#039;&#039;&#039;DO NOT USE THEM TO CHARGE COMPLEX DEVICES, OR YOU MAY CAUSE DAMAGE TO THEM!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
== First steps ==&lt;br /&gt;
# Your device may arrive uncharged or with low charge. Plug the USB port into a charger. A red LED will light up. On charge completion, a green or blue LED will light up next to the charge port.&lt;br /&gt;
# On the side of the device (next to the charging port), is an on/off switch. It&#039;s recommended to charge with the device being off.&lt;br /&gt;
# The charging may take up to 3 hours. &#039;&#039;Footnotes: The reason it takes so long to charge is because the USB spec for computers is limited to 500mA, and the battery size is 1500mAh. Smart charge modules are still quite pricey, so this was a price/user-friendliness tradeoff.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Connecting to WiFi ==&lt;br /&gt;
The VibHub uses WiFi to communicate. The first time you turn on your device, the status LED (near the USB output ports) will turn a solid blue, indicating that the device is in configuration mode.&lt;br /&gt;
&lt;br /&gt;
Note: You can always enter configuration mode by holding down the configuration button (next to the USB charge port) until the status LED turns blue.&lt;br /&gt;
&lt;br /&gt;
# Use a phone, laptop, or other WiFi device and look for networks. Locate the network called VibHub Micro (or similar for your device), and connect to it.&lt;br /&gt;
# On a phone, you usually get the popup &amp;quot;this network requires login&amp;quot; or similar, in which case click that button to enter the captive portal. If not, you can manually open a browser and go to http://192.168.4.1&lt;br /&gt;
# &#039;&#039;&#039;Make note of the device ID&#039;&#039;&#039;, which is the random letters and numbers in the yellow box. This is your &amp;quot;key&amp;quot; used to grant applications access to your device. Click the device ID to copy it. If you want to deauthorize all applications, you can generate a new device id (see below).&lt;br /&gt;
# Click &#039;&#039;Setup&#039;&#039; to configure WiFi.&lt;br /&gt;
# The WiFi page lists detected access points. Click the WiFi you want to connect to.&lt;br /&gt;
# Enter the WiFi password.&lt;br /&gt;
# Press &#039;&#039;Save&#039;&#039;. And wait for the device to reboot.&lt;br /&gt;
# If the Status LED turns GREEN, you&#039;re ready to start using the device! If it turns blue, reconnect to the device WiFi and make sure you entered the correct WiFi credentials.&lt;br /&gt;
&lt;br /&gt;
== Using an App ==&lt;br /&gt;
This comes down to the specific app you&#039;ll want to use. But in general, most apps will provide a way to enter your device ID, (and often a minimum value).&lt;br /&gt;
&lt;br /&gt;
=== Socket Demo ===&lt;br /&gt;
If you just want to quickly test if your device works, try the socket demo: https://jasxsl.github.io/VibHub-SocketDemo/&lt;br /&gt;
&lt;br /&gt;
# Paste your device ID into the text box. When connected, some sliders will be shown. &#039;&#039;Note: The VibHub cannot be used by an app while in WiFi configuration mode (blue LED).&#039;&#039;&lt;br /&gt;
# Drag the first two sliders up to max. You should see the blue LEDs on the USB vibrator ports on your device light up (and any vibrator plugged in will start moving).&lt;br /&gt;
# Pressing &amp;quot;send pulse&amp;quot; sends a pulse program.&lt;br /&gt;
# Pressing &amp;quot;Get Battery&amp;quot; gets a battery voltage reading (if supported).&lt;br /&gt;
&lt;br /&gt;
== Reconfiguring ==&lt;br /&gt;
&lt;br /&gt;
# To reconfigure your device. Turn it on first. Then long-press the config button until the status LED turns a solid blue.&lt;br /&gt;
# Connect again via WiFi (see first steps).&lt;br /&gt;
&lt;br /&gt;
=== Change device ID ===&lt;br /&gt;
&#039;&#039;Note: Changing device ID will de-authorize all apps that have access to your device.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# After entering the configuration portal, press New Normal ID to replace your current ID&lt;br /&gt;
# You can also choose to generate a secure ID. A secure ID is longer and mixes upper and lower case characters.&lt;br /&gt;
&lt;br /&gt;
=== Factory Reset ===&lt;br /&gt;
Factory reset will reset all configuration, including WiFi settings and your device ID. This can be useful if you intend to sell or give your device away and want to reset any personal information.&lt;br /&gt;
&lt;br /&gt;
# To perform a factory reset, turn your device off, then hold the config button while starting it. The status LED will flash RED. Upon performing a factory reset, the device will automatically enter WiFi configuration mode when started.&lt;br /&gt;
&lt;br /&gt;
=== Custom Server ===&lt;br /&gt;
VibHub is fully open source, so if you want to host your own server, you absolutely can (install instructions here: https://github.com/JasXSL/VibHub-Server/)! Or maybe you just want to connect to someone else&#039;s server. &lt;br /&gt;
&lt;br /&gt;
# In config mode, click Setup.&lt;br /&gt;
# At the bottom of the page, enter server host and server port. Do &#039;&#039;not&#039;&#039; use http or https:// etc in the server host, just the domain.&lt;br /&gt;
&lt;br /&gt;
== Status indicator ==&lt;br /&gt;
The status LED is located toward the USB output ports (where you plug in vibrators).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Color&lt;br /&gt;
!Status&lt;br /&gt;
|-&lt;br /&gt;
|Solid Blue&lt;br /&gt;
|Device is in WiFi Configuration mode. You can connect to it via WiFi, and configure it at http://192.168.4.1&lt;br /&gt;
|-&lt;br /&gt;
|Solid Green&lt;br /&gt;
|Device is connected and operational!&lt;br /&gt;
|-&lt;br /&gt;
|Slow flashing green/yellow&lt;br /&gt;
|Device is connected and operational, but battery is low.&lt;br /&gt;
|-&lt;br /&gt;
|Flashing blue/red&lt;br /&gt;
|WiFi error, try restarting or reconfiguring.&lt;br /&gt;
|-&lt;br /&gt;
|Flashign red/green&lt;br /&gt;
|Socket error, check if your server (usually vibhub.io) is up?&lt;br /&gt;
|-&lt;br /&gt;
|Cyan&lt;br /&gt;
|Connecting...&lt;br /&gt;
|-&lt;br /&gt;
|Slow red blink&lt;br /&gt;
|Disconnected from server.&lt;br /&gt;
|-&lt;br /&gt;
|Pink Flash&lt;br /&gt;
|A websocket app has connected to our device.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=User_Manual&amp;diff=22</id>
		<title>User Manual</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=User_Manual&amp;diff=22"/>
		<updated>2026-02-04T12:14:09Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VibHub is an open source, open hardware vibrator controller. It allows you to turn any non-battery-driven USB vibrator into a smart internet capable one, supporting 2 ports for the VibHub micro, and 4 ports for the classic 4xAA version. This manual is focused on the newer VibHub Micro version, but a lot of what&#039;s written here is also true for the older 4x AA version.&lt;br /&gt;
&lt;br /&gt;
=== WARNING ===&lt;br /&gt;
&lt;br /&gt;
* The VibHub USB output ports are ONLY for powering motors or similar simple devices such as lights. &#039;&#039;&#039;DO NOT USE THEM TO CHARGE COMPLEX DEVICES, OR YOU MAY CAUSE DAMAGE TO THEM!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
== First steps ==&lt;br /&gt;
* Your device may arrive uncharged or with low charge. Plug the USB port into a charger. A red LED will light up. On charge completion, a green or blue LED will light up next to the charge port.&lt;br /&gt;
* On the side of the device (next to the charging port), is an on/off switch. It&#039;s recommended to charge with the device being off.&lt;br /&gt;
* The charging may take up to 3 hours. &#039;&#039;Footnotes: The reason it takes so long to charge is because the USB spec for computers is limited to 500mA, and the battery size is 1500mAh. Smart charge modules are still quite pricey, so this was a price/user-friendliness tradeoff.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Connecting to WiFi ==&lt;br /&gt;
The VibHub uses WiFi to communicate. The first time you turn on your device, the status LED (near the USB output ports) will turn a solid blue, indicating that the device is in configuration mode.&lt;br /&gt;
&lt;br /&gt;
Note: You can always enter configuration mode by holding down the configuration button (next to the USB charge port) until the status LED turns blue.&lt;br /&gt;
&lt;br /&gt;
* Use a phone, laptop, or other WiFi device and look for networks. Locate the network called VibHub Micro (or similar for your device), and connect to it.&lt;br /&gt;
* On a phone, you usually get the popup &amp;quot;this network requires login&amp;quot; or similar, in which case click that button to enter the captive portal. If not, you can manually open a browser and go to http://192.168.4.1&lt;br /&gt;
* &#039;&#039;&#039;Make note of the device ID&#039;&#039;&#039;, which is the random letters and numbers in the yellow box. This is your &amp;quot;key&amp;quot; used to grant applications access to your device. Click the device ID to copy it. If you want to deauthorize all applications, you can generate a new device id (see below).&lt;br /&gt;
* Click &#039;&#039;Setup&#039;&#039; to configure WiFi.&lt;br /&gt;
* The WiFi page lists detected access points. Click the WiFi you want to connect to.&lt;br /&gt;
* Enter the WiFi password.&lt;br /&gt;
* Press &#039;&#039;Save&#039;&#039;. And wait for the device to reboot.&lt;br /&gt;
* If the Status LED turns GREEN, you&#039;re ready to start using the device! If it turns blue, reconnect to the device WiFi and make sure you entered the correct WiFi credentials.&lt;br /&gt;
&lt;br /&gt;
== Using an App ==&lt;br /&gt;
This comes down to the specific app you&#039;ll want to use. But in general, most apps will provide a way to enter your device ID, (and often a minimum value).&lt;br /&gt;
&lt;br /&gt;
=== Socket Demo ===&lt;br /&gt;
If you just want to quickly test if your device works, try the socket demo: https://jasxsl.github.io/VibHub-SocketDemo/&lt;br /&gt;
&lt;br /&gt;
* Paste your device ID into the text box. When connected, some sliders will be shown. &#039;&#039;Note: The VibHub cannot be used by an app while in WiFi configuration mode (blue LED).&#039;&#039;&lt;br /&gt;
* Drag the first two sliders up to max. You should see the blue LEDs on the USB vibrator ports on your device light up (and any vibrator plugged in will start moving).&lt;br /&gt;
* Pressing &amp;quot;send pulse&amp;quot; sends a pulse program.&lt;br /&gt;
* Pressing &amp;quot;Get Battery&amp;quot; gets a battery voltage reading (if supported).&lt;br /&gt;
&lt;br /&gt;
== Reconfiguring ==&lt;br /&gt;
&lt;br /&gt;
* To reconfigure your device. Turn it on first. Then long-press the config button until the status LED turns a solid blue.&lt;br /&gt;
* Connect again via WiFi (see first steps).&lt;br /&gt;
&lt;br /&gt;
=== Change device ID ===&lt;br /&gt;
&#039;&#039;Note: Changing device ID will de-authorize all apps that have access to your device.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* After entering the configuration portal, press New Normal ID to replace your current ID&lt;br /&gt;
* You can also choose to generate a secure ID. A secure ID is longer and mixes upper and lower case characters.&lt;br /&gt;
&lt;br /&gt;
=== Factory Reset ===&lt;br /&gt;
Factory reset will reset all configuration, including WiFi settings and your device ID. This can be useful if you intend to sell or give your device away and want to reset any personal information.&lt;br /&gt;
&lt;br /&gt;
To perform a factory reset, turn your device off, then hold the config button while starting it. The status LED will flash RED. Upon performing a factory reset, the device will automatically enter WiFi configuration mode when started.&lt;br /&gt;
&lt;br /&gt;
=== Custom Server ===&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=User_Manual&amp;diff=21</id>
		<title>User Manual</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=User_Manual&amp;diff=21"/>
		<updated>2026-02-04T11:29:43Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;VibHub is an open source, open hardware vibrator controller. It allows you to turn any non-battery-driven USB vibrator into a smart internet capable one, supporting 2 ports for the VibHub micro, and 4 ports for the classic 4xAA version. This manual is focused on the newer VibHub Micro version, but a lot of what&amp;#039;s written here is also true for the older 4x AA version.  === WARNING ===  * The VibHub USB output ports are ONLY for powering motors or similar simple devices su...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VibHub is an open source, open hardware vibrator controller. It allows you to turn any non-battery-driven USB vibrator into a smart internet capable one, supporting 2 ports for the VibHub micro, and 4 ports for the classic 4xAA version. This manual is focused on the newer VibHub Micro version, but a lot of what&#039;s written here is also true for the older 4x AA version.&lt;br /&gt;
&lt;br /&gt;
=== WARNING ===&lt;br /&gt;
&lt;br /&gt;
* The VibHub USB output ports are ONLY for powering motors or similar simple devices such as lights. &#039;&#039;&#039;DO NOT USE THEM TO CHARGE COMPLEX DEVICES, OR YOU MAY CAUSE DAMAGE TO THEM!&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
=== First steps ===&lt;br /&gt;
&lt;br /&gt;
* Your device may arrive uncharged or with low charge. Plug the USB port into a charger. A red LED will light up. On charge completion, a green or blue LED will light up next to the charge port.&lt;br /&gt;
* On the side of the device (next to the charging port), is an on/off switch. It&#039;s recommended to charge with the device being off.&lt;br /&gt;
* The charging may take up to 3 hours. &#039;&#039;Footnotes: The reason it takes so long to charge is because the USB spec for computers is limited to 500mA, and the battery size is 1500mAh. Smart charge modules are still quite pricey, so this was a price/user-friendliness tradeoff.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Connecting to WiFi ===&lt;br /&gt;
The VibHub uses WiFi to communicate. The first time you turn on your device, the status LED (near the USB output ports) will turn a solid blue, indicating that the device is in configuration mode.&lt;br /&gt;
&lt;br /&gt;
Note: You can always enter configuration mode by holding down the configuration button (next to the USB charge port) until the status LED turns blue.&lt;br /&gt;
&lt;br /&gt;
* Use a phone, laptop, or other WiFi device and look for networks. Locate the&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=20</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=20"/>
		<updated>2026-02-04T11:06:52Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you&#039;re a user rather than a dev, you may be interested in a [[User Manual]]!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Welcome to the VibHub wiki! Before we start, let&#039;s go over some terms:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Term&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|[[Firmware|Device]]&lt;br /&gt;
|This is the physical hardware VibHub, and also refers to the firmware.&lt;br /&gt;
|-&lt;br /&gt;
|[[App]]&lt;br /&gt;
|The code that sends vibration instructions to the Device. This is likely what you&#039;re here for! See the API documentation below!&lt;br /&gt;
|-&lt;br /&gt;
|[[Server]]&lt;br /&gt;
|This is the server that relays messages between the Device and the App. You can host your own!&lt;br /&gt;
|-&lt;br /&gt;
|deviceID&lt;br /&gt;
|A unique ID for each Device that allows the App to communicate with it&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Source Code ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Server VibHub Server]&lt;br /&gt;
|Host your own VibHub server!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Browser VibHub Browser]&lt;br /&gt;
|Official JS client library. See [[VibHub-Browser]] for documentation.&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/SL-XOBJ/blob/master/xobj_core/classes/jas%20VibHub.lsl XOBJ SL Library]&lt;br /&gt;
|Second Life library built on the XOBJ framework&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-SocketDemo Browser Example]&lt;br /&gt;
|Example browser app that lets you run VibHub locally with just a few lines of code!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!API Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[[REST]]&lt;br /&gt;
|Lets you send vibration programs to a device through simple HTTP requests.&lt;br /&gt;
|-&lt;br /&gt;
|[[Web Sockets]]&lt;br /&gt;
|Much faster than REST requests, recommended if your platform supports it!&lt;br /&gt;
|-&lt;br /&gt;
|[[Tasks|Tasks Reference]]&lt;br /&gt;
|Tasks that your device can handle.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=REST&amp;diff=19</id>
		<title>REST</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=REST&amp;diff=19"/>
		<updated>2026-01-29T16:50:41Z</updated>

		<summary type="html">&lt;p&gt;Jasx: /* vib */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The REST API allows you to send a set of tween instructions to a device. This is a good option if you want to send fewer requests that execute a program of pulses, turning on and off etc, or your platform can&#039;t do websockets.&lt;br /&gt;
&lt;br /&gt;
To send a program to a device, simply send a GET request to: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://vibhub.io/api?id=&amp;lt;/nowiki&amp;gt;&amp;lt;device_id&amp;gt;&amp;amp;type=&amp;lt;type&amp;gt;&amp;amp;data=&amp;lt;json_data_here&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(HTTP is also accepted but should only be used if your app can&#039;t use SSL)&lt;br /&gt;
&lt;br /&gt;
Query params explained:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string&lt;br /&gt;
|The deviceID you want to run the program on&lt;br /&gt;
|-&lt;br /&gt;
|type&lt;br /&gt;
|string&lt;br /&gt;
|The task to send. See Tasks below.&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|varies&lt;br /&gt;
|Depends on the type, see below.&lt;br /&gt;
|}&lt;br /&gt;
Don&#039;t forget to URL encode.&lt;br /&gt;
&lt;br /&gt;
= Types =&lt;br /&gt;
&lt;br /&gt;
=== vib ===&lt;br /&gt;
The &amp;quot;vib&amp;quot; task expects data to be a URL encoded array of objects with the following params:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Required&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|stages&lt;br /&gt;
|N/A&lt;br /&gt;
|Yes&lt;br /&gt;
|Array&lt;br /&gt;
|An array of stage objects to be tweened beetween. See below for stage objects&lt;br /&gt;
|-&lt;br /&gt;
|repeats&lt;br /&gt;
|0&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|Nr times the animation should repeat. 0 plays it once, 1 plays it twice etc. Use -1 for infinity&lt;br /&gt;
|-&lt;br /&gt;
|port&lt;br /&gt;
|0&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|Bitwise combination of ports to run the program on. 0x1 is the first port, 0x2 second and so forth. 0 or negative values will target ALL ports.&lt;br /&gt;
|-&lt;br /&gt;
|highres&lt;br /&gt;
|false&lt;br /&gt;
|No&lt;br /&gt;
|boolean&lt;br /&gt;
|When set, we will use all supported bits in the program. Check the &amp;quot;h&amp;quot; response in whois for max nr of bits the device supports.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Stages ===&lt;br /&gt;
The stage is an object containing tweening information for that stage of the program. It has the following properties:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|i&lt;br /&gt;
|0&lt;br /&gt;
|integer/obj/boolean&lt;br /&gt;
|A value between 0 and 255. Higher value = faster vibrations. Or false to use the previous value. Or a RandObject (see below).&lt;br /&gt;
|-&lt;br /&gt;
|d&lt;br /&gt;
|0&lt;br /&gt;
|integer/obj&lt;br /&gt;
|Time in milliseconds to reach specified intensity. 0 = instant. Or a RandObject (see below).&lt;br /&gt;
|-&lt;br /&gt;
|e&lt;br /&gt;
|&amp;quot;Linear.None&amp;quot;&lt;br /&gt;
|string&lt;br /&gt;
|A string denoting the tween.js easing type. See this example for the supported types.&lt;br /&gt;
|-&lt;br /&gt;
|r&lt;br /&gt;
|0&lt;br /&gt;
|integer/object&lt;br /&gt;
|Repeats. 0 = play this stage once, 1 = play this stage twice and so forth. Or a RandObject (see below)&lt;br /&gt;
|-&lt;br /&gt;
|y&lt;br /&gt;
|false&lt;br /&gt;
|boolean/truthy/falsy value&lt;br /&gt;
|Go back and forth. Requires repeats to work. Repeats of 1 goes back and forth once, repeats of 3 goes back and forth twice etc. An even number such as 2 will go forth, back, forth, and then start at forth on the next stage.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RandObject ===&lt;br /&gt;
A RandObject can be used in certain places of a vib call. It&#039;ll generate a random value. This value will be randomized at the start of each program loop, but not program stage loop.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|min&lt;br /&gt;
|0&lt;br /&gt;
|integer&lt;br /&gt;
|Min value to randomize&lt;br /&gt;
|-&lt;br /&gt;
|max&lt;br /&gt;
|varying&lt;br /&gt;
|integer&lt;br /&gt;
|Max value to randomize. The default value for this depends on the stage param you put it in. i=255, d=10000, r=9&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|0&lt;br /&gt;
|integer&lt;br /&gt;
|Adds an offset to the randomly generated value. Useful in yoyo type steps where you always want an odd number of repeats (combine with multi of 2).&lt;br /&gt;
|-&lt;br /&gt;
|multi&lt;br /&gt;
|1&lt;br /&gt;
|integer&lt;br /&gt;
|Multiplies the random value by this. Useful together with offset to generate pulses going up and down n times&lt;br /&gt;
|}&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;min&amp;quot;:0, &amp;quot;max&amp;quot;:3, &amp;quot;offset&amp;quot;:1, &amp;quot;multi&amp;quot;:2}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is useful in repeats with yoyo, as it always generates an odd number. In practice, the above line means &amp;quot;generate 1-4 pulses.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Run a program on device id &amp;quot;JasTestBullet&amp;quot;. The program resets the vibration level to 0, then goes up to 50% and down again 3 times, then resets back to 0.&lt;br /&gt;
Request:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GET &amp;lt;nowiki&amp;gt;https://vibhub.io/api/?id=JasTestBullet&amp;amp;type=vib&amp;amp;data=&amp;lt;/nowiki&amp;gt;[{&amp;quot;stages&amp;quot;:[{&amp;quot;i&amp;quot;:0,&amp;quot;d&amp;quot;:0},{&amp;quot;i&amp;quot;:50,&amp;quot;d&amp;quot;:500,&amp;quot;r&amp;quot;:5,&amp;quot;y&amp;quot;:1},{&amp;quot;i&amp;quot;:0,&amp;quot;d&amp;quot;:0}]}]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;message&amp;quot;:&amp;quot;OK&amp;quot;,&amp;quot;success&amp;quot;:true}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== whois ==&lt;br /&gt;
Lets you get meta information about a connected device:&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Request:&lt;br /&gt;
&amp;lt;code&amp;gt;GET &amp;lt;nowiki&amp;gt;https://vibhub.io/api/?id=JasTestBullet&amp;amp;type=whois&amp;amp;data=&amp;lt;/nowiki&amp;gt;[]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{&amp;quot;message&amp;quot;:{&amp;quot;numPorts&amp;quot;:4,&amp;quot;version&amp;quot;:&amp;quot;0.3.0&amp;quot;,&amp;quot;hwversion&amp;quot;:&amp;quot;esp32&amp;quot;,&amp;quot;custom&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;capabilities&amp;quot;:{&amp;quot;p&amp;quot;:true,&amp;quot;ps&amp;quot;:true,&amp;quot;vib&amp;quot;:&amp;quot;true&amp;quot;}},&amp;quot;success&amp;quot;:true}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=18</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=18"/>
		<updated>2026-01-29T13:16:00Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s set all ports on our device to max!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(1); // Sets all ports on the device to max intensity&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VhSocket ==&lt;br /&gt;
VhSocket is the main vibhub manager, allowing you to manage multiple devices from your app!&lt;br /&gt;
&lt;br /&gt;
Versions:&lt;br /&gt;
&lt;br /&gt;
* m - 2026 VibHub Micro&lt;br /&gt;
* o - Original VibHub 4x AA battery version.&lt;br /&gt;
&lt;br /&gt;
=== Overridable ===&lt;br /&gt;
These methods are meant to be overridden by your extended class or on the fly.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has come online.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has gone offline.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Battery status has been updated&lt;br /&gt;
|-&lt;br /&gt;
|onCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|string device_ID, string socket_ID, var data&lt;br /&gt;
|&lt;br /&gt;
|Raised when a custom message has been received (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|onConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has connected to a VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onDisconnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has disconnected from the VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onTick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised n times per second (based on what you passed to constructor).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|m,o&lt;br /&gt;
|string appName, string server = &amp;quot;https://vibhub.io&amp;quot;, int port = 443, int fps = 30, bool autoHighRes&lt;br /&gt;
|VhSocket&lt;br /&gt;
|&lt;br /&gt;
|Library constructor. &lt;br /&gt;
- appName can be anything you&#039;d like to call your app (mainly used for debugging.&lt;br /&gt;
- server is the server to connect to.&lt;br /&gt;
- port is the port (hurdur). Usually 443 (SSL) or 80&lt;br /&gt;
- fps sets a max limit on how often we can send messages to the device. I don&#039;t recommend setting this to more than 60.&lt;br /&gt;
- autoHighRes tries to automatically enable High Res mode if the device supports it. High Res gives you more granular control.&lt;br /&gt;
|-&lt;br /&gt;
|begin&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|this&lt;br /&gt;
|Yes&lt;br /&gt;
|Starts the app, connecting via socket.io and binding events.&lt;br /&gt;
|-&lt;br /&gt;
|isConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|&lt;br /&gt;
|Returns true if we&#039;re connected to the server.&lt;br /&gt;
|-&lt;br /&gt;
|setName&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|Yes&lt;br /&gt;
|Sends the app name to the server (auto handled in begin). Returns true on success.&lt;br /&gt;
|-&lt;br /&gt;
|handleNewIndex&lt;br /&gt;
|m,o&lt;br /&gt;
|array devices&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Internal handler for the server refreshing our managed devices.&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|array data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device data received. Data is an array of: string id, string socketID, var metadata&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device disconnect. Data is an array of: string id&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device battery updates. Data is an object with {string id, bool batteryLow, int mv(millivolts), int xv(max millivolts)}&lt;br /&gt;
|-&lt;br /&gt;
|addDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you want permissions to manage this device by id. Permissions are NOT lost if the device disconnects and reconnects. Permissions ARE lost if your app disconnects.&lt;br /&gt;
|-&lt;br /&gt;
|remDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you no longer want to manage a device. Note that devices are automatically disowned when you disconnect the app. But it&#039;s good practice to call this if you want to swap devices.&lt;br /&gt;
|-&lt;br /&gt;
|wipeDevices&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Removes all devices from your app.&lt;br /&gt;
|-&lt;br /&gt;
|getDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device OR undefined&lt;br /&gt;
|&lt;br /&gt;
|Gets a maintained device by ID if it exists, otherwise returns false.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Updates the vibration value of a device. Use VhDevice set (listed below) instead, as it automatically prevents overloading the device with too many requests.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, int channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Same as sendPWM but for specific ports. Use VhDevice set instead.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sends a program. Use VhDevice sendProgram instead.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Requests a battery update. Use VhDevice getBattery instead. If successful, the onDeviceBattery event will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|sendCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device, var data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Emits a dCustom event (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|tick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to rate-limit updates and prevent overloading your device with requests.&lt;br /&gt;
|-&lt;br /&gt;
|_addScript&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to make sure socket.io exists in the browser.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhDevice ==&lt;br /&gt;
A VhDevice is an object representation of a physical device (your VibHub).&lt;br /&gt;
&lt;br /&gt;
Capability names:&lt;br /&gt;
&lt;br /&gt;
* p : PWM batch updates (all devices support this)&lt;br /&gt;
* ps : PWM specific port updates (all devices support this)&lt;br /&gt;
* ph : PWM specific high res updates&lt;br /&gt;
* vib : REST programs over websockets (all devices support this)&lt;br /&gt;
* sb : Battery status updates&lt;br /&gt;
* app_offline : The device can tell when the app disconnects&lt;br /&gt;
* dCustom : Can handle custom tasks from app&lt;br /&gt;
* aCustom : Can send custom data to app&lt;br /&gt;
* h : int, how many bits the device supports in high res mode. Usually 10 if high res is supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|string deviceId, VhSocket parent&lt;br /&gt;
|VhDevice&lt;br /&gt;
|&lt;br /&gt;
|Constructor. Do not call this directly, use addDevice in VhSocket instead.&lt;br /&gt;
|-&lt;br /&gt;
|setHighRes&lt;br /&gt;
|bool on&lt;br /&gt;
|this&lt;br /&gt;
|&lt;br /&gt;
|Toggles high res mode. In high res mode you gain more granularity to your controls (if your device supports it). Note that you can enable autoHighRes in the VhSocket constructor to automatically manage high res. The only drawback to high res is that you need to send a bit more data.&lt;br /&gt;
|-&lt;br /&gt;
|isHighRes&lt;br /&gt;
|&lt;br /&gt;
|bool isHighres&lt;br /&gt;
|&lt;br /&gt;
|Returns true if your device supports high res. Note that the device must be connected first.&lt;br /&gt;
|-&lt;br /&gt;
|loadMeta&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to load device metadata. Currently supports:&lt;br /&gt;
- string version: Firmware Version&lt;br /&gt;
- string custom: Custom data (only used if you customize your firmware)&lt;br /&gt;
- string hwversion: Hardware info&lt;br /&gt;
- obj capabilities: See Capabilities above&lt;br /&gt;
|-&lt;br /&gt;
|getChannelval&lt;br /&gt;
|int channel&lt;br /&gt;
|int val&lt;br /&gt;
|&lt;br /&gt;
|Used internally to recalculate a float intensity to an integer based on supported device resolution.&lt;br /&gt;
|-&lt;br /&gt;
|calcMinPwm&lt;br /&gt;
|float input&lt;br /&gt;
|float output&lt;br /&gt;
|&lt;br /&gt;
|Used internally to convert a 0-1 value to a range where 0 is where the device just starts to spin, and 1 being max power. &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmBasic&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability&lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmSpecific&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPrograms&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapOffline&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToDevice&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToApp&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasBatteryStatus&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|getHiResBits&lt;br /&gt;
|&lt;br /&gt;
|int bits&lt;br /&gt;
|&lt;br /&gt;
|Returns nr bits the device supports for updates.&lt;br /&gt;
|-&lt;br /&gt;
|getCapabilityNames&lt;br /&gt;
|&lt;br /&gt;
|array names&lt;br /&gt;
|&lt;br /&gt;
|Returns a readable array of capability names for the device.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update the PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update single channel PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Send a [[REST]] program to run on the device.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Attempts to fetch battery status. On success, the VhSocket event onDeviceBattery will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|changed&lt;br /&gt;
|bool stash&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to prevent messages from being sent each frame if changes have been detected.&lt;br /&gt;
|-&lt;br /&gt;
|stashChange&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally.&lt;br /&gt;
|-&lt;br /&gt;
|set&lt;br /&gt;
|float val, int channel = -1&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets PWM (vibration intensity) between 0 and 1. If channel is less than 0, all channels will be affected. Otherwise only the specified channel.&lt;br /&gt;
|-&lt;br /&gt;
|setMinPwm&lt;br /&gt;
|amt = 0&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets a minimum value for the device turning on. This is useful since many vibrators don&#039;t turn on until 60% power or so. To get this value, keep min PWM to 0 and slowly crank up the intensity until it starts vibrating. Then use that value for 0.&lt;br /&gt;
|-&lt;br /&gt;
|remove&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|yes&lt;br /&gt;
|Removes this device from the parent VhSocket&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhProgram ==&lt;br /&gt;
VhProgram lets you build REST type programs to send to the device. Programs are beneficial if you want to send things like pulses, or ramp vibrations up/down instead of having direct input control.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|array ports/int port, repeats = 0&lt;br /&gt;
|VhProgram&lt;br /&gt;
|&lt;br /&gt;
|Ports: Ports to run program on (0 indexed). Can also be an integer to control 1 port.&lt;br /&gt;
Repeats: Nr repeats. Use -1 for infinity.&lt;br /&gt;
|-&lt;br /&gt;
|setPorts&lt;br /&gt;
|array ports/int port&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Lets you change the ports on the fly. Useful if you want to reuse programs.&lt;br /&gt;
|-&lt;br /&gt;
|addStage&lt;br /&gt;
|VhStage ...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Add one or more VhStage objects to the program.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|object data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the program into a generic object, with values automatically converted to integers based on device min PWM and high res capabilities.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhStage ==&lt;br /&gt;
VhStage describes a program stage, setting a value at time.&lt;br /&gt;
&lt;br /&gt;
* Supported easing types: In, Out, InOut, None.&lt;br /&gt;
* Supported easing algorithms: Linear, Sine, Quad, Cubic, Quart, Quint, Back, Bounce, Circular, Elastic, Exponential, None.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|obj settings&lt;br /&gt;
|VhStage&lt;br /&gt;
|&lt;br /&gt;
|Settings object supports the following keys:&lt;br /&gt;
- float intensity: A value between 0 and 1. OR a VhRandObject.&lt;br /&gt;
- int duration : Duration in milliseconds. OR a VhRandObject.&lt;br /&gt;
- string easing : Easing method. Default &amp;quot;Linear.None&amp;quot;&lt;br /&gt;
- int repeats : Nr of times to repeat this stage. OR a VhRandObject.&lt;br /&gt;
- bool yoyo : Requires repeats. Makes repeats alternate back and forth.&lt;br /&gt;
|-&lt;br /&gt;
|exportFloatOrRand&lt;br /&gt;
|var value, VhDevice device&lt;br /&gt;
|obj randObj OR float&lt;br /&gt;
|&lt;br /&gt;
|Used internally when flattening to a generic object.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the stage into a generic object.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhRandObject ==&lt;br /&gt;
VhRandObject can be used in a VhStage to add randomness to intensity, duration, and/or repeats.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|obj settings&lt;br /&gt;
|VhRandObject&lt;br /&gt;
|&lt;br /&gt;
|Settings object supports the following keys:&lt;br /&gt;
- float min: A value between 0 and 1&lt;br /&gt;
&lt;br /&gt;
- float max: A value between 0 and 1&lt;br /&gt;
&lt;br /&gt;
- bool absolute: When true, the min/max values won&#039;t be adjusted based on device min val and resolution. Useful for repeats.&lt;br /&gt;
&lt;br /&gt;
- int offset: Primarily used with yoyo and multi.&lt;br /&gt;
&lt;br /&gt;
- int multi: Primarily used with program repeats with yoyo. Multiplies the output value. Such as if you wanted yoyo back and forth 1-3 times you&#039;d set absolute to true, multi to 2, min to 0, max to 2, and offset to 1.&lt;br /&gt;
|-&lt;br /&gt;
|exportFloatOrRand&lt;br /&gt;
|var value, VhDevice device&lt;br /&gt;
|obj randObj OR float&lt;br /&gt;
|&lt;br /&gt;
|Used internally when flattening to a generic object.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the stage into a generic object.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Server&amp;diff=17</id>
		<title>Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Server&amp;diff=17"/>
		<updated>2026-01-29T13:12:51Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;The VibHub server acts as a relay between an App and a Device. The official server is written using vanilla NodeJS, and the source code can be found at https://github.com/JasXSL/VibHub-Server&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The VibHub server acts as a relay between an [[App]] and a [[Device]]. The official server is written using vanilla NodeJS, and the source code can be found at https://github.com/JasXSL/VibHub-Server&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=App&amp;diff=16</id>
		<title>App</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=App&amp;diff=16"/>
		<updated>2026-01-29T13:10:08Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;An app is basically a controller application for one or more VibHub Devices. Such as a website or Second Life relay.  Generally, VibHub communication goes User Input -&amp;gt; App -&amp;gt; Server -&amp;gt; Device.  VibHub currently has two methods of interfacing an App with the server: REST and Websockets. Websockets is faster and generally the go-to. But if your application can&amp;#039;t handle that, and you&amp;#039;re fine with less frequent updates, the REST API...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An app is basically a controller application for one or more VibHub [[Device|Devices]]. Such as a website or Second Life relay.&lt;br /&gt;
&lt;br /&gt;
Generally, VibHub communication goes User Input -&amp;gt; App -&amp;gt; [[Server]] -&amp;gt; [[Device]].&lt;br /&gt;
&lt;br /&gt;
VibHub currently has two methods of interfacing an App with the server: [[REST]] and [[VibHub-Browser|Websockets]]. Websockets is faster and generally the go-to. But if your application can&#039;t handle that, and you&#039;re fine with less frequent updates, the REST API is very easy to use!&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=15</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=15"/>
		<updated>2026-01-29T13:06:51Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s set all ports on our device to max!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(1); // Sets all ports on the device to max intensity&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VhSocket ==&lt;br /&gt;
VhSocket is the main vibhub manager, allowing you to manage multiple devices from your app!&lt;br /&gt;
&lt;br /&gt;
Versions:&lt;br /&gt;
&lt;br /&gt;
* m - 2026 VibHub Micro&lt;br /&gt;
* o - Original VibHub 4x AA battery version.&lt;br /&gt;
&lt;br /&gt;
=== Overridable ===&lt;br /&gt;
These methods are meant to be overridden by your extended class or on the fly.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has come online.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has gone offline.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Battery status has been updated&lt;br /&gt;
|-&lt;br /&gt;
|onCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|string device_ID, string socket_ID, var data&lt;br /&gt;
|&lt;br /&gt;
|Raised when a custom message has been received (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|onConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has connected to a VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onDisconnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has disconnected from the VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onTick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised n times per second (based on what you passed to constructor).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|m,o&lt;br /&gt;
|string appName, string server = &amp;quot;https://vibhub.io&amp;quot;, int port = 443, int fps = 30, bool autoHighRes&lt;br /&gt;
|VhSocket&lt;br /&gt;
|&lt;br /&gt;
|Library constructor. &lt;br /&gt;
- appName can be anything you&#039;d like to call your app (mainly used for debugging.&lt;br /&gt;
- server is the server to connect to.&lt;br /&gt;
- port is the port (hurdur). Usually 443 (SSL) or 80&lt;br /&gt;
- fps sets a max limit on how often we can send messages to the device. I don&#039;t recommend setting this to more than 60.&lt;br /&gt;
- autoHighRes tries to automatically enable High Res mode if the device supports it. High Res gives you more granular control.&lt;br /&gt;
|-&lt;br /&gt;
|begin&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|this&lt;br /&gt;
|Yes&lt;br /&gt;
|Starts the app, connecting via socket.io and binding events.&lt;br /&gt;
|-&lt;br /&gt;
|isConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|&lt;br /&gt;
|Returns true if we&#039;re connected to the server.&lt;br /&gt;
|-&lt;br /&gt;
|setName&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|Yes&lt;br /&gt;
|Sends the app name to the server (auto handled in begin). Returns true on success.&lt;br /&gt;
|-&lt;br /&gt;
|handleNewIndex&lt;br /&gt;
|m,o&lt;br /&gt;
|array devices&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Internal handler for the server refreshing our managed devices.&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|array data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device data received. Data is an array of: string id, string socketID, var metadata&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device disconnect. Data is an array of: string id&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device battery updates. Data is an object with {string id, bool batteryLow, int mv(millivolts), int xv(max millivolts)}&lt;br /&gt;
|-&lt;br /&gt;
|addDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you want permissions to manage this device by id. Permissions are NOT lost if the device disconnects and reconnects. Permissions ARE lost if your app disconnects.&lt;br /&gt;
|-&lt;br /&gt;
|remDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you no longer want to manage a device. Note that devices are automatically disowned when you disconnect the app. But it&#039;s good practice to call this if you want to swap devices.&lt;br /&gt;
|-&lt;br /&gt;
|wipeDevices&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Removes all devices from your app.&lt;br /&gt;
|-&lt;br /&gt;
|getDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device OR undefined&lt;br /&gt;
|&lt;br /&gt;
|Gets a maintained device by ID if it exists, otherwise returns false.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Updates the vibration value of a device. Use VhDevice set (listed below) instead, as it automatically prevents overloading the device with too many requests.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, int channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Same as sendPWM but for specific ports. Use VhDevice set instead.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sends a program. Use VhDevice sendProgram instead.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Requests a battery update. Use VhDevice getBattery instead. If successful, the onDeviceBattery event will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|sendCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device, var data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Emits a dCustom event (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|tick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to rate-limit updates and prevent overloading your device with requests.&lt;br /&gt;
|-&lt;br /&gt;
|_addScript&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to make sure socket.io exists in the browser.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhDevice ==&lt;br /&gt;
A VhDevice is an object representation of a physical device (your VibHub).&lt;br /&gt;
&lt;br /&gt;
Capability names:&lt;br /&gt;
&lt;br /&gt;
* p : PWM batch updates (all devices support this)&lt;br /&gt;
* ps : PWM specific port updates (all devices support this)&lt;br /&gt;
* ph : PWM specific high res updates&lt;br /&gt;
* vib : REST programs over websockets (all devices support this)&lt;br /&gt;
* sb : Battery status updates&lt;br /&gt;
* app_offline : The device can tell when the app disconnects&lt;br /&gt;
* dCustom : Can handle custom tasks from app&lt;br /&gt;
* aCustom : Can send custom data to app&lt;br /&gt;
* h : int, how many bits the device supports in high res mode. Usually 10 if high res is supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|string deviceId, VhSocket parent&lt;br /&gt;
|VhDevice&lt;br /&gt;
|&lt;br /&gt;
|Constructor. Do not call this directly, use addDevice in VhSocket instead.&lt;br /&gt;
|-&lt;br /&gt;
|setHighRes&lt;br /&gt;
|bool on&lt;br /&gt;
|this&lt;br /&gt;
|&lt;br /&gt;
|Toggles high res mode. In high res mode you gain more granularity to your controls (if your device supports it). Note that you can enable autoHighRes in the VhSocket constructor to automatically manage high res. The only drawback to high res is that you need to send a bit more data.&lt;br /&gt;
|-&lt;br /&gt;
|isHighRes&lt;br /&gt;
|&lt;br /&gt;
|bool isHighres&lt;br /&gt;
|&lt;br /&gt;
|Returns true if your device supports high res. Note that the device must be connected first.&lt;br /&gt;
|-&lt;br /&gt;
|loadMeta&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to load device metadata. Currently supports:&lt;br /&gt;
- string version: Firmware Version&lt;br /&gt;
- string custom: Custom data (only used if you customize your firmware)&lt;br /&gt;
- string hwversion: Hardware info&lt;br /&gt;
- obj capabilities: See Capabilities above&lt;br /&gt;
|-&lt;br /&gt;
|getChannelval&lt;br /&gt;
|int channel&lt;br /&gt;
|int val&lt;br /&gt;
|&lt;br /&gt;
|Used internally to recalculate a float intensity to an integer based on supported device resolution.&lt;br /&gt;
|-&lt;br /&gt;
|calcMinPwm&lt;br /&gt;
|float input&lt;br /&gt;
|float output&lt;br /&gt;
|&lt;br /&gt;
|Used internally to convert a 0-1 value to a range where 0 is where the device just starts to spin, and 1 being max power. &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmBasic&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability&lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmSpecific&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPrograms&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapOffline&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToDevice&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToApp&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasBatteryStatus&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|getHiResBits&lt;br /&gt;
|&lt;br /&gt;
|int bits&lt;br /&gt;
|&lt;br /&gt;
|Returns nr bits the device supports for updates.&lt;br /&gt;
|-&lt;br /&gt;
|getCapabilityNames&lt;br /&gt;
|&lt;br /&gt;
|array names&lt;br /&gt;
|&lt;br /&gt;
|Returns a readable array of capability names for the device.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update the PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update single channel PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Send a [[REST]] program to run on the device.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Attempts to fetch battery status. On success, the VhSocket event onDeviceBattery will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|changed&lt;br /&gt;
|bool stash&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to prevent messages from being sent each frame if changes have been detected.&lt;br /&gt;
|-&lt;br /&gt;
|stashChange&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally.&lt;br /&gt;
|-&lt;br /&gt;
|set&lt;br /&gt;
|float val, int channel = -1&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets PWM (vibration intensity) between 0 and 1. If channel is less than 0, all channels will be affected. Otherwise only the specified channel.&lt;br /&gt;
|-&lt;br /&gt;
|setMinPwm&lt;br /&gt;
|amt = 0&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets a minimum value for the device turning on. This is useful since many vibrators don&#039;t turn on until 60% power or so. To get this value, keep min PWM to 0 and slowly crank up the intensity until it starts vibrating. Then use that value for 0.&lt;br /&gt;
|-&lt;br /&gt;
|remove&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|yes&lt;br /&gt;
|Removes this device from the parent VhSocket&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhProgram ==&lt;br /&gt;
VhProgram lets you build REST type programs to send to the device. Programs are beneficial if you want to send things like pulses, or ramp vibrations up/down instead of having direct input control.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|array ports/int port, repeats = 0&lt;br /&gt;
|VhProgram&lt;br /&gt;
|&lt;br /&gt;
|Ports: Ports to run program on (0 indexed). Can also be an integer to control 1 port.&lt;br /&gt;
Repeats: Nr repeats. Use -1 for infinity.&lt;br /&gt;
|-&lt;br /&gt;
|setPorts&lt;br /&gt;
|array ports/int port&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Lets you change the ports on the fly. Useful if you want to reuse programs.&lt;br /&gt;
|-&lt;br /&gt;
|addStage&lt;br /&gt;
|VhStage ...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Add one or more VhStage objects to the program.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|object data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the program into a generic object, with values automatically converted to integers based on device min PWM and high res capabilities.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhStage ==&lt;br /&gt;
VhStage describes a program stage, setting a value at time.&lt;br /&gt;
&lt;br /&gt;
* Supported easing types: In, Out, InOut, None.&lt;br /&gt;
* Supported easing algorithms: Linear, Sine, Quad, Cubic, Quart, Quint, Back, Bounce, Circular, Elastic, Exponential, None.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|obj settings&lt;br /&gt;
|VhStage&lt;br /&gt;
|&lt;br /&gt;
|Settings object supports the following keys:&lt;br /&gt;
- float intensity: A value between 0 and 1. OR a VhRandObject.&lt;br /&gt;
- int duration : Duration in milliseconds. OR a VhRandObject.&lt;br /&gt;
- string easing : Easing method. Default &amp;quot;Linear.None&amp;quot;&lt;br /&gt;
- int repeats : Nr of times to repeat this stage. OR a VhRandObject.&lt;br /&gt;
- bool yoyo : Requires repeats. Makes repeats alternate back and forth.&lt;br /&gt;
|-&lt;br /&gt;
|exportFloatOrRand&lt;br /&gt;
|var value, VhDevice device&lt;br /&gt;
|obj randObj OR float&lt;br /&gt;
|&lt;br /&gt;
|Used internally when flattening to a generic object.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the stage into a generic object.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhRandObject ==&lt;br /&gt;
VhRandObject can be used in a VhStage to add randomness to intensity, duration, and/or repeats.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|obj settings&lt;br /&gt;
|VhRandObject&lt;br /&gt;
|&lt;br /&gt;
|Settings object supports the following keys:&lt;br /&gt;
- float min: A value between 0 and 1&lt;br /&gt;
&lt;br /&gt;
- float max: A value between 0 and 1&lt;br /&gt;
&lt;br /&gt;
- bool absolute: When true, the min/max values won&#039;t be adjusted based on device min val and resolution. Useful for repeats.&lt;br /&gt;
&lt;br /&gt;
- int offset: This is added to the random value. Legacy feature.&lt;br /&gt;
&lt;br /&gt;
- int multi: Primarily used with program repeats with yoyo. Multiplies the output value. Such as if you wanted yoyo back and forth 1-3 times you&#039;d set absolute to true, multi to 2, min to 0 and max to 2.&lt;br /&gt;
|-&lt;br /&gt;
|exportFloatOrRand&lt;br /&gt;
|var value, VhDevice device&lt;br /&gt;
|obj randObj OR float&lt;br /&gt;
|&lt;br /&gt;
|Used internally when flattening to a generic object.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the stage into a generic object.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Firmware&amp;diff=14</id>
		<title>Firmware</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Firmware&amp;diff=14"/>
		<updated>2026-01-29T13:01:59Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;Currently you can locate the firmware here: {| class=&amp;quot;wikitable&amp;quot; !Name/Link !Description |- |[https://github.com/JasXSL/VibHub-Micro VibHub Micro] |2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery! |- |[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32] |4xAA Version of the VibHub |}  == File Breakdown == {| class=&amp;quot;wikitable&amp;quot; |+ !File !Description |- |ApiClient |Handles messages received from VhWifi |- |BatteryReader...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Currently you can locate the firmware here:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File Breakdown ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!File&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|ApiClient&lt;br /&gt;
|Handles messages received from VhWifi&lt;br /&gt;
|-&lt;br /&gt;
|BatteryReader&lt;br /&gt;
|Used to get approx battery status.&lt;br /&gt;
|-&lt;br /&gt;
|ConfigButton&lt;br /&gt;
|Handles the configuration button.&lt;br /&gt;
|-&lt;br /&gt;
|Configuration&lt;br /&gt;
|Main configuration file for each device model.&lt;br /&gt;
|-&lt;br /&gt;
|Motor&lt;br /&gt;
|Handles PWM for the USB outputs.&lt;br /&gt;
|-&lt;br /&gt;
|StatusLED&lt;br /&gt;
|Handles the status RGB LED.&lt;br /&gt;
|-&lt;br /&gt;
|TweenEasing&lt;br /&gt;
|Easing algorithms for programs.&lt;br /&gt;
|-&lt;br /&gt;
|TweenProgram&lt;br /&gt;
|Manages programs received.&lt;br /&gt;
|-&lt;br /&gt;
|TweenProgramStage&lt;br /&gt;
|Manages program stages.&lt;br /&gt;
|-&lt;br /&gt;
|TweenRandObject&lt;br /&gt;
|Manages random objects.&lt;br /&gt;
|-&lt;br /&gt;
|UserSettings&lt;br /&gt;
|Manages settings set during operation via the web portal.&lt;br /&gt;
|-&lt;br /&gt;
|VhSerial&lt;br /&gt;
|Manages serial communication.&lt;br /&gt;
|-&lt;br /&gt;
|VhWifi&lt;br /&gt;
|Configures the web portal.&lt;br /&gt;
|-&lt;br /&gt;
|VibHub-&amp;lt;model&amp;gt;&lt;br /&gt;
|Main file to compile, links everything together.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=13</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=13"/>
		<updated>2026-01-29T12:55:12Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s set all ports on our device to max!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(1); // Sets all ports on the device to max intensity&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VhSocket ==&lt;br /&gt;
VhSocket is the main vibhub manager, allowing you to manage multiple devices from your app!&lt;br /&gt;
&lt;br /&gt;
Versions:&lt;br /&gt;
&lt;br /&gt;
* m - 2026 VibHub Micro&lt;br /&gt;
* o - Original VibHub 4x AA battery version.&lt;br /&gt;
&lt;br /&gt;
=== Overridable ===&lt;br /&gt;
These methods are meant to be overridden by your extended class or on the fly.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has come online.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has gone offline.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Battery status has been updated&lt;br /&gt;
|-&lt;br /&gt;
|onCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|string device_ID, string socket_ID, var data&lt;br /&gt;
|&lt;br /&gt;
|Raised when a custom message has been received (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|onConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has connected to a VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onDisconnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has disconnected from the VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onTick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised n times per second (based on what you passed to constructor).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|m,o&lt;br /&gt;
|string appName, string server = &amp;quot;https://vibhub.io&amp;quot;, int port = 443, int fps = 30, bool autoHighRes&lt;br /&gt;
|VhSocket&lt;br /&gt;
|&lt;br /&gt;
|Library constructor. &lt;br /&gt;
- appName can be anything you&#039;d like to call your app (mainly used for debugging.&lt;br /&gt;
- server is the server to connect to.&lt;br /&gt;
- port is the port (hurdur). Usually 443 (SSL) or 80&lt;br /&gt;
- fps sets a max limit on how often we can send messages to the device. I don&#039;t recommend setting this to more than 60.&lt;br /&gt;
- autoHighRes tries to automatically enable High Res mode if the device supports it. High Res gives you more granular control.&lt;br /&gt;
|-&lt;br /&gt;
|begin&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|this&lt;br /&gt;
|Yes&lt;br /&gt;
|Starts the app, connecting via socket.io and binding events.&lt;br /&gt;
|-&lt;br /&gt;
|isConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|&lt;br /&gt;
|Returns true if we&#039;re connected to the server.&lt;br /&gt;
|-&lt;br /&gt;
|setName&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|Yes&lt;br /&gt;
|Sends the app name to the server (auto handled in begin). Returns true on success.&lt;br /&gt;
|-&lt;br /&gt;
|handleNewIndex&lt;br /&gt;
|m,o&lt;br /&gt;
|array devices&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Internal handler for the server refreshing our managed devices.&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|array data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device data received. Data is an array of: string id, string socketID, var metadata&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device disconnect. Data is an array of: string id&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device battery updates. Data is an object with {string id, bool batteryLow, int mv(millivolts), int xv(max millivolts)}&lt;br /&gt;
|-&lt;br /&gt;
|addDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you want permissions to manage this device by id. Permissions are NOT lost if the device disconnects and reconnects. Permissions ARE lost if your app disconnects.&lt;br /&gt;
|-&lt;br /&gt;
|remDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you no longer want to manage a device. Note that devices are automatically disowned when you disconnect the app. But it&#039;s good practice to call this if you want to swap devices.&lt;br /&gt;
|-&lt;br /&gt;
|wipeDevices&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Removes all devices from your app.&lt;br /&gt;
|-&lt;br /&gt;
|getDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device OR undefined&lt;br /&gt;
|&lt;br /&gt;
|Gets a maintained device by ID if it exists, otherwise returns false.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Updates the vibration value of a device. Use VhDevice set (listed below) instead, as it automatically prevents overloading the device with too many requests.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, int channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Same as sendPWM but for specific ports. Use VhDevice set instead.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sends a program. Use VhDevice sendProgram instead.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Requests a battery update. Use VhDevice getBattery instead. If successful, the onDeviceBattery event will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|sendCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device, var data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Emits a dCustom event (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|tick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to rate-limit updates and prevent overloading your device with requests.&lt;br /&gt;
|-&lt;br /&gt;
|_addScript&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to make sure socket.io exists in the browser.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhDevice ==&lt;br /&gt;
A VhDevice is an object representation of a physical device (your VibHub).&lt;br /&gt;
&lt;br /&gt;
Capability names:&lt;br /&gt;
&lt;br /&gt;
* p : PWM batch updates (all devices support this)&lt;br /&gt;
* ps : PWM specific port updates (all devices support this)&lt;br /&gt;
* ph : PWM specific high res updates&lt;br /&gt;
* vib : REST programs over websockets (all devices support this)&lt;br /&gt;
* sb : Battery status updates&lt;br /&gt;
* app_offline : The device can tell when the app disconnects&lt;br /&gt;
* dCustom : Can handle custom tasks from app&lt;br /&gt;
* aCustom : Can send custom data to app&lt;br /&gt;
* h : int, how many bits the device supports in high res mode. Usually 10 if high res is supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|string deviceId, VhSocket parent&lt;br /&gt;
|VhDevice&lt;br /&gt;
|&lt;br /&gt;
|Constructor. Do not call this directly, use addDevice in VhSocket instead.&lt;br /&gt;
|-&lt;br /&gt;
|setHighRes&lt;br /&gt;
|bool on&lt;br /&gt;
|this&lt;br /&gt;
|&lt;br /&gt;
|Toggles high res mode. In high res mode you gain more granularity to your controls (if your device supports it). Note that you can enable autoHighRes in the VhSocket constructor to automatically manage high res. The only drawback to high res is that you need to send a bit more data.&lt;br /&gt;
|-&lt;br /&gt;
|isHighRes&lt;br /&gt;
|&lt;br /&gt;
|bool isHighres&lt;br /&gt;
|&lt;br /&gt;
|Returns true if your device supports high res. Note that the device must be connected first.&lt;br /&gt;
|-&lt;br /&gt;
|loadMeta&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to load device metadata. Currently supports:&lt;br /&gt;
- string version: Firmware Version&lt;br /&gt;
- string custom: Custom data (only used if you customize your firmware)&lt;br /&gt;
- string hwversion: Hardware info&lt;br /&gt;
- obj capabilities: See Capabilities above&lt;br /&gt;
|-&lt;br /&gt;
|getChannelval&lt;br /&gt;
|int channel&lt;br /&gt;
|int val&lt;br /&gt;
|&lt;br /&gt;
|Used internally to recalculate a float intensity to an integer based on supported device resolution.&lt;br /&gt;
|-&lt;br /&gt;
|calcMinPwm&lt;br /&gt;
|float input&lt;br /&gt;
|float output&lt;br /&gt;
|&lt;br /&gt;
|Used internally to convert a 0-1 value to a range where 0 is where the device just starts to spin, and 1 being max power. &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmBasic&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability&lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmSpecific&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPrograms&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapOffline&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToDevice&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToApp&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasBatteryStatus&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|getHiResBits&lt;br /&gt;
|&lt;br /&gt;
|int bits&lt;br /&gt;
|&lt;br /&gt;
|Returns nr bits the device supports for updates.&lt;br /&gt;
|-&lt;br /&gt;
|getCapabilityNames&lt;br /&gt;
|&lt;br /&gt;
|array names&lt;br /&gt;
|&lt;br /&gt;
|Returns a readable array of capability names for the device.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update the PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update single channel PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Send a [[REST]] program to run on the device.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Attempts to fetch battery status. On success, the VhSocket event onDeviceBattery will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|changed&lt;br /&gt;
|bool stash&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to prevent messages from being sent each frame if changes have been detected.&lt;br /&gt;
|-&lt;br /&gt;
|stashChange&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally.&lt;br /&gt;
|-&lt;br /&gt;
|set&lt;br /&gt;
|float val, int channel = -1&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets PWM (vibration intensity) between 0 and 1. If channel is less than 0, all channels will be affected. Otherwise only the specified channel.&lt;br /&gt;
|-&lt;br /&gt;
|setMinPwm&lt;br /&gt;
|amt = 0&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets a minimum value for the device turning on. This is useful since many vibrators don&#039;t turn on until 60% power or so. To get this value, keep min PWM to 0 and slowly crank up the intensity until it starts vibrating. Then use that value for 0.&lt;br /&gt;
|-&lt;br /&gt;
|remove&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|yes&lt;br /&gt;
|Removes this device from the parent VhSocket&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhProgram ==&lt;br /&gt;
VhProgram lets you build REST type programs to send to the device. Programs are beneficial if you want to send things like pulses, or ramp vibrations up/down instead of having direct input control.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|array ports/int port, repeats = 0&lt;br /&gt;
|VhProgram&lt;br /&gt;
|&lt;br /&gt;
|Ports: Ports to run program on (0 indexed). Can also be an integer to control 1 port.&lt;br /&gt;
Repeats: Nr repeats. Use -1 for infinity.&lt;br /&gt;
|-&lt;br /&gt;
|setPorts&lt;br /&gt;
|array ports/int port&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Lets you change the ports on the fly. Useful if you want to reuse programs.&lt;br /&gt;
|-&lt;br /&gt;
|addStage&lt;br /&gt;
|VhStage ...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Add one or more VhStage objects to the program.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|object data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the program into a generic object, with values automatically converted to integers based on device min PWM and high res capabilities.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhStage ==&lt;br /&gt;
VhStage describes a program stage, setting a value at time.&lt;br /&gt;
&lt;br /&gt;
* Supported easing types: In, Out, InOut, None.&lt;br /&gt;
* Supported easing algorithms: Linear, Sine, Quad, Cubic, Quart, Quint, Back, Bounce, Circular, Elastic, Exponential, None.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|obj settings&lt;br /&gt;
|VhStage&lt;br /&gt;
|&lt;br /&gt;
|Settings object supports the following keys:&lt;br /&gt;
- float intensity: A value between 0 and 1. OR a VhRandObject.&lt;br /&gt;
- int duration : Duration in milliseconds. OR a VhRandObject.&lt;br /&gt;
- string easing : Easing method. Default &amp;quot;Linear.None&amp;quot;&lt;br /&gt;
- int repeats : Nr of times to repeat this stage. OR a VhRandObject.&lt;br /&gt;
- bool yoyo : Requires repeats. Makes repeats alternate back and forth.&lt;br /&gt;
|-&lt;br /&gt;
|exportFloatOrRand&lt;br /&gt;
|var value, VhDevice device&lt;br /&gt;
|obj randObj OR float&lt;br /&gt;
|&lt;br /&gt;
|Used internally when flattening to a generic object.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the stage into a generic object.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhRandObject ==&lt;br /&gt;
VhRandObject can be used in a VhStage to add randomness to intensity, duration, and/or repeats.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|obj settings&lt;br /&gt;
|VhRandObject&lt;br /&gt;
|&lt;br /&gt;
|Settings object supports the following keys:&lt;br /&gt;
- float min : A value between 0 and 1&lt;br /&gt;
- float max : A value between 0 and 1&lt;br /&gt;
|-&lt;br /&gt;
|exportFloatOrRand&lt;br /&gt;
|var value, VhDevice device&lt;br /&gt;
|obj randObj OR float&lt;br /&gt;
|&lt;br /&gt;
|Used internally when flattening to a generic object.&lt;br /&gt;
|-&lt;br /&gt;
|export&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|Flattens the stage into a generic object.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=12</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=12"/>
		<updated>2026-01-29T12:33:39Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s set all ports on our device to max!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(1); // Sets all ports on the device to max intensity&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VhSocket ==&lt;br /&gt;
VhSocket is the main vibhub manager, allowing you to manage multiple devices from your app!&lt;br /&gt;
&lt;br /&gt;
Versions:&lt;br /&gt;
&lt;br /&gt;
* m - 2026 VibHub Micro&lt;br /&gt;
* o - Original VibHub 4x AA battery version.&lt;br /&gt;
&lt;br /&gt;
=== Overridable ===&lt;br /&gt;
These methods are meant to be overridden by your extended class or on the fly.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has come online.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has gone offline.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Battery status has been updated&lt;br /&gt;
|-&lt;br /&gt;
|onCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|string device_ID, string socket_ID, var data&lt;br /&gt;
|&lt;br /&gt;
|Raised when a custom message has been received (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|onConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has connected to a VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onDisconnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has disconnected from the VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onTick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised n times per second (based on what you passed to constructor).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|m,o&lt;br /&gt;
|string appName, string server = &amp;quot;https://vibhub.io&amp;quot;, int port = 443, int fps = 30, bool autoHighRes&lt;br /&gt;
|VhSocket&lt;br /&gt;
|&lt;br /&gt;
|Library constructor. &lt;br /&gt;
- appName can be anything you&#039;d like to call your app (mainly used for debugging.&lt;br /&gt;
- server is the server to connect to.&lt;br /&gt;
- port is the port (hurdur). Usually 443 (SSL) or 80&lt;br /&gt;
- fps sets a max limit on how often we can send messages to the device. I don&#039;t recommend setting this to more than 60.&lt;br /&gt;
- autoHighRes tries to automatically enable High Res mode if the device supports it. High Res gives you more granular control.&lt;br /&gt;
|-&lt;br /&gt;
|begin&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|this&lt;br /&gt;
|Yes&lt;br /&gt;
|Starts the app, connecting via socket.io and binding events.&lt;br /&gt;
|-&lt;br /&gt;
|isConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|&lt;br /&gt;
|Returns true if we&#039;re connected to the server.&lt;br /&gt;
|-&lt;br /&gt;
|setName&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|Yes&lt;br /&gt;
|Sends the app name to the server (auto handled in begin). Returns true on success.&lt;br /&gt;
|-&lt;br /&gt;
|handleNewIndex&lt;br /&gt;
|m,o&lt;br /&gt;
|array devices&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Internal handler for the server refreshing our managed devices.&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|array data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device data received. Data is an array of: string id, string socketID, var metadata&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device disconnect. Data is an array of: string id&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device battery updates. Data is an object with {string id, bool batteryLow, int mv(millivolts), int xv(max millivolts)}&lt;br /&gt;
|-&lt;br /&gt;
|addDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you want permissions to manage this device by id. Permissions are NOT lost if the device disconnects and reconnects. Permissions ARE lost if your app disconnects.&lt;br /&gt;
|-&lt;br /&gt;
|remDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you no longer want to manage a device. Note that devices are automatically disowned when you disconnect the app. But it&#039;s good practice to call this if you want to swap devices.&lt;br /&gt;
|-&lt;br /&gt;
|wipeDevices&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Removes all devices from your app.&lt;br /&gt;
|-&lt;br /&gt;
|getDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device OR undefined&lt;br /&gt;
|&lt;br /&gt;
|Gets a maintained device by ID if it exists, otherwise returns false.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Updates the vibration value of a device. Use VhDevice set (listed below) instead, as it automatically prevents overloading the device with too many requests.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, int channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Same as sendPWM but for specific ports. Use VhDevice set instead.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sends a program. Use VhDevice sendProgram instead.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Requests a battery update. Use VhDevice getBattery instead. If successful, the onDeviceBattery event will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|sendCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device, var data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Emits a dCustom event (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|tick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to rate-limit updates and prevent overloading your device with requests.&lt;br /&gt;
|-&lt;br /&gt;
|_addScript&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to make sure socket.io exists in the browser.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VhDevice ==&lt;br /&gt;
A VhDevice is an object representation of a physical device (your VibHub).&lt;br /&gt;
&lt;br /&gt;
Capability names:&lt;br /&gt;
&lt;br /&gt;
* p : PWM batch updates (all devices support this)&lt;br /&gt;
* ps : PWM specific port updates (all devices support this)&lt;br /&gt;
* ph : PWM specific high res updates&lt;br /&gt;
* vib : REST programs over websockets (all devices support this)&lt;br /&gt;
* sb : Battery status updates&lt;br /&gt;
* app_offline : The device can tell when the app disconnects&lt;br /&gt;
* dCustom : Can handle custom tasks from app&lt;br /&gt;
* aCustom : Can send custom data to app&lt;br /&gt;
* h : int, how many bits the device supports in high res mode. Usually 10 if high res is supported.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|string deviceId, VhSocket parent&lt;br /&gt;
|VhDevice&lt;br /&gt;
|&lt;br /&gt;
|Constructor. Do not call this directly, use addDevice in VhSocket instead.&lt;br /&gt;
|-&lt;br /&gt;
|setHighRes&lt;br /&gt;
|bool on&lt;br /&gt;
|this&lt;br /&gt;
|&lt;br /&gt;
|Toggles high res mode. In high res mode you gain more granularity to your controls (if your device supports it). Note that you can enable autoHighRes in the VhSocket constructor to automatically manage high res. The only drawback to high res is that you need to send a bit more data.&lt;br /&gt;
|-&lt;br /&gt;
|isHighRes&lt;br /&gt;
|&lt;br /&gt;
|bool isHighres&lt;br /&gt;
|&lt;br /&gt;
|Returns true if your device supports high res. Note that the device must be connected first.&lt;br /&gt;
|-&lt;br /&gt;
|loadMeta&lt;br /&gt;
|obj data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to load device metadata. Currently supports:&lt;br /&gt;
- string version: Firmware Version&lt;br /&gt;
- string custom: Custom data (only used if you customize your firmware)&lt;br /&gt;
- string hwversion: Hardware info&lt;br /&gt;
- obj capabilities: See Capabilities above&lt;br /&gt;
|-&lt;br /&gt;
|getChannelval&lt;br /&gt;
|int channel&lt;br /&gt;
|int val&lt;br /&gt;
|&lt;br /&gt;
|Used internally to recalculate a float intensity to an integer based on supported device resolution.&lt;br /&gt;
|-&lt;br /&gt;
|calcMinPwm&lt;br /&gt;
|float input&lt;br /&gt;
|float output&lt;br /&gt;
|&lt;br /&gt;
|Used internally to convert a 0-1 value to a range where 0 is where the device just starts to spin, and 1 being max power. &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmBasic&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability&lt;br /&gt;
|-&lt;br /&gt;
|hasCapPwmSpecific&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapPrograms&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCapOffline&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToDevice&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasCustomToApp&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|hasBatteryStatus&lt;br /&gt;
|&lt;br /&gt;
|boolean has&lt;br /&gt;
|&lt;br /&gt;
|Check if device has this capability &lt;br /&gt;
|-&lt;br /&gt;
|getHiResBits&lt;br /&gt;
|&lt;br /&gt;
|int bits&lt;br /&gt;
|&lt;br /&gt;
|Returns nr bits the device supports for updates.&lt;br /&gt;
|-&lt;br /&gt;
|getCapabilityNames&lt;br /&gt;
|&lt;br /&gt;
|array names&lt;br /&gt;
|&lt;br /&gt;
|Returns a readable array of capability names for the device.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update the PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to update single channel PWM. Use set instead of this.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Send a [[REST]] program to run on the device.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Attempts to fetch battery status. On success, the VhSocket event onDeviceBattery will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|changed&lt;br /&gt;
|bool stash&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to prevent messages from being sent each frame if changes have been detected.&lt;br /&gt;
|-&lt;br /&gt;
|stashChange&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally.&lt;br /&gt;
|-&lt;br /&gt;
|set&lt;br /&gt;
|float val, int channel = -1&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets PWM (vibration intensity) between 0 and 1. If channel is less than 0, all channels will be affected. Otherwise only the specified channel.&lt;br /&gt;
|-&lt;br /&gt;
|setMinPwm&lt;br /&gt;
|amt = 0&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sets a minimum value for the device turning on. This is useful since many vibrators don&#039;t turn on until 60% power or so. To get this value, keep min PWM to 0 and slowly crank up the intensity until it starts vibrating. Then use that value for 0.&lt;br /&gt;
|-&lt;br /&gt;
|remove&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|yes&lt;br /&gt;
|Removes this device from the parent VhSocket&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=11</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=11"/>
		<updated>2026-01-29T12:09:59Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s set all ports on our device to max!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(255); // Sets all ports on the device to max intensity (or 1/4 if you enable high res)&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VhSocket ==&lt;br /&gt;
Versions:&lt;br /&gt;
&lt;br /&gt;
* m - 2026 VibHub Micro&lt;br /&gt;
* o - Original VibHub 4x AA battery version.&lt;br /&gt;
&lt;br /&gt;
=== Overridable ===&lt;br /&gt;
These methods are meant to be overridden by your extended class or on the fly.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has come online.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has gone offline.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Battery status has been updated&lt;br /&gt;
|-&lt;br /&gt;
|onCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|string device_ID, string socket_ID, var data&lt;br /&gt;
|&lt;br /&gt;
|Raised when a custom message has been received (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|onConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has connected to a VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onDisconnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has disconnected from the VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onTick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised n times per second (based on what you passed to constructor).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|m,o&lt;br /&gt;
|string appName, string server = &amp;quot;https://vibhub.io&amp;quot;, int port = 443, int fps = 30, bool autoHighRes&lt;br /&gt;
|VhSocket&lt;br /&gt;
|&lt;br /&gt;
|Library constructor. &lt;br /&gt;
- appName can be anything you&#039;d like to call your app (mainly used for debugging.&lt;br /&gt;
- server is the server to connect to.&lt;br /&gt;
- port is the port (hurdur). Usually 443 (SSL) or 80&lt;br /&gt;
- fps sets a max limit on how often we can send messages to the device. I don&#039;t recommend setting this to more than 60.&lt;br /&gt;
- autoHighRes tries to automatically enable High Res mode if the device supports it. High Res gives you a resolution of 1024 instead of 256, for more granular control.&lt;br /&gt;
|-&lt;br /&gt;
|begin&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|VhSocket&lt;br /&gt;
|Yes&lt;br /&gt;
|Starts the app, connecting via socket.io and binding events.&lt;br /&gt;
|-&lt;br /&gt;
|isConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|&lt;br /&gt;
|Returns true if we&#039;re connected to the server.&lt;br /&gt;
|-&lt;br /&gt;
|setName&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|Yes&lt;br /&gt;
|Sends the app name to the server (auto handled in begin). Returns true on success.&lt;br /&gt;
|-&lt;br /&gt;
|handleNewIndex&lt;br /&gt;
|m,o&lt;br /&gt;
|array devices&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Internal handler for the server refreshing our managed devices.&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|array data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device data received. Data is an array of: string id, string socketID, var metadata&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device disconnect. Data is an array of: string id&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device battery updates. Data is an object with {string id, bool batteryLow, int mv(millivolts), int xv(max millivolts)}&lt;br /&gt;
|-&lt;br /&gt;
|addDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you want permissions to manage this device by id. Permissions are NOT lost if the device disconnects and reconnects. Permissions ARE lost if your app disconnects.&lt;br /&gt;
|-&lt;br /&gt;
|remDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Requires an active connection. Tells the server that you no longer want to manage a device. Note that devices are automatically disowned when you disconnect the app. But it&#039;s good practice to call this if you want to swap devices.&lt;br /&gt;
|-&lt;br /&gt;
|wipeDevices&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Removes all devices from your app.&lt;br /&gt;
|-&lt;br /&gt;
|getDevice&lt;br /&gt;
|m,o&lt;br /&gt;
|string deviceID&lt;br /&gt;
|VhDevice device OR undefined&lt;br /&gt;
|&lt;br /&gt;
|Gets a maintained device by ID if it exists, otherwise returns false.&lt;br /&gt;
|-&lt;br /&gt;
|sendPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Updates the vibration value of a device. Use VhDevice set (listed below) instead, as it automatically prevents overloading the device with too many requests.&lt;br /&gt;
|-&lt;br /&gt;
|sendSingleChannelPWM&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, int channel...&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Same as sendPWM but for specific ports. Use VhDevice set instead.&lt;br /&gt;
|-&lt;br /&gt;
|sendProgram&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device, VhProgram program&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Sends a program. Use VhDevice sendProgram instead.&lt;br /&gt;
|-&lt;br /&gt;
|getBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Requests a battery update. Use VhDevice getBattery instead. If successful, the onDeviceBattery event will be raised.&lt;br /&gt;
|-&lt;br /&gt;
|sendCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device, var data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Emits a dCustom event (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|tick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to rate-limit updates and prevent overloading your device with requests.&lt;br /&gt;
|-&lt;br /&gt;
|_addScript&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Used internally to make sure socket.io exists in the browser.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=10</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=10"/>
		<updated>2026-01-29T11:58:16Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s set all ports on our device to max!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(255); // Sets all ports on the device to max intensity (or 1/4 if you enable high res)&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VhSocket ==&lt;br /&gt;
Versions:&lt;br /&gt;
&lt;br /&gt;
* m - 2026 VibHub Micro&lt;br /&gt;
* o - Original VibHub 4x AA battery version.&lt;br /&gt;
&lt;br /&gt;
=== Overridable ===&lt;br /&gt;
These methods are meant to be overridden by your extended class or on the fly.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has come online.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Raised when a device has gone offline.&lt;br /&gt;
|-&lt;br /&gt;
|onDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|VhDevice device&lt;br /&gt;
|&lt;br /&gt;
|Battery status has been updated&lt;br /&gt;
|-&lt;br /&gt;
|onCustomMessage&lt;br /&gt;
|m&lt;br /&gt;
|string device_ID, string socket_ID, var data&lt;br /&gt;
|&lt;br /&gt;
|Raised when a custom message has been received (advanced).&lt;br /&gt;
|-&lt;br /&gt;
|onConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has connected to a VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onDisconnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised when the app itself has disconnected from the VibHub server.&lt;br /&gt;
|-&lt;br /&gt;
|onTick&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Raised n times per second (based on what you passed to constructor).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Method&lt;br /&gt;
!Versions&lt;br /&gt;
!Args&lt;br /&gt;
!Returns&lt;br /&gt;
!Async&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|constructor&lt;br /&gt;
|m,o&lt;br /&gt;
|string appName, string server = &amp;quot;https://vibhub.io&amp;quot;, int port = 443, int fps = 30, bool autoHighRes&lt;br /&gt;
|VhSocket&lt;br /&gt;
|&lt;br /&gt;
|Library constructor. &lt;br /&gt;
- appName can be anything you&#039;d like to call your app (mainly used for debugging.&lt;br /&gt;
- server is the server to connect to.&lt;br /&gt;
- port is the port (hurdur). Usually 443 (SSL) or 80&lt;br /&gt;
- fps sets a max limit on how often we can send messages to the device. I don&#039;t recommend setting this to more than 60.&lt;br /&gt;
- autoHighRes tries to automatically enable High Res mode if the device supports it. High Res gives you a resolution of 1024 instead of 256, for more granular control.&lt;br /&gt;
|-&lt;br /&gt;
|begin&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|VhSocket&lt;br /&gt;
|Yes&lt;br /&gt;
|Starts the app, connecting via socket.io and binding events.&lt;br /&gt;
|-&lt;br /&gt;
|isConnected&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|&lt;br /&gt;
|Returns true if we&#039;re connected to the server.&lt;br /&gt;
|-&lt;br /&gt;
|setName&lt;br /&gt;
|m,o&lt;br /&gt;
|&lt;br /&gt;
|bool&lt;br /&gt;
|Yes&lt;br /&gt;
|Sends the app name to the server (auto handled in begin). Returns true on success.&lt;br /&gt;
|-&lt;br /&gt;
|handleNewIndex&lt;br /&gt;
|m,o&lt;br /&gt;
|array devices&lt;br /&gt;
|&lt;br /&gt;
|Yes&lt;br /&gt;
|Internal handler for the server refreshing our managed devices.&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOnline&lt;br /&gt;
|m,o&lt;br /&gt;
|array data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device data received. Data is an array of: string id, string socketID, var metadata&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceOffline&lt;br /&gt;
|m,o&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device disconnect. Data is an array of: string id&lt;br /&gt;
|-&lt;br /&gt;
|handleDeviceBattery&lt;br /&gt;
|m&lt;br /&gt;
|data&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Internal handler for device battery updates. Data is an object with {string id, bool batteryLow, int mv(millivolts), int xv(max millivolts)}&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=9</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=9"/>
		<updated>2026-01-29T11:39:07Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be cloned from [https://github.com/JasXSL/VibHub-Browser here].&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
Start by importing the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import {default as VH, VhProgram as Program, VhStage as Stage} from &#039;vh-socket.js&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you&#039;ll want to extend VH with a class of your own.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;class App extends VH{&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructor:&amp;lt;pre&amp;gt;&lt;br /&gt;
constructor(...args){&lt;br /&gt;
	super(...args);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;All done for our VibHub manager class! Let&#039;s try sending a program!&amp;lt;pre&amp;gt;&lt;br /&gt;
(async () =&amp;gt; {&lt;br /&gt;
	const manager = new App();&lt;br /&gt;
	manager.onDeviceOnline = function(device){&lt;br /&gt;
		device.set(255); // Sets all ports on the device to max intensity (or 1/4 if you enable high res)&lt;br /&gt;
	};&lt;br /&gt;
	await manager.addDevice(&amp;quot;&amp;lt;your device ID&amp;gt;&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Tasks&amp;diff=8</id>
		<title>Tasks</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Tasks&amp;diff=8"/>
		<updated>2026-01-29T11:21:17Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;All communications between a Device, Server, and App are done through tasks. {| class=&amp;quot;wikitable&amp;quot; !Task !Args !REST !Websocket !Sender -&amp;gt; Receiver !Description |- |p |(string)hex_bytes | |X |App -&amp;gt; Server, Server -&amp;gt; Device |Sends a hex string to set the intensity of all motors. When sent from app to server, the first byte is the device to target. When sent to the device, each byte is a motor, big endian. Ex: Device -&amp;gt; Server &amp;lt;code&amp;gt;00FFAA00FF&amp;lt;/code&amp;gt; sets the first control...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All communications between a Device, Server, and App are done through tasks.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Task&lt;br /&gt;
!Args&lt;br /&gt;
!REST&lt;br /&gt;
!Websocket&lt;br /&gt;
!Sender -&amp;gt; Receiver&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|p&lt;br /&gt;
|(string)hex_bytes&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server, Server -&amp;gt; Device&lt;br /&gt;
|Sends a hex string to set the intensity of all motors. When sent from app to server, the first byte is the device to target. When sent to the device, each byte is a motor, big endian. Ex: Device -&amp;gt; Server &amp;lt;code&amp;gt;00FFAA00FF&amp;lt;/code&amp;gt; sets the first controlled device&#039;s motors to Motor1: FF, motor2: AA, Motor3: 00, Motor4 FF&lt;br /&gt;
|-&lt;br /&gt;
|ps&lt;br /&gt;
|(string)hex_bytes&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server, Server -&amp;gt; Device&lt;br /&gt;
|Similar to above, but you send blocks of 2 bytes where the first byte is the motor and the second byte is the PWM value. When sent from the device, the first value is the device to target. Ex: Device -&amp;gt; Server &amp;lt;code&amp;gt;0001FF03AA&amp;lt;/code&amp;gt; targets the first controlled device and sets its second port to FF and 4th port to AA.&lt;br /&gt;
|-&lt;br /&gt;
|vib&lt;br /&gt;
|(obj)program&lt;br /&gt;
|X&lt;br /&gt;
|X&lt;br /&gt;
|Server -&amp;gt; Device&lt;br /&gt;
|Sends a vib program object to the device.&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|(str)deviceID / (obj){id:(str)deviceID, ...meta_keys}&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|Device -&amp;gt; Server&lt;br /&gt;
|Sent from a device to the server to list itself on the server.&lt;br /&gt;
|-&lt;br /&gt;
|app&lt;br /&gt;
|(str)name&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server, Server -&amp;gt; Device&lt;br /&gt;
|Sent by an app to a server to list itself. When an app claims a device, this is also sent to the device, but with two args: (str)app_name, (str)app_connection_id&lt;br /&gt;
|-&lt;br /&gt;
|whois&lt;br /&gt;
|(str)deviceID&lt;br /&gt;
|X&lt;br /&gt;
|&lt;br /&gt;
|App -&amp;gt; Server&lt;br /&gt;
|Request info about a connected device by deviceID. See [Device&lt;br /&gt;
|-&lt;br /&gt;
|app_offline&lt;br /&gt;
|(str)name, (str)connectionID&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|Server -&amp;gt; Device&lt;br /&gt;
|Sent to a device when an app that had connected to it has gone offline&lt;br /&gt;
|-&lt;br /&gt;
|hookup&lt;br /&gt;
|(str)deviceID / (arr)deviceIDs&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server&lt;br /&gt;
|Sent by the app to start controlling one or many devices. Sends a callback with a list of all hooked up deviceIDs. The index of this list is used in p / ps calls.&lt;br /&gt;
|-&lt;br /&gt;
|hookdown&lt;br /&gt;
|(str)deviceID / (arr)deviceIDs&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server&lt;br /&gt;
|Sent by the app to stop controlling one or may devices. Sends a callback with a list of all hooked up deviceIDs. The index of this list is used in p / ps calls.&lt;br /&gt;
|-&lt;br /&gt;
|dev_online&lt;br /&gt;
|(str)deviceID, (str)socketID, (obj)meta&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|Server -&amp;gt; App&lt;br /&gt;
|Sent to the app when a device comes online.&lt;br /&gt;
|-&lt;br /&gt;
|dev_offline&lt;br /&gt;
|(str)deviceID, (str)socketID&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|Server -&amp;gt; App&lt;br /&gt;
|Sent to the app when a device goes offline.&lt;br /&gt;
|-&lt;br /&gt;
|dCustom&lt;br /&gt;
|(str)deviceID, (var)customData / (str)appName, (str)socketID, (var)customData&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server, Server -&amp;gt; Device&lt;br /&gt;
|Relays a custom message to a device. When sending from App to Server, you use deviceID and the custom data. The Device receives appName, the device&#039;s socket ID, and the custom data&lt;br /&gt;
|-&lt;br /&gt;
|aCustom&lt;br /&gt;
|(str)socketID, (var)customData / (str)deviceID, (str)socketID, (var)customData&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|Device -&amp;gt; Server, Server -&amp;gt; App&lt;br /&gt;
|Relays a custom message from a Device to an App. When sending from Device to Server, you use the socketID (which you can get from the &amp;quot;app&amp;quot; event or dCustom when an app requests data from a device). The app then receives (str)deviceID, (str)socketID_of_device, (var)customData&lt;br /&gt;
|-&lt;br /&gt;
|GET&lt;br /&gt;
|(obj){id:(str)deviceID, type:(str)type, data:(obj)data}&lt;br /&gt;
|&lt;br /&gt;
|X&lt;br /&gt;
|App -&amp;gt; Server&lt;br /&gt;
|Emulates a call to the [[REST]] endpoint with websockets.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=7</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=7"/>
		<updated>2026-01-29T11:20:20Z</updated>

		<summary type="html">&lt;p&gt;Jasx: /* Source Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the VibHub developer wiki! Before we start, let&#039;s go over some terms:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Term&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|[[Firmware|Device]]&lt;br /&gt;
|This is the physical hardware VibHub, and also refers to the firmware.&lt;br /&gt;
|-&lt;br /&gt;
|[[App]]&lt;br /&gt;
|The code that sends vibration instructions to the Device. This is likely what you&#039;re here for! See the API documentation below!&lt;br /&gt;
|-&lt;br /&gt;
|[[Server]]&lt;br /&gt;
|This is the server that relays messages between the Device and the App. You can host your own!&lt;br /&gt;
|-&lt;br /&gt;
|deviceID&lt;br /&gt;
|A unique ID for each Device that allows the App to communicate with it&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Source Code ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Server VibHub Server]&lt;br /&gt;
|Host your own VibHub server!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Browser VibHub Browser]&lt;br /&gt;
|Official JS client library. See [[VibHub-Browser]] for documentation.&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/SL-XOBJ/blob/master/xobj_core/classes/jas%20VibHub.lsl XOBJ SL Library]&lt;br /&gt;
|Second Life library built on the XOBJ framework&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-SocketDemo Browser Example]&lt;br /&gt;
|Example browser app that lets you run VibHub locally with just a few lines of code!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!API Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[[REST]]&lt;br /&gt;
|Lets you send vibration programs to a device through simple HTTP requests.&lt;br /&gt;
|-&lt;br /&gt;
|[[Web Sockets]]&lt;br /&gt;
|Much faster than REST requests, recommended if your platform supports it!&lt;br /&gt;
|-&lt;br /&gt;
|[[Tasks|Tasks Reference]]&lt;br /&gt;
|Tasks that your device can handle.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=6</id>
		<title>VibHub-Browser</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=VibHub-Browser&amp;diff=6"/>
		<updated>2026-01-29T11:19:32Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;The library can be clone from [https://github.com/JasXSL/VibHub-Browser here].&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The library can be clone from [https://github.com/JasXSL/VibHub-Browser here].&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Web_Sockets&amp;diff=5</id>
		<title>Web Sockets</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Web_Sockets&amp;diff=5"/>
		<updated>2026-01-29T11:18:41Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;If you want to control the level directly from an app by sending many update requests every second, you can use the websocket API. In this code we&amp;#039;ll use the device id &amp;quot;JasTestBullet&amp;quot;, replace that with your own.  == Install socket.io == Add the socket.io client to your website in your preferred fashion (such as NPM or websockets). After the page loads, connect to the socket:  let socket = io(&amp;#039;&amp;lt;nowiki&amp;gt;https://vibhub.io&amp;#039;&amp;lt;/nowiki&amp;gt;);  socket.on(&amp;#039;connect&amp;#039;, () =&amp;gt; {      // CO...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to control the level directly from an app by sending many update requests every second, you can use the websocket API. In this code we&#039;ll use the device id &amp;quot;JasTestBullet&amp;quot;, replace that with your own.&lt;br /&gt;
&lt;br /&gt;
== Install socket.io ==&lt;br /&gt;
Add the socket.io client to your website in your preferred fashion (such as NPM or websockets).&lt;br /&gt;
After the page loads, connect to the socket:&lt;br /&gt;
 let socket = io(&#039;&amp;lt;nowiki&amp;gt;https://vibhub.io&#039;&amp;lt;/nowiki&amp;gt;);&lt;br /&gt;
 socket.on(&#039;connect&#039;, () =&amp;gt; {&lt;br /&gt;
     // CODE GOES HERE&lt;br /&gt;
 });&lt;br /&gt;
This sets up a connection and an event listener for connection established. Let&#039;s set up a channel so we can push messages to the device. Replace the &amp;lt;code&amp;gt;// CODE GOES HERE&amp;lt;/code&amp;gt; bit with:&lt;br /&gt;
 console.log(&amp;quot;Socket connection established, setting up a channel&amp;quot;);&lt;br /&gt;
 socket.emit(&#039;app&#039;, &amp;quot;JasTestApp&amp;quot;, (success) =&amp;gt; {&lt;br /&gt;
     if( !success )&lt;br /&gt;
         return;&lt;br /&gt;
     socket.emit(&#039;hookup&#039;, &#039;JasTestBullet&#039;, (response) =&amp;gt; {&lt;br /&gt;
         let devices = response;&lt;br /&gt;
         if( !devices.length )&lt;br /&gt;
             return;&lt;br /&gt;
         let hex = &lt;br /&gt;
             &#039;00&#039;+&lt;br /&gt;
             &#039;FF&#039;+&lt;br /&gt;
             &#039;AA&#039;+&lt;br /&gt;
             &#039;10&#039;+&lt;br /&gt;
             &#039;00&#039;&lt;br /&gt;
         ;&lt;br /&gt;
         socket.emit(&#039;p&#039;, hex);&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
=== Explanation: ===&lt;br /&gt;
&amp;lt;code&amp;gt;socket.emit(&#039;app&#039;, &amp;quot;JasTestApp&amp;quot;, (success) =&amp;gt; {&amp;lt;/code&amp;gt;&lt;br /&gt;
This sets our connected socket to an app with the name JasTestApp. The name is generally only needed for debugging and in custom events. You can skip that step and directly hookup if you don&#039;t want to customize your VibHub device behavior.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;socket.emit(&#039;hookup&#039;, &#039;JasTestBullet&#039;, (response) =&amp;gt; {})&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;hookup&#039; is a task meaning we&#039;ll want to set up a channel to start pushing data. The opposite is hookdown if you want to remove a device. This needs to be sent if you get disconnected and reconnect as well, since all channels are cleared on disconnect.&lt;br /&gt;
* &#039;JasTestBullet&#039; is the ID of our device. Replace it with the user&#039;s device ID.&lt;br /&gt;
* (response) =&amp;gt; {} Sets up a callback function&lt;br /&gt;
&lt;br /&gt;
 let devices = response;&lt;br /&gt;
 if( !devices.length )&lt;br /&gt;
     return;&lt;br /&gt;
The response contains an array of connected devices. So if you hook up device A &#039;JasTestBullet&#039; and device B &#039;JasTestRing&#039;, the response will most likely be [&#039;JasTestBullet&#039;, &#039;JasTestRing&#039;]. You should generally save this array somewhere.&lt;br /&gt;
&lt;br /&gt;
The second part makes sure that at least one device is connected. In our case, devices will be [&#039;JasTestBullet&#039;]. Keep in mind here that JasTestBullet resides on index 0 of the array. This index is what we use to send the task that sets the power of the device:&lt;br /&gt;
 let hex = &lt;br /&gt;
     &#039;00&#039;+&lt;br /&gt;
     &#039;FF&#039;+&lt;br /&gt;
     &#039;AA&#039;+&lt;br /&gt;
     &#039;10&#039;+&lt;br /&gt;
     &#039;00&#039;&lt;br /&gt;
 ;&lt;br /&gt;
This sets up a hex value to send to the server in order:&lt;br /&gt;
&lt;br /&gt;
* &#039;00&#039; = Target device index 0 (&amp;quot;JasTestBullet&amp;quot;)&lt;br /&gt;
* &#039;FF&#039; = Set port 0 to max (255)&lt;br /&gt;
* &#039;AA&#039; = Set port 1 to AA (170)&lt;br /&gt;
* &#039;10&#039; = Set port 2&lt;br /&gt;
* &#039;00&#039; = Turn off port 3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;socket.emit(&#039;p&#039;, buffer);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This sends the command to the server. &#039;p&#039; is always the task used for socket send, so you can just leave it as &#039;p&#039;.&lt;br /&gt;
&lt;br /&gt;
== Better practices ==&lt;br /&gt;
Store devices as an array somewhere, and whenever you want to send a new intensity value to the device, check for the device ID in the devices array. For an instance:&lt;br /&gt;
 let index = devices.indexOf(&#039;JasTestBullet&#039;);&lt;br /&gt;
For a full list of tasks and their documentation, see Tasks.&lt;br /&gt;
&lt;br /&gt;
== Or just our JavaScript Library ==&lt;br /&gt;
See [[VibHub-Browser]] for documentation!&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=REST&amp;diff=4</id>
		<title>REST</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=REST&amp;diff=4"/>
		<updated>2026-01-29T11:15:28Z</updated>

		<summary type="html">&lt;p&gt;Jasx: Created page with &amp;quot;The REST API allows you to send a set of tween instructions to a device. This is a good option if you want to send fewer requests that execute a program of pulses, turning on and off etc, or your platform can&amp;#039;t do websockets.  To send a program to a device, simply send a GET request to: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://vibhub.io/api?id=&amp;lt;/nowiki&amp;gt;&amp;lt;device_id&amp;gt;&amp;amp;type=&amp;lt;type&amp;gt;&amp;amp;data=&amp;lt;json_data_here&amp;gt;&amp;lt;/code&amp;gt;  (HTTP is also accepted but should only be used if your app can&amp;#039;t use SSL)  Query para...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The REST API allows you to send a set of tween instructions to a device. This is a good option if you want to send fewer requests that execute a program of pulses, turning on and off etc, or your platform can&#039;t do websockets.&lt;br /&gt;
&lt;br /&gt;
To send a program to a device, simply send a GET request to: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://vibhub.io/api?id=&amp;lt;/nowiki&amp;gt;&amp;lt;device_id&amp;gt;&amp;amp;type=&amp;lt;type&amp;gt;&amp;amp;data=&amp;lt;json_data_here&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(HTTP is also accepted but should only be used if your app can&#039;t use SSL)&lt;br /&gt;
&lt;br /&gt;
Query params explained:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string&lt;br /&gt;
|The deviceID you want to run the program on&lt;br /&gt;
|-&lt;br /&gt;
|type&lt;br /&gt;
|string&lt;br /&gt;
|The task to send. See Tasks below.&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|varies&lt;br /&gt;
|Depends on the type, see below.&lt;br /&gt;
|}&lt;br /&gt;
Don&#039;t forget to URL encode.&lt;br /&gt;
&lt;br /&gt;
= Types =&lt;br /&gt;
&lt;br /&gt;
=== vib ===&lt;br /&gt;
The &amp;quot;vib&amp;quot; task expects data to be a URL encoded array of objects with the following params:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Required&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|stages&lt;br /&gt;
|N/A&lt;br /&gt;
|Yes&lt;br /&gt;
|Array&lt;br /&gt;
|An array of stage objects to be tweened beetween. See below for stage objects&lt;br /&gt;
|-&lt;br /&gt;
|repeats&lt;br /&gt;
|0&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|Nr times the animation should repeat. 0 plays it once, 1 plays it twice etc. Use -1 for infinity&lt;br /&gt;
|-&lt;br /&gt;
|port&lt;br /&gt;
|0&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|Bitwise combination of ports to run the program on. 0x1 is the first port, 0x2 second and so forth. 0 or negative values will target ALL ports.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Stages ===&lt;br /&gt;
The stage is an object containing tweening information for that stage of the program. It has the following properties:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|i&lt;br /&gt;
|0&lt;br /&gt;
|integer/obj/boolean&lt;br /&gt;
|A value between 0 and 255. Higher value = faster vibrations. Or false to use the previous value. Or a RandObject (see below).&lt;br /&gt;
|-&lt;br /&gt;
|d&lt;br /&gt;
|0&lt;br /&gt;
|integer/obj&lt;br /&gt;
|Time in milliseconds to reach specified intensity. 0 = instant. Or a RandObject (see below).&lt;br /&gt;
|-&lt;br /&gt;
|e&lt;br /&gt;
|&amp;quot;Linear.None&amp;quot;&lt;br /&gt;
|string&lt;br /&gt;
|A string denoting the tween.js easing type. See this example for the supported types.&lt;br /&gt;
|-&lt;br /&gt;
|r&lt;br /&gt;
|0&lt;br /&gt;
|integer/object&lt;br /&gt;
|Repeats. 0 = play this stage once, 1 = play this stage twice and so forth. Or a RandObject (see below)&lt;br /&gt;
|-&lt;br /&gt;
|y&lt;br /&gt;
|false&lt;br /&gt;
|boolean/truthy/falsy value&lt;br /&gt;
|Go back and forth. Requires repeats to work. Repeats of 1 goes back and forth once, repeats of 3 goes back and forth twice etc. An even number such as 2 will go forth, back, forth, and then start at forth on the next stage.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== RandObject ===&lt;br /&gt;
A RandObject can be used in certain places of a vib call. It&#039;ll generate a random value. This value will be randomized at the start of each program loop, but not program stage loop.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Param&lt;br /&gt;
!Default&lt;br /&gt;
!Type&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|min&lt;br /&gt;
|0&lt;br /&gt;
|integer&lt;br /&gt;
|Min value to randomize&lt;br /&gt;
|-&lt;br /&gt;
|max&lt;br /&gt;
|varying&lt;br /&gt;
|integer&lt;br /&gt;
|Max value to randomize. The default value for this depends on the stage param you put it in. i=255, d=10000, r=9&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|0&lt;br /&gt;
|integer&lt;br /&gt;
|Adds an offset to the randomly generated value. Useful in yoyo type steps where you always want an odd number of repeats (combine with multi of 2).&lt;br /&gt;
|-&lt;br /&gt;
|multi&lt;br /&gt;
|1&lt;br /&gt;
|integer&lt;br /&gt;
|Multiplies the random value by this. Useful together with offset to generate pulses going up and down n times&lt;br /&gt;
|}&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;min&amp;quot;:0, &amp;quot;max&amp;quot;:3, &amp;quot;offset&amp;quot;:1, &amp;quot;multi&amp;quot;:2}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is useful in repeats with yoyo, as it always generates an odd number. In practice, the above line means &amp;quot;generate 1-4 pulses.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Run a program on device id &amp;quot;JasTestBullet&amp;quot;. The program resets the vibration level to 0, then goes up to 50% and down again 3 times, then resets back to 0.&lt;br /&gt;
Request:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GET &amp;lt;nowiki&amp;gt;https://vibhub.io/api/?id=JasTestBullet&amp;amp;type=vib&amp;amp;data=&amp;lt;/nowiki&amp;gt;[{&amp;quot;stages&amp;quot;:[{&amp;quot;i&amp;quot;:0,&amp;quot;d&amp;quot;:0},{&amp;quot;i&amp;quot;:50,&amp;quot;d&amp;quot;:500,&amp;quot;r&amp;quot;:5,&amp;quot;y&amp;quot;:1},{&amp;quot;i&amp;quot;:0,&amp;quot;d&amp;quot;:0}]}]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;message&amp;quot;:&amp;quot;OK&amp;quot;,&amp;quot;success&amp;quot;:true}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== whois ==&lt;br /&gt;
Lets you get meta information about a connected device:&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
Request:&lt;br /&gt;
&amp;lt;code&amp;gt;GET &amp;lt;nowiki&amp;gt;https://vibhub.io/api/?id=JasTestBullet&amp;amp;type=whois&amp;amp;data=&amp;lt;/nowiki&amp;gt;[]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{&amp;quot;message&amp;quot;:{&amp;quot;numPorts&amp;quot;:4,&amp;quot;version&amp;quot;:&amp;quot;0.3.0&amp;quot;,&amp;quot;hwversion&amp;quot;:&amp;quot;esp32&amp;quot;,&amp;quot;custom&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;capabilities&amp;quot;:{&amp;quot;p&amp;quot;:true,&amp;quot;ps&amp;quot;:true,&amp;quot;vib&amp;quot;:&amp;quot;true&amp;quot;}},&amp;quot;success&amp;quot;:true}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=3</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=3"/>
		<updated>2026-01-29T11:13:03Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the VibHub developer wiki! Before we start, let&#039;s go over some terms:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Term&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|[[Firmware|Device]]&lt;br /&gt;
|This is the physical hardware VibHub, and also refers to the firmware.&lt;br /&gt;
|-&lt;br /&gt;
|[[App]]&lt;br /&gt;
|The code that sends vibration instructions to the Device. This is likely what you&#039;re here for! See the API documentation below!&lt;br /&gt;
|-&lt;br /&gt;
|[[Server]]&lt;br /&gt;
|This is the server that relays messages between the Device and the App. You can host your own!&lt;br /&gt;
|-&lt;br /&gt;
|deviceID&lt;br /&gt;
|A unique ID for each Device that allows the App to communicate with it&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Source Code ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Server VibHub Server]&lt;br /&gt;
|Host your own VibHub server!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Browser VibHub Browser]&lt;br /&gt;
|Official JS client library&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/SL-XOBJ/blob/master/xobj_core/classes/jas%20VibHub.lsl XOBJ SL Library]&lt;br /&gt;
|Second Life library built on the XOBJ framework&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-SocketDemo Browser Example]&lt;br /&gt;
|Example browser app that you can run locally&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!API Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[[REST]]&lt;br /&gt;
|Lets you send vibration programs to a device through simple HTTP requests.&lt;br /&gt;
|-&lt;br /&gt;
|[[Web Sockets]]&lt;br /&gt;
|Much faster than REST requests, recommended if your platform supports it!&lt;br /&gt;
|-&lt;br /&gt;
|[[Tasks|Tasks Reference]]&lt;br /&gt;
|Tasks that your device can handle.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
	<entry>
		<id>https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=2</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.vibhub.io/index.php?title=Main_Page&amp;diff=2"/>
		<updated>2026-01-29T11:07:58Z</updated>

		<summary type="html">&lt;p&gt;Jasx: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the VibHub developer wiki! Before we start, let&#039;s go over some terms:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Term&lt;br /&gt;
!Explanation&lt;br /&gt;
|-&lt;br /&gt;
|Device&lt;br /&gt;
|This is the physical hardware VibHub&lt;br /&gt;
|-&lt;br /&gt;
|App&lt;br /&gt;
|The code that sends vibration instructions to the Device&lt;br /&gt;
|-&lt;br /&gt;
|Server&lt;br /&gt;
|This is the server that relays messages between the Device and the App&lt;br /&gt;
|-&lt;br /&gt;
|deviceID&lt;br /&gt;
|A unique ID for each Device that allows the App to communicate with it&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Source Code ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name/Link&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Micro VibHub Micro]&lt;br /&gt;
|2026 Revision of the board. Featuring high res commands, 2 ports, and a built in rechargeable battery!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-ESP32 VibHub ESP32]&lt;br /&gt;
|4xAA Version of the VibHub&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Server VibHub Server]&lt;br /&gt;
|Host your own VibHub server!&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-Browser VibHub Browser]&lt;br /&gt;
|Official JS client library&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/SL-XOBJ/blob/master/xobj_core/classes/jas%20VibHub.lsl XOBJ SL Library]&lt;br /&gt;
|Second Life library built on the XOBJ framework&lt;br /&gt;
|-&lt;br /&gt;
|[https://github.com/JasXSL/VibHub-SocketDemo Browser Example]&lt;br /&gt;
|Example browser app that you can run locally&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jasx</name></author>
	</entry>
</feed>