After the Program Code v0.1, I made a better but still simple code. There is no need for wsgi module anymore. But there is need of zmq module. See the new Preparing the Raspberry Pi.
The new system works with three files. The chimeService.py runs continuously and it is waiting for calling on port 5555. The chimeClient.py can send a request for pattern to the service. This python file can be called from cron, from other scripts, etc. The chimes.php is the file on the webserver. It can call the chimeClient when that is needed.
- You can send a pattern to make music. For example http://your_ip_address/chimes.php?pattern=1:0.5-1:0.5-4:1. That means: hit the rod 1, then wait 0.5 sec, then hit the rod 1, then wait 0.5 sec, then hit the rod 4, then wait 1 sec.
- You can use the IFTTT's Maker channel to make a specific chime web request. So the chimes can be triggered when you receive in important email, or you wife comes home, or there is a new instagram photo, etc. etc.
chimeService.py
import sys, zmq
import RPi.GPIO as GPIO
import time, datetime, re
port = "5555"
GPIO.setmode(GPIO.BOARD)
#Connect the RodNumbers to the GPIO board numbers.
chimeRod2Pin = {0: 37, 1: 36, 2: 33, 3: 31, 4: 29}
GPIO.setwarnings(False)
for pin in chimeRod2Pin:
GPIO.setup(chimeRod2Pin[pin], GPIO.OUT,initial=GPIO.LOW)
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:%s" % port)
power = float
def calculatePower():
power = 0.06
now = datetime.datetime.now()
if ( now.hour > 21 ) or (now.hour < 9 ):
power = 0.03
else:
power = 0.05
return power
def hitRod( number ):
GPIO.output(chimeRod2Pin[number], GPIO.HIGH)
time.sleep(power)
GPIO.output(chimeRod2Pin[number], GPIO.LOW)
def hitPattern( pattern ):
hit = map(str, pattern.split('-'))
for i in range(0, len(hit)):
if hit[i] != '':
tmp = map(float, hit[i].split(':'))
hitRod(tmp[0])
time.sleep(tmp[1])
def validatePattern( subject ):
pattern = "^([0-4]{1}:\d{1}(\.\d{1,2}|)(-|$))+$"
matchObj = re.match(pattern, subject)
if not matchObj:
return False
else:
return True
while True:
# Wait for next request from client
message = socket.recv()
print "Received request: ", message,
if not validatePattern(message):
print "=> Invalid pattern!!"
socket.send("Invalid pattern!")
else:
power = calculatePower()
hitPattern(message)
print "=> Done."
socket.send("Done.")
chimeClient.py
import sys, zmq
port = "5555"
context = zmq.Context()
print "Connecting to server..."
socket = context.socket(zmq.REQ)
socket.connect ("tcp://localhost:%s" % port)
if len(sys.argv) > 1:
pattern = sys.argv[1]
print "Sending pattern: ", pattern
socket.send (pattern)
message = socket.recv()
print "Received reply: ", message
chimes.php
<strong>Let's make some noise!</strong><br/><br/>
Please send the request pattern in the url.<br/>
See for example: <i>?pattern=4:0.5-3:0.5-2:0.5-1:0.5-0:1-0:1</i><br/><br/>
<?php
$pattern = $_REQUEST['pattern'];
if(!validatePattern($pattern)) {
echo "<strong>Invalid pattern! Please see the example.</strong>";
exit;
}
echo "<strong>Current request:</strong> ".$pattern;
/* Run the pattern without waiting for response */
exec('python /path/to/file/chimeClient.py "'. $pattern .'" > /dev/null 2>/dev/null &');
/* Run the pattern and wait for the response
exec('python /path/to/file/chimeClient.py "'. $pattern .'" ',$output,$return);
echo "<pre>";
foreach($output as $line)
echo $line."\n";
echo "</pre>";
*/
function validatePattern($pattern) {
if(preg_match('/^([0-4]{1}:\d{1}(\.\d{1,2}|)(-|$))+$/', $pattern))
return true;
else
return false;
}
?>
Important notes:
- The GPIO access needs superuser role (sudo). So the chimeService should run by the root. Or another possible solution is to add a chime runner user to the group pi as described here. (Or to add this chime runner user to the root group.) (The chimeClient does not need special access.)
Development for the future:
- The webpage could send the request with ajax so it could receive the answer.
- Anybody can make me crazy if he knows my public ip.
- It cannot hit more than one rod in the same time.
- API for switch off/on? It can be useful for an afternoon nap.
Do you have any other comment, idea, suggestion?
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.