Skip to content

consumer_control: Add press and release #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2021

Conversation

JPEWdev
Copy link
Contributor

@JPEWdev JPEWdev commented Mar 28, 2021

Adds support for pressing and releasing the consumer control code

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! The CI tests are failing due to missing function comments. Do you want this to work like Keyboard? https://github.com/adafruit/Adafruit_CircuitPython_HID/blob/master/adafruit_hid/keyboard.py#L67 It tracks everything that is currently pressed. Otherwise I think a second press call would release the code from the first.

@dhalbert
Copy link
Collaborator

Could you describe the use case(s) for separate press and release instead of just send? Do long presses repeat sometimes, or something like that?

@JPEWdev
Copy link
Contributor Author

JPEWdev commented Mar 30, 2021

Could you describe the use case(s) for separate press and release instead of just send? Do long presses repeat sometimes, or something like that?

Yes, it does repeat. I'm not sure if this is because of the OS, or the USB device. For example if I send the volume down ID, the volume will decrease while it is held instead of just one step.

My specific use case is that I'm interacting with a device that treats a long press of the power button differently that a short press, so I need the press & release to get the timing correct.

@JPEWdev
Copy link
Contributor Author

JPEWdev commented Mar 30, 2021

Thanks for the PR! The CI tests are failing due to missing function comments. Do you want this to work like Keyboard? https://github.com/adafruit/Adafruit_CircuitPython_HID/blob/master/adafruit_hid/keyboard.py#L67 It tracks everything that is currently pressed. Otherwise I think a second press call would release the code from the first.

Can you send multiple consumer codes in a report? I'm not positive, but it looks like you can only send one, so there isn't any need to track the current one because it will be released when either a new press comes in or release() is called (this is why release() doesn't take an argument; it will release the one and only key being pressed).

@dhalbert
Copy link
Collaborator

Yes, it does repeat.

I'm confused, though, is this something you want to do? What is it that you cannot do with send() that you want to do with press() and release()?

so there isn't any need to track the current one because it will be released when either a new press comes in

This does seem to be true on my keyboard with some multimedia keys. There is no n-key rollover. But I could not find this spec'd in the USB documents. Do you have a reference? thanks.

@JPEWdev
Copy link
Contributor Author

JPEWdev commented Mar 30, 2021

Yes, it does repeat.

I'm confused, though, is this something you want to do? What is it that you cannot do with send() that you want to do with press() and release()?

I'm trying to control a device that distinguishes between a "long" press of it's power button from a "short" press, so I need a way to keep the key held down for a specific duration.

so there isn't any need to track the current one because it will be released when either a new press comes in

This does seem to be true on my keyboard with some multimedia keys. There is no n-key rollover. But I could not find this spec'd in the USB documents. Do you have a reference? thanks.

I do not have a reference; it was an empirical observation. If you know somewhere I can look, I'll try and dig a little more. However, I suspect that the repeating behavior is actually implemented in the OS, not the USB spec.

@dhalbert
Copy link
Collaborator

I'm trying to control a device that distinguishes between a "long" press of it's power button from a "short" press, so I need a way to keep the key held down for a specific duration.

Aha, got it. That is a clear use case. But, I'm interested, is the power button SysControl or Consumer Control? What is the code? We have a SysControl HID descriptor too, but it's not turned on by default.

@dhalbert
Copy link
Collaborator

I tried three differerent keyboards, and they all act rather differently. Sometimes the repeating appears to be done in the OS, and sometimes the keyboard is doing something special.

All this testing was done with sudo evtest on Ubuntu 20.04.

  1. Kinesis FreeStyle Edge: Trying to press another key while one of the keys is down does nothing. The value indicated is 0 or 1: it goes to 1 when the key is pressed, and 0 when released.
  2. Dell Multimedia Keyboard: Pressing a key sends a press and a release (1 and then 0 on evtest) immediately. There is no repeating beahvior.
  3. Logitech K400+: Multiple keys pressed at once works: there appears to be 2-key rollover for the ConsumerControl keys. If a key is held, the value goes to 2 (!).

The USB HID descriptors for these are vastly different from each other. I extracted the descriptors with sudo usbhid-dump and parsed them with http://eleccelerator.com/usbdescreqparser/.

The one we use in CircuitPython is this. It has one 16-bit slot:

0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x75, 0x10,        //   Report Size (16)
0x95, 0x01,        //   Report Count (1)
0x15, 0x01,        //   Logical Minimum (1)
0x26, 0x8C, 0x02,  //   Logical Maximum (652)
0x19, 0x01,        //   Usage Minimum (Consumer Control)
0x2A, 0x8C, 0x02,  //   Usage Maximum (AC Send)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

The Kinesis breaks out the specific functionality as bits.

0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x04,        //   Report Count (4)
0x09, 0xB5,        //   Usage (Scan Next Track)
0x09, 0xB6,        //   Usage (Scan Previous Track)
0x09, 0xCD,        //   Usage (Play/Pause)
0x09, 0xB7,        //   Usage (Stop)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x09, 0xE2,        //   Usage (Mute)
0x81, 0x22,        //   Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
0x95, 0x02,        //   Report Count (2)
0x09, 0xE9,        //   Usage (Volume Increment)
0x09, 0xEA,        //   Usage (Volume Decrement)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x0A, 0x92, 0x01,  //   Usage (AL Calculator)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x80,        // Usage (Sys Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x02,        //   Report ID (2)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x09, 0x81,        //   Usage (Sys Power Down)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x07,        //   Report Count (7)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

The Dell is also a bitwise report, with each function listed:

0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x0A, 0x24, 0x02,  //   Usage (AC Back)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x25, 0x02,  //   Usage (AC Forward)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x26, 0x02,  //   Usage (AC Stop)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x27, 0x02,  //   Usage (AC Refresh)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x23, 0x02,  //   Usage (AC Home)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x8A, 0x01,  //   Usage (AL Email Reader)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x94, 0x01,  //   Usage (AL Local Machine Browser)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x92, 0x01,  //   Usage (AL Calculator)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xB5,        //   Usage (Scan Next Track)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xB6,        //   Usage (Scan Previous Track)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xCD,        //   Usage (Play/Pause)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xB7,        //   Usage (Stop)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x83, 0x01,  //   Usage (AL Consumer Control Configuration)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x0B,        //   Report Count (11)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

The Logitech has two 16-bit slots, I think to get 2-key rollover. I'm still not sure where evtest is getting the value 2 from based on this report; it may be a function of the OS driver, but I'm not at all sure.

x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x75, 0x10,        //   Report Size (16)
0x95, 0x02,        //   Report Count (2)
0x15, 0x01,        //   Logical Minimum (1)
0x26, 0x8C, 0x02,  //   Logical Maximum (652)
0x19, 0x01,        //   Usage Minimum (Consumer Control)
0x2A, 0x8C, 0x02,  //   Usage Maximum (AC Send)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

From all this it appears that any particular behavior about what can be done is dependent on the descriptor. Does your long-press thing work for you right now? The press() and release() semantics you chose make sense for our particular descriptor, since it does not do rollover.

@JPEWdev
Copy link
Contributor Author

JPEWdev commented Mar 31, 2021

xx

I tried three differerent keyboards, and they all act rather differently. Sometimes the repeating appears to be done in the OS, and sometimes the keyboard is doing something special.

All this testing was done with sudo evtest on Ubuntu 20.04.

1. Kinesis FreeStyle Edge: Trying to press another key while one of the keys is down does nothing. The value indicated is 0 or 1: it goes to 1 when the key is pressed, and 0 when released.

2. Dell Multimedia Keyboard: Pressing a key sends a press and a release (1 and then 0 on `evtest`) immediately. There is no repeating beahvior.

3. Logitech K400+: Multiple keys pressed at once works: there appears to be 2-key rollover for the ConsumerControl keys. If a key is held, the value goes to 2 (!).

The USB HID descriptors for these are vastly different from each other. I extracted the descriptors with sudo usbhid-dump and parsed them with http://eleccelerator.com/usbdescreqparser/.

The one we use in CircuitPython is this. It has one 16-bit slot:

0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x75, 0x10,        //   Report Size (16)
0x95, 0x01,        //   Report Count (1)
0x15, 0x01,        //   Logical Minimum (1)
0x26, 0x8C, 0x02,  //   Logical Maximum (652)
0x19, 0x01,        //   Usage Minimum (Consumer Control)
0x2A, 0x8C, 0x02,  //   Usage Maximum (AC Send)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

The Kinesis breaks out the specific functionality as bits.

0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x04,        //   Report Count (4)
0x09, 0xB5,        //   Usage (Scan Next Track)
0x09, 0xB6,        //   Usage (Scan Previous Track)
0x09, 0xCD,        //   Usage (Play/Pause)
0x09, 0xB7,        //   Usage (Stop)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x09, 0xE2,        //   Usage (Mute)
0x81, 0x22,        //   Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
0x95, 0x02,        //   Report Count (2)
0x09, 0xE9,        //   Usage (Volume Increment)
0x09, 0xEA,        //   Usage (Volume Decrement)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x0A, 0x92, 0x01,  //   Usage (AL Calculator)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x80,        // Usage (Sys Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x02,        //   Report ID (2)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x09, 0x81,        //   Usage (Sys Power Down)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x07,        //   Report Count (7)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

The Dell is also a bitwise report, with each function listed:

0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x0A, 0x24, 0x02,  //   Usage (AC Back)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x25, 0x02,  //   Usage (AC Forward)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x26, 0x02,  //   Usage (AC Stop)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x27, 0x02,  //   Usage (AC Refresh)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x23, 0x02,  //   Usage (AC Home)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x8A, 0x01,  //   Usage (AL Email Reader)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x94, 0x01,  //   Usage (AL Local Machine Browser)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x92, 0x01,  //   Usage (AL Calculator)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xB5,        //   Usage (Scan Next Track)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xB6,        //   Usage (Scan Previous Track)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xCD,        //   Usage (Play/Pause)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xB7,        //   Usage (Stop)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x0A, 0x83, 0x01,  //   Usage (AL Consumer Control Configuration)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x0B,        //   Report Count (11)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

The Logitech has two 16-bit slots, I think to get 2-key rollover. I'm still not sure where evtest is getting the value 2 from based on this report; it may be a function of the OS driver, but I'm not at all sure.

x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x75, 0x10,        //   Report Size (16)
0x95, 0x02,        //   Report Count (2)
0x15, 0x01,        //   Logical Minimum (1)
0x26, 0x8C, 0x02,  //   Logical Maximum (652)
0x19, 0x01,        //   Usage Minimum (Consumer Control)
0x2A, 0x8C, 0x02,  //   Usage Maximum (AC Send)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

Excellent. Thanks for digging into that; it all makes sense

From all this it appears that any particular behavior about what can be done is dependent on the descriptor. Does your long-press thing work for you right now? The press() and release() semantics you chose make sense for our particular descriptor, since it does not do rollover.

Yes, this change allows me to do the exact behavior that I'm looking for where I can do either a quick or long press of the power button and the device it's attached to behaves appropriately.

I'll fix up the comments so that the CI job passes

Adds support for pressing and releasing the consumer control code. This
allows for the keys to be pressed for a specific duration of time
instead of a simple press and release.
@JPEWdev JPEWdev force-pushed the consumer-press-release branch from 11450fd to c7e1f85 Compare March 31, 2021 00:57
Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Thanks!

@tannewt tannewt merged commit e9a81ba into adafruit:master Mar 31, 2021
adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Apr 9, 2021
Updating https://github.com/adafruit/Adafruit_CircuitPython_BNO055 to 5.2.6 from 5.2.5:
  > Merge pull request adafruit/Adafruit_CircuitPython_BNO055#76 from ViennaMike/fix_fusion_modes
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_AzureIoT to 2.3.5 from 2.3.4:
  > Moved a function around
  > Merge pull request adafruit/Adafruit_CircuitPython_AzureIoT#28 from jimbobbennett/master
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_Bitmap_Font to 1.4.0 from 1.3.7:
  > Merge pull request adafruit/Adafruit_CircuitPython_Bitmap_Font#42 from FoamyGuy/add_forkawesome_example
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_BLE_Heart_Rate to 1.1.8 from 1.1.7:
  > Merge pull request adafruit/Adafruit_CircuitPython_BLE_Heart_Rate#13 from adafruit/tannewt-patch-1
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_BLE_iBBQ to 1.2.5 from 1.2.4:
  > Merge pull request adafruit/Adafruit_CircuitPython_BLE_iBBQ#5 from adafruit/tannewt-patch-1
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_BLE_MIDI to 1.0.5 from 1.0.4:
  > Merge pull request adafruit/Adafruit_CircuitPython_BLE_MIDI#7 from adafruit/tannewt-patch-1
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_Debouncer to 1.3.11 from 1.3.10:
  > Merge pull request adafruit/Adafruit_CircuitPython_Debouncer#27 from adafruit/linting
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout to 1.9.1 from 1.9.0:
  > Merge pull request adafruit/Adafruit_CircuitPython_DisplayIO_Layout#33 from makermelissa/main

Updating https://github.com/adafruit/Adafruit_CircuitPython_FeatherWing to 1.14.2 from 1.14.1:
  > Merge pull request adafruit/Adafruit_CircuitPython_FeatherWing#71 from makermelissa/master

Updating https://github.com/adafruit/Adafruit_CircuitPython_FunHouse to 1.1.0 from 1.0.0:
  > Merge pull request adafruit/Adafruit_CircuitPython_FunHouse#6 from makermelissa/main
  > Merge pull request adafruit/Adafruit_CircuitPython_FunHouse#5 from makermelissa/main
  > Merge pull request adafruit/Adafruit_CircuitPython_FunHouse#3 from makermelissa/main

Updating https://github.com/adafruit/Adafruit_CircuitPython_HID to 4.3.0 from 4.2.0:
  > Merge pull request adafruit/Adafruit_CircuitPython_HID#63 from JPEWdev/consumer-press-release

Updating https://github.com/adafruit/Adafruit_CircuitPython_MatrixPortal to 2.2.2 from 2.2.1:
  > Merge pull request adafruit/Adafruit_CircuitPython_MatrixPortal#71 from makermelissa/master
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_MIDI to 1.3.5 from 1.3.4:
  > Merge pull request adafruit/Adafruit_CircuitPython_MIDI#32 from jepler/update-simpletest

Updating https://github.com/adafruit/Adafruit_CircuitPython_PIOASM to 0.4.0 from 0.3.0:
  > Merge pull request adafruit/Adafruit_CircuitPython_PIOASM#20 from adafruit/jepler-frequency-too-low
  > Merge pull request adafruit/Adafruit_CircuitPython_PIOASM#17 from gamblor21/mov_operators

Updating https://github.com/adafruit/Adafruit_CircuitPython_Requests to 1.9.9 from 1.9.8:
  > Merge pull request adafruit/Adafruit_CircuitPython_Requests#76 from askpatrickw/fix-48
  > "Increase duplicate code check threshold "
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants