Giter Club home page Giter Club logo

buttplug-py's People

Contributors

dependabot[bot] avatar qdot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

buttplug-py's Issues

Stringify Device Objects

I need to pull the devices list and their features and names from the client.devices object. However, due to how the dict is structured, it is complex to work with it. It'd be very useful to get a quick json that shows the needed information.

send_vibrate_cmd(float) only works with single-motor devices

Devices with multiple motors will not vibrate as expected when using send_vibrate_cmd(float). Instead, only the first motor of that device will vibrate.

Steps to reproduce:

  1. Connect a device with multiple motors (e.g. Lovense Edge)
  2. Perform send_vibrate_cmd(1.0) on that device.
  3. The first motor will vibrate while the second does not.

Expected behavior:

All motors will vibrate with the same intensity.

It appears to be because Line 255 of buttplug/client/client.py only sets the speed of the motor at index 0 and does not consider devices with multiple motors.

Workaround: Multiplying a list by the number of motors:
e.g.

vibratorCount = dev.allowed_messages["VibrateCmd"].feature_count
intensity = [1.0] * vibratorCount
await dev.send_vibrate_cmd(intensity)

Finish and release buttplug-py v1

Epic for issues relating to releasing a full v1 of buttplug-py.

v1 is a client only release (no plans to release a python buttplug server). It should be able to connect to Intiface Desktop/CLI instances, through either websockets or IPC. These connectors may come as external packages since multiple websocket solutions exist.

client.device_removed_handler throws AttributeError("'dict' object has no attribute 'remove'")

When client.device_removed_handler += device_removed is called, the error below is thrown.

DeviceRemoved(device_index=0)
Task exception was never retrieved
future: <Task finished coro=<ButtplugClientWebsocketConnector._consumer_handler() done, defined at /usr/local/lib/python3.7/dist-packages/buttplug/client/websocket_connector.py:24> exception=AttributeError("'dict' object has no attribute 'remove'") created at /usr/lib/python3.7/asyncio/tasks.py:325>
source_traceback: Object created at (most recent call last):
File "Buttplug_Example.py", line 186, in
asyncio.run(main(), debug=True)
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 571, in run_until_complete
self.run_forever()
File "/usr/lib/python3.7/asyncio/base_events.py", line 539, in run_forever
self._run_once()
File "/usr/lib/python3.7/asyncio/base_events.py", line 1767, in _run_once
handle._run()
File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "Buttplug_Example.py", line 44, in try_connect
await client.connect(connector)
File "/usr/local/lib/python3.7/dist-packages/buttplug/client/client.py", line 85, in connect
await self.connector.connect()
File "/usr/local/lib/python3.7/dist-packages/buttplug/client/websocket_connector.py", line 22, in connect
asyncio.create_task(self._consumer_handler())
File "/usr/lib/python3.7/asyncio/tasks.py", line 325, in create_task
return loop.create_task(coro)
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/buttplug/client/websocket_connector.py", line 37, in _consumer_handler
await self._notify_observers(bp_msg)
File "/usr/local/lib/python3.7/dist-packages/buttplug/client/connector.py", line 52, in _notify_observers
await obs._handle_message(msg)
File "/usr/local/lib/python3.7/dist-packages/buttplug/client/client.py", line 176, in _handle_message
await self._parse_message(msg)
File "/usr/local/lib/python3.7/dist-packages/buttplug/client/client.py", line 144, in _parse_message
self.devices.remove(dr.device_index)
AttributeError: 'dict' object has no attribute 'remove
`

Should device_added and device_removed take the same type?

Your ButtplugClient.device_added_handler takes a ButtplugClientDevice as a param (link), and the ButtplugClient.device_removed_handler takes an int (link) referring to the device's index. It makes more sense to me personally for it to take a ButtplugClientDevice both times.

This would be a breaking change, but to me it makes more sense than right now. Please do say if you did this deliberately.

Example for wrapping asyncio loop in thread

Hello, I tried to wrap the examples/example.py in a thread as suggested to be able to use this library in a synchronous project.

I'm new to Python and it doesn't work. Can someone please have a look on this and/or add an example to the repository?

from buttplug.client import (ButtplugClientWebsocketConnector, ButtplugClient,
							 ButtplugClientDevice, ButtplugClientConnectorError)
from buttplug.core import ButtplugLogLevel
import asyncio
import threading
import time 
from queue import Queue

class ButtplugConnectorThread(threading.Thread):
	def __init__(self, queue, args=(), kwargs=None):
			threading.Thread.__init__(self, args=(), kwargs=None)
			self.queue = queue
			self.daemon = True

	def run(self):
		self.buttplug_connector = asyncio.run(ButtplugConnector.create())
		while True:
			val = self.queue.get()
			if val is None:
				return
			self.message_received(val)

	def message_received(self, message):
		print("Received {}".format(message))
		self.buttplug_connector.set_vibration(message)

class ButtplugConnector:
	@classmethod
	async def create(cls):
		self = ButtplugConnector()
		self.client = ButtplugClient("Something")
		self.connector = ButtplugClientWebsocketConnector("ws://127.0.0.1:12345")
		self.devices = []
		await self.connect()
		return self

	async def connect(self):
		self.client.device_added_handler += self.device_added

		try:
			await self.client.connect(self.connector)
			await self.client.request_log('Debug')
		except ButtplugClientConnectorError as e:
			print("Could not connect to Intiface: {}".format(e.message))
			return

		await self.client.start_scanning()

	async def set_vibration(self, value):
		for device in self.devices:
			await device.send_vibrate_cmd(value)

	async def device_added_task(self, dev: ButtplugClientDevice):
		self.devices.append(dev)
		print("Device Added: {}".format(dev.name))

	def device_added(self, emitter, dev: ButtplugClientDevice):
		asyncio.create_task(self.device_added_task(dev))

	async def disconnect(self):
		try:
			await self.client.stop_scanning()
			await self.client.disconnect()
		except:
			pass


buttplug_thread = ButtplugConnectorThread(Queue())
buttplug_thread.start()
buttplug_thread.queue.put(0.5)
while True:
	time.sleep(100)
	pass

It connects but it disconnects right away.

Connection closed event needed.

There's currently no way to handle a connection closed that I am aware of. Especially when receiving the below:
code = 1006 (connection closed abnormally [internal]), no reason
This could totally be my poor knowledge of asyncio but it seems like we need an event in those situations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.