Skip to content

Commit 4757584

Browse files
blackspherefollowerqdot
authored andcommitted
feat: Adding support for Kiiroo Spot and WeVibe Wand 2
1 parent 1bd70d2 commit 4757584

File tree

6 files changed

+228
-0
lines changed

6 files changed

+228
-0
lines changed

buttplug/buttplug-device-config/build-config/buttplug-device-config-v3.json

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3773,6 +3773,26 @@
37733773
}
37743774
]
37753775
},
3776+
{
3777+
"identifier": [
3778+
"Wand 2"
3779+
],
3780+
"name": "WeVibe Wand 2",
3781+
"features": [
3782+
{
3783+
"feature-type": "Vibrate",
3784+
"actuator": {
3785+
"step-range": [
3786+
0,
3787+
22
3788+
],
3789+
"messages": [
3790+
"ScalarCmd"
3791+
]
3792+
}
3793+
}
3794+
]
3795+
},
37763796
{
37773797
"identifier": [
37783798
"Bond",
@@ -3843,6 +3863,7 @@
38433863
"Moxie",
38443864
"Vector",
38453865
"Wand",
3866+
"Wand 2",
38463867
"Bond",
38473868
"Nelson",
38483869
"Nova2",
@@ -4929,6 +4950,57 @@
49294950
}
49304951
]
49314952
},
4953+
"kiiroo-spot": {
4954+
"defaults": {
4955+
"name": "Kiiroo Spot",
4956+
"features": [
4957+
{
4958+
"feature-type": "Vibrate",
4959+
"actuator": {
4960+
"step-range": [
4961+
0,
4962+
100
4963+
],
4964+
"messages": [
4965+
"ScalarCmd"
4966+
]
4967+
}
4968+
},
4969+
{
4970+
"feature-type": "Battery",
4971+
"description": "Battery Level",
4972+
"sensor": {
4973+
"value-range": [
4974+
[
4975+
0,
4976+
100
4977+
]
4978+
],
4979+
"messages": [
4980+
"SensorReadCmd"
4981+
]
4982+
}
4983+
}
4984+
]
4985+
},
4986+
"communication": [
4987+
{
4988+
"btle": {
4989+
"names": [
4990+
"SPOT W1"
4991+
],
4992+
"services": {
4993+
"00001400-0000-1000-8000-00805f9b34fb": {
4994+
"tx": "00001401-0000-1000-8000-00805f9b34fb"
4995+
},
4996+
"0000180f-0000-1000-8000-00805f9b34fb": {
4997+
"rxblebattery": "00002a19-0000-1000-8000-00805f9b34fb"
4998+
}
4999+
}
5000+
}
5001+
}
5002+
]
5003+
},
49325004
"vorze-cyclone-x": {
49335005
"defaults": {
49345006
"name": "Vorze Cyclone X10 Device",

buttplug/buttplug-device-config/device-config-v3/buttplug-device-config-v3.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2166,6 +2166,17 @@ protocols:
21662166
- 22
21672167
messages:
21682168
- ScalarCmd
2169+
- identifier:
2170+
- Wand 2
2171+
name: WeVibe Wand 2
2172+
features:
2173+
- feature-type: Vibrate
2174+
actuator:
2175+
step-range:
2176+
- 0
2177+
- 22
2178+
messages:
2179+
- ScalarCmd
21692180
- identifier:
21702181
- Bond
21712182
- Nelson
@@ -2208,6 +2219,7 @@ protocols:
22082219
- Moxie
22092220
- Vector
22102221
- Wand
2222+
- Wand 2
22112223
- Bond
22122224
- Nelson
22132225
- Nova2
@@ -2833,6 +2845,34 @@ protocols:
28332845
tx: 00001401-0000-1000-8000-00805f9b34fb
28342846
0000180f-0000-1000-8000-00805f9b34fb:
28352847
rxblebattery: 00002a19-0000-1000-8000-00805f9b34fb
2848+
kiiroo-spot:
2849+
defaults:
2850+
name: Kiiroo Spot
2851+
features:
2852+
- feature-type: Vibrate
2853+
actuator:
2854+
step-range:
2855+
- 0
2856+
- 100
2857+
messages:
2858+
- ScalarCmd
2859+
- feature-type: Battery
2860+
description: Battery Level
2861+
sensor:
2862+
value-range:
2863+
- - 0
2864+
- 100
2865+
messages:
2866+
- SensorReadCmd
2867+
communication:
2868+
- btle:
2869+
names:
2870+
- SPOT W1
2871+
services:
2872+
00001400-0000-1000-8000-00805f9b34fb:
2873+
tx: 00001401-0000-1000-8000-00805f9b34fb
2874+
0000180f-0000-1000-8000-00805f9b34fb:
2875+
rxblebattery: 00002a19-0000-1000-8000-00805f9b34fb
28362876
vorze-cyclone-x:
28372877
defaults:
28382878
name: Vorze Cyclone X10 Device
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Buttplug Rust Source Code File - See https://buttplug.io for more info.
2+
//
3+
// Copyright 2016-2025 Nonpolynomial Labs LLC. All rights reserved.
4+
//
5+
// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
6+
// for full license information.
7+
8+
use crate::{
9+
core::{
10+
errors::ButtplugDeviceError,
11+
message::{self, ButtplugDeviceMessage, Endpoint, SensorReadingV4},
12+
},
13+
server::device::{
14+
hardware::{Hardware, HardwareCommand, HardwareReadCmd, HardwareWriteCmd},
15+
protocol::{generic_protocol_setup, ProtocolHandler},
16+
},
17+
};
18+
use futures::{future::BoxFuture, FutureExt};
19+
use std::{default::Default, sync::Arc};
20+
21+
generic_protocol_setup!(KiirooSpot, "kiiroo-spot");
22+
23+
#[derive(Default)]
24+
pub struct KiirooSpot {}
25+
26+
impl ProtocolHandler for KiirooSpot {
27+
fn handle_scalar_vibrate_cmd(
28+
&self,
29+
_: u32,
30+
scalar: u32,
31+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
32+
Ok(vec![HardwareWriteCmd::new(
33+
Endpoint::Tx,
34+
vec![0x00, 0xff, 0x00, 0x00, 0x00, scalar as u8],
35+
false,
36+
)
37+
.into()])
38+
}
39+
40+
fn handle_battery_level_cmd(
41+
&self,
42+
device: Arc<Hardware>,
43+
message: message::SensorReadCmdV4,
44+
) -> BoxFuture<Result<SensorReadingV4, ButtplugDeviceError>> {
45+
debug!("Trying to get battery reading.");
46+
let message = message.clone();
47+
let msg = HardwareReadCmd::new(Endpoint::RxBLEBattery, 20, 0);
48+
let fut = device.read_value(&msg);
49+
async move {
50+
let hw_msg = fut.await?;
51+
let data = hw_msg.data();
52+
let battery_level = data[0] as i32;
53+
let battery_reading = message::SensorReadingV4::new(
54+
message.device_index(),
55+
*message.feature_index(),
56+
*message.sensor_type(),
57+
vec![battery_level],
58+
);
59+
debug!("Got battery reading: {}", battery_level);
60+
Ok(battery_reading)
61+
}
62+
.boxed()
63+
}
64+
}

buttplug/src/server/device/protocol/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub mod joyhub_v5;
4747
pub mod joyhub_v6;
4848
pub mod kgoal_boost;
4949
pub mod kiiroo_prowand;
50+
pub mod kiiroo_spot;
5051
pub mod kiiroo_v2;
5152
pub mod kiiroo_v21;
5253
pub mod kiiroo_v21_initialized;
@@ -335,6 +336,10 @@ pub fn get_default_protocol_map() -> HashMap<String, Arc<dyn ProtocolIdentifierF
335336
&mut map,
336337
kiiroo_prowand::setup::KiirooProWandIdentifierFactory::default(),
337338
);
339+
add_to_protocol_map(
340+
&mut map,
341+
kiiroo_spot::setup::KiirooSpotIdentifierFactory::default(),
342+
);
338343
add_to_protocol_map(
339344
&mut map,
340345
kiiroo_v2::setup::KiirooV2IdentifierFactory::default(),

buttplug/tests/test_device_protocols.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ async fn load_test_case(test_file: &str) -> DeviceTestCase {
120120
#[test_case("test_tcode_linear_and_vibrate.yaml" ; "TCode (Linear + Vibrate)")]
121121
#[test_case("test_serveu_protocol.yaml" ; "ServeU")]
122122
#[test_case("test_kiiroo_prowand.yaml" ; "Kiiroo ProWand Protocol")]
123+
#[test_case("test_kiiroo_spot.yaml" ; "Kiiroo Spot Protocol")]
123124
#[test_case("test_fleshy_thrust_protocol.yaml" ; "Fleshy Thrust Sync Protocol")]
124125
#[test_case("test_nexus_revo.yaml" ; "Nexus Revo Protocol")]
125126
#[test_case("test_luvmazer_protocol.yaml" ; "Luvmazer Protocol")]
@@ -235,6 +236,7 @@ async fn test_device_protocols_embedded_v3(test_file: &str) {
235236
#[test_case("test_tcode_linear_and_vibrate.yaml" ; "TCode (Linear + Vibrate)")]
236237
#[test_case("test_serveu_protocol.yaml" ; "ServeU")]
237238
#[test_case("test_kiiroo_prowand.yaml" ; "Kiiroo ProWand Protocol")]
239+
#[test_case("test_kiiroo_spot.yaml" ; "Kiiroo Spot Protocol")]
238240
#[test_case("test_fleshy_thrust_protocol.yaml" ; "Fleshy Thrust Sync Protocol")]
239241
#[test_case("test_nexus_revo.yaml" ; "Nexus Revo Protocol")]
240242
#[test_case("test_luvmazer_protocol.yaml" ; "Luvmazer Protocol")]
@@ -320,6 +322,7 @@ async fn test_device_protocols_json_v3(test_file: &str) {
320322
#[test_case("test_tcode_linear_and_vibrate.yaml" ; "TCode (Linear + Vibrate)")]
321323
#[test_case("test_serveu_protocol.yaml" ; "ServeU")]
322324
#[test_case("test_kiiroo_prowand.yaml" ; "Kiiroo ProWand Protocol")]
325+
#[test_case("test_kiiroo_spot.yaml" ; "Kiiroo Spot Protocol")]
323326
#[test_case("test_fleshy_thrust_protocol.yaml" ; "Fleshy Thrust Sync Protocol")]
324327
#[test_case("test_nexus_revo.yaml" ; "Nexus Revo Protocol")]
325328
#[test_case("test_omobo_protocol.yaml" ; "Omobo Protocol")]
@@ -402,6 +405,7 @@ async fn test_device_protocols_embedded_v2(test_file: &str) {
402405
#[test_case("test_tcode_linear_and_vibrate.yaml" ; "TCode (Linear + Vibrate)")]
403406
#[test_case("test_serveu_protocol.yaml" ; "ServeU")]
404407
#[test_case("test_kiiroo_prowand.yaml" ; "Kiiroo ProWand Protocol")]
408+
#[test_case("test_kiiroo_spot.yaml" ; "Kiiroo Spot Protocol")]
405409
#[test_case("test_fleshy_thrust_protocol.yaml" ; "Fleshy Thrust Sync Protocol")]
406410
#[test_case("test_nexus_revo.yaml" ; "Nexus Revo Protocol")]
407411
#[test_case("test_omobo_protocol.yaml" ; "Omobo Protocol")]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
devices:
2+
- identifier:
3+
name: "SPOT W1"
4+
expected_name: "Kiiroo Spot"
5+
device_commands:
6+
# Commands
7+
- !Messages
8+
device_index: 0
9+
messages:
10+
- !Vibrate
11+
- Index: 0
12+
Speed: 0.5
13+
- !Commands
14+
device_index: 0
15+
commands:
16+
- !Write
17+
endpoint: tx
18+
data: [0x00, 0xff, 0x00, 0x00, 0x00, 0x32]
19+
write_with_response: false
20+
- !Messages
21+
device_index: 0
22+
messages:
23+
- !Vibrate
24+
- Index: 0
25+
Speed: 1.0
26+
- !Commands
27+
device_index: 0
28+
commands:
29+
- !Write
30+
endpoint: tx
31+
data: [0x00, 0xff, 0x00, 0x00, 0x00, 0x64]
32+
write_with_response: false
33+
- !Messages
34+
device_index: 0
35+
messages:
36+
- !Stop
37+
- !Commands
38+
device_index: 0
39+
commands:
40+
- !Write
41+
endpoint: tx
42+
data: [0x00, 0xff, 0x00, 0x00, 0x00, 0x00]
43+
write_with_response: false

0 commit comments

Comments
 (0)