Code Monkey home page Code Monkey logo

Comments (6)

mcsarge avatar mcsarge commented on June 26, 2024

So in doing a bit more investigation, it looks like you are always expecting the data sent to the device to be encoded as a HEX string. I need to be able to send data to my device as a string terminated with a .
There is a line in btle.py :
self._writeCmd("%s %X %s\n" % (cmd, handle, binascii.b2a_hex(val).decode('utf-8')))

That appears to convert the data into a HEX string. Should I change this for when I am sending straight character data?

In looking at the code on the C++ side, it does not appear that you unpack that data and turn it back into a string before sending to the device is that the case since device you are interfacing to uses this HEX format?

from bluepy.

IanHarvey avatar IanHarvey commented on June 26, 2024

There's a small example of how to write to a characteristic in SensorBase in sensortag.py. It gets a characteristic object (self.ctrl) using service.getCharacteristics(), and then calls write() on that characteristic.

The value you pass to write() will be passed to binascii.b2a_hex() as you found above. For Python 2.x, it needs to be of type str, and for Python 3.x, it needs to be bytes. If you want to write code which works on both, you can do the following:

characteristic.write( "read temp\r".encode('utf-8') )

as encode() will return the right type of result on both 2.x and 3.x

Hope that helps,
Ian

from bluepy.

mcsarge avatar mcsarge commented on June 26, 2024

Thanks!, and I think it helped, but I am not sure, so I made that change and the device may be receiving the command, but the only way I know it is if I am able to read the data returned in the response from the write command. It looks like in the char_write_req_cb of bluepy-helper.c that user_data never has anything done with it. Is it possible that the command returned some data and it is lost because user_data is never looked at?
Here is the code:

static void char_write_req_cb(guint8 status, const guint8 *pdu, guint16 plen,
                            gpointer user_data)
{
    if (status != 0) {
        resp_error(err_COMM_ERR); // Todo: status
        return;
    }
    if (!dec_write_resp(pdu, plen) && !dec_exec_write_resp(pdu, plen)) {
        resp_error(err_PROTO_ERR);
        return;
    }
    resp_begin(rsp_WRITE);
    resp_end();
}

I am thinking that the user_data needs to be sent back too, I think that is where the response to my "read temp\r" is.

from bluepy.

mcsarge avatar mcsarge commented on June 26, 2024

OK, I have more information. So, if I use the gatttool, I can send and receive the updates to the characteristics. Here is what happens. I write a characteristic, like read temp\r and it is sent to the device, the device then sends a characteristic update with the response. In the gatttool, this is received and printed by the events_handler. Here is it running in gatttool:

image

How would I get the response that is created in the events_handler using the helper code? It looks like it is sending it somehow, but I do not know how to catch it. Can I register a callback in the Python code somehow or can I make a call that will collect the response that has been written using the resp_begin etc.? in the Here is that in the helper code:

static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
    uint8_t *opdu;
        uint8_t evt;
    uint16_t handle, i, olen;
    size_t plen;

        evt = pdu[0];

        if ( evt != ATT_OP_HANDLE_NOTIFY && evt != ATT_OP_HANDLE_IND )
        {
          printf("#Invalid opcode %02X in event handler??\n", evt);
          return;
        }

        assert( len >= 3 );
    handle = att_get_u16(&pdu[1]);

        resp_begin( evt==ATT_OP_HANDLE_NOTIFY ? rsp_NOTIFY : rsp_IND );
        send_uint( tag_HANDLE, handle );
        send_data( pdu+3, len-3 );
        resp_end();

    if (evt == ATT_OP_HANDLE_NOTIFY)
        return;

    opdu = g_attrib_get_buffer(attrib, &plen);
    olen = enc_confirmation(opdu, plen);

    if (olen > 0)
        g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
}

from bluepy.

mcsarge avatar mcsarge commented on June 26, 2024

OK,
I think i solved it. Here is what I did. I added a method in the Peripheral class that allowed me to ask for the "ntfy" response. Here is the code in the Peripheral:
image

I then added a method to the Characteristic class that called that for the particular characteristic.

Down in my main code, I added a loop after I write the characteristic that calls this readNtfy repeatedly until it gets an answer, this seems to work. Here is that code:
image

I will, of course, update the code so that it does not check forever and also to chain the responses together because the device can write back lots of data in 20 byte chunks. Also, it seems that both a ntfy and an ind can be sent from the callback so I will research if I need to update and rename my readNtfy to something more event-ish. I will update my version and if you are interested, you can merge my changes in.

from bluepy.

IanHarvey avatar IanHarvey commented on June 26, 2024

I have now (version 0.9.0, just pushed) made some proper arrangements for handling notifications from peripherals. It lets you register an object to be called whenever a notification is sent, and has a method which waits for notifications with a selectable timeout.

The main documentation page describing this is at http://ianharvey.github.io/bluepy-doc/notifications.html
If you're still developing this, I'd be happy to hear whether this is useful.

Thanks
Ian

from bluepy.

Related Issues (20)

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.