diff --git a/crates/buttplug_server/src/device/protocol_impl/kiiroo_spot_v2.rs b/crates/buttplug_server/src/device/protocol_impl/kiiroo_spot_v2.rs new file mode 100644 index 000000000..bb81e3e30 --- /dev/null +++ b/crates/buttplug_server/src/device/protocol_impl/kiiroo_spot_v2.rs @@ -0,0 +1,67 @@ +// Buttplug Rust Source Code File - See https://buttplug.io for more info. +// +// Copyright 2016-2026 Nonpolynomial Labs LLC. All rights reserved. +// +// Licensed under the BSD 3-Clause license. See LICENSE file in the project root +// for full license information. + +use crate::device::{ + hardware::{Hardware, HardwareCommand, HardwareReadCmd, HardwareWriteCmd}, + protocol::{ProtocolHandler, generic_protocol_setup}, +}; +use buttplug_core::{ + errors::ButtplugDeviceError, + message::{self, InputReadingV4, InputTypeReading, InputValue}, +}; +use buttplug_server_device_config::Endpoint; +use futures::{FutureExt, future::BoxFuture}; +use std::{default::Default, sync::Arc}; +use uuid::Uuid; + +generic_protocol_setup!(KiirooSpotV2, "kiiroo-spot-v2"); + +#[derive(Default)] +pub struct KiirooSpotV2 {} + +impl ProtocolHandler for KiirooSpotV2 { + fn handle_output_vibrate_cmd( + &self, + _feature_index: u32, + feature_id: Uuid, + speed: u32, + ) -> Result, ButtplugDeviceError> { + Ok(vec![ + HardwareWriteCmd::new( + &[feature_id], + Endpoint::Tx, + vec![0x01, speed as u8, speed as u8, 0x03, 0xe8, 0xff], + true, + ) + .into(), + ]) + } + + fn handle_battery_level_cmd( + &self, + device_index: u32, + device: Arc, + feature_index: u32, + feature_id: Uuid, + ) -> BoxFuture<'_, Result> { + debug!("Trying to get battery reading."); + let msg = HardwareReadCmd::new(feature_id, Endpoint::RxBLEBattery, 20, 0); + let fut = device.read_value(&msg); + async move { + let hw_msg = fut.await?; + let data = hw_msg.data(); + let battery_reading = message::InputReadingV4::new( + device_index, + feature_index, + InputTypeReading::Battery(InputValue::new(data[0])), + ); + debug!("Got battery reading: {}", data[0]); + Ok(battery_reading) + } + .boxed() + } +} diff --git a/crates/buttplug_server/src/device/protocol_impl/mod.rs b/crates/buttplug_server/src/device/protocol_impl/mod.rs index 5e9ff3293..b9c2811f7 100644 --- a/crates/buttplug_server/src/device/protocol_impl/mod.rs +++ b/crates/buttplug_server/src/device/protocol_impl/mod.rs @@ -45,6 +45,7 @@ pub mod kgoal_boost; pub mod kiiroo_powershot; pub mod kiiroo_prowand; pub mod kiiroo_spot; +pub mod kiiroo_spot_v2; pub mod kiiroo_v2; pub mod kiiroo_v21; pub mod kiiroo_v21_initialized; @@ -114,6 +115,7 @@ pub mod thehandy_v3; pub mod tryfun; pub mod tryfun_blackhole; pub mod tryfun_meta2; +pub mod umove; pub mod utimi; pub mod vibcrafter; pub mod vibratissimo; @@ -246,6 +248,10 @@ pub fn get_default_protocol_map() -> HashMap HashMap &str { + "umove" + } + + fn create(&self) -> Box { + Box::new(super::UmoveIdentifier::default()) + } + } +} + +#[derive(Default)] +pub struct UmoveIdentifier {} + +#[async_trait] +impl ProtocolIdentifier for UmoveIdentifier { + async fn identify( + &mut self, + hardware: Arc, + _specifier: ProtocolCommunicationSpecifier, + ) -> Result<(UserDeviceIdentifier, Box), ButtplugDeviceError> { + let device_identifier = hardware.name()[2..4].to_string(); + Ok(( + UserDeviceIdentifier::new(hardware.address(), "umove", &Some(device_identifier)), + Box::new(UmoveInitializer::default()), + )) + } +} + +#[derive(Default)] +pub struct UmoveInitializer {} + +#[async_trait] +impl ProtocolInitializer for UmoveInitializer { + async fn initialize( + &mut self, + hardware: Arc, + _device_definition: &ServerDeviceDefinition, + ) -> Result, ButtplugDeviceError> { + let state = Arc::new(Umove::default()); + buttplug_core::spawn!( + "Umove update linear movement", + update_linear_movement(hardware.clone(), state.clone(),) + ); + Ok(state) + } +} + +#[derive(Default)] +pub struct Umove { + packet_id: AtomicU32, + vibrate: AtomicU16, + goal_position: AtomicU32, + current_position: AtomicU32, + duration: AtomicU32, +} + +async fn update_linear_movement(device: Arc, state: Arc) { + let mut last_goal_position = 0i32; + let mut current_move_amount = 0i32; + let mut current_position = 0i32; + loop { + // See if we've updated our goal position + let goal_position = state.goal_position.load(Ordering::Relaxed) as i32; + // If we have and it's not the same, recalculate based on current status. + if last_goal_position != goal_position { + last_goal_position = goal_position; + // We move every 100ms, so divide the movement into that many chunks. + // If we're moving so fast it'd be under our 100ms boundary, just move in 1 step. + let move_steps = (state.duration.load(Ordering::Relaxed) / 100).max(1); + let distance = goal_position - current_position; + current_move_amount = distance / move_steps as i32; + if current_move_amount == 0 { + current_move_amount = distance.signum(); + } + } + + // If we aren't going anywhere, just pause then restart + if current_position == last_goal_position { + async_manager::sleep(Duration::from_millis(100)).await; + continue; + } + + // Update our position, make sure we don't overshoot + current_position += current_move_amount; + if current_move_amount < 0 { + if current_position < last_goal_position { + current_position = last_goal_position; + } + } else if current_position > last_goal_position { + current_position = last_goal_position; + } + state + .current_position + .store(current_position as u32, Ordering::Relaxed); + + let hardware_cmd: HardwareWriteCmd = HardwareWriteCmd::new( + &[UMOVE_PROTOCOL_UUID], + Endpoint::Tx, + form_command(state.as_ref()), + false, + ); + if device.write_value(&hardware_cmd).await.is_err() { + return; + } + async_manager::sleep(Duration::from_millis(50)).await; + } +} + +fn form_command(state: &Umove) -> Vec { + let mut data = vec![0x5A, 0xA5, 0x55, 0x00]; + data.append(&mut state.vibrate.load(Ordering::Relaxed).to_le_bytes().to_vec()); + data.append(&mut 1u16.to_le_bytes().to_vec()); + data.append( + &mut state + .packet_id + .fetch_add(1u32, Ordering::Relaxed) + .to_le_bytes() + .to_vec(), + ); + data.append( + &mut state + .current_position + .load(Ordering::Relaxed) + .to_le_bytes() + .to_vec(), + ); + info!("Formed command: {:?}", data); + data +} + +impl ProtocolHandler for Umove { + fn keepalive_strategy(&self) -> ProtocolKeepaliveStrategy { + ProtocolKeepaliveStrategy::RepeatLastPacketStrategyWithTiming(Duration::from_millis(500)) + } + + fn handle_output_vibrate_cmd( + &self, + _feature_index: u32, + _feature_id: Uuid, + speed: u32, + ) -> Result, ButtplugDeviceError> { + self.vibrate.store(speed as u16, Ordering::Relaxed); + if self.current_position.load(Ordering::Relaxed) != self.goal_position.load(Ordering::Relaxed) { + return Ok(vec![]); + } + Ok(vec![ + HardwareWriteCmd::new( + &[UMOVE_PROTOCOL_UUID], + Endpoint::Tx, + form_command(self), + false, + ) + .into(), + ]) + } + + fn handle_hw_position_with_duration_cmd( + &self, + _feature_index: u32, + _feature_id: Uuid, + position: u32, + duration: u32, + ) -> Result, ButtplugDeviceError> { + self.goal_position.store(position, Ordering::Relaxed); + self.duration.store(duration, Ordering::Relaxed); + Ok(vec![]) + } + fn handle_output_position_cmd( + &self, + _feature_index: u32, + _feature_id: Uuid, + position: u32, + ) -> Result, ButtplugDeviceError> { + self.goal_position.store(position, Ordering::Relaxed); + self.current_position.store(position, Ordering::Relaxed); + self.duration.store(0, Ordering::Relaxed); + Ok(vec![ + HardwareWriteCmd::new( + &[UMOVE_PROTOCOL_UUID], + Endpoint::Tx, + form_command(self), + false, + ) + .into(), + ]) + } + + fn handle_output_temperature_cmd( + &self, + _feature_index: u32, + feature_id: Uuid, + level: i32, + ) -> Result, ButtplugDeviceError> { + Ok(vec![ + HardwareWriteCmd::new( + &[feature_id], + Endpoint::Tx, + vec![ + 0x5a, + 0xa5, + 0x55, + 0x06, + 0xff, + 0xff, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + level as u8, + 0xff, + ], + false, + ) + .into(), + ]) + } +} diff --git a/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json b/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json index 54d841f9a..555478412 100644 --- a/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json +++ b/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json @@ -1,7 +1,7 @@ { "version": { "major": 5, - "minor": 13 + "minor": 27 }, "protocols": { "activejoy": { @@ -6080,7 +6080,10 @@ "J-MutantX", "J-Marino", "J-Jason", - "J-MartinoIII" + "J-MartinoIII", + "J-Punisher", + "J-Prismcy", + "J-AresIII" ], "services": { "0000ffa0-0000-1000-8000-00805f9b34fb": { @@ -9561,10 +9564,10 @@ { "features": [ { - "id": "12f36e6d-e9ce-439c-b6f5-3f80a4f4b47d", + "id": "cbd851bb-a0de-43b6-89df-947d5872454d", "index": 0, "output": { - "oscillate": { + "vibrate": { "value": [ 0, 255 @@ -9573,10 +9576,10 @@ } }, { - "id": "94025679-badf-49bb-a247-1dab022d9204", + "id": "2e5385b3-82be-4047-b998-49ee07aefa5e", "index": 2, "output": { - "vibrate": { + "oscillate": { "value": [ 0, 255 @@ -10641,6 +10644,65 @@ "J-MartinoIII" ], "name": "JoyHub Martino III" + }, + { + "features": [ + { + "id": "4272e178-cfb0-4e1f-a6cc-1083d83ede14", + "index": 0, + "output": { + "oscillate": { + "value": [ + 0, + 255 + ] + } + } + }, + { + "id": "de639d48-47e2-440d-b2c7-3c46068fc13d", + "index": 1, + "output": { + "vibrate": { + "value": [ + 0, + 255 + ] + } + } + }, + { + "id": "95a9b5b2-fc5f-45e9-b307-bd2941fd6883", + "index": 2, + "output": { + "vibrate": { + "value": [ + 0, + 255 + ] + } + } + } + ], + "id": "e437baf4-9e60-431e-a30f-5870faf5c1ad", + "identifier": [ + "J-Punisher" + ], + "name": "JoyHub Punisher" + }, + { + "id": "fcf3aa9b-8e2f-4751-8f7d-b208a62ef6c9", + "identifier": [ + "J-Prismcy" + ], + "name": "JoyHub Prismcy" + }, + { + "id": "5f902050-ee3f-4503-abcb-d0794c27180c", + "identifier": [ + "J-AresIII" + ], + "name": "JoyHub Ares III" } ], "defaults": { @@ -10926,6 +10988,61 @@ "name": "Kiiroo Spot" } }, + "kiiroo-spot-v2": { + "communication": [ + { + "btle": { + "names": [ + "SPOT W2" + ], + "services": { + "00001400-0000-1000-8000-00805f9b34fb": { + "tx": "00001801-0000-1000-8000-00805f9b34fb" + }, + "0000180f-0000-1000-8000-00805f9b34fb": { + "rxblebattery": "00002a19-0000-1000-8000-00805f9b34fb" + } + } + } + } + ], + "defaults": { + "features": [ + { + "id": "296348ed-8bfa-45d2-a4f4-771a54580eb1", + "index": 0, + "output": { + "vibrate": { + "value": [ + 0, + 100 + ] + } + } + }, + { + "description": "battery Level", + "id": "adec0f91-dbb1-49d3-a135-8d1b7f8e76b1", + "index": 1, + "input": { + "battery": { + "command": [ + "Read" + ], + "value": [ + [ + 0, + 100 + ] + ] + } + } + } + ], + "id": "91d3c325-8bbd-4843-a61d-e7175d14fae2", + "name": "Kiiroo Spot 2" + } + }, "kiiroo-v1": { "communication": [ { @@ -11819,9 +11936,14 @@ "btle": { "names": [ "KEON WIFI", - "Keon Wifi" + "Keon Wifi", + "KEON2" ], "services": { + "00001400-0000-1000-8000-00805f9b34fb": { + "tx": "00001801-0000-1000-8000-00805f9b34fb", + "whitelist": "00002a19-0000-1000-8000-00805f9b34fb" + }, "00001900-0000-1000-8000-00805f9b34fb": { "rx": "00001903-0000-1000-8000-00805f9b34fb", "tx": "00001800-0000-1000-8000-00805f9b34fb" @@ -11874,6 +11996,49 @@ "Keon Wifi" ], "name": "Kiiroo Keon" + }, + { + "features": [ + { + "id": "b7bd2527-b0a5-465f-98d9-f6b55aa9645b", + "index": 0, + "output": { + "hw_position_with_duration": { + "duration": [ + 0, + 100000 + ], + "value": [ + 0, + 100 + ] + } + } + }, + { + "description": "Battery Level", + "id": "8ab0640d-ac9b-408b-878a-76e95082896b", + "index": 1, + "input": { + "battery": { + "command": [ + "Read" + ], + "value": [ + [ + 0, + 100 + ] + ] + } + } + } + ], + "id": "23940e92-ddd2-42b4-a589-744c0d14f04b", + "identifier": [ + "KEON2" + ], + "name": "Kiiroo Keon 2" } ], "defaults": { @@ -21969,6 +22134,7 @@ "Aogu SUV", "Aogu SCB", "Emma NEO", + "Emma Neo", "Phoenix NEO" ], "services": { @@ -21998,7 +22164,8 @@ { "id": "68d39a06-e350-47ef-8834-e3197178b00e", "identifier": [ - "Emma NEO" + "Emma NEO", + "Emma Neo" ], "name": "Svakom Emma Neo" } @@ -23177,6 +23344,151 @@ "name": "Twerking Butt" } }, + "umove": { + "communication": [ + { + "btle": { + "names": [ + "ALVxB*", + "ALMiB*", + "ALNxB*", + "UMVxB*", + "UMMiB*", + "UMNxB*" + ], + "services": { + "6e400001-b5a3-f393-e0a9-e50e24dcca9e": { + "rx": "6e400003-b5a3-f393-e0a9-e50e24dcca9e", + "tx": "6e400002-b5a3-f393-e0a9-e50e24dcca9e" + } + } + } + } + ], + "configurations": [ + { + "id": "65dba547-9ebd-4a7a-a6a1-b4b7f34bb7e8", + "identifier": [ + "Mi" + ], + "name": "Umove Mira" + }, + { + "features": [ + { + "id": "0d6dc2b6-87cf-44a1-ac79-8b3d0c50ad6f", + "index": 1, + "output": { + "hw_position_with_duration": { + "duration": [ + 0, + 10000 + ], + "value": [ + 0, + 732 + ] + }, + "position": { + "value": [ + 0, + 732 + ] + } + } + } + ], + "id": "ebfa5881-cab0-4218-a14f-592ef44fd2c8", + "identifier": [ + "Vx" + ], + "name": "Umove Vero" + }, + { + "features": [ + { + "id": "8f08d8a1-0f5e-4915-af56-e02d4553ae89", + "index": 1, + "output": { + "hw_position_with_duration": { + "duration": [ + 0, + 10000 + ], + "value": [ + 0, + 1232 + ] + }, + "position": { + "value": [ + 0, + 1232 + ] + } + } + } + ], + "id": "1694dace-5a53-4d56-9620-9251be4da5ce", + "identifier": [ + "Nx" + ], + "name": "Umove Nexo" + } + ], + "defaults": { + "features": [ + { + "id": "27d5e07a-5880-4595-8c12-2f231b4ef2d2", + "index": 0, + "output": { + "vibrate": { + "value": [ + 0, + 10000 + ] + } + } + }, + { + "id": "44cef1b2-dc95-4abf-a27b-a6d8a266d827", + "index": 1, + "output": { + "hw_position_with_duration": { + "duration": [ + 0, + 10000 + ], + "value": [ + 0, + 632 + ] + }, + "position": { + "value": [ + 0, + 632 + ] + } + } + }, + { + "id": "2d7f0be1-b41f-4cb9-aea6-585d2b0ee7ba", + "index": 2, + "output": { + "temperature": { + "value": [ + 37, + 42 + ] + } + } + } + ], + "id": "45648a20-cb18-43a0-9d6c-8bc4ed63ef63", + "name": "Umove Device" + } + }, "utimi": { "communication": [ { diff --git a/crates/buttplug_server_device_config/device-config/protocols/joyhub.yml b/crates/buttplug_server_device_config/device-config/protocols/joyhub.yml index 114ce0f7a..2f943dfe3 100644 --- a/crates/buttplug_server_device_config/device-config/protocols/joyhub.yml +++ b/crates/buttplug_server_device_config/device-config/protocols/joyhub.yml @@ -2028,16 +2028,16 @@ configurations: - J-Perseus name: JoyHub Perseus features: - - id: 12f36e6d-e9ce-439c-b6f5-3f80a4f4b47d + - id: cbd851bb-a0de-43b6-89df-947d5872454d output: - oscillate: + vibrate: value: - 0 - 255 index: 0 - - id: 94025679-badf-49bb-a247-1dab022d9204 + - id: 2e5385b3-82be-4047-b998-49ee07aefa5e output: - vibrate: + oscillate: value: - 0 - 255 @@ -2651,6 +2651,40 @@ configurations: - 7 index: 4 id: 67da4fc4-66d4-49ea-bd40-dbca9f0e5fed +- identifier: + - J-Punisher + name: JoyHub Punisher + features: + - id: 4272e178-cfb0-4e1f-a6cc-1083d83ede14 + output: + oscillate: + value: + - 0 + - 255 + index: 0 + - id: de639d48-47e2-440d-b2c7-3c46068fc13d + output: + vibrate: + value: + - 0 + - 255 + index: 1 + - id: 95a9b5b2-fc5f-45e9-b307-bd2941fd6883 + output: + vibrate: + value: + - 0 + - 255 + index: 2 + id: e437baf4-9e60-431e-a30f-5870faf5c1ad +- identifier: + - J-Prismcy + name: JoyHub Prismcy + id: fcf3aa9b-8e2f-4751-8f7d-b208a62ef6c9 +- identifier: + - J-AresIII + name: JoyHub Ares III + id: 5f902050-ee3f-4503-abcb-d0794c27180c communication: - btle: names: @@ -2806,6 +2840,9 @@ communication: - J-Marino - J-Jason - J-MartinoIII + - J-Punisher + - J-Prismcy + - J-AresIII services: 0000ffa0-0000-1000-8000-00805f9b34fb: tx: 0000ffa1-0000-1000-8000-00805f9b34fb diff --git a/crates/buttplug_server_device_config/device-config/protocols/kiiroo-spot-v2.yml b/crates/buttplug_server_device_config/device-config/protocols/kiiroo-spot-v2.yml new file mode 100644 index 000000000..695ca10b0 --- /dev/null +++ b/crates/buttplug_server_device_config/device-config/protocols/kiiroo-spot-v2.yml @@ -0,0 +1,31 @@ +--- +defaults: + name: Kiiroo Spot 2 + features: + - id: 296348ed-8bfa-45d2-a4f4-771a54580eb1 + output: + vibrate: + value: + - 0 + - 100 + index: 0 + - description: battery Level + id: adec0f91-dbb1-49d3-a135-8d1b7f8e76b1 + input: + battery: + value: + - - 0 + - 100 + command: + - Read + index: 1 + id: 91d3c325-8bbd-4843-a61d-e7175d14fae2 +communication: +- btle: + names: + - SPOT W2 + services: + 00001400-0000-1000-8000-00805f9b34fb: + tx: 00001801-0000-1000-8000-00805f9b34fb + '0000180f-0000-1000-8000-00805f9b34fb': + rxblebattery: 00002a19-0000-1000-8000-00805f9b34fb diff --git a/crates/buttplug_server_device_config/device-config/protocols/kiiroo-v3.yml b/crates/buttplug_server_device_config/device-config/protocols/kiiroo-v3.yml index ae772750c..529ac9de2 100644 --- a/crates/buttplug_server_device_config/device-config/protocols/kiiroo-v3.yml +++ b/crates/buttplug_server_device_config/device-config/protocols/kiiroo-v3.yml @@ -4,38 +4,67 @@ defaults: features: [] id: b3b6151e-79b8-4aac-a777-0de6b9f2d893 configurations: -- identifier: - - KEON WIFI - - Keon Wifi - name: Kiiroo Keon - features: - - id: f4ee99e7-1a14-4315-9870-3990bca7ff94 - output: - hw_position_with_duration: - value: - - 0 - - 99 - duration: - - 0 - - 100000 - index: 0 - - description: Battery Level - id: 90319514-ff68-40ae-805d-54ce392a60bd - input: - battery: - value: - - - 0 - - 100 - command: - - Read - index: 1 - id: 62ba81c4-0ada-41be-b49d-d53426cdc277 + - identifier: + - KEON WIFI + - Keon Wifi + name: Kiiroo Keon + features: + - id: f4ee99e7-1a14-4315-9870-3990bca7ff94 + output: + hw_position_with_duration: + value: + - 0 + - 99 + duration: + - 0 + - 100000 + index: 0 + - description: Battery Level + id: 90319514-ff68-40ae-805d-54ce392a60bd + input: + battery: + value: + - - 0 + - 100 + command: + - Read + index: 1 + id: 62ba81c4-0ada-41be-b49d-d53426cdc277 + - identifier: + - KEON2 + name: Kiiroo Keon 2 + features: + - id: b7bd2527-b0a5-465f-98d9-f6b55aa9645b + output: + hw_position_with_duration: + value: + - 0 + - 100 + duration: + - 0 + - 100000 + index: 0 + - description: Battery Level + id: 8ab0640d-ac9b-408b-878a-76e95082896b + input: + battery: + value: + - - 0 + - 100 + command: + - Read + index: 1 + id: 23940e92-ddd2-42b4-a589-744c0d14f04b communication: - btle: names: - KEON WIFI - Keon Wifi + - KEON2 services: '00001900-0000-1000-8000-00805f9b34fb': tx: '00001800-0000-1000-8000-00805f9b34fb' rx: '00001903-0000-1000-8000-00805f9b34fb' + '00001400-0000-1000-8000-00805f9b34fb': + tx: '00001801-0000-1000-8000-00805f9b34fb' + whitelist: '00002a19-0000-1000-8000-00805f9b34fb' diff --git a/crates/buttplug_server_device_config/device-config/protocols/svakom-v1.yml b/crates/buttplug_server_device_config/device-config/protocols/svakom-v1.yml index bf8affe2b..3d6c9d42f 100644 --- a/crates/buttplug_server_device_config/device-config/protocols/svakom-v1.yml +++ b/crates/buttplug_server_device_config/device-config/protocols/svakom-v1.yml @@ -21,6 +21,7 @@ configurations: id: c9556aba-5bda-4f23-a690-623c4b9ee04b - identifier: - Emma NEO + - Emma Neo name: Svakom Emma Neo id: 68d39a06-e350-47ef-8834-e3197178b00e communication: @@ -29,6 +30,7 @@ communication: - Aogu SUV - Aogu SCB - Emma NEO + - Emma Neo - Phoenix NEO services: 0000ffe0-0000-1000-8000-00805f9b34fb: diff --git a/crates/buttplug_server_device_config/device-config/protocols/umove.yml b/crates/buttplug_server_device_config/device-config/protocols/umove.yml new file mode 100644 index 000000000..299dbed17 --- /dev/null +++ b/crates/buttplug_server_device_config/device-config/protocols/umove.yml @@ -0,0 +1,89 @@ +--- +defaults: + name: Umove Device + features: + - id: 27d5e07a-5880-4595-8c12-2f231b4ef2d2 + output: + vibrate: + value: + - 0 + - 10000 + index: 0 + - id: 44cef1b2-dc95-4abf-a27b-a6d8a266d827 + output: + hw_position_with_duration: + value: + - 0 + - 632 + duration: + - 0 + - 10000 + position: + value: + - 0 + - 632 + index: 1 + - id: 2d7f0be1-b41f-4cb9-aea6-585d2b0ee7ba + output: + temperature: + value: + - 37 + - 42 + index: 2 + id: 45648a20-cb18-43a0-9d6c-8bc4ed63ef63 +configurations: + - identifier: + - Mi + name: Umove Mira + id: 65dba547-9ebd-4a7a-a6a1-b4b7f34bb7e8 + - identifier: + - Vx + name: Umove Vero + features: + - id: 0d6dc2b6-87cf-44a1-ac79-8b3d0c50ad6f + output: + hw_position_with_duration: + value: + - 0 + - 732 + duration: + - 0 + - 10000 + position: + value: + - 0 + - 732 + index: 1 + id: ebfa5881-cab0-4218-a14f-592ef44fd2c8 + - identifier: + - Nx + name: Umove Nexo + features: + - id: 8f08d8a1-0f5e-4915-af56-e02d4553ae89 + output: + hw_position_with_duration: + value: + - 0 + - 1232 + duration: + - 0 + - 10000 + position: + value: + - 0 + - 1232 + index: 1 + id: 1694dace-5a53-4d56-9620-9251be4da5ce +communication: +- btle: + names: + - ALVxB* + - ALMiB* + - ALNxB* + - UMVxB* + - UMMiB* + - UMNxB* + services: + 6e400001-b5a3-f393-e0a9-e50e24dcca9e: + tx: 6e400002-b5a3-f393-e0a9-e50e24dcca9e + rx: 6e400003-b5a3-f393-e0a9-e50e24dcca9e diff --git a/crates/buttplug_server_device_config/device-config/version.yaml b/crates/buttplug_server_device_config/device-config/version.yaml index c69f148aa..680dc09ac 100644 --- a/crates/buttplug_server_device_config/device-config/version.yaml +++ b/crates/buttplug_server_device_config/device-config/version.yaml @@ -1,3 +1,3 @@ version: major: 5 - minor: 13 + minor: 27