diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f3cfa5c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: Build + +on: + pull_request: + push: + branches: + - main + +jobs: + test: + name: Python ${{ matrix.python }} + runs-on: ubuntu-latest + strategy: + matrix: + python: ['3.9', '3.10', '3.11'] + + env: + RELEASE_FILE: ${{ github.event.repository.name }}-${{ github.event.release.tag_name || github.sha }}-py${{ matrix.python }} + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python }} + + - name: Install Dependencies + run: | + make dev-deps + + - name: Build Packages + run: | + make build + + - name: Upload Packages + uses: actions/upload-artifact@v3 + with: + name: ${{ env.RELEASE_FILE }} + path: dist/ \ No newline at end of file diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml new file mode 100644 index 0000000..4f17183 --- /dev/null +++ b/.github/workflows/qa.yml @@ -0,0 +1,36 @@ +name: QA + +on: + pull_request: + push: + branches: + - main + +jobs: + test: + name: linting & spelling + runs-on: ubuntu-latest + + env: + TERM: xterm-256color + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Set up Python '3,11' + uses: actions/setup-python@v3 + with: + python-version: '3.11' + + - name: Install Dependencies + run: | + make dev-deps + + - name: Run Quality Assurance + run: | + make qa + + - name: Run Code Checks + run: | + make check \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c0aa4ef..4522974 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Python Tests +name: Tests on: pull_request: @@ -8,30 +8,33 @@ on: jobs: test: + name: Python ${{ matrix.python }} runs-on: ubuntu-latest strategy: matrix: - python: [3.6, 3.7, 3.8, 3.9] + python: ['3.9', '3.10', '3.11'] steps: - - uses: actions/checkout@v2 + - name: Checkout Code + uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python }} + - name: Install Dependencies run: | - python -m pip install --upgrade setuptools tox + make dev-deps + - name: Run Tests - working-directory: library run: | - tox -e py + make pytest + - name: Coverage + if: ${{ matrix.python == '3.9' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - working-directory: library run: | python -m pip install coveralls - coveralls --service=github - if: ${{ matrix.python == '3.9' }} - + coveralls --service=github \ No newline at end of file diff --git a/.stickler.yml b/.stickler.yml index 2466815..67742ae 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -2,4 +2,4 @@ linters: flake8: python: 3 - max-line-length: 160 + max-line-length: 160 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 79decd6..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: python -sudo: false -cache: pip - -git: - submodules: true - -matrix: - include: - - python: "2.7" - env: TOXENV=py27 - - python: "3.5" - env: TOXENV=py35 - -install: - - pip install --ignore-installed --upgrade setuptools pip tox coveralls - -script: - - cd library - - tox -vv - -after_success: if [ "$TOXENV" == "py35" ]; then coveralls; fi - -notifications: - email: false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..17675fd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +0.0.2 +----- + +* Values will now always be float +* Fixed backlight pin +* Fixed latest/average mph + +0.0.1 +----- + +* Initial Release diff --git a/Makefile b/Makefile index 0813324..9e0c15c 100644 --- a/Makefile +++ b/Makefile @@ -1,70 +1,60 @@ -LIBRARY_VERSION=$(shell grep version library/setup.cfg | awk -F" = " '{print $$2}') -LIBRARY_NAME=$(shell grep name library/setup.cfg | awk -F" = " '{print $$2}') +LIBRARY_NAME := $(shell hatch project metadata name 2> /dev/null) +LIBRARY_VERSION := $(shell hatch version 2> /dev/null) -.PHONY: usage install uninstall +.PHONY: usage install uninstall check pytest qa build-deps check tag wheel sdist clean dist testdeploy deploy usage: +ifdef LIBRARY_NAME @echo "Library: ${LIBRARY_NAME}" @echo "Version: ${LIBRARY_VERSION}\n" +else + @echo "WARNING: You should 'make dev-deps'\n" +endif @echo "Usage: make , where target is one of:\n" - @echo "install: install the library locally from source" - @echo "uninstall: uninstall the local library" - @echo "check: peform basic integrity checks on the codebase" - @echo "python-readme: generate library/README.md from README.md + library/CHANGELOG.txt" - @echo "python-wheels: build python .whl files for distribution" - @echo "python-sdist: build python source distribution" - @echo "python-clean: clean python build and dist directories" - @echo "python-dist: build all python distribution files" - @echo "python-testdeploy: build all and deploy to test PyPi" - @echo "tag: tag the repository with the current version" + @echo "install: install the library locally from source" + @echo "uninstall: uninstall the local library" + @echo "dev-deps: install Python dev dependencies" + @echo "check: perform basic integrity checks on the codebase" + @echo "qa: run linting and package QA" + @echo "pytest: run Python test fixtures" + @echo "clean: clean Python build and dist directories" + @echo "build: build Python distribution files" + @echo "testdeploy: build and upload to test PyPi" + @echo "deploy: build and upload to PyPi" + @echo "tag: tag the repository with the current version\n" install: - ./install.sh + ./install.sh --unstable uninstall: ./uninstall.sh -check: - @echo "Checking for trailing whitespace" - @! grep -IUrn --color "[[:blank:]]$$" --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO - @echo "Checking for DOS line-endings" - @! grep -lIUrn --color " " --exclude-dir=sphinx --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile - @echo "Checking library/CHANGELOG.txt" - @cat library/CHANGELOG.txt | grep ^${LIBRARY_VERSION} - @echo "Checking library/${LIBRARY_NAME}/__init__.py" - @cat library/${LIBRARY_NAME}/__init__.py | grep "^__version__ = '${LIBRARY_VERSION}'" - -tag: - git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}" +dev-deps: + python3 -m pip install -r requirements-dev.txt + sudo apt install dos2unix -python-readme: library/README.md - -python-license: library/LICENSE.txt +check: + @bash check.sh -library/README.md: README.md library/CHANGELOG.txt - cp README.md library/README.md - printf "\n# Changelog\n" >> library/README.md - cat library/CHANGELOG.txt >> library/README.md +qa: + tox -e qa -library/LICENSE.txt: LICENSE - cp LICENSE library/LICENSE.txt +pytest: + tox -e py -python-wheels: python-readme python-license - cd library; python3 setup.py bdist_wheel - cd library; python setup.py bdist_wheel +nopost: + @bash check.sh --nopost -python-sdist: python-readme python-license - cd library; python setup.py sdist +tag: + git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}" -python-clean: - -rm -r library/dist - -rm -r library/build - -rm -r library/*.egg-info +build: check + @hatch build -python-dist: python-clean python-wheels python-sdist - ls library/dist +clean: + -rm -r dist -python-testdeploy: python-dist - twine upload --repository-url https://test.pypi.org/legacy/ library/dist/* +testdeploy: build + twine upload --repository testpypi dist/* -python-deploy: check python-dist - twine upload library/dist/* +deploy: nopost build + twine upload dist/* diff --git a/README.md b/README.md index 39e3661..c1ebbc5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Weather HAT Python Library & Examples -[![Build Status](https://shields.io/github/workflow/status/pimoroni/weatherhat-python/Python%20Tests.svg)](https://github.com/pimoroni/weatherhat-python/actions/workflows/test.yml) +[![Build Status](https://img.shields.io/github/actions/workflow/status/pimoroni/weatherhat-python/test.yml?branch=main)](https://github.com/pimoroni/weatherhat-python/actions/workflows/test.yml) [![Coverage Status](https://coveralls.io/repos/github/pimoroni/weatherhat-python/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/weatherhat-python?branch=master) [![PyPi Package](https://img.shields.io/pypi/v/weatherhat.svg)](https://pypi.python.org/pypi/weatherhat) [![Python Versions](https://img.shields.io/pypi/pyversions/weatherhat.svg)](https://pypi.python.org/pypi/weatherhat) @@ -28,7 +28,7 @@ Latest/development library from GitHub: * `git clone https://github.com/pimoroni/weatherhat-python` * `cd weatherhat-python` -* `sudo ./install.sh` +* `./install.sh --unstable` Some of the examples use additional libraries. You can install them with: diff --git a/check.sh b/check.sh new file mode 100644 index 0000000..4ca0d17 --- /dev/null +++ b/check.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# This script handles some basic QA checks on the source + +NOPOST=$1 +LIBRARY_NAME=`hatch project metadata name` +LIBRARY_VERSION=`hatch version | awk -F "." '{print $1"."$2"."$3}'` +POST_VERSION=`hatch version | awk -F "." '{print substr($4,0,length($4))}'` + +success() { + echo -e "$(tput setaf 2)$1$(tput sgr0)" +} + +inform() { + echo -e "$(tput setaf 6)$1$(tput sgr0)" +} + +warning() { + echo -e "$(tput setaf 1)$1$(tput sgr0)" +} + +while [[ $# -gt 0 ]]; do + K="$1" + case $K in + -p|--nopost) + NOPOST=true + shift + ;; + *) + if [[ $1 == -* ]]; then + printf "Unrecognised option: $1\n"; + exit 1 + fi + POSITIONAL_ARGS+=("$1") + shift + esac +done + +inform "Checking $LIBRARY_NAME $LIBRARY_VERSION\n" + +inform "Checking for trailing whitespace..." +grep -IUrn --color "[[:blank:]]$" --exclude-dir=dist --exclude-dir=.tox --exclude-dir=.git --exclude=PKG-INFO +if [[ $? -eq 0 ]]; then + warning "Trailing whitespace found!" + exit 1 +else + success "No trailing whitespace found." +fi +printf "\n" + +inform "Checking for DOS line-endings..." +grep -lIUrn --color $'\r' --exclude-dir=dist --exclude-dir=.tox --exclude-dir=.git --exclude=Makefile +if [[ $? -eq 0 ]]; then + warning "DOS line-endings found!" + exit 1 +else + success "No DOS line-endings found." +fi +printf "\n" + +inform "Checking CHANGELOG.md..." +cat CHANGELOG.md | grep ^${LIBRARY_VERSION} > /dev/null 2>&1 +if [[ $? -eq 1 ]]; then + warning "Changes missing for version ${LIBRARY_VERSION}! Please update CHANGELOG.md." + exit 1 +else + success "Changes found for version ${LIBRARY_VERSION}." +fi +printf "\n" + +inform "Checking for git tag ${LIBRARY_VERSION}..." +git tag -l | grep -E "${LIBRARY_VERSION}$" +if [[ $? -eq 1 ]]; then + warning "Missing git tag for version ${LIBRARY_VERSION}" +fi +printf "\n" + +if [[ $NOPOST ]]; then + inform "Checking for .postN on library version..." + if [[ "$POST_VERSION" != "" ]]; then + warning "Found .$POST_VERSION on library version." + inform "Please only use these for testpypi releases." + exit 1 + else + success "OK" + fi +fi \ No newline at end of file diff --git a/examples/BME280-compensated.py b/examples/BME280-compensated.py index 3a13662..a7b4769 100644 --- a/examples/BME280-compensated.py +++ b/examples/BME280-compensated.py @@ -1,7 +1,8 @@ import time + import weatherhat -print(f""" +print(""" BME280-compensated.py - Print compensated readings from the BME280 weather sensor. Press Ctrl+C to exit! """) diff --git a/examples/BME280.py b/examples/BME280.py index f6264a5..e29e4e2 100644 --- a/examples/BME280.py +++ b/examples/BME280.py @@ -1,7 +1,8 @@ import time + import weatherhat -print(f""" +print(""" BME280.py - Print raw readings from the BME280 weather sensor. Press Ctrl+C to exit! """) diff --git a/examples/adafruit-io.py b/examples/adafruit-io.py index 7ce2420..5e6bc4b 100644 --- a/examples/adafruit-io.py +++ b/examples/adafruit-io.py @@ -1,10 +1,12 @@ from time import sleep + +from Adafruit_IO import Client, Dashboard, Feed, RequestError + import weatherhat -from Adafruit_IO import Client, Feed, Dashboard, RequestError sensor = weatherhat.WeatherHAT() -print(f""" +print(""" adafruit-io.py - Example showing how to send sensor data from Weather HAT into adafruit.io. Sign up for an account at https://io.adafruit.com/ to obtain a username and key. Press Ctrl+C to exit! diff --git a/examples/averaging.py b/examples/averaging.py index 9bda46e..7f3462a 100644 --- a/examples/averaging.py +++ b/examples/averaging.py @@ -3,7 +3,7 @@ import weatherhat from weatherhat import history -print(f""" +print(""" averaging.py - Basic example showing how to use Weather HAT's history/averaging functions. Press Ctrl+C to exit! """) diff --git a/examples/basic.py b/examples/basic.py index f78c093..ef097aa 100644 --- a/examples/basic.py +++ b/examples/basic.py @@ -4,7 +4,7 @@ sensor = weatherhat.WeatherHAT() -print(f""" +print(""" basic.py - Basic example showing how to read Weather HAT's sensors. Press Ctrl+C to exit! """) diff --git a/examples/buttons.py b/examples/buttons.py index b6001cc..732ed8a 100644 --- a/examples/buttons.py +++ b/examples/buttons.py @@ -1,4 +1,5 @@ import signal + import RPi.GPIO as GPIO print("""buttons.py - Detect which button has been pressed diff --git a/examples/lcd.py b/examples/lcd.py index 29d827d..fffe60c 100644 --- a/examples/lcd.py +++ b/examples/lcd.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 import ST7789 -from PIL import Image, ImageDraw, ImageFont from fonts.ttf import ManropeBold as UserFont +from PIL import Image, ImageDraw, ImageFont -print(f""" +print(""" lcd.py - Hello, World! example on the 1.54" LCD. Press Ctrl+C to exit! """) diff --git a/examples/weather.py b/examples/weather.py index ce4f3d5..e11e37b 100644 --- a/examples/weather.py +++ b/examples/weather.py @@ -3,17 +3,15 @@ import pathlib import time -import yaml - import RPi.GPIO as GPIO import ST7789 +import yaml from fonts.ttf import ManropeBold as UserFont from PIL import Image, ImageDraw, ImageFont import weatherhat from weatherhat import history - FPS = 10 BUTTONS = [5, 6, 16, 24] diff --git a/install-bullseye.sh b/install-bullseye.sh deleted file mode 100755 index 76743a9..0000000 --- a/install-bullseye.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/bash -CONFIG=/boot/config.txt -DATESTAMP=`date "+%Y-%m-%d-%H-%M-%S"` -CONFIG_BACKUP=false -APT_HAS_UPDATED=false -USER_HOME=/home/$SUDO_USER -RESOURCES_TOP_DIR=$USER_HOME/Pimoroni -WD=`pwd` -USAGE="sudo ./install.sh (--unstable)" -POSITIONAL_ARGS=() -UNSTABLE=false -PYTHON="/usr/bin/python3" -CODENAME=`lsb_release -sc` - -distro_check() { - if [[ $CODENAME != "bullseye" ]]; then - printf "This installer is for Raspberry Pi OS: Bullseye only, current distro: $CODENAME\n" - exit 1 - fi -} - -user_check() { - if [ $(id -u) -ne 0 ]; then - printf "Script must be run as root. Try 'sudo ./install.sh'\n" - exit 1 - fi -} - -confirm() { - if [ "$FORCE" == '-y' ]; then - true - else - read -r -p "$1 [y/N] " response < /dev/tty - if [[ $response =~ ^(yes|y|Y)$ ]]; then - true - else - false - fi - fi -} - -prompt() { - read -r -p "$1 [y/N] " response < /dev/tty - if [[ $response =~ ^(yes|y|Y)$ ]]; then - true - else - false - fi -} - -success() { - echo -e "$(tput setaf 2)$1$(tput sgr0)" -} - -inform() { - echo -e "$(tput setaf 6)$1$(tput sgr0)" -} - -warning() { - echo -e "$(tput setaf 1)$1$(tput sgr0)" -} - -function do_config_backup { - if [ ! $CONFIG_BACKUP == true ]; then - CONFIG_BACKUP=true - FILENAME="config.preinstall-$LIBRARY_NAME-$DATESTAMP.txt" - inform "Backing up $CONFIG to /boot/$FILENAME\n" - cp $CONFIG /boot/$FILENAME - mkdir -p $RESOURCES_TOP_DIR/config-backups/ - cp $CONFIG $RESOURCES_TOP_DIR/config-backups/$FILENAME - if [ -f "$UNINSTALLER" ]; then - echo "cp $RESOURCES_TOP_DIR/config-backups/$FILENAME $CONFIG" >> $UNINSTALLER - fi - fi -} - -function apt_pkg_install { - PACKAGES=() - PACKAGES_IN=("$@") - for ((i = 0; i < ${#PACKAGES_IN[@]}; i++)); do - PACKAGE="${PACKAGES_IN[$i]}" - if [ "$PACKAGE" == "" ]; then continue; fi - printf "Checking for $PACKAGE\n" - dpkg -L $PACKAGE > /dev/null 2>&1 - if [ "$?" == "1" ]; then - PACKAGES+=("$PACKAGE") - fi - done - PACKAGES="${PACKAGES[@]}" - if ! [ "$PACKAGES" == "" ]; then - echo "Installing missing packages: $PACKAGES" - if [ ! $APT_HAS_UPDATED ]; then - apt update - APT_HAS_UPDATED=true - fi - apt install -y $PACKAGES - if [ -f "$UNINSTALLER" ]; then - echo "apt uninstall -y $PACKAGES" - fi - fi -} - -while [[ $# -gt 0 ]]; do - K="$1" - case $K in - -u|--unstable) - UNSTABLE=true - shift - ;; - -p|--python) - PYTHON=$2 - shift - shift - ;; - *) - if [[ $1 == -* ]]; then - printf "Unrecognised option: $1\n"; - printf "Usage: $USAGE\n"; - exit 1 - fi - POSITIONAL_ARGS+=("$1") - shift - esac -done - -distro_check -user_check - -if [ ! -f "$PYTHON" ]; then - printf "Python path $PYTHON not found!\n" - exit 1 -fi - -PYTHON_VER=`$PYTHON --version` - -inform "Installing. Please wait..." - -$PYTHON -m pip install --upgrade configparser - -CONFIG_VARS=`$PYTHON - < $UNINSTALLER -printf "It's recommended you run these steps manually.\n" -printf "If you want to run the full script, open it in\n" -printf "an editor and remove 'exit 1' from below.\n" -exit 1 -EOF - -printf "$LIBRARY_NAME $LIBRARY_VERSION Python Library: Installer\n\n" - -if $UNSTABLE; then - warning "Installing unstable library from source.\n\n" -else - printf "Installing stable library from pypi.\n\n" -fi - -cd library - -printf "Installing for $PYTHON_VER...\n" -apt_pkg_install "${PY3_DEPS[@]}" -if $UNSTABLE; then - $PYTHON setup.py install > /dev/null -else - $PYTHON -m pip install --upgrade $LIBRARY_NAME -fi -if [ $? -eq 0 ]; then - success "Done!\n" - echo "$PYTHON -m pip uninstall $LIBRARY_NAME" >> $UNINSTALLER -fi - -cd $WD - -for ((i = 0; i < ${#SETUP_CMDS[@]}; i++)); do - CMD="${SETUP_CMDS[$i]}" - # Attempt to catch anything that touches /boot/config.txt and trigger a backup - if [[ "$CMD" == *"raspi-config"* ]] || [[ "$CMD" == *"$CONFIG"* ]] || [[ "$CMD" == *"\$CONFIG"* ]]; then - do_config_backup - fi - eval $CMD -done - -for ((i = 0; i < ${#CONFIG_TXT[@]}; i++)); do - CONFIG_LINE="${CONFIG_TXT[$i]}" - if ! [ "$CONFIG_LINE" == "" ]; then - do_config_backup - inform "Adding $CONFIG_LINE to $CONFIG\n" - sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG - if ! grep -q "^$CONFIG_LINE" $CONFIG; then - printf "$CONFIG_LINE\n" >> $CONFIG - fi - fi -done - -if [ -d "examples" ]; then - if confirm "Would you like to copy examples to $RESOURCES_DIR?"; then - inform "Copying examples to $RESOURCES_DIR" - cp -r examples/ $RESOURCES_DIR - echo "rm -r $RESOURCES_DIR" >> $UNINSTALLER - success "Done!" - fi -fi - -printf "\n" - -if [ -f "/usr/bin/pydoc" ]; then - printf "Generating documentation.\n" - pydoc -w $LIBRARY_NAME > /dev/null - if [ -f "$LIBRARY_NAME.html" ]; then - cp $LIBRARY_NAME.html $RESOURCES_DIR/docs.html - rm -f $LIBRARY_NAME.html - inform "Documentation saved to $RESOURCES_DIR/docs.html" - success "Done!" - else - warning "Error: Failed to generate documentation." - fi -fi - -success "\nAll done!" -inform "If this is your first time installing you should reboot for hardware changes to take effect.\n" -inform "Find uninstall steps in $UNINSTALLER\n" diff --git a/install.sh b/install.sh index 5e61ac7..b45e7c8 100755 --- a/install.sh +++ b/install.sh @@ -1,31 +1,27 @@ #!/bin/bash - +LIBRARY_NAME=`grep -m 1 name pyproject.toml | awk -F" = " '{print substr($2,2,length($2)-2)}'` CONFIG=/boot/config.txt DATESTAMP=`date "+%Y-%m-%d-%H-%M-%S"` CONFIG_BACKUP=false APT_HAS_UPDATED=false -USER_HOME=/home/$SUDO_USER -RESOURCES_TOP_DIR=$USER_HOME/Pimoroni +RESOURCES_TOP_DIR=$HOME/Pimoroni WD=`pwd` -USAGE="sudo ./install.sh (--unstable)" +USAGE="./install.sh (--unstable)" POSITIONAL_ARGS=() +FORCE=false UNSTABLE=false -CODENAME=`lsb_release -sc` +PYTHON="/usr/bin/python3" -if [[ $CODENAME == "bullseye" ]]; then - bash ./install-bullseye.sh $@ - exit $? -fi user_check() { - if [ $(id -u) -ne 0 ]; then - printf "Script must be run as root. Try 'sudo ./install.sh'\n" + if [ $(id -u) -eq 0 ]; then + printf "Script should not be run as root. Try './install.sh'\n" exit 1 fi } confirm() { - if [ "$FORCE" == '-y' ]; then + if $FORCE; then true else read -r -p "$1 [y/N] " response < /dev/tty @@ -63,7 +59,7 @@ function do_config_backup { CONFIG_BACKUP=true FILENAME="config.preinstall-$LIBRARY_NAME-$DATESTAMP.txt" inform "Backing up $CONFIG to /boot/$FILENAME\n" - cp $CONFIG /boot/$FILENAME + sudo cp $CONFIG /boot/$FILENAME mkdir -p $RESOURCES_TOP_DIR/config-backups/ cp $CONFIG $RESOURCES_TOP_DIR/config-backups/$FILENAME if [ -f "$UNINSTALLER" ]; then @@ -88,16 +84,20 @@ function apt_pkg_install { if ! [ "$PACKAGES" == "" ]; then echo "Installing missing packages: $PACKAGES" if [ ! $APT_HAS_UPDATED ]; then - apt update + sudo apt update APT_HAS_UPDATED=true fi - apt install -y $PACKAGES + sudo apt install -y $PACKAGES if [ -f "$UNINSTALLER" ]; then - echo "apt uninstall -y $PACKAGES" + echo "apt uninstall -y $PACKAGES" >> $UNINSTALLER fi fi } +function pip_pkg_install { + PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring $PYTHON -m pip install --upgrade "$@" +} + while [[ $# -gt 0 ]]; do K="$1" case $K in @@ -105,6 +105,15 @@ while [[ $# -gt 0 ]]; do UNSTABLE=true shift ;; + -f|--force) + FORCE=true + shift + ;; + -p|--python) + PYTHON=$2 + shift + shift + ;; *) if [[ $1 == -* ]]; then printf "Unrecognised option: $1\n"; @@ -118,27 +127,29 @@ done user_check -apt_pkg_install python-configparser - -CONFIG_VARS=`python - < $UNINSTALLER @@ -163,40 +181,22 @@ printf "an editor and remove 'exit 1' from below.\n" exit 1 EOF -printf "$LIBRARY_NAME $LIBRARY_VERSION Python Library: Installer\n\n" - if $UNSTABLE; then warning "Installing unstable library from source.\n\n" else printf "Installing stable library from pypi.\n\n" fi -cd library - -printf "Installing for Python 2..\n" -apt_pkg_install "${PY2_DEPS[@]}" +inform "Installing for $PYTHON_VER...\n" +apt_pkg_install "${APT_PACKAGES[@]}" if $UNSTABLE; then - python setup.py install > /dev/null + pip_pkg_install . else - pip install --upgrade $LIBRARY_NAME + pip_pkg_install $LIBRARY_NAME fi if [ $? -eq 0 ]; then success "Done!\n" - echo "pip uninstall $LIBRARY_NAME" >> $UNINSTALLER -fi - -if [ -f "/usr/bin/python3" ]; then - printf "Installing for Python 3..\n" - apt_pkg_install "${PY3_DEPS[@]}" - if $UNSTABLE; then - python3 setup.py install > /dev/null - else - pip3 install --upgrade $LIBRARY_NAME - fi - if [ $? -eq 0 ]; then - success "Done!\n" - echo "pip3 uninstall $LIBRARY_NAME" >> $UNINSTALLER - fi + echo "$PYTHON -m pip uninstall $LIBRARY_NAME" >> $UNINSTALLER fi cd $WD @@ -215,9 +215,9 @@ for ((i = 0; i < ${#CONFIG_TXT[@]}; i++)); do if ! [ "$CONFIG_LINE" == "" ]; then do_config_backup inform "Adding $CONFIG_LINE to $CONFIG\n" - sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG + sudo sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG if ! grep -q "^$CONFIG_LINE" $CONFIG; then - printf "$CONFIG_LINE\n" >> $CONFIG + printf "$CONFIG_LINE\n" | sudo tee --append $CONFIG fi fi done @@ -233,13 +233,12 @@ fi printf "\n" -if [ -f "/usr/bin/pydoc" ]; then +if confirm "Would you like to generate documentation?"; then + pip_pkg_install pdoc printf "Generating documentation.\n" - pydoc -w $LIBRARY_NAME > /dev/null - if [ -f "$LIBRARY_NAME.html" ]; then - cp $LIBRARY_NAME.html $RESOURCES_DIR/docs.html - rm -f $LIBRARY_NAME.html - inform "Documentation saved to $RESOURCES_DIR/docs.html" + $PYTHON -m pdoc $LIBRARY_NAME -o $RESOURCES_DIR/docs > /dev/null + if [ $? -eq 0 ]; then + inform "Documentation saved to $RESOURCES_DIR/docs" success "Done!" else warning "Error: Failed to generate documentation." diff --git a/library/.coveragerc b/library/.coveragerc deleted file mode 100644 index 1235645..0000000 --- a/library/.coveragerc +++ /dev/null @@ -1,4 +0,0 @@ -[run] -source = weatherhat -omit = - .tox/* diff --git a/library/CHANGELOG.txt b/library/CHANGELOG.txt deleted file mode 100644 index 0f98d12..0000000 --- a/library/CHANGELOG.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0.1 ------ - -* Initial Release diff --git a/library/LICENSE.txt b/library/LICENSE.txt deleted file mode 100644 index aed751a..0000000 --- a/library/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Pimoroni Ltd. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/library/MANIFEST.in b/library/MANIFEST.in deleted file mode 100644 index 07a8018..0000000 --- a/library/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include CHANGELOG.txt -include LICENSE.txt -include README.md -include setup.py -recursive-include weatherhat *.py diff --git a/library/README.md b/library/README.md deleted file mode 100644 index 00e0db5..0000000 --- a/library/README.md +++ /dev/null @@ -1,217 +0,0 @@ -# Weather HAT Python Library & Examples - -[![Build Status](https://shields.io/github/workflow/status/pimoroni/weatherhat-python/Python%20Tests.svg)](https://github.com/pimoroni/weatherhat-python/actions/workflows/test.yml) -[![Coverage Status](https://coveralls.io/repos/github/pimoroni/weatherhat-python/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/weatherhat-python?branch=master) -[![PyPi Package](https://img.shields.io/pypi/v/weatherhat.svg)](https://pypi.python.org/pypi/weatherhat) -[![Python Versions](https://img.shields.io/pypi/pyversions/weatherhat.svg)](https://pypi.python.org/pypi/weatherhat) - -# Pre-requisites - -You must enable: - -* i2c: `sudo raspi-config nonint do_i2c 0` -* spi: `sudo raspi-config nonint do_spi 0` - -You can optionally run `sudo raspi-config` or the graphical Raspberry Pi Configuration UI to enable interfaces. - -# Installing - -Stable library from PyPi: - -* Just run `pip3 install weatherhat` - -In some cases you may need to use `sudo` or install pip with: `sudo apt install python3-pip` - -Latest/development library from GitHub: - -* `git clone https://github.com/pimoroni/weatherhat-python` -* `cd weatherhat-python` -* `sudo ./install.sh` - -Some of the examples use additional libraries. You can install them with: - -```bash -pip3 install fonts font-manrope pyyaml adafruit-io -``` - -# Using The Library - -Import the `weatherhat` module and create an instance of the `WeatherHAT` class. - -```python -import weatherhat - -sensor = weatherhat.WeatherHAT() -``` - -Weather HAT updates the sensors when you call `update(interval=5)`. - -Temperature, pressure, humidity, light and wind direction are updated continuously. - -Rain and Wind measurements are measured over an `interval` period. Weather HAT will count ticks of the rain gauge and (half) rotations of the anemometer, calculate rain/wind every `interval` seconds and reset the counts for the next pass. - -For example the following code will update rain/wind speed every 5 seconds, and all other readings will be updated on demand: - -```python -import time -import weatherhat - -sensor = weatherhat.WeatherHAT() - -while True: - sensor.update(interval=5.0) - time.sleep(1.0) -``` - -# Averaging Readings - -The Weather HAT library supplies set of "history" classes intended to save readings over a period of time and provide access to things like minimum, maximum and average values with unit conversions. - -For example `WindSpeedHistory` allows you to store wind readings and retrieve them in mp/h or km/h, in addition to determining the "gust" (maximum wind speed) in a given period of time: - -```python -import time -import weatherhat -from weatherhat.history import WindSpeedHistory - -sensor = weatherhat.WeatherHAT() -wind_speed_history = WindSpeedHistory() - -while True: - sensor.update(interval=5.0) - if sensor.updated_wind_rain: - wind_speed_history.append(sensor.wind_speed) - print(f"Average wind speed: {wind_speed_history.average_mph()}mph") - print(f"Wind gust: {wind_speed_history.gust_mph()}mph") - time.sleep(1.0) -``` - -# Quick Reference - -## Temperature - -Temperature readings are given as degrees celsius and are measured from the Weather HAT's onboard BME280. - -### Device Temperature - -```python -sensor.device_temperature -``` - -Device temperature in degrees celsius. - -This is the temperature read directly from the BME280 onboard Weather HAT. It's not compensated and tends to read slightly higher than ambient due to heat from the Pi. - -### Compensated (Air) Temperature - -```python -sensor.temperature -``` - -Temperature in degrees celsius. - -This is the temperature once an offset has been applied. This offset is fixed, and taken from `sensor.temperature_offset`. - -## Pressure - -```python -sensor.pressure -``` - -Pressure in hectopascals. - -## Humidity - -```python -sensor.humidity -``` - -Humidity in %. - -### Relative Humidity - -```python -sensor.relative_humidity -``` - -Relative humidity in %. - -Relative humidity is the water content of the air compensated for temperature, since warmer air can hold more water. - -It's expressed as a percentage from 0 (no moisture) to 100 (fully saturated). - -### Dew Point - -```python -sensor.dewpoint -``` - -Dew point in degrees celsius. - -Dew point is the temperature at which water - at the current humidity - will condense out of the air. - -## Light / Lux - -```python -sensor.lux -``` - -Light is given in lux. - -Lux ranges from 0 (complete darkness) to. - -## Wind - -Both wind and rain are updated on an interval, rather than on-demand. - -To see if an `update()` call has resulted in new wind/rain measurements, check: - -```python -sensor.updated_wind_rain -``` - -### Wind Direction - -```python -sensor.wind_direction -``` - -Wind direction in degrees. - -Wind direction is measured using a potentiometer and uses an analog reading internally. This is converted to degrees for convenience, and will snap to the nearest 45-degree increment with 0 degrees indicating North. - -### Wind Speed - -```python -sensor.wind_speed -``` - -Wind speed in meters per second. - -Weather HAT counts every half rotation and converts this to cm/s using the anemometer circumference and factor. - -It's updated depending on the update interval requested. - -## Rain - -```python -sensor.rain -``` - -Rain amount in millimeters per second. - -Weather HAT counts every "tick" of the rain gauge (roughly .28mm) over the given update internal and converts this into mm/sec. - -### Total Rain - -```python -sensor.rain_total -``` - -Total rain amount in millimeters for the current update period. - -# Changelog -0.0.1 ------ - -* Initial Release diff --git a/library/pyproject.toml b/library/pyproject.toml deleted file mode 100644 index 2f21011..0000000 --- a/library/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build-system] -requires = ["setuptools>=40.8.0", "wheel"] -build-backend = "setuptools.build_meta" diff --git a/library/setup.cfg b/library/setup.cfg deleted file mode 100644 index 6f5c67d..0000000 --- a/library/setup.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -[metadata] -name = weatherhat -version = 0.0.1 -author = Philip Howard -author_email = phil@pimoroni.com -description = Library for Weather HAT -long_description = file: README.md -long_description_content_type = text/markdown -keywords = Raspberry Pi -url = https://www.pimoroni.com -project_urls = - GitHub=https://www.github.com/pimoroni/weatherhat-python -license = MIT -# This includes the license file(s) in the wheel. -# https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file -license_files = LICENSE.txt -classifiers = - Development Status :: 4 - Beta - Operating System :: POSIX :: Linux - License :: OSI Approved :: MIT License - Intended Audience :: Developers - Programming Language :: Python :: 3 - Topic :: Software Development - Topic :: Software Development :: Libraries - Topic :: System :: Hardware - -[options] -python_requires = >= 3.6 -packages = weatherhat -install_requires = - pimoroni-bme280 - ltr559 - pimoroni-ioexpander - st7789 - -[flake8] -exclude = - .tox, - .eggs, - .git, - __pycache__, - build, - dist -ignore = - E501 - -[pimoroni] -py2deps = -py3deps = - python3 - python3-pip - python3-smbus - python3-pil -configtxt = -commands = - printf "Setting up i2c and SPI..\n" - raspi-config nonint do_spi 0 - raspi-config nonint do_i2c 0 diff --git a/library/setup.py b/library/setup.py deleted file mode 100755 index afb1ee1..0000000 --- a/library/setup.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Copyright (c) 2016 Pimoroni - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -""" - -from setuptools import setup, __version__ -from pkg_resources import parse_version - -minimum_version = parse_version('30.4.0') - -if parse_version(__version__) < minimum_version: - raise RuntimeError("Package setuptools must be at least version {}".format(minimum_version)) - -setup() diff --git a/library/tox.ini b/library/tox.ini deleted file mode 100644 index bdcc0e5..0000000 --- a/library/tox.ini +++ /dev/null @@ -1,24 +0,0 @@ -[tox] -envlist = py{36,37,38,39},qa -skip_missing_interpreters = True - -[testenv] -commands = - python setup.py install - coverage run -m py.test -v -r wsx - coverage report -deps = - mock - pytest>=3.1 - pytest-cov - -[testenv:qa] -commands = - check-manifest --ignore tox.ini,tests/*,.coveragerc - python setup.py sdist bdist_wheel - twine check dist/* - flake8 --ignore E501 -deps = - check-manifest - flake8 - twine diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6318fff --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,126 @@ +[build-system] +requires = ["hatchling", "hatch-fancy-pypi-readme"] +build-backend = "hatchling.build" + +[project] +name = "weatherhat" +dynamic = ["version", "readme"] +description = "Library for the Pimoroni Weather HAT" +license = {file = "LICENSE"} +requires-python = ">= 3.7" +authors = [ + { name = "Philip Howard", email = "phil@pimoroni.com" }, +] +maintainers = [ + { name = "Philip Howard", email = "phil@pimoroni.com" }, +] +keywords = [ + "Pi", + "Raspberry", +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development", + "Topic :: Software Development :: Libraries", + "Topic :: System :: Hardware", +] +dependencies = [ + "pimoroni-bme280", + "ltr559", + "pimoroni-ioexpander", + "st7789", + "smbus2" +] + +[project.urls] +GitHub = "https://www.github.com/pimoroni/weatherhat-python" +Homepage = "https://www.pimoroni.com" + +[tool.hatch.version] +path = "weatherhat/__init__.py" + +[tool.hatch.build] +include = [ + "weatherhat/*.py", + "README.md", + "CHANGELOG.md", + "LICENSE" +] + +[tool.hatch.build.targets.sdist] +include = [ + "*" +] +exclude = [ + ".*", + "dist" +] + +[tool.hatch.metadata.hooks.fancy-pypi-readme] +content-type = "text/markdown" +fragments = [ + { path = "README.md" }, + { text = "\n" }, + { path = "CHANGELOG.md" } +] + +[tool.ruff] +exclude = [ + '.tox', + '.egg', + '.git', + '__pycache__', + 'build', + 'dist' +] +line-length = 200 + +[tool.codespell] +skip = """ +./.tox,\ +./.egg,\ +./.git,\ +./__pycache__,\ +./build,\ +./dist.\ +""" +ignore-words-list = """ +pres,\ +""" + +[tool.isort] +line_length = 200 + +[tool.check-manifest] +ignore = [ + '.stickler.yml', + 'boilerplate.md', + 'check.sh', + 'install.sh', + 'uninstall.sh', + 'Makefile', + 'tox.ini', + 'tests/*', + 'examples/*', + '.coveragerc', + 'requirements-dev.txt' +] + +[pimoroni] +apt_packages = [] +configtxt = [] +commands = [ + "printf \"Setting up i2c and SPI..\n\"", + "raspi-config nonint do_spi 0", + "raspi-config nonint do_i2c 0" +] \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..525b042 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,9 @@ +check-manifest +ruff +codespell +isort +twine +hatch +hatch-fancy-pypi-readme +tox +pdoc diff --git a/testing/ST7789/__init__.py b/testing/ST7789/__init__.py index d89b755..7a0f7bb 100644 --- a/testing/ST7789/__init__.py +++ b/testing/ST7789/__init__.py @@ -1,8 +1,9 @@ +import pathlib +import sys import tkinter + from PIL import ImageTk -import pathlib -import sys modpath = pathlib.Path("../").resolve() sys.path.insert(0, str(modpath)) import RPi.GPIO as GPIO # noqa: E402 diff --git a/testing/weatherhat/__init__.py b/testing/weatherhat/__init__.py index b65291d..dce6936 100644 --- a/testing/weatherhat/__init__.py +++ b/testing/weatherhat/__init__.py @@ -1,11 +1,10 @@ -import time -import threading import math import random +import threading +import time from .history import wind_degrees_to_cardinal - __version__ = '0.0.1' diff --git a/testing/weatherhat/history.py b/testing/weatherhat/history.py index b5981b8..108b9b8 120000 --- a/testing/weatherhat/history.py +++ b/testing/weatherhat/history.py @@ -1 +1 @@ -../../library/weatherhat/history.py \ No newline at end of file +../../weatherhat/history.py \ No newline at end of file diff --git a/library/tests/conftest.py b/tests/conftest.py similarity index 99% rename from library/tests/conftest.py rename to tests/conftest.py index 47ba943..3d2d93c 100644 --- a/library/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,7 @@ import sys -import pytest + import mock +import pytest @pytest.fixture(scope='function', autouse=True) diff --git a/library/tests/test_setup.py b/tests/test_setup.py similarity index 84% rename from library/tests/test_setup.py rename to tests/test_setup.py index 8c38000..68c7928 100644 --- a/library/tests/test_setup.py +++ b/tests/test_setup.py @@ -4,9 +4,9 @@ def test_setup(gpio, ioe, bme280, ltr559, smbus2): bus = smbus2.SMBus(1) - bme280.BME280.called_once_with(i2c_dev=bus) - ltr559.LTR559.called_once_with(i2c_dev=bus) - ioe.IOE.called_once_with(i2c_addr=0x12, interrupt_pin=4) + bme280.BME280.assert_called_once_with(i2c_dev=bus) + ltr559.LTR559.assert_called_once_with(i2c_dev=bus) + ioe.IOE.assert_called_once_with(i2c_addr=0x12, interrupt_pin=4) del library diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..a088862 --- /dev/null +++ b/tox.ini @@ -0,0 +1,33 @@ +[tox] +envlist = py,qa +skip_missing_interpreters = True +isolated_build = true +minversion = 4.0.0 + +[testenv] +commands = + coverage run -m pytest -v -r wsx + coverage report +deps = + mock + pytest>=3.1 + pytest-cov + build + +[testenv:qa] +commands = + check-manifest + python -m build --no-isolation + python -m twine check dist/* + isort --check . + ruff --format=github . + codespell . +deps = + check-manifest + ruff + codespell + isort + twine + build + hatch + hatch-fancy-pypi-readme \ No newline at end of file diff --git a/uninstall.sh b/uninstall.sh index 4848039..d5e1b5f 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -1,25 +1,62 @@ #!/bin/bash -LIBRARY_VERSION=`cat library/setup.cfg | grep version | awk -F" = " '{print $2}'` -LIBRARY_NAME=`cat library/setup.cfg | grep name | awk -F" = " '{print $2}'` - -printf "$LIBRARY_NAME $LIBRARY_VERSION Python Library: Uninstaller\n\n" - -if [ $(id -u) -ne 0 ]; then - printf "Script must be run as root. Try 'sudo ./uninstall.sh'\n" - exit 1 +FORCE=false +LIBRARY_NAME=`grep -m 1 name pyproject.toml | awk -F" = " '{print substr($2,2,length($2)-2)}'` +RESOURCES_DIR=$HOME/Pimoroni/$LIBRARY_NAME +PYTHON="/usr/bin/python3" + +user_check() { + if [ $(id -u) -eq 0 ]; then + printf "Script should not be run as root. Try './install.sh'\n" + exit 1 + fi +} + +confirm() { + if $FORCE; then + true + else + read -r -p "$1 [y/N] " response < /dev/tty + if [[ $response =~ ^(yes|y|Y)$ ]]; then + true + else + false + fi + fi +} + +prompt() { + read -r -p "$1 [y/N] " response < /dev/tty + if [[ $response =~ ^(yes|y|Y)$ ]]; then + true + else + false + fi +} + +success() { + echo -e "$(tput setaf 2)$1$(tput sgr0)" +} + +inform() { + echo -e "$(tput setaf 6)$1$(tput sgr0)" +} + +warning() { + echo -e "$(tput setaf 1)$1$(tput sgr0)" +} + +printf "$LIBRARY_NAME Python Library: Uninstaller\n\n" + +user_check + +printf "Uninstalling for Python 3...\n" +$PYTHON -m pip uninstall $LIBRARY_NAME + +if [ -d $RESOURCES_DIR ]; then + if confirm "Would you like to delete $RESOURCES_DIR?"; then + rm -r $RESOURCES_DIR + fi fi -cd library - -printf "Unnstalling for Python 2..\n" -pip uninstall $LIBRARY_NAME - -if [ -f "/usr/bin/pip3" ]; then - printf "Uninstalling for Python 3..\n" - pip3 uninstall $LIBRARY_NAME -fi - -cd .. - printf "Done!\n" diff --git a/library/weatherhat/__init__.py b/weatherhat/__init__.py similarity index 99% rename from library/weatherhat/__init__.py rename to weatherhat/__init__.py index e67b3d6..c773cdb 100644 --- a/library/weatherhat/__init__.py +++ b/weatherhat/__init__.py @@ -1,17 +1,16 @@ -import time -import threading import math +import threading +import time -import RPi.GPIO as GPIO import ioexpander as io +import RPi.GPIO as GPIO from bme280 import BME280 from ltr559 import LTR559 from smbus2 import SMBus from .history import wind_degrees_to_cardinal - -__version__ = '0.0.1' +__version__ = '0.0.2' # Wind Vane diff --git a/library/weatherhat/history.py b/weatherhat/history.py similarity index 100% rename from library/weatherhat/history.py rename to weatherhat/history.py