Compare commits
20 Commits
Author | SHA1 | Date |
---|---|---|
Kevin Matz | de0a7a6bb6 | |
Kevin Matz | 0bacdf670f | |
Kevin Matz | 55e0efc093 | |
Kevin Matz | 21c5c1787f | |
Kevin Matz | b775e51633 | |
Kevin Matz | 92656f7676 | |
Kevin Matz | b408015444 | |
Kevin Matz | 2baf87d7a0 | |
Kevin Matz | f1505037b1 | |
Kevin Matz | 35d20682fc | |
Kevin Matz | 5c32645105 | |
Kevin Matz | 499b20c079 | |
Kevin Matz | 23c3daecd6 | |
Kevin Matz | e3a151c7fa | |
Kevin Matz | fa24f5543c | |
Kevin Matz | a2e1fed1b9 | |
Kevin Matz | 0e50fc8bef | |
Kevin Matz | 6d01679f05 | |
Kevin Matz | 5d5a075250 | |
Kevin Matz | 042dc81414 |
|
@ -1,3 +1,5 @@
|
||||||
|
*.cfg
|
||||||
|
|
||||||
# Antlr4
|
# Antlr4
|
||||||
*.interp
|
*.interp
|
||||||
*.tokens
|
*.tokens
|
||||||
|
|
238
README.md
238
README.md
|
@ -1,94 +1,210 @@
|
||||||
# onsetswitch
|
# ContactPi
|
||||||
Use buttons connected to a Rasberry Pi GPIO to trigger Hog 4 comment macros.
|
Use buttons connected to a Rasberry Pi GPIO to trigger Hog 4 comment macros.
|
||||||
|
|
||||||
## Prep
|
> If you are new to Raspberry Pi consider reading some [brief introductory tips.](https://thepihut.com/blogs/raspberry-pi-tutorials/the-raspberry-pi-tutorial-beginners-guide)
|
||||||
|
|
||||||
|
## Preparing the Raspberry Pi
|
||||||
|
|
||||||
* Install Raspbian [the usual way.](https://www.raspberrypi.org/documentation/installation/installing-images/README.md)
|
* Install Raspbian [the usual way.](https://www.raspberrypi.org/documentation/installation/installing-images/README.md)
|
||||||
* Enable the ssh server. On a mac:
|
|
||||||
```sh
|
* Enable the ssh server.
|
||||||
touch /Volumes/boot/ssh
|
- On a Mac within the terminal:
|
||||||
|
```
|
||||||
|
> touch /Volumes/boot/ssh
|
||||||
|
```
|
||||||
|
- On Windows:
|
||||||
|
1. Go to the boot folder created on the SD card
|
||||||
|
2. Create a blank text document named SSH
|
||||||
|
|
||||||
|
|
||||||
|
* Eject the SD card and boot the Raspberry Pi.
|
||||||
|
|
||||||
|
* Use SSH to log into the Pi from your computers Command Line (Windows) or Terminal (Mac):
|
||||||
```
|
```
|
||||||
|
> ssh pi@PI_IP_ADDRESS
|
||||||
* Eject the SD card and boot the Raspberry Pi.
|
|
||||||
* Use SSH to log into the Pi:
|
|
||||||
```sh
|
|
||||||
ssh pi@raspberrypi
|
|
||||||
```
|
```
|
||||||
|
* The default password is `raspberry`.
|
||||||
|
|
||||||
* Use raspi-config to;
|
* Use `sudo raspi-config` to;
|
||||||
```sh
|
- set locale
|
||||||
sudo raspi-config
|
- set timezone
|
||||||
|
- enlarge the file-system to fill the SD card
|
||||||
|
- reboot
|
||||||
|
|
||||||
|
|
||||||
|
* Update the package manager and install the aptitude program.
|
||||||
```
|
```
|
||||||
* set locale
|
> sudo apt-get update
|
||||||
* set timezone
|
> sudo apt-get install aptitude
|
||||||
* enable ssh server
|
|
||||||
* enlarge the file-system to fill the SD card
|
|
||||||
* reboot
|
|
||||||
|
|
||||||
|
|
||||||
* Update the Apt and install aptitude
|
|
||||||
```sh
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install aptitude
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* Use aptitude to upgrade the Pi.
|
* Use aptitude to upgrade the Pi.
|
||||||
```sh
|
```
|
||||||
sudo aptitude upgrade
|
> sudo aptitude upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
* Reboot the Pi.
|
* Reboot the Pi.
|
||||||
```sh
|
```
|
||||||
sudo shutdown -r now
|
> sudo shutdown -r now
|
||||||
```
|
```
|
||||||
|
|
||||||
* Logging back into the Pi, install sane set of software packages.
|
* Logging back into the Pi, install sane set of software packages.
|
||||||
```sh
|
```
|
||||||
sudo aptitude install git python3-pip python3-gpiozero
|
> sudo aptitude install git python3-pip python3-gpiozero
|
||||||
sudo pip3 install gpiozero antlr4-python3-runtime python-osc
|
> sudo pip3 install gpiozero antlr4-python3-runtime python-osc
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
```sh
|
* Change directory into `/home/pi`:
|
||||||
cd /home/pi
|
```
|
||||||
git clone --recurse-submodules https://git.company235.com/kevin/onsetswitch.git
|
> cd /home/pi
|
||||||
cd onsetswitch
|
```
|
||||||
|
> If you didn't notice any change you might already be in the correct directory. You can confirm this by using the command `pwd` to print the working directory. It should print: `/home/pi`
|
||||||
|
|
||||||
|
* Download ContactPi:
|
||||||
|
```
|
||||||
|
> git clone --recurse-submodules https://git.company235.com/kevin/ContactPi.git
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuring
|
* Change directory into ContactPi:
|
||||||
|
```
|
||||||
### Input
|
> cd ContactPi
|
||||||
Connect one side of the button to ground, the other to a GPIO pin.
|
|
||||||
|
|
||||||
![](https://gpiozero.readthedocs.io/en/stable/_images/button_bb.svg)
|
|
||||||
|
|
||||||
Configure the buttons:
|
|
||||||
```sh
|
|
||||||
nano buttons.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
### Output
|
|
||||||
|
|
||||||
Configure the Hog4 OSC server:
|
|
||||||
```sh
|
|
||||||
nano server.cfg
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Enabling on Boot
|
## Enabling on Boot
|
||||||
Link the onsetswitch service file to systemd:
|
|
||||||
|
* Link the service file to systemd:
|
||||||
```
|
```
|
||||||
sudo cp buttons.service /lib/systemd/system/buttons.service
|
> sudo cp buttons.service /lib/systemd/system/buttons.service
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable the service at startup:
|
* Enable the service at startup:
|
||||||
```sh
|
```
|
||||||
sudo systemctl daemon-reload
|
> sudo systemctl daemon-reload
|
||||||
sudo systemctl enable buttons.service
|
> sudo systemctl enable buttons.service
|
||||||
```
|
```
|
||||||
|
|
||||||
Start the buttond service:
|
* Start the buttons service:
|
||||||
```
|
```
|
||||||
sudo systemctl start buttons.service
|
> sudo systemctl start buttons.service
|
||||||
sudo systemctl status buttons.service
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Hardware Setup
|
||||||
|
|
||||||
|
* Connect one side of the button to ground, the other to a GPIO pin.
|
||||||
|
|
||||||
|
![](https://gpiozero.readthedocs.io/en/stable/_images/button_bb.svg)
|
||||||
|
|
||||||
|
You may use any of the numbered GPIO pins available on the PI:
|
||||||
|
|
||||||
|
![](https://www.raspberrypi.org/documentation/usage/gpio/images/GPIO.png)
|
||||||
|
|
||||||
|
## Configuring
|
||||||
|
|
||||||
|
### Buttons and Macros
|
||||||
|
|
||||||
|
>Nano is a command line text editor that is available by default on the Pi. For a usage overview, read [The Beginner's Guide to Nano](https://www.howtogeek.com/howto/42980/the-beginners-guide-to-nano-the-linux-command-line-text-editor/)
|
||||||
|
|
||||||
|
|
||||||
|
* Use nano to configure the pinout and macro settings.
|
||||||
|
```
|
||||||
|
> nano buttons.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
This file configures which Raspberry Pi GPIO pins trigger which comment macros.
|
||||||
|
|
||||||
|
The `button` section contains a comma separated list of named button sections.
|
||||||
|
|
||||||
|
This is a sample buttons.cfg file:
|
||||||
|
```
|
||||||
|
[button]
|
||||||
|
names=switch1,switch2,switch3,switch4
|
||||||
|
|
||||||
|
[switch1]
|
||||||
|
pin: 12
|
||||||
|
close: "gl21/2"
|
||||||
|
open: "gl21/1"
|
||||||
|
|
||||||
|
[switch2]
|
||||||
|
pin: 16
|
||||||
|
close: "gl22/2"
|
||||||
|
open: "gl22/1"
|
||||||
|
|
||||||
|
[switch3]
|
||||||
|
pin: 20
|
||||||
|
close: "gl23/2"
|
||||||
|
open: "gl23/1"
|
||||||
|
|
||||||
|
[switch4]
|
||||||
|
pin: 21
|
||||||
|
close: "gl24/2"
|
||||||
|
open: "gl24/1"
|
||||||
|
```
|
||||||
|
|
||||||
|
> ContactPi uses [Bacon Script](https://git.company235.com/kevin/baconscript) to abstract the underlying OSC. The [README](https://git.company235.com/kevin/baconscript/src/branch/master/README.md) file of that project contains additional details about the syntax for configuring comment macros.
|
||||||
|
|
||||||
|
* Once the file has been configured press `ctrl+x` to exit.
|
||||||
|
|
||||||
|
### Hog Servers
|
||||||
|
|
||||||
|
* Use nano to configure the Hog server settings.
|
||||||
|
```
|
||||||
|
> nano server.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
> Contact Pi only sends OSC commands to the first server in this list unless the net number is explicitly specified in the comment macro.
|
||||||
|
> `EXAMPLEh22`.
|
||||||
|
|
||||||
|
This is a sample server.cfg file:
|
||||||
|
```
|
||||||
|
[network]
|
||||||
|
hogs = hog4_235, hedgehog_235, server_pc, server_rackhog
|
||||||
|
|
||||||
|
[hog4_235]
|
||||||
|
ip: 10.235.1.53
|
||||||
|
port: 7001
|
||||||
|
net: 53
|
||||||
|
|
||||||
|
[hedgehog_235]
|
||||||
|
ip: 10.235.1.63
|
||||||
|
port: 7001
|
||||||
|
net: 63
|
||||||
|
|
||||||
|
[server_pc]
|
||||||
|
ip: 10.235.1.12
|
||||||
|
port: 7001
|
||||||
|
net: 12
|
||||||
|
|
||||||
|
[server_rackhog]
|
||||||
|
ip: 10.235.1.22
|
||||||
|
port: 7001
|
||||||
|
net: 22
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
* Once the file has been configured `ctrl+x` to exit.
|
||||||
|
|
||||||
|
* Restart buttons.service to apply changes.
|
||||||
|
```
|
||||||
|
> sudo systemctl restart buttons.service
|
||||||
|
```
|
||||||
|
|
||||||
|
* Check the status of the `buttons` systemd service.
|
||||||
|
```
|
||||||
|
> sudo systemctl status buttons.service
|
||||||
|
|
||||||
|
● buttons.service - OSC Button Watcher
|
||||||
|
Loaded: loaded (/lib/systemd/system/buttons.service; enabled; vendor preset: enabled)
|
||||||
|
Active: active (running) since Fri 2020-11-20 14:27:43 EST; 3s ago
|
||||||
|
Main PID: 1032 (python3)
|
||||||
|
Tasks: 6 (limit: 1433)
|
||||||
|
CGroup: /system.slice/buttons.service
|
||||||
|
└─1032 /usr/bin/python3 /home/pi/ContactPi/buttond.py
|
||||||
|
|
||||||
|
Nov 20 14:27:43 raspberrypi systemd[1]: Started OSC Button Watcher.
|
||||||
|
Nov 20 14:27:43 raspberrypi python3[1032]: Adding Hog device at net# 53
|
||||||
|
Nov 20 14:27:43 raspberrypi python3[1032]: Adding Hog device at net# 63
|
||||||
|
Nov 20 14:27:43 raspberrypi python3[1032]: Adding Hog device at net# 12
|
||||||
|
Nov 20 14:27:43 raspberrypi python3[1032]: Adding Hog device at net# 22
|
||||||
|
```
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c1a7ad48b2ea848f59717832f938a3687b88e781
|
Subproject commit 1c499437d76503dd420eac4f735813dfed262715
|
133
buttond.py
133
buttond.py
|
@ -8,78 +8,121 @@ __copyright__ = "Copyright 2019, Company 235, LLC"
|
||||||
__credits__ = ["Kevin Matz"]
|
__credits__ = ["Kevin Matz"]
|
||||||
|
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__version__ = "1.0"
|
__version__ = "1.1"
|
||||||
__maintainer__ = "Kevin Matz"
|
__maintainer__ = "Kevin Matz"
|
||||||
__email__ = "kevin@company235.com"
|
__email__ = "kevin@company235.com"
|
||||||
|
|
||||||
__status__ = "Prototype"
|
__status__ = "Prototype"
|
||||||
|
|
||||||
|
import argparse
|
||||||
import configparser
|
import configparser
|
||||||
from baconscript.comment import comment
|
import logging
|
||||||
from gpiozero import Button, GPIODeviceError
|
|
||||||
from signal import pause
|
from signal import pause
|
||||||
|
from baconscript import comment, HogNet, LISTENER, load_servers
|
||||||
|
from gpiozero import Button, GPIODeviceError
|
||||||
|
|
||||||
# use mock pins when not working on Pi hardware
|
# use mock pins when not working on Pi hardware
|
||||||
# from gpiozero.pins.mock import MockFactory
|
# from gpiozero.pins.mock import MockFactory
|
||||||
# from gpiozero import Device
|
# from gpiozero import Device
|
||||||
# Device.pin_factory = MockFactory()
|
# Device.pin_factory = MockFactory()
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
# callback intermidiary to sanitize user input
|
|
||||||
def _activate(macro):
|
def main():
|
||||||
|
"""Entry point for direct execution."""
|
||||||
|
## parse the command line
|
||||||
|
args = get_command_arguments()
|
||||||
|
## configure logging
|
||||||
|
log_levels = {
|
||||||
|
0: logging.CRITICAL,
|
||||||
|
1: logging.ERROR,
|
||||||
|
2: logging.WARN,
|
||||||
|
3: logging.INFO,
|
||||||
|
4: logging.DEBUG,
|
||||||
|
}
|
||||||
|
if args.verbosity is None:
|
||||||
|
args.verbosity = 0 if args.quiet else 3
|
||||||
|
logging.basicConfig(level=log_levels.get(args.verbosity, logging.DEBUG))
|
||||||
|
## output header
|
||||||
|
print(f"Version: {__version__}\t{__copyright__}")
|
||||||
|
## load config files
|
||||||
|
LISTENER.osc = HogNet(load_servers(args.servers))
|
||||||
|
load_config(args.buttons)
|
||||||
|
## run the event loop
|
||||||
|
try:
|
||||||
|
pause()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def get_command_arguments():
|
||||||
|
"""Parse the command line arguments."""
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Exec Hog4 comment macros on RasPi GPIO activity.',
|
||||||
|
epilog=__copyright__)
|
||||||
|
parser.add_argument('-b', '--buttons', default="buttons.cfg",
|
||||||
|
help="button configuration file")
|
||||||
|
parser.add_argument('-s', '--servers', default="server.cfg",
|
||||||
|
help="OSC servers configuration file")
|
||||||
|
parser.add_argument('-q', '--quiet', action='store_true',
|
||||||
|
help="sets the default log level to 0, otherwise 3.")
|
||||||
|
parser.add_argument("-v", dest="verbosity",
|
||||||
|
action="count", default=None,
|
||||||
|
help="verbosity (between 1-4 with more printing more "
|
||||||
|
" verbose logging). "
|
||||||
|
"CRITICAL=0, ERROR=1, WARN=2, INFO=3, DEBUG=4")
|
||||||
|
parser.add_argument('--version', action='version',
|
||||||
|
version=f'%(prog)s {__version__}')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(file):
|
||||||
|
"""Load a configuration file."""
|
||||||
|
config = configparser.ConfigParser(allow_no_value=True)
|
||||||
|
log.debug("Loading config from %s", file)
|
||||||
|
config.read(file)
|
||||||
|
# set up each buttons
|
||||||
|
for button in config.get('button', 'names').split(','):
|
||||||
|
try:
|
||||||
|
# move to config section
|
||||||
|
cfg = config[button]
|
||||||
|
# read from settings
|
||||||
|
pin = cfg.get('pin', None)
|
||||||
|
closed = cfg.get('close', None)
|
||||||
|
opened = cfg.get('open', None)
|
||||||
|
# set up button on pin
|
||||||
|
log.debug('init %s on GPIO %s', button, pin)
|
||||||
|
_buttons[button] = Button(pin)
|
||||||
|
# connect button callbacks to anonymous functions
|
||||||
|
log.info('connecting %s "closed" to macro %s', button, closed)
|
||||||
|
_buttons[button].when_pressed = lambda macro=closed: activate(macro)
|
||||||
|
log.info('connecting %s "opened" to macro %s', button, opened)
|
||||||
|
_buttons[button].when_released = lambda macro=opened: activate(macro)
|
||||||
|
except (KeyError, GPIODeviceError) as error:
|
||||||
|
log.error('Error configuring button %s: %s', button, error)
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
def activate(macro):
|
||||||
|
"""Sanitize user configured macros."""
|
||||||
if macro is None:
|
if macro is None:
|
||||||
return
|
return
|
||||||
macro = macro.strip('\"').upper()
|
macro = macro.strip('\"').upper()
|
||||||
if macro is "":
|
if macro == "":
|
||||||
return
|
return
|
||||||
# pass macro to baconscript
|
# pass macro to baconscript
|
||||||
print("doing macro ", macro)
|
log.debug("doing macro %s", macro)
|
||||||
comment(macro)
|
comment(macro)
|
||||||
|
|
||||||
|
|
||||||
# empty button directory
|
# empty button directory
|
||||||
_buttons = {}
|
_buttons = {}
|
||||||
|
|
||||||
# open config file
|
|
||||||
config = configparser.ConfigParser(allow_no_value=True)
|
|
||||||
config.read('buttons.cfg')
|
|
||||||
# set up each buttons
|
|
||||||
for b in config.get('button', 'names').split(','):
|
|
||||||
try:
|
|
||||||
# move to config section
|
|
||||||
c = config[b]
|
|
||||||
# read from settings
|
|
||||||
pin = c.get('pin', None)
|
|
||||||
closed = c.get('close', None)
|
|
||||||
opened = c.get('open', None)
|
|
||||||
# set up button on pin
|
|
||||||
print('init', b, 'on GPIO', pin)
|
|
||||||
_buttons[b] = Button(pin)
|
|
||||||
# connect button callbacks to anonymous functions
|
|
||||||
print('connecting', b, '"closed" to macro', closed)
|
|
||||||
_buttons[b].when_pressed = lambda macro=closed: _activate(macro)
|
|
||||||
print('connecting', b, '"opened" to macro', opened)
|
|
||||||
_buttons[b].when_released = lambda macro=opened: _activate(macro)
|
|
||||||
|
|
||||||
except (KeyError, GPIODeviceError) as e:
|
|
||||||
print('Error configuring button', b, e)
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
# clear temp variables off the stack
|
|
||||||
try:
|
|
||||||
del pin, closed, opened
|
|
||||||
del c, config
|
|
||||||
except NameError as e:
|
|
||||||
print('failed to release memory', e)
|
|
||||||
|
|
||||||
|
|
||||||
# when run directly, sleep until button signal or KeyboardInterrupt
|
# when run directly, sleep until button signal or KeyboardInterrupt
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
main()
|
||||||
pause()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print()
|
|
||||||
else:
|
else:
|
||||||
# indicate prefered method of sleeping when laoded as a module
|
# indicate prefered method of sleeping when laoded as a module
|
||||||
print('call signal.pause() instead of time.sleep()')
|
log.debug('call signal.pause() instead of time.sleep()')
|
||||||
|
|
22
buttons.cfg
22
buttons.cfg
|
@ -1,22 +0,0 @@
|
||||||
[button]
|
|
||||||
names=switch1,switch2,switch3,switch4
|
|
||||||
|
|
||||||
[switch1]
|
|
||||||
pin: 12
|
|
||||||
close: "gm21/2"
|
|
||||||
open: "gm21/1"
|
|
||||||
|
|
||||||
[switch2]
|
|
||||||
pin: 16
|
|
||||||
close: "gm22/2"
|
|
||||||
open: "gm22/1"
|
|
||||||
|
|
||||||
[switch3]
|
|
||||||
pin: 20
|
|
||||||
close: "gm23/2"
|
|
||||||
open: "gm23/1"
|
|
||||||
|
|
||||||
[switch4]
|
|
||||||
pin: 21
|
|
||||||
close: "gm24/2"
|
|
||||||
open: "gm24/1"
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
; This file contains the configuration data for the buttons.
|
||||||
|
|
||||||
|
[button]
|
||||||
|
; comma seperated list of button names
|
||||||
|
; button names omited from this list will be omited.
|
||||||
|
names=switch1,switch2,switch3,switch4
|
||||||
|
|
||||||
|
; The button is named as a section.
|
||||||
|
; When adding additional buttons, be sure to add the section
|
||||||
|
; name to the index on line 6.
|
||||||
|
[example]
|
||||||
|
; the GPIO pin to watch
|
||||||
|
pin: 1
|
||||||
|
; macro to run when the pin goes low
|
||||||
|
close: "gl1"
|
||||||
|
; macro to run when the pin goes high
|
||||||
|
open: "gm*"
|
||||||
|
|
||||||
|
[switch1]
|
||||||
|
pin: 12
|
||||||
|
close: "gl21/2"
|
||||||
|
open: "gl21/1"
|
||||||
|
|
||||||
|
[switch2]
|
||||||
|
pin: 16
|
||||||
|
close: "gl22/2"
|
||||||
|
open: "gl22/1"
|
||||||
|
|
||||||
|
[switch3]
|
||||||
|
pin: 20
|
||||||
|
close: "gl23/2"
|
||||||
|
open: "gl23/1"
|
||||||
|
|
||||||
|
[switch4]
|
||||||
|
pin: 21
|
||||||
|
close: "gl24/2"
|
||||||
|
open: "gl24/1"
|
|
@ -1 +0,0 @@
|
||||||
baconscript/server.cfg
|
|
|
@ -0,0 +1 @@
|
||||||
|
baconscript/server.cfg.example
|
Loading…
Reference in New Issue