robot-hat


Namerobot-hat JSON
Version 1.7.1 PyPI version JSON
download
home_pageNone
SummaryCustom version of Robot Hat Python library for Sunfounder's Raspberry Pi robots.
upload_time2025-01-14 09:36:14
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseGNU
keywords i2c raspberrypi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![PyPI](https://img.shields.io/pypi/v/robot-hat)](https://pypi.org/project/robot-hat/)
[![codecov](https://codecov.io/gh/KarimAziev/robot-hat/graph/badge.svg?token=2C863KHRLU)](https://codecov.io/gh/KarimAziev/robot-hat)

# Robot Hat

This is a Python library for controlling hardware peripherals commonly used in robotics. This library provides APIs for controlling **motors**, **servos**, **ultrasonic sensors**, **analog-to-digital converters (ADCs)**, and more, with a focus on extensibility, ease of use, and modern Python practices.

The motivation comes from dissatisfaction with the code quality, safety, and unnecessary `sudo` requirements found in many mainstream libraries provided by well-known robotics suppliers, such as [Sunfounder's Robot-HAT](https://github.com/sunfounder/robot-hat/tree/v2.0) or [Freenove's Pidog](https://github.com/Freenove/Freenove_Robot_Dog_Kit_for_Raspberry_Pi). That being said, this library was originally written as a replacement for Sunfounder's Robot-HAT.

Unlike the aforementioned libraries:

- This library scales well for **both small and large robotics projects**. For example, advanced usage is demonstrated in the [Picar-X Racer](https://github.com/KarimAziev/picar-x-racer) project.
- It offers type safety and portability.
- It avoids requiring **sudo calls** or introducing unnecessary system dependencies, focusing instead on clean, self-contained operations.

<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->

**Table of Contents**

> - [Robot Hat](#robot-hat)
>   - [Installation](#installation)
>   - [Usage Examples](#usage-examples)
>     - [Motor Control](#motor-control)
>     - [Controlling a Servo Motor with ServoCalibrationMode](#controlling-a-servo-motor-with-servocalibrationmode)
>       - [Available Modes](#available-modes)
>       - [Configuring the `ServoService`](#configuring-the-servoservice)
>         - [Example 1: Steering Servo Using `ServoCalibrationMode.SUM`](#example-1-steering-servo-using-servocalibrationmodesum)
>         - [Example 2: Head Servos Using `ServoCalibrationMode.NEGATIVE`](#example-2-head-servos-using-servocalibrationmodenegative)
>       - [Custom Calibration Mode](#custom-calibration-mode)
>     - [I2C Example](#i2c-example)
>     - [Ultrasonic Sensor for Distance Measurement](#ultrasonic-sensor-for-distance-measurement)
>     - [Reading Battery Voltage](#reading-battery-voltage)
>   - [Comparison with Other Libraries](#comparison-with-other-libraries)
>     - [No sudo](#no-sudo)
>     - [Type Hints](#type-hints)
>     - [Mock Support for Testing](#mock-support-for-testing)
>   - [Development Environment Setup](#development-environment-setup)
>     - [Prerequisites](#prerequisites)
>     - [Steps to Set Up](#steps-to-set-up)
>   - [Distribution](#distribution)
>   - [Common Commands](#common-commands)
>   - [Notes & Recommendations](#notes--recommendations)

<!-- markdown-toc end -->

## Installation

Install this via `pip` or your favorite package manager:

```bash
pip install robot-hat
```

## Usage Examples

### Motor Control

Control dual motors using the `MotorService` modules.

```python
from robot_hat import MotorConfig, MotorService, MotorFabric

left_motor, right_motor = MotorFabric.create_motor_pair(
    MotorConfig(
        dir_pin="D4",
        pwm_pin="P12",
        name="LeftMotor",
    ),
    MotorConfig(
        dir_pin="D5",
        pwm_pin="P13",
        name="RightMotor",
    ),
)
motor_service = MotorService(left_motor=left_motor, right_motor=right_motor)

# move forward
speed = 40
motor_service.move(speed, 1)

# move backward
motor_service.move(speed, -1)

# stop
motor_service.stop_all()

```

### Controlling a Servo Motor with ServoCalibrationMode

The `ServoCalibrationMode` is an enum used to define how the calibration offsets are applied to the servo's angle. It supports two predefined modes and also allows for custom calibration functions for advanced use cases.

#### Available Modes

1. **SUM**: Adds a constant offset (`calibration_offset`) to the input angle. This is generally used for steering operations, like managing front wheels in a robotics car.
   - Formula:
     \( \text{calibrated_angle} = \text{input_angle} + \text{calibration_offset} \)
2. **NEGATIVE**: Subtracts the constant offset after inverting the input angle. This mode may be helpful for servos that require an inverted adjustment, like a camera tilt mechanism.
   - Formula:
     \( \text{calibrated_angle} = -1 \times (\text{input_angle} + (-1 \times \text{calibration_offset})) \)

#### Configuring the `ServoService`

The `ServoService` provides a high-level abstraction for managing servo operations. It allows for easy configuration of the calibration mode, constraints for the servo's movement bounds, and custom calibration logic if needed.

Here's how to use `ServoCalibrationMode` in your servo configuration:

##### Example 1: Steering Servo Using `ServoCalibrationMode.SUM`

For steering purposes (e.g., controlling front wheels of a robotics car):

```python
from robot_hat import ServoCalibrationMode, ServoService

steering_servo = ServoService(
    servo_pin="P2",
    min_angle=-30,  # Maximum left turn
    max_angle=30,   # Maximum right turn
    calibration_mode=ServoCalibrationMode.SUM,  # Adds offset directly
    calibration_offset=-14.4,  # Adjust servo position for centered alignment
)

# Turn left
steering_servo.set_angle(-30)

# Turn slightly right
steering_servo.set_angle(15)

# Center position
steering_servo.reset()
```

##### Example 2: Head Servos Using `ServoCalibrationMode.NEGATIVE`

For tilting a camera head (e.g., up-and-down movement):

```python
from robot_hat import ServoCalibrationMode, ServoService

cam_tilt_servo = ServoService(
    servo_pin="P1",
    min_angle=-35,  # Maximum downward tilt
    max_angle=65,   # Maximum upward tilt
    calibration_mode=ServoCalibrationMode.NEGATIVE,  # Inverted adjustment
    calibration_offset=1.4,  # Adjust alignment for neutral center
)

# Tilt down
cam_tilt_servo.set_angle(-20)

# Tilt up
cam_tilt_servo.set_angle(25)

# Center position
cam_tilt_servo.reset()
```

---

#### Custom Calibration Mode

If the predefined modes (`SUM` or `NEGATIVE`) don’t meet your requirements, you can provide a custom calibration function. The function should accept the `angle` and `calibration_offset` as inputs and return the calibrated angle.

Example:

```python
def custom_calibration_function(angle: float, offset: float) -> float:
    # Example: Scale angle by 2 and add offset to fine-tune servo position
    return (angle * 2) + offset

servo = ServoService(
    servo_pin="P3",
    calibration_mode=custom_calibration_function,
    calibration_offset=5.0,
    min_angle=-35,
    max_angle=65,
)
servo.set_angle(10)  # Custom logic will process the input angle
```

### I2C Example

Scan and communicate with connected I2C devices.

```python
from robot_hat.i2c import I2C

# Initialize I2C connection
i2c_device = I2C(address=[0x15, 0x17], bus=1)

# Write a byte to the device
i2c_device.write(0x01)

# Read data from the device
data = i2c_device.read(5)
print("I2C Data Read:", data)

# Scan for connected devices
devices = i2c_device.scan()
print("I2C Devices Detected:", devices)
```

### Ultrasonic Sensor for Distance Measurement

Measure distance using the `HC-SR04` ultrasonic sensor module.

```python
from robot_hat.pin import Pin
from robot_hat.ultrasonic import Ultrasonic

# Initialize Ultrasonic Sensor
trig_pin = Pin("P9")
echo_pin = Pin("P10")
ultrasonic = Ultrasonic(trig_pin, echo_pin)

# Measure distance
distance_cm = ultrasonic.read(times=5)
print(f"Distance: {distance_cm} cm")
```

### Reading Battery Voltage

Use the ADC module to measure and scale the battery voltage.

```python
from robot_hat.battery import Battery

# Initialize Battery module
battery = Battery(channel="A4")

# Get battery voltage
voltage = battery.get_battery_voltage()
print(f"Battery Voltage: {voltage} V")
```

## Comparison with Other Libraries

### No sudo

For reasons that remain a mystery (and a source of endless frustration), the providers of many popular DRY robotics libraries insist on requiring `sudo` for the most basic operations. For example:

```python
User = os.popen('echo ${SUDO_USER:-$LOGNAME}').readline().strip()
UserHome = os.popen('getent passwd %s | cut -d: -f 6' % User).readline().strip()
config_file = '%s/.config/robot-hat/robot-hat.conf' % UserHome
```

And later, they modify file permissions with commands like:

```python
os.popen('sudo chmod %s %s' % (mode, file_path))  # 🤦
os.popen('sudo chown -R %s:%s %s' % (owner, owner, some_path))
```

This library removes all such archaic and potentially unsafe patterns by leveraging user-friendly Python APIs like `pathlib`. File-related operations are scoped to user-accessible directories (e.g., `~/.config`) rather than requiring administrative access
via `sudo`.

### Type Hints

This version prioritizes:

- **Type hints** for better developer experience.
- Modular, maintainable, and well-documented code.

### Mock Support for Testing

`Sunfounder` (and similar libraries) offer no direct way to mock their hardware APIs, making it nearly impossible to write meaningful unit tests on non-Raspberry Pi platforms.

```python
import os
os.environ["GPIOZERO_PIN_FACTORY"] = "mock"
os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "1"
```

---

## Development Environment Setup

### Prerequisites

1. **Python 3.10 or newer** must be installed.
2. Ensure you have `pip` installed (a recent version is recommended):
   ```bash
   python3 -m pip install --upgrade pip
   ```

### Steps to Set Up

1. **Clone the Repository**:

   ```bash
   git clone https://github.com/KarimAziev/robot-hat.git
   cd robot-hat
   ```

2. **Set Up a Virtual Environment**:

   ```bash
   python3 -m venv .venv
   source .venv/bin/activate  # Linux/Mac
   # OR
   .venv\Scripts\activate     # Windows
   ```

3. **Upgrade Core Tools**:

   ```bash
   pip install --upgrade pip setuptools wheel
   ```

4. **Install in Development Mode**:
   ```bash
   pip install -e ".[dev]"  # Installs all dev dependencies (e.g., black, isort, pre-commit)
   ```

---

## Distribution

To create distributable artifacts (e.g., `.tar.gz` and `.whl` files):

1. Install the build tool:

   ```bash
   pip install build
   ```

2. Build the project:
   ```bash
   python -m build
   ```
   The built files will be located in the `dist/` directory:

- Source distribution: `robot_hat-x.y.z.tar.gz`
- Wheel: `robot_hat-x.y.z-py3-none-any.whl`

These can be installed locally for testing or uploaded to PyPI for distribution.

---

## Common Commands

- **Clean Build Artifacts**:
  ```bash
  rm -rf build dist *.egg-info
  ```
- **Deactivate Virtual Environment**:
  ```bash
  deactivate
  ```

---

## Notes & Recommendations

- The library uses `setuptools_scm` for versioning, which dynamically determines the version based on Git tags. Use proper semantic versioning (e.g., `v1.0.0`) in your repository for best results.
- Development tools like `black` (code formatter) and `isort` (import sorter) are automatically installed with `[dev]` dependencies.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "robot-hat",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "i2c, raspberrypi",
    "author": null,
    "author_email": "Karim Aziiev <karim.aziiev@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/7e/39/421bfcce2033a2b5503917a15d743890f1e572d0b7a5b82810211c65e9a4/robot_hat-1.7.1.tar.gz",
    "platform": null,
    "description": "[![PyPI](https://img.shields.io/pypi/v/robot-hat)](https://pypi.org/project/robot-hat/)\n[![codecov](https://codecov.io/gh/KarimAziev/robot-hat/graph/badge.svg?token=2C863KHRLU)](https://codecov.io/gh/KarimAziev/robot-hat)\n\n# Robot Hat\n\nThis is a Python library for controlling hardware peripherals commonly used in robotics. This library provides APIs for controlling **motors**, **servos**, **ultrasonic sensors**, **analog-to-digital converters (ADCs)**, and more, with a focus on extensibility, ease of use, and modern Python practices.\n\nThe motivation comes from dissatisfaction with the code quality, safety, and unnecessary `sudo` requirements found in many mainstream libraries provided by well-known robotics suppliers, such as [Sunfounder's Robot-HAT](https://github.com/sunfounder/robot-hat/tree/v2.0) or [Freenove's Pidog](https://github.com/Freenove/Freenove_Robot_Dog_Kit_for_Raspberry_Pi). That being said, this library was originally written as a replacement for Sunfounder's Robot-HAT.\n\nUnlike the aforementioned libraries:\n\n- This library scales well for **both small and large robotics projects**. For example, advanced usage is demonstrated in the [Picar-X Racer](https://github.com/KarimAziev/picar-x-racer) project.\n- It offers type safety and portability.\n- It avoids requiring **sudo calls** or introducing unnecessary system dependencies, focusing instead on clean, self-contained operations.\n\n<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->\n\n**Table of Contents**\n\n> - [Robot Hat](#robot-hat)\n>   - [Installation](#installation)\n>   - [Usage Examples](#usage-examples)\n>     - [Motor Control](#motor-control)\n>     - [Controlling a Servo Motor with ServoCalibrationMode](#controlling-a-servo-motor-with-servocalibrationmode)\n>       - [Available Modes](#available-modes)\n>       - [Configuring the `ServoService`](#configuring-the-servoservice)\n>         - [Example 1: Steering Servo Using `ServoCalibrationMode.SUM`](#example-1-steering-servo-using-servocalibrationmodesum)\n>         - [Example 2: Head Servos Using `ServoCalibrationMode.NEGATIVE`](#example-2-head-servos-using-servocalibrationmodenegative)\n>       - [Custom Calibration Mode](#custom-calibration-mode)\n>     - [I2C Example](#i2c-example)\n>     - [Ultrasonic Sensor for Distance Measurement](#ultrasonic-sensor-for-distance-measurement)\n>     - [Reading Battery Voltage](#reading-battery-voltage)\n>   - [Comparison with Other Libraries](#comparison-with-other-libraries)\n>     - [No sudo](#no-sudo)\n>     - [Type Hints](#type-hints)\n>     - [Mock Support for Testing](#mock-support-for-testing)\n>   - [Development Environment Setup](#development-environment-setup)\n>     - [Prerequisites](#prerequisites)\n>     - [Steps to Set Up](#steps-to-set-up)\n>   - [Distribution](#distribution)\n>   - [Common Commands](#common-commands)\n>   - [Notes & Recommendations](#notes--recommendations)\n\n<!-- markdown-toc end -->\n\n## Installation\n\nInstall this via `pip` or your favorite package manager:\n\n```bash\npip install robot-hat\n```\n\n## Usage Examples\n\n### Motor Control\n\nControl dual motors using the `MotorService` modules.\n\n```python\nfrom robot_hat import MotorConfig, MotorService, MotorFabric\n\nleft_motor, right_motor = MotorFabric.create_motor_pair(\n    MotorConfig(\n        dir_pin=\"D4\",\n        pwm_pin=\"P12\",\n        name=\"LeftMotor\",\n    ),\n    MotorConfig(\n        dir_pin=\"D5\",\n        pwm_pin=\"P13\",\n        name=\"RightMotor\",\n    ),\n)\nmotor_service = MotorService(left_motor=left_motor, right_motor=right_motor)\n\n# move forward\nspeed = 40\nmotor_service.move(speed, 1)\n\n# move backward\nmotor_service.move(speed, -1)\n\n# stop\nmotor_service.stop_all()\n\n```\n\n### Controlling a Servo Motor with ServoCalibrationMode\n\nThe `ServoCalibrationMode` is an enum used to define how the calibration offsets are applied to the servo's angle. It supports two predefined modes and also allows for custom calibration functions for advanced use cases.\n\n#### Available Modes\n\n1. **SUM**: Adds a constant offset (`calibration_offset`) to the input angle. This is generally used for steering operations, like managing front wheels in a robotics car.\n   - Formula:\n     \\( \\text{calibrated_angle} = \\text{input_angle} + \\text{calibration_offset} \\)\n2. **NEGATIVE**: Subtracts the constant offset after inverting the input angle. This mode may be helpful for servos that require an inverted adjustment, like a camera tilt mechanism.\n   - Formula:\n     \\( \\text{calibrated_angle} = -1 \\times (\\text{input_angle} + (-1 \\times \\text{calibration_offset})) \\)\n\n#### Configuring the `ServoService`\n\nThe `ServoService` provides a high-level abstraction for managing servo operations. It allows for easy configuration of the calibration mode, constraints for the servo's movement bounds, and custom calibration logic if needed.\n\nHere's how to use `ServoCalibrationMode` in your servo configuration:\n\n##### Example 1: Steering Servo Using `ServoCalibrationMode.SUM`\n\nFor steering purposes (e.g., controlling front wheels of a robotics car):\n\n```python\nfrom robot_hat import ServoCalibrationMode, ServoService\n\nsteering_servo = ServoService(\n    servo_pin=\"P2\",\n    min_angle=-30,  # Maximum left turn\n    max_angle=30,   # Maximum right turn\n    calibration_mode=ServoCalibrationMode.SUM,  # Adds offset directly\n    calibration_offset=-14.4,  # Adjust servo position for centered alignment\n)\n\n# Turn left\nsteering_servo.set_angle(-30)\n\n# Turn slightly right\nsteering_servo.set_angle(15)\n\n# Center position\nsteering_servo.reset()\n```\n\n##### Example 2: Head Servos Using `ServoCalibrationMode.NEGATIVE`\n\nFor tilting a camera head (e.g., up-and-down movement):\n\n```python\nfrom robot_hat import ServoCalibrationMode, ServoService\n\ncam_tilt_servo = ServoService(\n    servo_pin=\"P1\",\n    min_angle=-35,  # Maximum downward tilt\n    max_angle=65,   # Maximum upward tilt\n    calibration_mode=ServoCalibrationMode.NEGATIVE,  # Inverted adjustment\n    calibration_offset=1.4,  # Adjust alignment for neutral center\n)\n\n# Tilt down\ncam_tilt_servo.set_angle(-20)\n\n# Tilt up\ncam_tilt_servo.set_angle(25)\n\n# Center position\ncam_tilt_servo.reset()\n```\n\n---\n\n#### Custom Calibration Mode\n\nIf the predefined modes (`SUM` or `NEGATIVE`) don\u2019t meet your requirements, you can provide a custom calibration function. The function should accept the `angle` and `calibration_offset` as inputs and return the calibrated angle.\n\nExample:\n\n```python\ndef custom_calibration_function(angle: float, offset: float) -> float:\n    # Example: Scale angle by 2 and add offset to fine-tune servo position\n    return (angle * 2) + offset\n\nservo = ServoService(\n    servo_pin=\"P3\",\n    calibration_mode=custom_calibration_function,\n    calibration_offset=5.0,\n    min_angle=-35,\n    max_angle=65,\n)\nservo.set_angle(10)  # Custom logic will process the input angle\n```\n\n### I2C Example\n\nScan and communicate with connected I2C devices.\n\n```python\nfrom robot_hat.i2c import I2C\n\n# Initialize I2C connection\ni2c_device = I2C(address=[0x15, 0x17], bus=1)\n\n# Write a byte to the device\ni2c_device.write(0x01)\n\n# Read data from the device\ndata = i2c_device.read(5)\nprint(\"I2C Data Read:\", data)\n\n# Scan for connected devices\ndevices = i2c_device.scan()\nprint(\"I2C Devices Detected:\", devices)\n```\n\n### Ultrasonic Sensor for Distance Measurement\n\nMeasure distance using the `HC-SR04` ultrasonic sensor module.\n\n```python\nfrom robot_hat.pin import Pin\nfrom robot_hat.ultrasonic import Ultrasonic\n\n# Initialize Ultrasonic Sensor\ntrig_pin = Pin(\"P9\")\necho_pin = Pin(\"P10\")\nultrasonic = Ultrasonic(trig_pin, echo_pin)\n\n# Measure distance\ndistance_cm = ultrasonic.read(times=5)\nprint(f\"Distance: {distance_cm} cm\")\n```\n\n### Reading Battery Voltage\n\nUse the ADC module to measure and scale the battery voltage.\n\n```python\nfrom robot_hat.battery import Battery\n\n# Initialize Battery module\nbattery = Battery(channel=\"A4\")\n\n# Get battery voltage\nvoltage = battery.get_battery_voltage()\nprint(f\"Battery Voltage: {voltage} V\")\n```\n\n## Comparison with Other Libraries\n\n### No sudo\n\nFor reasons that remain a mystery (and a source of endless frustration), the providers of many popular DRY robotics libraries insist on requiring `sudo` for the most basic operations. For example:\n\n```python\nUser = os.popen('echo ${SUDO_USER:-$LOGNAME}').readline().strip()\nUserHome = os.popen('getent passwd %s | cut -d: -f 6' % User).readline().strip()\nconfig_file = '%s/.config/robot-hat/robot-hat.conf' % UserHome\n```\n\nAnd later, they modify file permissions with commands like:\n\n```python\nos.popen('sudo chmod %s %s' % (mode, file_path))  # \ud83e\udd26\nos.popen('sudo chown -R %s:%s %s' % (owner, owner, some_path))\n```\n\nThis library removes all such archaic and potentially unsafe patterns by leveraging user-friendly Python APIs like `pathlib`. File-related operations are scoped to user-accessible directories (e.g., `~/.config`) rather than requiring administrative access\nvia `sudo`.\n\n### Type Hints\n\nThis version prioritizes:\n\n- **Type hints** for better developer experience.\n- Modular, maintainable, and well-documented code.\n\n### Mock Support for Testing\n\n`Sunfounder` (and similar libraries) offer no direct way to mock their hardware APIs, making it nearly impossible to write meaningful unit tests on non-Raspberry Pi platforms.\n\n```python\nimport os\nos.environ[\"GPIOZERO_PIN_FACTORY\"] = \"mock\"\nos.environ[\"PYGAME_HIDE_SUPPORT_PROMPT\"] = \"1\"\n```\n\n---\n\n## Development Environment Setup\n\n### Prerequisites\n\n1. **Python 3.10 or newer** must be installed.\n2. Ensure you have `pip` installed (a recent version is recommended):\n   ```bash\n   python3 -m pip install --upgrade pip\n   ```\n\n### Steps to Set Up\n\n1. **Clone the Repository**:\n\n   ```bash\n   git clone https://github.com/KarimAziev/robot-hat.git\n   cd robot-hat\n   ```\n\n2. **Set Up a Virtual Environment**:\n\n   ```bash\n   python3 -m venv .venv\n   source .venv/bin/activate  # Linux/Mac\n   # OR\n   .venv\\Scripts\\activate     # Windows\n   ```\n\n3. **Upgrade Core Tools**:\n\n   ```bash\n   pip install --upgrade pip setuptools wheel\n   ```\n\n4. **Install in Development Mode**:\n   ```bash\n   pip install -e \".[dev]\"  # Installs all dev dependencies (e.g., black, isort, pre-commit)\n   ```\n\n---\n\n## Distribution\n\nTo create distributable artifacts (e.g., `.tar.gz` and `.whl` files):\n\n1. Install the build tool:\n\n   ```bash\n   pip install build\n   ```\n\n2. Build the project:\n   ```bash\n   python -m build\n   ```\n   The built files will be located in the `dist/` directory:\n\n- Source distribution: `robot_hat-x.y.z.tar.gz`\n- Wheel: `robot_hat-x.y.z-py3-none-any.whl`\n\nThese can be installed locally for testing or uploaded to PyPI for distribution.\n\n---\n\n## Common Commands\n\n- **Clean Build Artifacts**:\n  ```bash\n  rm -rf build dist *.egg-info\n  ```\n- **Deactivate Virtual Environment**:\n  ```bash\n  deactivate\n  ```\n\n---\n\n## Notes & Recommendations\n\n- The library uses `setuptools_scm` for versioning, which dynamically determines the version based on Git tags. Use proper semantic versioning (e.g., `v1.0.0`) in your repository for best results.\n- Development tools like `black` (code formatter) and `isort` (import sorter) are automatically installed with `[dev]` dependencies.\n",
    "bugtrack_url": null,
    "license": "GNU",
    "summary": "Custom version of Robot Hat Python library for Sunfounder's Raspberry Pi robots.",
    "version": "1.7.1",
    "project_urls": null,
    "split_keywords": [
        "i2c",
        " raspberrypi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cd0a9b677808305ca2593f4f648572434a1591b66e41708c4b245a8e73dc5d14",
                "md5": "0f741cf8e6e12dae38487954c1580470",
                "sha256": "6f4d596226520cb8a60c350e11cba6c24133471adde652ea3055e9576c3330fd"
            },
            "downloads": -1,
            "filename": "robot_hat-1.7.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0f741cf8e6e12dae38487954c1580470",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 74907,
            "upload_time": "2025-01-14T09:36:12",
            "upload_time_iso_8601": "2025-01-14T09:36:12.561568Z",
            "url": "https://files.pythonhosted.org/packages/cd/0a/9b677808305ca2593f4f648572434a1591b66e41708c4b245a8e73dc5d14/robot_hat-1.7.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7e39421bfcce2033a2b5503917a15d743890f1e572d0b7a5b82810211c65e9a4",
                "md5": "de9570156ee3123cb77e368c7bd11e45",
                "sha256": "eac778126a8148f66bbeb93809b600dc2f5e5d42eede5176785946f095c7de4d"
            },
            "downloads": -1,
            "filename": "robot_hat-1.7.1.tar.gz",
            "has_sig": false,
            "md5_digest": "de9570156ee3123cb77e368c7bd11e45",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 71055,
            "upload_time": "2025-01-14T09:36:14",
            "upload_time_iso_8601": "2025-01-14T09:36:14.782513Z",
            "url": "https://files.pythonhosted.org/packages/7e/39/421bfcce2033a2b5503917a15d743890f1e572d0b7a5b82810211c65e9a4/robot_hat-1.7.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-14 09:36:14",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "robot-hat"
}
        
Elapsed time: 1.63757s