Open Gremious opened 10 months ago
Yeah, welcome to the fun of trying to maintain a generic API for a set of devices that are in no way generic.
So, first off: Hadn't seen Handy's new API. Main issue I see here (and I'm making big assumptions about architecture) is that it still requires talking to their server for every command, so you're network round-tripping off their endpoints, versus local control. That was mainly what we were trying to avoid when we said no wifi/web APIs in Buttplug: I don't want to debug everyone's individual network latency in a platform that should really not require it in the first place, but we're forced into these weird control models and local network discovery is the w o r s t (I just had a bad time with mDNS last month).
Now, that said, if you want a build a system where you take a vibration and turn that into an oscillation through Handy's Wifi system, that's completely possible through our poorly documented "Websocket Device Manager". Turning this on pops open yet another websocket server port that you can connect to and receive buttplug commands either as the raw JSON that they come in as, or formatted to the values of any other protocol our system handles. It does require setup via it's own simple protocol, and setting up the configuration part is still hellish (I'm working on integrating configuration of this into Intiface now, but it's requiring a ton of ground-up reworking), but once all the setup is done, it's pretty simple. There's documentation on this at https://docs.buttplug.io/docs/dev-guide/inflating-buttplug/devices/websocket-device-manager, or just poke me on here/discord/etc if you have other questions.
That was mainly what we were trying to avoid when we said no wifi/web APIs in Buttplug ...
100% understandandable
"Websocket Device Manager" looks, at least in principle, like the right solution so far - thank you very much!
I think it wouldn't be far fetched to write some software that actually handles oscilation and ether translates vibrations or just immidates a handy more properly. I can probably still directly communicate with a BLE connected handy and do looping movements manually too, so I don't need to ask for wifi keys everywhere.
Thanks again, I'll look into it more properly and pop around if I have any questions!
Heya! I set it up and it was honestly not that bad! And hey intiface seems to have GUI buttons to add user configs for websocket devices now, so that's nice.
My thoughts are that I can emulate a vibrating device/accept vibration messages, since most applications expect that, and simply route those to a connected handy appropriately.
However, it's a lil lame to show up as a "lovense hush" or something - I was wondering if buttplug has a "Generic/Software Device" that supports all types of signals? Or perhaps I can extend the handy user config with a linear message somehow?
I tried some random funky things e.g. :
But that didn't really change anything, no nice oscillation/vibration buttons in intiface.
Ok, so this is going to delve a bit into how protocols and configurations work internally.
You do not want to use thehandy
as your basis. That's referring to OUR implementation of the Handy Protocol, which means a buttplug message gets turned into Handy's protocol format, THEN gets sent to you. That conversion from buttplug -> proprietary protocol is lossy; if a toy using that protocol does not provide a feature type, we don't implement it. The Handy (at the moment, disregarding CES news) does not currently have a vibrator, so we don't implement there, meaning even if you add new configurations, we'll just toss it because you're routing through our implementation of the protocol.
On top of that, setting new configuration on The Handy would require an identification step that does not exist on that protocol. Identification steps happen on some brands like Lovense or Satisfyer, where we have to use some extra data like response to a certain command or advertising manufacturer data to figure out what kind of toy under that brand we're talking to and specialize for it. For The Handy, there's just... The Handy. So we didn't create identification logic and I don't think there's the ability to do that otherwise.
What you probably want to do is choose either the "buttplug-passthru" protocol and parse raw buttplug messages yourself, or choose the protocol of something that already supports vibration, make a separate configuration, take the output of that, and translate the vibration/output to the corresponding handy web commands.
Yep, that all makes perfect sense from what what I've seen working with this.
buttplug-passthru
is what I am looking for - thank you very much! My only reference was the buttplug-device-config.json and passthru was not there, so I didn't see it.
Though, using it and sending a handshake immediately gives me a Close message and then a 10053: ConnectionAborted - unlike when e.g emulating a lovense device. I can't find it in the docs so I'd like to ask how this thing behaves differently from a regular device, please, do I need to configure/do anything special?
Ok, so the important error message here is:
No viable protocols for hardware Websocket(WebsocketSpecifier { names: {"HandyCoordinator"} }), ignoring.
That means the system isn't matching your specifier to a protocol. Can you post what your current config file looks like?
(I am currently replacing this device config mess with a sqlite based DB mess, so this is a temporary thing)
Knew I should have included that, here you go:
{
"version": {
"major": 2,
"minor": 0
},
"user-configs": {
"specifiers": {
"buttplug-passthru": {
"websocket": {
"names": [
"HandyCoordinator"
]
},
"configurations": []
}
},
"devices": [
{
"identifier": {
"address": "PeripheralId(80:64:6F:27:B0:C6)",
"protocol": "thehandy",
"identifier": "The Handy"
},
"config": {
"index": 0
}
}
]
}
}
Ok, I think you need to set up a default
in the buttplug-passthru
specifier, where configurations
currently is. That's how we say "if I can't identify a device, just use this". Just copy something simple out of the main device config, that has a vibrator with 100 steps or something. I usually use the aneros one, it's fairly simple.
I tried both
"buttplug-passthru": {
"websocket": {
"names": [
"HandyCoordinator"
]
},
"defaults": {
"name": "HandyCoordinator",
"messages": {
"ScalarCmd": [
{
"StepRange": [
0,
127
],
"FeatureDescriptor": "Perineum Vibrator",
"ActuatorType": "Vibrate"
},
{
"StepRange": [
0,
127
],
"FeatureDescriptor": "Internal Vibrator",
"ActuatorType": "Vibrate"
}
]
}
}
}
and
"buttplug-passthru": {
"websocket": {
"names": [
"HandyCoordinator"
]
},
"configurations": [
{
"defaults": {
"name": "HandyCoordinator",
"messages": {
"ScalarCmd": [
{
"StepRange": [
0,
127
],
"FeatureDescriptor": "Perineum Vibrator",
"ActuatorType": "Vibrate"
},
{
"StepRange": [
0,
127
],
"FeatureDescriptor": "Internal Vibrator",
"ActuatorType": "Vibrate"
}
]
}
}
}
]
}
and it did not lead to any changes, unless I misunderstood the assignment.
p.s. idk if u prefer discord so i joined just in case, u can ping me if you want, same name. I don't mind ether, though I will be dropping out in like 30 min tops for the night
sorry to put you on debug duty, I appreciate the help <3
update: yep it broken just emulate a real toy for now
Ok, so, thanks to the Lovense Solace Pro, this just got weird.
The Solace Pro implements exactly what The Handy's WiFi API does, except over bluetooth. You can load funscripts to the device, and control them via pattern timing updates, but it's all local.
I don't foresee us getting this into buttplug in the message spec v4 update, but this may influence how we handle patterns in v5.
I raise this discussion from having spent an evening reading the implementation for the Handy, and it's bluetooth interface handyplug. At first, I thought "haha @qdot left angry comments, that's funny to read". As I spent time familiarizing myself with the code, that feeling has since grown into a deep understanding. I am so sorry.
The handy is a stroker. The handyplug protocol is a little chunk of code (?) that hasn't been touched in two years, and implements a single useful control command: move to point X and take Y ms doing it. A linear movement, not an oscillation, for an oscillating toy.
The dev team for the handy does not care for developing this further:
Through great difficulty, handyplug was used and
buttplug
now supports a linear movement for the handy.Intiface has a button to oscillate said linear movement so that's cool.
The handy, however, remains an oscillating piece of hardware.
This sucks lmao. I want to hack on existing code and update it to oscillate the handy, but I have to write manual back and forth motions with timings and sleeps between them, instead of ideally just translating a vibration call to an oscillation call.
On the other hand, the web API for this toy looks actually reasonable, as it implements alternating motions - start, stop, intensity, etc.
My questions then are the following:
Is connecting over Wi-Fi/implementing web API's for toys in scope for this project? Would it be reasonable to open a request for that? If it happens I probably wouldn't mind doing a PR the Handy API, at the very least for the alternating motions part.
Alternatively idk, can I communicate with intiface somehow and tell it to do whatever it does when I press the oscillation button?
Is there a magical third way?
Maybe I can write some sort of compatibility layer that handles looping movement, that also connects to intiface somehow someway...
Basically, it should not be my job to manually oscillate a toy, I should just tell buttplug to do it. It should not be buttplug's job to do it manually ether, it should just relay to the toy to do it. The toys suck and doesn't do it - so I'm just kinda looking for alternate solutions here.