Repackage to latest boilerplate.

This commit is contained in:
Phil Howard
2023-11-17 09:11:10 +00:00
parent 2b0c8aefd7
commit bebe4504ed
28 changed files with 541 additions and 309 deletions

View File

@@ -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 <target>, 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.rst from README.md"
@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
dev-deps:
python3 -m pip install -r requirements-dev.txt
sudo apt install dos2unix
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"
@bash check.sh
qa:
tox -e qa
pytest:
tox -e py
nopost:
@bash check.sh --nopost
tag:
git tag -a "v${LIBRARY_VERSION}" -m "Version ${LIBRARY_VERSION}"
build: check
@hatch build
clean:
-rm -r dist
library/README.md: README.md library/CHANGELOG.txt
cp README.md library/README.md
printf "\n# Changelog\n" >> library/README.md
testdeploy: build
twine upload --repository testpypi dist/*
library/LICENSE.txt: LICENSE
cp LICENSE library/LICENSE.txt
python-wheels: python-readme python-license
cd library; python3 setup.py bdist_wheel
cd library; python setup.py bdist_wheel
python-sdist: python-readme python-license
cd library; python setup.py sdist
python-clean:
-rm -r library/dist
-rm -r library/build
-rm -r library/*.egg-info
python-dist: python-clean python-wheels python-sdist
ls library/dist
python-testdeploy: python-dist
twine upload --repository-url https://test.pypi.org/legacy/ library/dist/*
python-deploy: check python-dist
deploy: nopost build
twine upload dist/*

View File

@@ -2,10 +2,10 @@
Designed as a tiny valet for your plants, Grow HAT mini will monitor the soil moiture for up to 3 plants, water them with tiny pumps, and show you their health on its small but informative screen. Learn more - https://shop.pimoroni.com/products/grow
[![Build Status](https://travis-ci.com/pimoroni/enviroplus-python.svg?branch=master)](https://travis-ci.com/pimoroni/grow-python)
[![Build Status](https://img.shields.io/github/actions/workflow/status/pimoroni/grow-python/test.yml?branch=main)](https://github.com/pimoroni/grow-python/actions/workflows/test.yml)
[![Coverage Status](https://coveralls.io/repos/github/pimoroni/grow-python/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/grow-python?branch=master)
[![PyPi Package](https://img.shields.io/pypi/v/enviroplus.svg)](https://pypi.python.org/pypi/growhat)
[![Python Versions](https://img.shields.io/pypi/pyversions/enviroplus.svg)](https://pypi.python.org/pypi/growhat)
[![PyPi Package](https://img.shields.io/pypi/v/growhat.svg)](https://pypi.python.org/pypi/growhat)
[![Python Versions](https://img.shields.io/pypi/pyversions/growhat.svg)](https://pypi.python.org/pypi/growhat)
# Installing
@@ -55,3 +55,14 @@ You should read the following to get up and running with our monitoring script:
* GPIO Pinout - https://pinout.xyz/pinout/grow_hat_mini
* Support forums - http://forums.pimoroni.com/c/support
* Discord - https://discord.gg/hr93ByC
# Changelog
0.0.2
-----
* Add mutually exclusive locking to pumps to avoid brownout running multiple pumps at once
0.0.1
-----
* Initial Release

88
check.sh Executable file
View File

@@ -0,0 +1,88 @@
#!/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))}'`
TERM=${TERM:="xterm-256color"}
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

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env python3
import ST7735
from PIL import Image, ImageDraw, ImageFont
from fonts.ttf import RobotoMedium as UserFont
import logging
import ST7735
from fonts.ttf import RobotoMedium as UserFont
from PIL import Image, ImageDraw, ImageFont
logging.basicConfig(
format="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s",
level=logging.INFO,

View File

@@ -2,7 +2,6 @@ import time
from grow.moisture import Moisture
print("""moisture.py - Print out sensor reading in Hz
Press Ctrl+C to exit!

View File

@@ -10,15 +10,14 @@ import time
import ltr559
import RPi.GPIO as GPIO
import ST7735
import yaml
from fonts.ttf import RobotoMedium as UserFont
from PIL import Image, ImageDraw, ImageFont
import yaml
from grow import Piezo
from grow.moisture import Moisture
from grow.pump import Pump
FPS = 10
BUTTONS = [5, 6, 16, 24]

View File

@@ -1,15 +1,14 @@
import time
import logging
import time
import RPi.GPIO as GPIO
from PIL import Image, ImageDraw, ImageFont
from fonts.ttf import RobotoMedium as UserFont
import ST7735
from fonts.ttf import RobotoMedium as UserFont
from PIL import Image, ImageDraw, ImageFont
from grow.moisture import Moisture
from grow.pump import Pump
"""
Auto water a single target with the channel/pump selected below.

View File

@@ -3,10 +3,12 @@
License: MIT
Description: Web API for moisture readings: http://<your-pi-host>:8080/
"""
from functools import partial
import json
import logging
from functools import partial
from aiohttp import web
from grow.moisture import Moisture
json_response = partial(web.json_response, dumps=partial(json.dumps, default=str))

View File

@@ -1,8 +1,9 @@
__version__ = '0.0.2'
import time
import atexit
import threading
import time
import RPi.GPIO as GPIO

View File

@@ -1,4 +1,5 @@
import time
import RPi.GPIO as GPIO
MOISTURE_1_PIN = 23

View File

@@ -1,6 +1,7 @@
import time
import atexit
import threading
import time
import RPi.GPIO as GPIO
PUMP_1_PIN = 17

View File

@@ -1,31 +1,31 @@
#!/bin/bash
CONFIG=/boot/config.txt
LIBRARY_NAME=`grep -m 1 name pyproject.toml | awk -F" = " '{print substr($2,2,length($2)-2)}'`
MODULE_NAME="grow"
CONFIG_FILE=config.txt
CONFIG_DIR="/boot/firmware"
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
VENV_BASH_SNIPPET=$RESOURCES_DIR/auto_venv.sh
VENV_DIR=$HOME/.virtualenvs/pimoroni
WD=`pwd`
USAGE="sudo ./install.sh (--unstable)"
USAGE="./install.sh (--unstable)"
POSITIONAL_ARGS=()
FORCE=false
UNSTABLE=false
CODENAME=`lsb_release -sc`
PYTHON="python"
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
@@ -58,16 +58,72 @@ warning() {
echo -e "$(tput setaf 1)$1$(tput sgr0)"
}
find_config() {
if [ ! -f "$CONFIG_DIR/$CONFIG_FILE" ]; then
CONFIG_DIR="/boot"
if [ ! -f "$CONFIG_DIR/$CONFIG_FILE"]; then
warning "Could not find $CONFIG_FILE!"
exit 1
fi
else
if [ -f "/boot/$CONFIG_FILE" ] && [ ! -L "/boot/$CONFIG_FILE" ]; then
warning "Oops! It looks like /boot/$CONFIG_FILE is not a link to $CONFIG_DIR/$CONFIG_FILE"
warning "You might want to fix this!"
fi
fi
inform "Using $CONFIG_FILE in $CONFIG_DIR"
}
venv_bash_snippet() {
if [ ! -f $VENV_BASH_SNIPPET ]; then
cat << EOF > $VENV_BASH_SNIPPET
# Add `source $RESOURCES_DIR/auto_venv.sh` to your ~/.bashrc to activate
# the Pimoroni virtual environment automagically!
VENV_DIR="$VENV_DIR"
if [ ! -f \$VENV_DIR/bin/activate ]; then
printf "Creating user Python environment in \$VENV_DIR, please wait...\n"
mkdir -p \$VENV_DIR
python3 -m venv --system-site-packages \$VENV_DIR
fi
printf " ↓ ↓ ↓ ↓ Hello, we've activated a Python venv for you. To exit, type \"deactivate\".\n"
source \$VENV_DIR/bin/activate
EOF
fi
}
venv_check() {
PYTHON_BIN=`which $PYTHON`
if [[ $VIRTUAL_ENV == "" ]] || [[ $PYTHON_BIN != $VIRTUAL_ENV* ]]; then
printf "This script should be run in a virtual Python environment.\n"
if confirm "Would you like us to create one for you?"; then
if [ ! -f $VENV_DIR/bin/activate ]; then
inform "Creating virtual Python environment in $VENV_DIR, please wait...\n"
mkdir -p $VENV_DIR
/usr/bin/python3 -m venv $VENV_DIR --system-site-packages
venv_bash_snippet
else
inform "Found existing virtual Python environment in $VENV_DIR\n"
fi
inform "Activating virtual Python environment in $VENV_DIR..."
inform "source $VENV_DIR/bin/activate\n"
source $VENV_DIR/bin/activate
else
exit 1
fi
fi
}
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
inform "Backing up $CONFIG_DIR/$CONFIG_FILE to $CONFIG_DIR/$FILENAME\n"
sudo cp $CONFIG_DIR/$CONFIG_FILE $CONFIG_DIR/$FILENAME
mkdir -p $RESOURCES_TOP_DIR/config-backups/
cp $CONFIG $RESOURCES_TOP_DIR/config-backups/$FILENAME
cp $CONFIG_DIR/$CONFIG_FILE $RESOURCES_TOP_DIR/config-backups/$FILENAME
if [ -f "$UNINSTALLER" ]; then
echo "cp $RESOURCES_TOP_DIR/config-backups/$FILENAME $CONFIG" >> $UNINSTALLER
echo "cp $RESOURCES_TOP_DIR/config-backups/$FILENAME $CONFIG_DIR/$CONFIG_FILE" >> $UNINSTALLER
fi
fi
}
@@ -88,16 +144,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 +165,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";
@@ -117,28 +186,31 @@ while [[ $# -gt 0 ]]; do
done
user_check
venv_check
apt_pkg_install python-configparser
if [ ! -f `which $PYTHON` ]; then
printf "Python path $PYTHON not found!\n"
exit 1
fi
CONFIG_VARS=`python - <<EOF
from configparser import ConfigParser
c = ConfigParser()
c.read('library/setup.cfg')
p = dict(c['pimoroni'])
# Convert multi-line config entries into bash arrays
for k in p.keys():
fmt = '"{}"'
if '\n' in p[k]:
p[k] = "'\n\t'".join(p[k].split('\n')[1:])
fmt = "('{}')"
p[k] = fmt.format(p[k])
PYTHON_VER=`$PYTHON --version`
printf "$LIBRARY_NAME Python Library: Installer\n\n"
inform "Checking Dependencies. Please wait..."
pip_pkg_install toml
CONFIG_VARS=`$PYTHON - <<EOF
import toml
config = toml.load("pyproject.toml")
p = dict(config['tool']['pimoroni'])
# Convert list config entries into bash arrays
for k, v in p.items():
v = "'\n\t'".join(v)
p[k] = f"('{v}')"
print("""
LIBRARY_NAME="{name}"
LIBRARY_VERSION="{version}"
""".format(**c['metadata']))
print("""
PY3_DEPS={py3deps}
PY2_DEPS={py2deps}
APT_PACKAGES={apt_packages}
SETUP_CMDS={commands}
CONFIG_TXT={configtxt}
""".format(**p))
@@ -154,6 +226,13 @@ eval $CONFIG_VARS
RESOURCES_DIR=$RESOURCES_TOP_DIR/$LIBRARY_NAME
UNINSTALLER=$RESOURCES_DIR/uninstall.sh
RES_DIR_OWNER=`stat -c "%U" $RESOURCES_TOP_DIR`
if [[ "$RES_DIR_OWNER" == "root" ]]; then
warning "\n\nFixing $RESOURCES_TOP_DIR permissions!\n\n"
sudo chown -R $USER:$USER $RESOURCES_TOP_DIR
fi
mkdir -p $RESOURCES_DIR
cat << EOF > $UNINSTALLER
@@ -161,50 +240,35 @@ 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
source $VIRTUAL_ENV/bin/activate
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
find_config
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
# Attempt to catch anything that touches config.txt and trigger a backup
if [[ "$CMD" == *"raspi-config"* ]] || [[ "$CMD" == *"$CONFIG_DIR/$CONFIG_FILE"* ]] || [[ "$CMD" == *"\$CONFIG_DIR/\$CONFIG_FILE"* ]]; then
do_config_backup
fi
eval $CMD
@@ -214,10 +278,10 @@ 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
inform "Adding $CONFIG_LINE to $CONFIG_DIR/$CONFIG_FILE\n"
sudo sed -i "s/^#$CONFIG_LINE/$CONFIG_LINE/" $CONFIG_DIR/$CONFIG_FILE
if ! grep -q "^$CONFIG_LINE" $CONFIG_DIR/$CONFIG_FILE; then
printf "$CONFIG_LINE\n" | sudo tee --append $CONFIG_DIR/$CONFIG_FILE
fi
fi
done
@@ -231,14 +295,17 @@ if [ -d "examples" ]; then
fi
fi
if [ -d "service" ]; then
inform "Grow includes a service that runs on boot and monitors your plants."
if confirm "Would you like to install the service?"; then
cd service
sudo ./install.sh
echo "rm /usr/bin/grow" >> $UNINSTALLER
echo "rm -r /usr/share/grow-monitor" >> $UNINSTALLER
echo "rm /etc/default/grow" >> $UNINSTALLER
printf "\n"
if confirm "Would you like to generate documentation?"; then
pip_pkg_install pdoc
printf "Generating documentation.\n"
$PYTHON -m pdoc $MODULE_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."
fi
fi

View File

@@ -1,4 +0,0 @@
[run]
source = grow
omit =
.tox/*

View File

@@ -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.

View File

@@ -1,68 +0,0 @@
# Grow HAT Mini
Designed as a tiny valet for your plants, Grow HAT mini will monitor the soil moiture for up to 3 plants, water them with tiny pumps, and show you their health on its small but informative screen. Learn more - https://shop.pimoroni.com/products/grow
[![Build Status](https://travis-ci.com/pimoroni/enviroplus-python.svg?branch=master)](https://travis-ci.com/pimoroni/grow-python)
[![Coverage Status](https://coveralls.io/repos/github/pimoroni/grow-python/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/grow-python?branch=master)
[![PyPi Package](https://img.shields.io/pypi/v/enviroplus.svg)](https://pypi.python.org/pypi/growhat)
[![Python Versions](https://img.shields.io/pypi/pyversions/enviroplus.svg)](https://pypi.python.org/pypi/growhat)
# Installing
You're best using the "One-line" install method.
## One-line (Installs from GitHub)
```
curl -sSL https://get.pimoroni.com/grow | bash
```
**Note** report issues with one-line installer here: https://github.com/pimoroni/get
## Or... Install and configure dependencies from GitHub:
* `git clone https://github.com/pimoroni/grow-python`
* `cd grow-python`
* `sudo ./install.sh`
**Note** Raspbian Lite users may first need to install git: `sudo apt install git`
## Or... Install from PyPi and configure manually:
* Install dependencies:
```
sudo apt install python3-setuptools python3-pip python3-yaml python3-smbus python3-pil python3-spidev python3-rpi.gpio
```
* Run `sudo pip3 install growhat`
**Note** this wont perform any of the required configuration changes on your Pi, you may additionally need to:
* Enable i2c: `sudo raspi-config nonint do_i2c 0`
* Enable SPI: `sudo raspi-config nonint do_spi 0`
* Add the following to `/boot/config.txt`: `dtoverlay=spi0-cs,cs0_pin=14`
## Monitoring
You should read the following to get up and running with our monitoring script:
* [Using and configuring monitor.py](examples/README.md)
* [Setting up monitor.py as a service](service/README.md)
## Help & Support
* GPIO Pinout - https://pinout.xyz/pinout/grow_hat_mini
* Support forums - http://forums.pimoroni.com/c/support
* Discord - https://discord.gg/hr93ByC
# Changelog
0.0.2
-----
* Add mutually exclusive locking to pumps to avoid brownout running multiple pumps at once
0.0.1
-----
* Initial Release

View File

@@ -1,28 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2020 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
setup()

View File

@@ -1,24 +0,0 @@
[tox]
envlist = py,qa
skip_missing_interpreters = True
[testenv]
commands =
python setup.py install
coverage run -m pytest -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

124
pyproject.toml Normal file
View File

@@ -0,0 +1,124 @@
[build-system]
requires = ["hatchling", "hatch-fancy-pypi-readme"]
build-backend = "hatchling.build"
[project]
name = "growhat"
dynamic = ["version", "readme"]
description = "Grow HAT Mini. A plant valet add-on for the Raspberry Pi"
license = {file = "LICENSE"}
requires-python = ">= 3.7"
authors = [
{ name = "Philip Howard", email = "phil@pimoroni.com" },
{ name = "Paul Beech", email = "paul@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 = [
"ltr559",
"st7735>=0.0.5",
"pyyaml",
"fonts",
"font-roboto"
]
[project.urls]
GitHub = "https://www.github.com/pimoroni/grow-python"
Homepage = "https://www.pimoroni.com"
[tool.hatch.version]
path = "grow/__init__.py"
[tool.hatch.build]
include = [
"grow",
"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.\
"""
[tool.isort]
line_length = 200
[tool.black]
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',
'requirements-examples.txt'
]
[tool.pimoroni]
apt_packages = []
configtxt = []
commands = []

9
requirements-dev.txt Normal file
View File

@@ -0,0 +1,9 @@
check-manifest
ruff
codespell
isort
twine
hatch
hatch-fancy-pypi-readme
tox
pdoc

View File

@@ -0,0 +1,3 @@
pyyaml
pillow>=10.0.0
numpy

View File

@@ -3,6 +3,7 @@ These allow the mocking of various Python modules
that might otherwise have runtime side-effects.
"""
import sys
import mock
import pytest
from i2cdevice import MockSMBus

View File

@@ -28,7 +28,7 @@ def test_moisture_read(GPIO, smbus):
def test_pump_setup(GPIO, smbus):
from grow.pump import Pump, PUMP_PWM_FREQ
from grow.pump import PUMP_PWM_FREQ, Pump
ch1 = Pump(channel=1)
ch2 = Pump(channel=2)

34
tox.ini Normal file
View File

@@ -0,0 +1,34 @@
[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 .
codespell .
deps =
check-manifest
ruff
codespell
isort
twine
build
hatch
hatch-fancy-pypi-readme

View File

@@ -1,25 +1,72 @@
#!/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}'`
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="python"
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
venv_check() {
PYTHON_BIN=`which $PYTHON`
if [[ $VIRTUAL_ENV == "" ]] || [[ $PYTHON_BIN != $VIRTUAL_ENV* ]]; then
printf "This script should be run in a virtual Python environment.\n"
exit 1
fi
}
user_check() {
if [ $(id -u) -eq 0 ]; then
printf "Script should not be run as root. Try './uninstall.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
venv_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"