BLE使用gatttool或bluepy订阅通知

时间:2015-09-27 12:16:09

标签: python linux bluetooth-lowenergy gatt

我正在编写一个程序,使用bluepy来监听蓝牙设备发送的特性。我也可以使用任何库或语言,唯一的限制是在Linux上运行而不是在移动环境中运行(它似乎只在移动设备中广泛使用,没有人使用BLE与桌面)。 使用bluepy我注册了委托,并在尝试注册调用write('\x01\x00')的通知后,如蓝牙rfc中所述。 但它不起作用,收到任何关于特征的通知。 也许我在编写订阅消息时错了。 我写的小片段中有错误吗?非常感谢你。

class MyDelegate(btle.DefaultDelegate):

    def __init__(self, hndl):
        btle.DefaultDelegate.__init__(self)
   self.hndl=hndl;

   def handleNotification(self, cHandle, data):
   if (cHandle==self.hndl):
            val = binascii.b2a_hex(data)
            val = binascii.unhexlify(val)
            val = struct.unpack('f', val)[0]
            print str(val) + " deg C"


p = btle.Peripheral("xx:xx:xx:xx", "random")

try:
   srvs = (p.getServices());
   chs=srvs[2].getCharacteristics();
   ch=chs[1];
   print(str(ch)+str(ch.propertiesToString()));
   p.setDelegate(MyDelegate(ch.getHandle()));
   # Setup to turn notifications on, e.g.
   ch.write("\x01\x00");

   # Main loop --------
   while True:
      if p.waitForNotifications(1.0):
      continue

      print "Waiting..."
finally:
    p.disconnect();

3 个答案:

答案 0 :(得分:4)

我自己也在苦苦挣扎,而jgrant的评论确实有帮助。如果可以帮助任何人,我想分享我的解决方案。

请注意,我需要指示,因此需要x02而不是x01。

如果可以使用bluepy读取描述符,我会这样做,但它似乎不起作用(bluepy v 1.0.5)。服务类中的方法似乎丢失了,当我尝试使用它时,外围类中的方法会被卡住。

import javax.swing.*;
import java.awt.event.*;
import java.sql.*;



     public class Manager {
         Connection con;
         Statement st;
         ResultSet rs;

JFrame f = new JFrame("User Login");
JLabel U = new JLabel("Username");
JLabel P = new JLabel("Password");
JTextField t = new JTextField(10);
JTextField t1 = new JTextField(10);
JButton b = new JButton("Login");


public Manager()
{
    connect();
    frame();
}
public void connect()
{

try
{    

String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
Class.forName(driver);
String db = "jdbc:odbc:db1";
con = DriverManager.getConnection(db);
st = con.createStatement();
}
catch(Exception ex)
{

}
}
public void frame()
{
    f.setSize(600,400);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);

    JPanel p = new JPanel();
    p.add(U);
    p.add(t);
    p.add(P);
    p.add(t1);
    p.add(b);

    f.add(p);

    b.addActionListener(new ActionListener(){


        public void actionPerformed(ActionEvent e)
        {
            try
            {
            String User = t.getText().trim();
            String Password =t1.getText().trim();


            String sql = "select User,Password from Table1 where User = '" + User +"'and Password='"+ Password"'";


            rs = st.executeQuery(sql);

            int count = 0;
            while(rs.next())
            {
                count = count + 1;
            }
            if(count == 1)
                    {
                        JOptionPane.showMessageDialog(null,"User found, Acces");
                    }
            else if(count > 1)
            {
                JOptionPane.showMessageDialog(null,"Duplicated User, Access denied");

            }
            else
            {
                JOptionPane.showMessageDialog(null,"User Not found");
            }
            }
            catch(Exception ex)
            {

            }
        }
    });
}


public static void main(String[] args) {

    new Manager();
}

答案 1 :(得分:2)

看起来问题是你正在尝试将\x01\x00写入特征本身。您需要将其写入进行它的客户端特性配置描述符(0x2902)。句柄可能比特征大1(但您可能希望通过阅读描述符来确认)。

ch=chs[1]
cccd = ch.valHandle + 1
cccd.write("\x01\x00")

答案 2 :(得分:0)

让我感到困惑的是,在https://ianharvey.github.io/bluepy-doc/notifications.html中 启用通知的部分包含在注释中,因此对我来说不是必需的。

对我来说,最低限度是

(假设您已经知道MAC地址,并且已经包含了所有内容并声明了Delegateclass)。
componentDidUpdate

请注意,我已经知道我想从特征3获取通知。 另外,如果没有'\ x0 \ x00'前面的'b'-bytesprefix,它对我也将无效。