BLE-protocol

Bedien uw OSSM draadloos met behulp van Bluetooth Low Energy (BLE) vanaf elk compatibel apparaat of elke applicatie

De OSSM maakt gebruik van Bluetooth Low Energy (BLE) voor draadloze bediening en monitoring. U kunt clienttoepassingen bouwen die verbinding maken met de OSSM om opdrachten te verzenden en realtime statusupdates te ontvangen.

BLE biedt draadloze bediening met lage latentie, automatische herverbinding en statussynchronisatie.

Voordat u begint

Om verbinding te maken met uw OSSM via BLE, zorg ervoor dat:

  • Uw apparaat ondersteunt Bluetooth Low Energy (BLE 4.0+)
  • De OSSM is ingeschakeld en niet verbonden met een andere BLE-client
  • U bevindt zich binnen ongeveer 10 meter van het apparaat

Service-architectuur

De OSSM implementeert een aangepaste BLE-service met meerdere kenmerken, georganiseerd in functionele groepen.

Primaire service-UUID

522b443a-4f53-534d-0001-420badbabe69

Kenmerken zijn georganiseerd door naamruimtebereiken voor eenvoudige uitbreiding en ontdekking.

Referentie van de kenmerken

Opdrachtkenmerken (schrijfbaar)

Gebruik deze kenmerken om opdrachten te verzenden en de OSSM te configureren.

Primair commandokenmerk

EigenschapWaarde
UUID522b443a-4f53-534d-1000-420badbabe69
EigenschappenREAD, WRITE
DoelStuur opdrachten om het OSSM-gedrag te besturen

Opdrachtformaat

set:<parameter>:<value>
go:<state>

Beschikbare opdrachten

CommandoParameterWaardebereikBeschrijving
set:speed:<value>speed0-100Stel het percentage slagsnelheid in
set:stroke:<value>stroke0-100Stel het percentage van de slaglengte in
set:depth:<value>depth0-100Stel het penetratiedieptepercentage in
set:sensation:<value>sensation0-100Stel het percentage van de sensatie-intensiteit in
set:pattern:<value>pattern0-6Stel het slagpatroon in (zie patronen)
go:simplePenetration--Schakel via het menu over naar de eenvoudige penetratiemodus
go:strokeEngine--Schakel vanuit het menu naar de Stroke Engine-modus
go:streaming--Schakel vanuit het menu naar de streamingmodus (experimenteel).
go:menu--Keer vanuit elke modus terug naar het hoofdmenu
stream:<pos>:<time>pos, timepos: 0-100, time: msEen positiecommando verzenden in streamingmodus (experimenteel)

Reactieformaat

AntwoordBetekenis
ok:<original_command>Opdracht succesvol uitgevoerd
fail:<original_command>Opdracht mislukt (controleer formaat of huidige status)

Wacht altijd op het antwoord voordat u een nieuw commando verzendt. Commando's worden opeenvolgend verwerkt.

Configuratiekenmerk van de snelheidsknop

EigenschapWaarde
UUID522b443a-4f53-534d-1010-420badbabe69
EigenschappenREAD, WRITE
DoelConfigureer of de fysieke snelheidsknop BLE-snelheidsopdrachten beperkt

Configuratiewaarden

WaardeBeschrijving
true, 1, tSnelheidsknop fungeert als bovengrens (standaard)
false, 0, fSnelheidsknop en BLE-snelheid zijn onafhankelijk

Indien ingesteld op true, worden BLE-snelheidsopdrachten (0-100) behandeld als een percentage van de huidige fysieke knoppositie.

Voorbeeld: Knop op 50%, BLE-commando set:speed:80 → Effectieve snelheid = 40%

Deze modus biedt een hardwareveiligheidslimiet die gebruikers fysiek kunnen bedienen.

Reactieformaat

AntwoordBetekenis
true of falseHuidige configuratiewaarde
error:invalid_valueOngeldige invoer opgegeven

Configuratiekenmerk voor latentiecompensatie

EigenschapWaarde
UUID522b443a-4f53-534d-1030-420badbabe69
EigenschappenREAD, WRITE
DoelConfigureer of de OSSM de latentie probeert te compenseren

Configuratiewaarden

WaardeBeschrijving
true, 1, tLatentiecompensatie is actief
false, 0, fLatentiecompensatie is inactief (standaard)

Wanneer ingesteld op true, verwacht de OSSM de exacte opdrachten en tijden van het funscript te ontvangen en dat de opdrachten worden verzonden met dezelfde vertraging tussen opdrachten als de tijdswaarde. Door de tijd tussen ontvangen opdrachten en de tijdvariabele te berekenen, kan de OSSM de door BLE geïntroduceerde latentie bepalen en hiervoor corrigeren met kleine veranderingen in de bewegingssnelheid. Als de tijd tussen opdrachten niet overeenkomt met de intime-variabele, mag deze optie niet worden ingeschakeld. De bufferinstelling wordt gebruikt om kunstmatig vertraging toe te voegen aan alle bewegingen. Zo krijgt de OSSM tijd om de volgende opdracht te ontvangen voordat de vorige is voltooid. Hierdoor kunnen vertragingen door late opdrachten worden verwijderd en kunnen bewegingen worden afgevlakt door bewegingen in dezelfde richting te combineren. Funscript-spelers moeten deze bufferwaarde toevoegen aan hun afspeeloffset en een extra instelling toevoegen om de afspeeloffset nauwkeurig af te stellen, rekening houdend met de transmissietijd en eventuele vertragingen die inherent zijn aan het funscript zelf.

Reactieformaat

AntwoordBetekenis
true of falseHuidige configuratiewaarde
error:invalid_valueOngeldige invoer opgegeven

Configuratiekenmerk voor WiFi

EigenschapWaarde
UUID522b443a-4f53-534d-1020-420badbabe69
EigenschappenREAD, WRITE
DoelConfigureer WiFi-inloggegevens en controleer de verbindingsstatus

Schrijfformaat

set:wifi:<ssid>|<password>

Het pipe-teken (|) wordt gebruikt als scheidingsteken tussen SSID en wachtwoord. Hierdoor kunnen zowel de SSID als het wachtwoord dubbele punten bevatten.

Leesformaat (JSON)

{
  "connected": true,
  "ssid": "NetworkName",
  "ip": "192.168.1.100",
  "rssi": -45
}

Als er geen verbinding is, bevat het veld ssid de laatst opgeslagen SSID (indien aanwezig), ip is leeg en rssi is 0.

Reactieformaat

AntwoordBetekenis
ok:wifi:connectedSuccesvol verbonden
ok:wifi:savedInloggegevens opgeslagen, poging tot verbinding
fail:wifi:invalid_formatOpdrachtformaat onjuist (ontbrekend pijpscheidingsteken)
fail:wifi:invalid_ssidSSID-lengte ongeldig (moet 1-32 tekens bevatten)
fail:wifi:invalid_passwordWachtwoordlengte ongeldig (moet 8-63 tekens bevatten)
fail:wifi:connection_failedKan geen verbinding maken met het netwerk
fail:wifi:save_failedKan de inloggegevens niet opslaan in NVS

WiFi-inloggegevens worden bewaard in niet-vluchtige opslag (NVS) en blijven behouden wanneer het apparaat opnieuw wordt opgestart. Het apparaat probeert bij het opstarten automatisch verbinding te maken met behulp van de opgeslagen inloggegevens.

WiFi-inloggegevens worden in platte tekst via BLE verzonden. Zorg ervoor dat u de verbinding vertrouwt en dat u zich in een veilige omgeving bevindt wanneer u de WiFi-instellingen configureert.

Voorbeeldgebruik

// Configure WiFi
const wifiCommand = "set:wifi:MyNetwork|MyPassword123";
await commandChar.writeValue(new TextEncoder().encode(wifiCommand));

// Read the response
const response = await commandChar.readValue();
console.log(new TextDecoder().decode(response)); // "ok:wifi:connected"

// Check WiFi status
const wifiConfigChar = await service.getCharacteristic(
  "522b443a-4f53-534d-1020-420badbabe69"
);
const statusValue = await wifiConfigChar.readValue();
const status = JSON.parse(new TextDecoder().decode(statusValue));
console.log(status);
// { "connected": true, "ssid": "MyNetwork", "ip": "192.168.1.100", "rssi": -45 }

Statuskenmerken (alleen-lezen)

Abonneer u op deze kenmerken om de huidige status van de OSSM te controleren.

Kenmerk van de huidige toestand

EigenschapWaarde
UUID522b443a-4f53-534d-2000-420badbabe69
EigenschappenREAD, NOTIFY
DoelBewaak de huidige OSSM-status en -instellingen

JSON-indeling van de toestand

{
  "state": "<state_name>",
  "speed": 0-100,
  "stroke": 0-100,
  "sensation": 0-100,
  "depth": 0-100,
  "pattern": 0-6
}

Meldingsgedrag

  • Statuswijzigingen leiden tot onmiddellijke meldingen
  • Periodieke meldingen elke 1000 ms als er geen statuswijziging plaatsvindt
  • Meldingen stoppen als er geen clients zijn verbonden

Kenmerken van patrooninformatie

Kenmerk van de patroonlijst

EigenschapWaarde
UUID522b443a-4f53-534d-3000-420badbabe69
EigenschappenREAD
DoelBeschikbare slagpatronen ophalen

Reactieformaat

[
  { "name": "Simple Stroke", "idx": 0 },
  { "name": "Teasing Pounding", "idx": 1 },
  { "name": "Robo Stroke", "idx": 2 },
  { "name": "Half'n'Half", "idx": 3 },
  { "name": "Deeper", "idx": 4 },
  { "name": "Stop'n'Go", "idx": 5 },
  { "name": "Insist", "idx": 6 }
]

Kenmerk voor patroonbeschrijvingen

EigenschapWaarde
UUID522b443a-4f53-534d-3010-420badbabe69
EigenschappenREAD, WRITE
DoelOntvang beschrijvingen voor individuele slagpatronen

Een patroonbeschrijving ophalen:

Schrijf de patroonindex

Schrijf het indexnummer (0-6) naar het kenmerk.

Lees de beschrijving

Lees het kenmerk om de patroonbeschrijvingsreeks te ontvangen.

Patroonbeschrijvingen

PatroonIndexBeschrijving
Simple Stroke0Versnelling, uitrollen en vertraging gelijkmatig verdeeld; geen sensatie
Teasing Pounding1Snelheid varieert met sensatie; compenseert snellere slagen
Robo Stroke2Sensatie varieert de versnelling; van robotachtig tot geleidelijk
Half'n'Half3Slagen op volledige en halve diepte wisselen elkaar af; sensatie beïnvloedt de snelheid
Deeper4De slagdiepte neemt per cyclus toe; sensatie bepaalt het aantal
Stop'n'Go5Pauzes tussen slagen; sensatie past de lengte aan
Insist6Wijzigt de lengte, handhaaft de snelheid; sensatie beïnvloedt de richting

Streamingopdrachten (experimenteel)

Positiestreaming is experimenteel en wordt niet aanbevolen voor algemeen gebruik. Het protocol en het gedrag kunnen veranderen in toekomstige firmware-updates.

In de streamingmodus (go:streaming) accepteert de OSSM real-time positieopdrachten die gesynchroniseerd afspelen met externe inhoud zoals funscripts mogelijk maken.

Commando voor streampositie

EigenschapWaarde
Formaatstream:<position>:<time>
Positie0-100 (percentage van de slag)
TijdMilliseconden om de doelpositie te bereiken

Voorbeeldopdrachten

stream:0:200      # Move to 0% (retracted) in 200ms
stream:100:150    # Move to 100% (extended) in 150ms
stream:50:300     # Move to 50% (mid-stroke) in 300ms

Hoe het werkt

  1. Ga naar de streamingmodus met go:streaming
  2. De OSSM homet naar positie 0 (volledig ingetrokken)
  3. Verzend stream:<pos>:<time>-opdrachten om beweging te besturen
  4. De firmware berekent de vereiste snelheid om de doelpositie binnen de opgegeven tijd te bereiken
  5. De beweging gebruikt maximale versnelling voor een responsief gevoel

Positie 0 staat voor volledig ingetrokken (thuis), en positie 100 staat voor volledig uitgeschoven. De tijdparameter geeft aan hoe lang de beweging moet duren, waardoor de OSSM de juiste snelheid kan berekenen voor een soepele weergave.

Vereisten

  • Firmwareversie 3.0 of hoger
  • OSSM moet in streamingmodus staan ​​(status: streaming of streaming.idle)
  • Commando's verzonden via het primaire commandokenmerk

Voor het afspelen van funscripts, zie de Funscript-speler-tool die automatisch de timing en het genereren van opdrachten afhandelt.

GPIO-kenmerken

GPIO-besturingskenmerk

EigenschapWaarde
UUID522b443a-4f53-534d-4000-420badbabe69
EigenschappenREAD, WRITE
DoelBeheer GPIO-uitgangspinnen voor accessoires en integraties

Schrijf opdrachten in het formaat <pin>:<state>, waarbij pin 1-4 is en de status high/low of 1/0 is.

Pin-toewijzing:

Logische pinESP32 GPIO
1GPIO 2
2GPIO 15
3GPIO 22
4GPIO 33

Reactieformaat:

AntwoordBetekenis
ok:<pin>:<state>Pin succesvol ingesteld
error:invalid_formatCommandoformaat niet herkend
error:pin_out_of_rangePinnummer niet 1-4

Zie GPIO-besturing voor gedetailleerde GPIO-documentatie, inclusief voorbeelden van hardware-integratie.

Fleshy Thrust Sync-emulatie (alleen testen)

Deze functie is alleen bedoeld voor ontwikkelingstests en wordt niet aanbevolen voor gebruik. Deze vereist een speciale firmware-build en kan in toekomstige versies worden verwijderd.

De OSSM-firmware kan optioneel het Fleshy Thrust Sync (FTS) BLE-protocol emuleren voor compatibiliteitstests met applicaties zoals faptap.net. Deze functie is standaard uitgeschakeld en vereist het compileren van firmware met de vlag PRETEND_TO_BE_FLESHY_THRUST_SYNC.

FTS-service

EigenschapWaarde
Service-UUID0000ffe0-0000-1000-8000-00805f9b34fb
Kenmerk-UUID0000ffe1-0000-1000-8000-00805f9b34fb
EigenschappenREAD, WRITE, NOTIFY, INDICATE

Binair protocolformaat

FTS gebruikt een compact binair formaat in plaats van tekstopdrachten:

ByteBeschrijvingBereik
0Positie0-180 (uint8)
1Tijd hoge byteMSB van tijd in ms
2Tijd lage byteLSB van tijd in ms

Positietoewijzing: 0 = volledig ingetrokken, 180 = volledig uitgeschoven

Tijdnotatie: 16-bit geheel getal zonder teken in big-endian (volgorde van netwerkbytes)

Voorbeeld

Om binnen 250 ms naar positie 90 (50% uitgeschoven) te gaan:

Byte 0: 0x5A (90 decimal - position)
Byte 1: 0x00 (250 >> 8 = 0)
Byte 2: 0xFA (250 & 0xFF = 250)

De FTS-emulatie gebruikt hetzelfde onderliggende streamingmechanisme als de native stream:pos:time-opdracht. De OSSM moet zich in de streamingmodus bevinden om opdrachten van kracht te laten worden.

Waarom niet aanbevolen

  • Het FTS-protocol is een specificatie van derden die niet wordt beheerd door het OSSM-project
  • Protocolwijzigingen in FTS-compatibele applicaties kunnen de compatibiliteit verbreken
  • Het native OSSM-streamingprotocol (stream:pos:time) heeft de voorkeur voor nieuwe integraties
  • Deze functie is voornamelijk bedoeld voor het testen van de compatibiliteit met bestaande FTS-ecosystemen

Apparaatinformatiedienst

De OSSM implementeert de standaard BLE-apparaatinformatieservice voor identificatie.

KenmerkUUIDWaarde
Dienst180AApparaatinformatieservice
Naam van de fabrikant2A29"Research And Desire"
Systeem-ID2A2388:1A:14:FF:FE:34:29:63

UUID-naamruimtestructuur

De OSSM gebruikt een gestructureerde UUID-naamruimte voor georganiseerde uitbreiding.

Service-UUID

0x0001 = Service UUID

Naamruimtebereiken

BereikHex-bereikBeschrijving
0x00x0000–0x0FFFGereserveerd voor systeemberichten
0x10x1000–0x1FFFCommando's en configuratie
0x20x2000–0x2FFFStatusinformatie
0x30x3000–0x3FFFPatrooninformatie
0x40x4000–0x4FFFGPIO-pininstelling
0x5–0xD0x5000–0xDFFFGereserveerd voor toekomstig gebruik
0xE0xE000–0xEFFFGereserveerd voor statistieken
0xF0xF000–0xFFFFExperimenteel / sandbox (vluchtig)

Huidige kenmerktoewijzingen

522b443a-4f53-534d-1000-420badbabe69  # Primary command
522b443a-4f53-534d-1010-420badbabe69  # Speed knob configuration
522b443a-4f53-534d-1020-420badbabe69  # WiFi configuration

Verbindingsbeheer

Advertising

InstellingWaarde
ApparaatnaamOSSM
Service-UUID'sPrimaire service + Apparaatinformatieservice
Advertising-interval20-40 ms (geoptimaliseerd voor betrouwbaarheid)
Automatische herstartAdvertising wordt hervat wanneer alle clients de verbinding verbreken

Beveiliging

InstellingWaarde
Koppelen"Just Works" (geen authenticatie vereist)
EncryptieBLE Secure Connections ingeschakeld
BondingUitgeschakeld (geen permanente koppeling)

De OSSM maakt gebruik van "Just Works"-koppeling voor gebruiksgemak. Iedereen binnen het BLE-bereik kan verbinding maken wanneer het apparaat Advertising uitvoert.

Veiligheid bij verbreking

Wanneer een BLE-verbinding onverwacht wordt verbroken, verlaagt de OSSM automatisch de snelheid om ongecontroleerde werking te voorkomen.

Uitloopgedrag:

  1. Verbindingsverlies gedetecteerd
  2. 1 seconde vertraging — zorgt voor korte signaaluitval zonder triggering
  3. 2 seconden afbouw — de snelheid neemt af van de huidige waarde naar nul met een ease-in-out-sinecurve
  4. Het apparaat blijft op nulsnelheid totdat het opnieuw wordt aangesloten of handmatig wordt gestopt

De ease-in-out-sinecurve zorgt voor een soepele vertraging die natuurlijk aanvoelt en de mechanische belasting vermindert. Als de snelheid bij het ontkoppelen al nul was, vindt er geen afbouw plaats.

Overwegingen voor clients:

  • Implementeer verbindingsmonitoring om verbroken verbindingen snel te detecteren
  • Overweeg automatische herverbindingslogica
  • Lokale bedieningselementen (potentiometer, encoder) blijven actief tijdens en na het ontkoppelen
  • Gebruikers kunnen handmatig stoppen via de snelheidsknop of lang indrukken voor een noodstop

Implementatiehandleiding voor clients

Verbindingsproces

Volg deze stappen om een ​​verbinding tot stand te brengen en uw OSSM te bedienen:

Scan naar het apparaat

Scan naar BLE-apparaten met de naam "OSSM".

Apparaat verschijnt in scanresultaten.

Maak verbinding met het apparaat

Breng een GATT-verbinding met de OSSM tot stand.

Ontdek diensten

Ontdek alle diensten en kenmerken op het toestel.

Primaire service UUID 522b443a-4f53-534d-0001-420badbabe69 is gevonden.

Abonneer u op statusmeldingen

Schakel meldingen over het statuskenmerk in om realtime updates te ontvangen.

Lees de beginstatus

Lees de huidige toestand en de patroonlijst om uw toepassing te initialiseren.

Stuur opdrachten

Begin met het verzenden van opdrachten om de OSSM te besturen.

Beste praktijken

Commandoafhandeling

  • Valideer het opdrachtformaat voordat u het verzendt
  • Behandel zowel ok:- als fail:-reacties
  • Implementeer logica voor opnieuw proberen voor kritieke opdrachten
  • Controleer statuswijzigingen om de uitvoering van opdrachten te bevestigen

Statusbewaking

  • Abonneer u op statuskenmerkmeldingen
  • Parseer JSON-statusupdates op betrouwbare wijze
  • Ga op de juiste manier om met statusovergangen
  • Implementeer time-outafhandeling voor ontbrekende updates

Voorbeeldcode

// Connect to OSSM
const device = await navigator.bluetooth.requestDevice({
  filters: [{ name: "OSSM" }],
  optionalServices: ["522b443a-4f53-534d-0001-420badbabe69"],
});

const server = await device.gatt.connect();
const service = await server.getPrimaryService(
  "522b443a-4f53-534d-0001-420badbabe69"
);

// Get characteristics
const commandChar = await service.getCharacteristic(
  "522b443a-4f53-534d-1000-420badbabe69"
);
const stateChar = await service.getCharacteristic(
  "522b443a-4f53-534d-2000-420badbabe69"
);
const speedKnobConfigChar = await service.getCharacteristic(
  "522b443a-4f53-534d-1010-420badbabe69"
);
const wifiConfigChar = await service.getCharacteristic(
  "522b443a-4f53-534d-1020-420badbabe69"
);
const patternsChar = await service.getCharacteristic(
  "522b443a-4f53-534d-3000-420badbabe69"
);

// Subscribe to state updates
await stateChar.startNotifications();
stateChar.addEventListener("characteristicvaluechanged", (event) => {
  const state = JSON.parse(new TextDecoder().decode(event.target.value));
  console.log("State update:", state);
});

// Configure speed knob behavior (true = knob as limit, false = independent)
await speedKnobConfigChar.writeValue(new TextEncoder().encode("true"));

// Configure WiFi
await wifiConfigChar.writeValue(new TextEncoder().encode("set:wifi:MyNetwork|MyPassword123"));

// Check WiFi status
const wifiStatus = await wifiConfigChar.readValue();
console.log("WiFi:", JSON.parse(new TextDecoder().decode(wifiStatus)));

// Send a command
const command = "set:speed:75";
await commandChar.writeValue(new TextEncoder().encode(command));

// Read available patterns
const patterns = await patternsChar.readValue();
const patternList = JSON.parse(new TextDecoder().decode(patterns));
console.log("Available patterns:", patternList);
import asyncio
import json
from bleak import BleakClient

SERVICE_UUID = "522b443a-4f53-534d-0001-420badbabe69"
COMMAND_UUID = "522b443a-4f53-534d-1000-420badbabe69"
STATE_UUID = "522b443a-4f53-534d-2000-420badbabe69"
SPEED_KNOB_UUID = "522b443a-4f53-534d-1010-420badbabe69"
WIFI_CONFIG_UUID = "522b443a-4f53-534d-1020-420badbabe69"

def state_callback(sender, data):
    """Handle state update notifications."""
    state = json.loads(data.decode())
    print(f"State update: {state}")

async def connect_to_ossm():
    async with BleakClient("OSSM") as client:
        # Subscribe to state updates
        await client.start_notify(STATE_UUID, state_callback)

        # Configure speed knob behavior
        await client.write_gatt_char(
            SPEED_KNOB_UUID,
            "true".encode()  # Knob acts as upper limit
        )

        # Configure WiFi
        await client.write_gatt_char(
            WIFI_CONFIG_UUID,
            "set:wifi:MyNetwork|MyPassword123".encode()
        )

        # Check WiFi status
        wifi_status = await client.read_gatt_char(WIFI_CONFIG_UUID)
        print(f"WiFi status: {json.loads(wifi_status.decode())}")

        # Send a command
        command = "set:speed:75"
        await client.write_gatt_char(COMMAND_UUID, command.encode())

        # Keep connection alive to receive notifications
        await asyncio.sleep(10)

asyncio.run(connect_to_ossm())

Problemen oplossen

Foutopsporingsinformatie

Schakel ESP32-logboekregistratie op DEBUG-niveau in voor gedetailleerde protocolinformatie. Bewaak de BLE-verbindingsstatus, MTU-wijzigingen en toestandsmachine-overgangen.

Op deze pagina