1
0
Fork 0

Compare commits

...

20 Commits
v1.0 ... master

Author SHA1 Message Date
Kevin Matz de0a7a6bb6 fix link for server config example 2022-05-13 00:15:05 -04:00
Kevin Matz 0bacdf670f ship example config files 2022-05-13 00:03:35 -04:00
Kevin Matz 55e0efc093 don't ship config files 2022-05-13 00:03:21 -04:00
Kevin Matz 21c5c1787f bump version 2022-05-12 23:32:09 -04:00
Kevin Matz b775e51633 hog server config file can be specified 2022-05-12 23:31:56 -04:00
Kevin Matz 92656f7676 lower priority of some messages 2022-05-12 23:30:57 -04:00
Kevin Matz b408015444 button config file can be specified 2022-05-12 23:30:24 -04:00
Kevin Matz 2baf87d7a0 use argparse for command arguments 2022-05-12 23:27:25 -04:00
Kevin Matz f1505037b1 move the event loop to a main() function 2022-05-12 23:25:14 -04:00
Kevin Matz 35d20682fc the activate function doesn't need to be private 2022-05-12 23:23:46 -04:00
Kevin Matz 5c32645105 unify logging 2022-05-12 19:53:40 -04:00
Kevin Matz 499b20c079 the baconscript package now has proper includes 2022-05-12 19:17:54 -04:00
Kevin Matz 23c3daecd6 fix comparison 2022-05-12 18:46:53 -04:00
Kevin Matz e3a151c7fa fix module import order 2022-05-12 18:46:33 -04:00
Kevin Matz fa24f5543c baconscript built with ANTLR 4.10.1 2022-05-12 18:21:54 -04:00
Kevin Matz a2e1fed1b9 Update 'README.md' 2021-01-28 09:23:53 -05:00
Kevin Matz 0e50fc8bef update to latest baconscript 2021-01-28 08:28:50 -05:00
Kevin Matz 6d01679f05 baconscript doesn't support GOTO on masters. use lists. 2019-11-17 14:29:28 -05:00
Kevin Matz 5d5a075250 latest baconscript 2019-11-17 14:28:57 -05:00
Kevin Matz 042dc81414 update submodule 2019-11-17 11:50:26 -05:00
8 changed files with 306 additions and 130 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
*.cfg
# Antlr4
*.interp
*.tokens

238
README.md
View File

@ -1,94 +1,210 @@
# onsetswitch
# ContactPi
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)
* Enable the ssh server. On a mac:
```sh
touch /Volumes/boot/ssh
* Enable the ssh server.
- 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):
```
* Eject the SD card and boot the Raspberry Pi.
* Use SSH to log into the Pi:
```sh
ssh pi@raspberrypi
> ssh pi@PI_IP_ADDRESS
```
* The default password is `raspberry`.
* Use raspi-config to;
```sh
sudo raspi-config
* Use `sudo raspi-config` to;
- set locale
- set timezone
- enlarge the file-system to fill the SD card
- reboot
* Update the package manager and install the aptitude program.
```
* set locale
* set timezone
* 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
> sudo apt-get update
> sudo apt-get install aptitude
```
* Use aptitude to upgrade the Pi.
```sh
sudo aptitude upgrade
```
> sudo aptitude upgrade
```
* Reboot the Pi.
```sh
sudo shutdown -r now
```
> sudo shutdown -r now
```
* Logging back into the Pi, install sane set of software packages.
```sh
sudo aptitude install git python3-pip python3-gpiozero
sudo pip3 install gpiozero antlr4-python3-runtime python-osc
```
> sudo aptitude install git python3-pip python3-gpiozero
> sudo pip3 install gpiozero antlr4-python3-runtime python-osc
```
## Installing
```sh
cd /home/pi
git clone --recurse-submodules https://git.company235.com/kevin/onsetswitch.git
cd onsetswitch
* Change directory into `/home/pi`:
```
> cd /home/pi
```
> 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
### Input
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
* Change directory into ContactPi:
```
> cd ContactPi
```
## 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:
```sh
sudo systemctl daemon-reload
sudo systemctl enable buttons.service
* Enable the service at startup:
```
> sudo systemctl daemon-reload
> sudo systemctl enable buttons.service
```
Start the buttond service:
* Start the buttons service:
```
sudo systemctl start buttons.service
sudo systemctl status buttons.service
> sudo systemctl start 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

View File

@ -8,78 +8,121 @@ __copyright__ = "Copyright 2019, Company 235, LLC"
__credits__ = ["Kevin Matz"]
__license__ = "MIT"
__version__ = "1.0"
__version__ = "1.1"
__maintainer__ = "Kevin Matz"
__email__ = "kevin@company235.com"
__status__ = "Prototype"
import argparse
import configparser
from baconscript.comment import comment
from gpiozero import Button, GPIODeviceError
import logging
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
# from gpiozero.pins.mock import MockFactory
# from gpiozero import Device
# 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:
return
macro = macro.strip('\"').upper()
if macro is "":
if macro == "":
return
# pass macro to baconscript
print("doing macro ", macro)
log.debug("doing macro %s", macro)
comment(macro)
# empty button directory
_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
if __name__ == '__main__':
try:
pause()
except KeyboardInterrupt:
print()
main()
else:
# 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()')

View File

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

37
buttons.cfg.example Normal file
View File

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

View File

@ -1 +0,0 @@
baconscript/server.cfg

1
server.cfg.example Symbolic link
View File

@ -0,0 +1 @@
baconscript/server.cfg.example