I'm using a Python GATT client software (Bleak) over an RPI, in order to scan, connect and read/write values from BLE devices, to collect the status of them.
The actual problem comes when it reaches the "write to GATT characteristic" time, which eventually ends in "Write not permitted" error.
I use the following scanning method:
device = await BleakScanner.find_device_by_address(mac_addr, timeout=5.0)
Once the device is found, I access to it and do the following:
async with BleakClient(address) as client:
print(f"Connected: {client.is_connected}")
# Subscribe to desired GATT characteristic UUID
await client.start_notify(CHAR_UUID_TO_READ, notification_handler)
await asyncio.sleep(2.0)
...
# Write one byte to a different GATT characteristic UUID
# which will alter the value displayed on the CHAR_UUID_TO_READ
await client.write_gatt_char(CHAR_UUID_TO_WRITE, b'\x01')
await asyncio.sleep(1.0)
...
# Once found the specified end-of-text pattern, it shall disconnect
# from the device
await client.stop_notify(char_uuid)
By proceeding as described, I get the following error:
[org.bluez.Error.NotPermitted] Write not permitted
Traceback (most recent call last):
File "scan_and_connect.py", line 462, in main
await client.start_notify(CHAR_UUID_TO_READ, notification_handler)
File "/usr/local/lib/python3.7/dist-packages/bleak/backends/bluezdbus/client.py", line 931, in start_notify
assert_reply(reply)
File "/usr/local/lib/python3.7/dist-packages/bleak/backends/bluezdbus/utils.py", line 23, in assert_reply
raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.NotPermitted] Write not permitted
Any help on this topic would be appreciated.
Thanks in advance.
Related
I am trying to verify email addresses using this approach (see below) that is cited and recommended in one form or another in countless different places. The problem is that when I get to the "server.connect(mxRecord)" part, it stalls & times out 100% of the time.
I have tried:
at least 30 different domain names to make sure this isn't some networking issue that's specific to a certain domain
adjusting the timeout limit
explicitly specifying the port to connect over (465 & 587)
running "smtplib.SMTP_SSL()" instead of "smtplib.SMTP()"
My setup:
Home wifi
No proxies
import dns.resolver
import smtplib
import socket
addressToVerify = 'rickymartin#yahoo.com'
domainToVerify = 'yahoo.com'
records = dns.resolver.query(domainToVerify, 'MX')
mxRecord = records[0].exchange
mxRecord = str(mxRecord)
print(mxRecord)
server = smtplib.SMTP(timeout=20)
server.set_debuglevel(0)
server.connect(mxRecord)
server.helo(server.local_hostname)
server.mail('me#domain.com')
code, message = server.rcpt(str(addressToVerify))
server.quit()
if code == 250:
print('Valid')
else:
print('Invalid')
This is the error that I receive:
Traceback (most recent call last):
File "email-validator.py", line 17, in <module>
server.connect(mxRecord)
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 336, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 307, in _get_socket
self.source_address)
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 727, in create_connection
raise err
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 716, in create_connection
sock.connect(sa)
socket.timeout: timed out
You need an SMTP server, to get this working.
From the SMTP documentation
smtplib.SMTP(host='', port=0, local_hostname=None, [timeout,]source_address=None)
It takes a 2-tuple (host, port), for the socket to bind to as its source address before connecting. If omitted (or if host or port are '' and/or 0 respectively) the OS default behavior will be used.
You get the timeout because the connection can't be establised.
Try to find and use some free SMTP servers or use a docker image and set it up locally.
To unblock your execution from timeout, use system timeout exception for this.
except TimeoutError as t:
return
I am running a BlueZ Gatt server based upon BlueZ V5.50 and the example-gatt-server.py file contained in the BlueZ test directory. Many times when the server program exits/terminates the D-Bus is left in an unstable condition and I cannot successfully execute the program again without rebooting.
The error message received follows. This error persists until the system is rebooted.
('adapter (val/add) = ', dbus.ObjectPath('/org/bluez/hci0/dev_62_D9_BD_2F_9D_DB/service0018/char0019/desc001b'), '/', '0x75e2a020')
('service_manager (val/loc) = ', <Interface <ProxyObject wrapping <dbus._dbus.SystemBus (system) at 0x75dbbea0> :1.7 /org/bluez/hci0/dev_62_D9_BD_2F_9D_DB/service0018/char0019/desc001b at 0x75e5bf90> implementing 'org.bluez.GattManager1' at 0x75db9f70>, '/', '0x75e168a0')
ERROR:dbus.connection:Unable to set arguments (dbus.ObjectPath('/'), {}) according to signature None: <type 'exceptions.ValueError'>: Unable to guess signature from an empty dict
Resting bluetooth adapter power off/on has no effect
The error occurs asynchronous to the program so pdb has not helped
System information:
GNU/Lunix 4.19.42-v7 #1219
Bluez 5.50 with experimental flag set
So I'm accessing a GPIO Chip in Linux using /dev/gpiochipX and ioctls on Linux 4.14. I'd like to get an event from a pin and then very quickly afterwards read the pin value as well.
Right now, I can get the event by registering a line request for events, and catching the event by polling for it, with poll(2), through something like this:
returnValue = ioctl(fileDescriptor, GPIO_GET_LINEEVENT_IOCTL, &requestEvent);
I'd like to have a line request for values for the same pin ready in the background, so that I can check the pin state as quickly as possible after getting the event.
However, when I try to register the line request for values for the same pin with something like this:
returnValue = ioctl(fileDescriptor, GPIO_GET_LINEHANDLE_IOCTL, &requestValue);
the Linux returns Device or resource busy error.
As far as I can see, I have to release the GPIO Line request for event, register the new line request for value, and then check the value.
So am I missing something, or is it really impossible to have a line request for events and for value active at the same time?
I have a small form interface where users can add the amount of money they want to load into their account. Users have to load a minimum amount of money. So I need to reject if users put an amount less then certain amount (ie. 50 USD).
I have js validation on place for the form for minimum load. Users put the desired amount then click checkout. After the checkout process stripe js api returns with a token. Token with other data (like amount, currency) are sent to server.
Now I need to validate the amount in the server. I can check the amount and print error message if it does not validate. The token that stripe js api created will remain unused if the validation is rejected.
My question is, what are the problems that can arise if I keep the token unused?
So actually, you don't need to validate on your server. If you attempt to call the Create a Charge API Endpoint with a value less than the minimum (in any currency) Stripe will simply raise an error (400 Bad Request).
Example in Python:
>>> stripe.Charge.create(amount=49, currency="usd", source="tok_visa")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/lib/python2.7/site-packages/stripe/api_resources/abstract/createable_api_resource.py", line 17, in create
response, api_key = requestor.request('post', url, params, headers)
File "~/lib/python2.7/site-packages/stripe/api_requestor.py", line 153, in request
resp = self.interpret_response(rbody, rcode, rheaders)
File "~/lib/python2.7/site-packages/stripe/api_requestor.py", line 365, in interpret_response
self.handle_error_response(rbody, rcode, resp.data, rheaders)
File "~/lib/python2.7/site-packages/stripe/api_requestor.py", line 178, in handle_error_response
raise err
stripe.error.InvalidRequestError: Request req_xxx: Amount must be at least 50 cents
I have a subscription to a topic using filters in Azure Service Bus develop with Python 3.x and when I wait the information sent to that topic (information that pass the filter) I can not receive it.
I need to create a daemon that is always listening and that when I receive that information I send it to an internal service of my application, so the receiver is running in a thread inside a loop While True
The code I use to receive the messages is as follows:
while True:
msg = bus_service.receive_subscription_message(topic_name, subscription_name, peek_lock=True)
print('Mensaje Recibido-->',msg.body)
data = msg.body
send_MyApp(data.decode("utf-8"))
msg.delete()
What I get when I run it is the next information:
Message --> None
Exception in thread Thread-1:
Traceback (most recent call last):
File "..\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "..\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "../Python/ServiceBusSuscription/receive_subscription.py", line 19, in receive_subscription
send_MyApp(data.decode("utf-8"))
AttributeError: 'NoneType' object has no attribute 'decode'
If I run the receiver out of the thread, this is the error message it shows (again when the timeout is skipped, which timeout I should delete because in a daemon that is waiting it can not skip). Basically, it is the same error:
Traceback (most recent call last):
File "../Python/ServiceBusSuscription/receive_subscription.py", line 76, in <module>
main()
File "../Python/ServiceBusSuscription/receive_subscription.py", line 72, in main
demo(bus_service)
File "../Python/ServiceBusSuscription//receive_subscription.py", line 25, in demo
print(msg.body.decode("utf-8"))
AttributeError: 'NoneType' object has no attribute 'decode'
I do not receive the information I'm waiting and also skip a Service Bus timeout (which I have not programmed).
Can anybody help me? Microsoft's documentation does not help much, really.
Thanks in advance
UPDATE
I think that the problem is from Azure Service Bus and the subscriptions and filters. Actually, I have 23 filters and I think Azure Service Bus only works with 1 subscription :( But I'm not sure about this point.
I tried to reproduce your issue successfully, then I discovered that it happended if there is no message in your topic.
So you need to check the value or type of msg.body whether be None or type(None) before decode the bytes of msg.body, as below.
data = msg.body
if data != None:
# Or if type(data) == type(b''):
send_MyApp(data.decode("utf-8"))
msg.delete()
else:
...
Hope it helps.