LLMBTPLG
January 27, 2026 · View on GitHub
A web interface for controlling Intiface Central devices using LM Studio. Experience AI-controlled haptic feedback through natural language interaction with local LLMs.
Features
Core Functionality
- Natural Language Control: AI embeds vibration commands directly in conversation
- Real-Time Visualization: Live vibration graph with smooth 60 FPS rendering
- Emotion System: Color-coded AI responses with 14+ customizable emotions
- Macro System: Create, save, and reuse complex vibration patterns
- Autonomous Mode: Hands-free pattern generation with configurable intervals
- Manual Testing: Direct control sliders for immediate device testing
Safety and Privacy
- Local LLM: All processing happens on your machine (LM Studio)
- Emergency Stop: Instant halt button with queue clearing
- Queue Visibility: See pending commands before execution
- Intensity Caps: Built-in safety limits to prevent device damage
Technical Highlights
- Streaming Chat: Real-time token-by-token AI responses
- Command Parsing: Regex-based extraction of
stroke()andwait()commands - Multi-Device Support: Control multiple toys simultaneously
- WebSocket Architecture: <100ms latency from AI output to device
- Responsive UI: Clean 2-column layout, works on mobile
Prerequisites
Required Software
-
LM Studio (Free)
- Download and install LM Studio
- Load your preferred model
- Start the Local Server (default port
1234) - ✅ Verify server is running at
http://localhost:1234
-
Intiface Central (Free)
- Download and install Intiface Central
- Start the server (default port
12345) - Connect your Bluetooth/USB devices
- ✅ Ensure devices show as connected
-
Python 3.10+
- Download from python.org
- ✅ Verify with
python --version
Installation
Quick Start
# Clone the repository
git clone https://github.com/cyongjin37/LLMBTPLG.git
cd LLMBTPLG
# Install dependencies
pip install -r requirements.txt
# Start the server
python server.py
First Run
- Open your browser to
http://127.0.0.1:8000 - Check Connection Status in the right panel:
- ✅ Intiface Central should show "Active (X Devices)"
- ✅ LM Studio should show "Active"
- Click Test Vibration to verify device control
- Start chatting with the AI!
Usage Guide
Basic Chat
Simply type a message and the AI will respond. The AI can embed vibration commands naturally:
You: "Can you tease me a little?"
AI: "Of course... let me start gently stroke(1000, 0.3)
How does that feel?"
Command Syntax
The AI uses these commands (you don't need to type them):
-
stroke(duration, intensity)- Vibrate for specified timeduration: milliseconds (e.g., 1000 = 1 second)intensity: 0.0 to 1.0 (e.g., 0.5 = 50% power)
-
wait(duration)- Pause for specified timeduration: milliseconds
-
Macros - Reusable patterns:
set_sequence("name", [stroke(500,1), wait(200)])call_sequence("name")delete_sequence("name")
Control Panel Features
Connection Status
- Intiface Central: Shows device count and connection state
- LM Studio: Verify LLM server connectivity
- Quick reconnect buttons if needed
Test Controls
- Duration Slider: 100ms to 5000ms
- Intensity Slider: 0% to 100%
- Test Button: Immediate device response
- Stop Button: Emergency halt
Device Settings
- Oscillation: Toggle vibration pulsing mode
- Remote Vibrator Mode: AI outputs pattern commands only (no dialogue)
Autonomous Mode
- Auto-Reply: AI continues generating patterns automatically
- Wait Interval: 1-60 seconds between generations
- Force Chat: Manually trigger next AI response
Settings (Collapsible)
- Prompt Management: Save/load custom roleplay scenarios
- Emotion Settings: Add/remove emotion tags with colors
- Dynamic Context: View auto-generated AI instructions
Emotion System
The AI can express emotions by starting responses with tags:
[Happy] That feels great!
[Teasing] Oh, you like that? stroke(500, 0.8)
Default Emotions: Neutral, Happy, Satisfied, Angry, Sad, Passionate, Dominant, Teasing, Love, Excited, Scared, Surprised, Begging, Disappointed
Custom Emotions: Add your own in Settings → Emotion Settings
Macro System Examples
Simple Pulse
set_sequence("pulse", [stroke(200, 1), wait(100), stroke(200, 1)])
call_sequence("pulse")
Complex Pattern
set_sequence("waves", [
stroke(500, 0.3),
stroke(500, 0.6),
stroke(500, 0.9),
wait(1000),
stroke(1000, 0.5)
])
Quick Tease
set_sequence("tease", [stroke(300, 0.4), wait(500), stroke(300, 0.8)])
Advanced Configuration
Changing Ports
Edit server.py to modify default ports:
DEFAULT_LM_STUDIO_URL = "http://localhost:1234/v1" # LM Studio
DEFAULT_ROUTER_PORT = 8769 # Stroke server
Edit stroke.py for Intiface Central:
intiface_central_port = "12345" # Intiface Central
Custom Prompts
- Navigate to Settings → Prompt Management
- Enter filename
- Write your custom roleplay prompt
- Click Save
- Select from dropdown and click Load
Architecture
[Browser] ←HTTP→ [FastAPI Server] ←WS→ [Stroke Server] ←Buttplug→ [Intiface] ←BT/USB→ [Devices]
↓
[LM Studio]
- Frontend: Vanilla JavaScript with Canvas visualization
- Backend: FastAPI with streaming support
- Device Control: Async Python with buttplug-py
- AI Integration: OpenAI-compatible API (LM Studio)
Troubleshooting
Intiface Central shows "Disconnected"
- ✅ Ensure Intiface Central is running
- ✅ Check server is on port 12345
- ✅ Click "Reconnect" button (waits 10s for device scan)
- ✅ Verify devices are paired in Bluetooth settings
LM Studio shows "Error"
- ✅ Ensure LM Studio server is running
- ✅ Check port 1234 is accessible
- ✅ Try changing URL in the textbox
- ✅ Click "Check" to verify connection
Device doesn't vibrate
- ✅ Click "Test Vibration" to isolate issue
- ✅ Check device battery level
- ✅ Verify device is connected in Intiface Central
- ✅ Try reconnecting device via Bluetooth
AI doesn't output commands
- ✅ Check Technical Prompt is properly set
- ✅ Some models need explicit instruction ("use stroke() to vibrate me")
- ✅ Try Remote Vibrator Mode for pure pattern generation
- ✅ Small models (<7B) may struggle with command syntax
Graph not updating
- ✅ Commands need to be executing for graph to show
- ✅ Refresh browser if frozen
- ✅ Check browser console for JavaScript errors
Privacy and Security
- 100% Local: No data leaves your machine
- No Analytics: Zero tracking or telemetry
- Open Source: Inspect all code yourself
- LM Studio: Your conversations stay private
- Local Network Only: Server binds to 127.0.0.1
⚠️ Warning: Do not expose port 8000 to the internet without adding authentication.
Contributing
This is an open-source project. Contributions welcome:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
Ideas for contributions:
- Additional device support (e-stim, strokers)
- Voice control integration
- Pattern library/marketplace
- Multi-user support
- Mobile app
- VR integration
Disclaimer
This software is intended for adult use only. Use responsibly and consensually. The developers are not responsible for misuse, device damage, or injury. Always use the stop button if uncomfortable. Never exceed safe intensity levels for your specific devices.
Credits
Built with:
- FastAPI - Modern web framework
- buttplug-py - Device protocol library
- LM Studio - Local LLM runtime
- Intiface Central - Device server
Special thanks to the open-source community for making this possible.
Support
- GitHub Issues: Report bugs or request features
- Community: (Add Discord/Forum links if available)
Enjoy responsibly!