-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7829073
Showing
16 changed files
with
1,125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/bin/python | ||
import os | ||
|
||
import ConfigParser | ||
|
||
import socket | ||
import sys | ||
import md5 | ||
|
||
class GPIOClient(): | ||
config=False | ||
authMode=False | ||
pma=False | ||
service=False | ||
|
||
def __init__(self): | ||
self.config = ConfigParser.ConfigParser() | ||
self.config.read([os.path.dirname(os.path.abspath(__file__)) + '/../etc/GPIO.conf']) | ||
|
||
self.authMode=not self.config.get('auth', 'token') in ('0', 'False') | ||
if not self.authMode: | ||
# Poor Man Authenticathion SECRET | ||
self.pma=self.config.get('auth', 'pma') | ||
|
||
#create an INET, STREAMing socket | ||
self.service = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#now connect to the GPIO server on custom port | ||
self.service.connect((self.config.get('client', 'host'), int(self.config.get('common', 'port')))) | ||
|
||
def getToken(self): | ||
#create an INET, STREAMing socket | ||
a = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#now connect to the token daemon on custom port | ||
a.connect((self.config.get('auth', 'host'), int(self.config.get('auth', 'port')))) | ||
|
||
a.send('get') | ||
t = a.recv(64) | ||
return t | ||
|
||
def sendCommand(self, command): | ||
a = md5.new() | ||
payload = [command] | ||
if self.authMode: | ||
t = self.getToken() | ||
a.update(t) | ||
payload.append(t) | ||
else: | ||
a.update(pma) | ||
a.update(command) | ||
payload.insert(0, a.digest()) | ||
self.service.send('::'.join(payload)) | ||
|
||
if __name__ == "__main__": | ||
o = GPIOClient() | ||
o.sendCommand(sys.argv[1]) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
import os | ||
import ConfigParser | ||
|
||
import socket | ||
import sys | ||
|
||
binpath=os.path.dirname(os.path.abspath(__file__)) | ||
sys.path.insert(0, binpath + '/../lib') | ||
|
||
from myGPIO import mnemonic | ||
import RPi.GPIO as GPIO | ||
import Daemon | ||
|
||
import re | ||
import md5 | ||
import time | ||
|
||
class GPIODaemon(Daemon.Daemon): | ||
config=False | ||
tokenMode=True | ||
pma='' | ||
setupMap = {} | ||
eventsMap = {} | ||
persistence=False | ||
|
||
def init(self): | ||
self.config = ConfigParser.ConfigParser() | ||
self.config.read([binpath + '/../etc/GPIO.conf']) | ||
|
||
def checkToken(self, token): | ||
#create an INET, STREAMing socket | ||
s = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#now connect to the daemon on custom port | ||
s.connect((self.config.get('auth', 'host'), int(self.config.get('auth', 'port')))) | ||
|
||
s.send('auth:' + token) | ||
if s.recv(8) == '0': | ||
return True | ||
return False | ||
|
||
def eventTrigger(self, channel): | ||
if channel in self.eventsMap: | ||
pushsocket = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#connect the socket to the event's owner host, | ||
pushsocket.connect((self.eventsMap[int(channel)], int(self.config.get('common', 'pushEventPort')) )) | ||
#TODO: auth stuff | ||
pushsocket.send(str(channel)) | ||
else: | ||
#error | ||
print 'Error Triggering event, eventMap entry does not exists!?' | ||
|
||
def run(self): | ||
self.tokenMode=not self.config.get('auth', 'token') in ('0', 'False') | ||
if not self.tokenMode: | ||
# Poor Man Secret (copy it on your client script, too!) | ||
self.pma=self.config.get('auth', 'pma') | ||
|
||
o=mnemonic() | ||
|
||
#create an INET, STREAMing socket | ||
serversocket = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#bind the socket to a public host, | ||
# and the daemon port | ||
serversocket.bind(('', int(self.config.get('common', 'port')))) | ||
#become a server socket, GPIO is ONE, so we accept only 1 connection at a time! | ||
serversocket.listen(1) | ||
|
||
while 1: | ||
if not self.persistence: | ||
#accept connections from outside | ||
(clientsocket, address) = serversocket.accept() | ||
#now do something with the clientsocket | ||
(auth, input, token) = clientsocket.recv(4096).split('::') | ||
a = md5.new() | ||
if self.tokenMode: | ||
if self.checkToken(token) == False: | ||
clientsocket.send('-4') | ||
continue | ||
a.update(token) | ||
else: | ||
a.update(self.pma) | ||
a.update(input) | ||
if (a.digest() != auth): | ||
clientsocket.send('-4') | ||
continue | ||
if input=='system.quit': | ||
exit() | ||
elif input=='system.persistence.on': | ||
self.persistence=True | ||
clientsocket.send('0') | ||
continue | ||
elif input=='system.persistence.off': | ||
self.persistence=False | ||
clientsocket.send('0') | ||
continue | ||
#try: | ||
if True: | ||
m = re.search('^GPIO\.([a-zA-Z]+)\(([^\)]+)\)$', input) | ||
if m is not None: | ||
params=m.group(2).split(',') | ||
# Basic commands | ||
if m.group(1) == 'setup': | ||
if len(params) == 3: | ||
GPIO.setup(int(params[0]), int(params[1]), pull_up_down=int(params[2])) | ||
else: | ||
GPIO.setup(int(params[0]), int(params[1])) | ||
clientsocket.send('0') | ||
elif m.group(1) == 'output': | ||
self.autoSetup(int(params[0]), GPIO.OUT) | ||
GPIO.output(int(params[0]), int(params[1])) | ||
clientsocket.send('0') | ||
elif m.group(1) == 'input': | ||
self.autoSetup(int(params[0]), GPIO.IN) | ||
clientsocket.send(str(GPIO.input(int(params[0])))) | ||
|
||
# Events | ||
elif m.group(1) == 'addEvent': | ||
if int(params[0]) in self.eventsMap: | ||
for k in self.eventsMap.keys(): | ||
print "%d : %s" % (k, self.eventsMap[k]) | ||
# just existing event! | ||
clientsocket.send('-1') | ||
continue | ||
# All events are input events | ||
self.autoSetup(int(params[0]), GPIO.IN) | ||
if len(params) == 3: | ||
GPIO.add_event_detect(int(params[0]), int(params[1]), bouncetime=int(params[2]), callback=self.eventTrigger) | ||
else: | ||
GPIO.add_event_detect(int(params[0]), int(params[1]), callback=self.ventTrigger) | ||
self.eventsMap[int(params[0])] = address[0] # The Event is OWNED by the request client! | ||
clientsocket.send('0') | ||
elif m.group(1) == 'delEvent': | ||
if int(params[0]) in self.eventsMap and self.eventsMap[int(params[0])] == address[0]: | ||
GPIO.remove_event_detect(int(params[0])) | ||
clientsocket.send('0') | ||
else: | ||
clientsocket.send('-1') | ||
|
||
# Enhanced commands | ||
elif m.group(1) == 'blink': | ||
try: | ||
pid = os.fork() | ||
if pid > 0: | ||
clientsocket.send('0') | ||
# parent stuff finished, listen again | ||
continue | ||
self.enableAtExit=False | ||
self.blink(params) | ||
exit() | ||
except OSError, e: | ||
# not forked blink, main process listen STOPS until it ends | ||
clientsocket.send('1') | ||
self.blink(params) | ||
else: | ||
clientsocket.send('-1') | ||
continue | ||
#except: | ||
# clientsocket.send('-2') | ||
# continue | ||
clientsocket.send('-1') | ||
|
||
def blink(self, params): | ||
self.autoSetup(int(params[1]), GPIO.OUT) | ||
active = 1; | ||
if len(params) == 3: | ||
active = int(params[2]) | ||
for i in range(0, int(params[0])): | ||
GPIO.output(int(params[1]), active) | ||
time.sleep(0.5) | ||
GPIO.output(int(params[1]), not active) | ||
time.sleep(0.5) | ||
|
||
def autoSetup(self, port, type): | ||
if port in self.setupMap: | ||
if self.setupMap[port] == type: | ||
return | ||
GPIO.setup(port, type) | ||
self.setupMap[port] = type | ||
|
||
|
||
if __name__ == "__main__": | ||
daemon = GPIODaemon('/tmp/gpiod.pid') | ||
daemon.init() | ||
Daemon.Daemon.manage(daemon) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#!/usr/bin/python | ||
import os | ||
|
||
import ConfigParser | ||
|
||
config = ConfigParser.ConfigParser() | ||
config.read([os.path.dirname(__file__) + '/../etc/GPIO.conf']) | ||
|
||
authMode=not config.get('auth', 'token') in ('0', 'False') | ||
|
||
import socket | ||
import sys | ||
|
||
sys.path.insert(0, os.path.dirname(__file__) + '/../lib') | ||
from myGPIO import mnemonic | ||
|
||
import md5 | ||
|
||
def getToken(): | ||
#create an INET, STREAMing socket | ||
a = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#now connect to the token daemon on custom port | ||
a.connect((config.get('auth', 'host'), int(config.get('auth', 'port')))) | ||
|
||
a.send('get') | ||
t = a.recv(64) | ||
return t | ||
|
||
|
||
#create an INET, STREAMing socket | ||
s = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#now connect to the daemon listening port | ||
s.connect((config.get('client', 'host'), int(config.get('common', 'port')))) | ||
|
||
tr = socket.socket( | ||
socket.AF_INET, socket.SOCK_STREAM) | ||
#now connect to listen on the event trigger port | ||
tr.bind((config.get('client', 'host'), int(config.get('common', 'pushEventPort')))) | ||
tr.listen(1) | ||
|
||
debounce = '10' | ||
if 2 in sys.argv: | ||
debounce=sys.argv[2] | ||
cmd = 'GPIO.addEvent(' + sys.argv[1] + ',' + str(mnemonic.BOTH) + ',' + debounce + ')' | ||
a = md5.new() | ||
if authMode: | ||
t = getToken() | ||
a.update(t) | ||
a.update(cmd) | ||
s.send(a.digest() + '::' + cmd + '::' + t) | ||
else: | ||
# Poor Man Authenticathion SECRET | ||
pma=config.get('auth', 'pma') | ||
|
||
a.update(pma) | ||
a.update(cmd) | ||
s.send(a.digest() + '::' + cmd) | ||
print s.recv(16); | ||
|
||
while (1): | ||
(pushsocket, address) = tr.accept() | ||
if pushsocket.recv(8) == sys.argv[1]: | ||
print('[SUCCESS] Event detected') | ||
else: | ||
print('[ FAIL! ] Error detected') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import sys | ||
sys.path.insert(0, '../lib') | ||
|
||
import time | ||
import myGPIO | ||
import RPi.GPIO as GPIO | ||
|
||
print "GPIO.PUD_UP %d" % GPIO.PUD_UP | ||
print "GPIO.PUD_DOWN %d" % GPIO.PUD_DOWN | ||
o = myGPIO.mnemonic() | ||
|
||
myRed=getattr(o, 'GPIO24') | ||
myGreen=o.GPIO25 | ||
myBlue=o.GPIO8 | ||
|
||
GPIO.setup(myRed, GPIO.OUT) | ||
GPIO.setup(myGreen, GPIO.OUT) | ||
GPIO.setup(myBlue, GPIO.OUT) | ||
|
||
GPIO.output(myRed, False) | ||
GPIO.output(myGreen, True) | ||
GPIO.output(myBlue, True) | ||
|
||
for i in range(1,6): | ||
time.sleep(1) | ||
GPIO.output(myRed, (i % 2)) | ||
time.sleep(1) | ||
GPIO.output(myBlue, False) | ||
time.sleep(2) | ||
GPIO.output(myBlue, True) | ||
GPIO.output(myGreen, False) | ||
time.sleep(2) | ||
GPIO.output(myGreen, True) |
Oops, something went wrong.