Python Bleak BLE not getting UUID - bluetooth-lowenergy

I have a respberry server and a windows client, both implemented in Python. The server transmits a BLE signal like a iBeacon signal.
Here is the code of the server:
import time
from bluetooth.ble import BeaconService
service = BeaconService()
uuid = "11111111-2222-3333-4444-555555555555"
major = 2 # 1 - 65535
minor = 1 # 1 - 65535
txpower = 1
interval = 200
service.start_advertising(uuid, major, minor, txpower, interval)
try:
time.sleep(300)
service.stop_advertising()
except KeyboardInterrupt:
print("cancelled")
finally:
service.stop_advertising()
print("Done.")
This code is working fine. I checked by installing an android app and I could find the device with that information.
Now I need to get that information in the windows client. In the windows client I'm using bleak library.
I have the following code to scan for beacon devices:
import asyncio
from bleak import discover
async def run():
devices = await discover()
for d in devices:
#if d.address == "B8:27:EB:03:5A:D6":
print(d.address, d.name, d.metadata, d.rssi)
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
The problem is when I check the console, I dont see the major, minor and UUID information:
There are showed other devices and I can see in one of them that the UUID is readable.
What I'm doing wrong here? Is bleak impossible to get the information I want? (minor, major) or am I transmitting in the wrong way? I dont think so because the mobile app is reading fine. Is there another library available to windows to get this information?
Thanks for the help. Have a good day.

Do not confuse the GATT Service UUID list returned by bleak with the iBeacon ProximityUUID you want. They are two totally different identifiers. The iBeacon ProximityUUID is encoded inside the manufacturer data returned by bleak. It will not parse it for you, but you could write a parser yourself. If you print out the manufacturer data bytes as hex you will see the pattern.
I wrote a Windows Beacon Library that does what you want. It is a port of the Android Beacon Library for Windows 10. But the documentation is sorely lacking. If you are stuck, I can help you use it, but it is designed to be used with Visual Studio languages not Python.
Using that library you can parse an iBeacon frame from BluetoothLEAdvertisementReceivedEventArgs in C# like this:
var beaconParser = new BeaconParser();
beaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
Beacon beacon = beaconParser.FromAdvertisement(args.Advertisement, args.RawSignalStrengthInDBm, args.BluetoothAddress);
if (beacon != null)
{
OLogger.Debug("Found iBeacon: UUID=" + beacon.Id1 + " major=" + beacon.Id2 + " minor=" + beacon.Id3 + " rssi: " + beacon.Rssi);
}

Related

Scanning for Bluetooth Devices using Plugin.BluetoothLE but name is blank

I'm using the NuGet package Plugin.BluetoothLE v6.3.0.19 and I can scan for nearby devices but mostly the names are blank. A few devices show their names but most do not. I also cannot see the mac address of the device I'm looking for.
The scenario is that I know the device name but need to look up the mac for connecting.
As I check the devices I need to check the device.name to see if it matches the device I'm looking for. If found it will attempt to pair and connect.
I'm thinking this LE (Low Energy) version does not get the names from every device unless it broadcasts it. So maybe I need to request more info? If so I don't know how to do that with this plugin.
var adapter = CrossBleAdapter.Current;
adapter.ScanExtra(new ScanConfig { ScanType = BleScanType.Balanced });
var scanner = CrossBleAdapter.Current.Scan().Subscribe(scanResult =>
{
var x = scanResult.Device;
System.Diagnostics.Debug.Print($"{x.Name} - {x.Status} _ {x.ToString()}");
});
I am not very familiar with the BluetoothLE, but I found a course about the problem. I hope this can help you.
In addition, you can put the issue on this git. People who know the problem may help you.

Getting device information in class library with Uno Platform

I'm trying to develop a class library for use from Uno Platform applications that can be distributed as a NuGet package. In the code, I need to be able to extract various information about the device currently running the code. I already figured out how to get the screen dimensions but now I'm stuck in getting the current operating system and version. I have seen code like this:
#if __ANDROID__
os = "android";
#elif __IOS__
os = "ios";
#endif
But as I understand, this is not supported in class libraries. I have also experimented with the Uno port of Xamarin.Essentials to use the DeviceInfo class. I couldn't get this to work, though.
Any help would be appreciated.
I approach getting the OS info in a different manner. I grab the OS info using the following code:
public static string getOSVersion()
{
string osInfo = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily.ToString();
int dotPosition = osInfo.IndexOf('.');
string shortOsInfo = osInfo.Substring(0, dotPosition);
return shortOsInfo + " " + Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamilyVersion.ToString();
}
If you are on Android- it will return Android 11, on IOS it will return iOS 14.4(Keep in mind the version number will probably be different- just using it for example purposes). I have not run this on WASM, UWP, Linux, or MacOS- but it should work. Hopefully this will be helpful to you!

Create a bluetooth connection Kivy

This is more of a basic OOP question than a Kivy one. I have an app with 4 buttons. When I press one, I want to initialize a bluetooth connection from my laptop to an arduino uno and also schedule a function that sends bluetooth info every second.
I'm using the following code:
class HomeScreen(Screen):
def OnConnect(self):
print('Start')
port = "COM7"
#connect to bluetooth
bluetooth = serial.Serial(port, 9600)
print("Connected to HC-06")
bluetooth.flushInput()
#schedule a function that sends tester present to arduino
Clock.schedule_interval(self.SendData, 1)
def SendData(self,*args):
bluetooth.write(b"Boop")
Obviously "bluetooth" is not visible outside fct "OnConnect". I want bluetooth to be visible to both OnConnect & SendData but I only want to connect to the arudino when OnConnect is called. Any help is appreciated.
I've looked at the documentation at:
https://kivy.org/doc/stable/api-kivy.clock.html
It says:
If you want to schedule a function to call with default arguments, you can use the functools.partial python module:
So I would think something like this should work:
#schedule a function that sends tester present to arduino
Clock.schedule_interval(partial(self.SendData, bluetooth), 1)
def SendData(self, bt):
bt.write(b"Boop")

BlueNRG Bluetooth: how to receive data via chateractic

Currently I implement code bluetooth low engine (BLE) for STM32L476 + X-NUCLEO-IDB04A1 base on example "sensor demo".
In "Sensor Demo" example, it only code to send data to smart phone. And don't have receive data.
I think can use function below to read data:
tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
And can read data from HCI_Event_CB(hciReadPacket->dataBuff);
However I don't know how to get parameter "uint16_t attr_handle" for function
tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
Could you explain for me about this problem?
That would be the value of the handle for this connection.
When IDB04A1 successfully connects to the smart phone, it shall send a HCI_LE_META_EVENT with information for this connection. Connection_Handle can be found in the event, to be specific, a 16-byte value:
(offset 6 | offset 5)

Asterisk system ignore some DTMF digits when it called by PABX phone

I am using Asterisk E1 card on CentOS 6.2.
When I call on my asterisk system using a simple pstn or by a mobile phone, the call perfectly run. But when the same number has called by a PABX phone, the asterisk system ignored some digits.
I am using asterisk 1.4 and dahdi 2.4.
I have also tried the dtmfmode = rfc2833 in the sip.conf file. Please some one hemp me resolve this problem.
eg: What actually Our system do, when some one call on our system, we ask for for a 14 digit registration id, and perform some operation on it and it work fine. But when some one call from their own PBX phone (or PABX or soft phone) and enter the registration id, then our system ignore some digits.
I also had this problem some times ago this some PBXs.
this help for me:
relexdtmf=yes
Example of my channel.conf:
; SPAN 1-4 = E1 (1-15,17-31,32-46,48-62,63-77,79-93,94-108,110-124)
; ------------------
switchtype = euroisdn
; Type of Number (TON) for called number
pridialplan = local
; Type of Number (TON) for calling number
prilocaldialplan = private
signalling = pri_cpe
context = incoming
group = 1
immediate = no
overlapdial = yes
channel => 1-15,17-31,32-46,48-62,63-77,79-93,94-108,110-124
; activate this option if there are problems with dtmf detection
relexdtmf=yes
I suppose you meant 'call from PBX internal extension' from 'call from their own PBX phone'.
I have faced issue like this. In my case the issue was with the phone. some old or broken IP phone failed to generate proper DTMF signals. Have you tried different phones like soft phones.

Resources