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 # Antlr4
*.interp *.interp
*.tokens *.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. 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

View File

@ -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()')

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