I am trying to get an RPi3 robot to accept commands from both the Web and from a touchscreen/keyboard interface. I have a script that handles the keyboard and I am looking for that current script I have in Python to be expanded to accept real-time input from the web. As well as trying to figure out how to send the data to the script.
More detail is below but that is the basic question.
I created the robot using a raspberry pi and 3 arduinos controlling DC motors and servos to make the bot move. The program is written in Python and is run from the command line. when run it:
queries the active serial ports on the Raspberry
opens each available port
sends an integer to the receiving arduino
the arduino responds with an identifying integer so the RPI can name the port
then the script waits for user input like "Forward"
the command is translated and sent to the correct port
the robot moves
This all works perfect. Now I want to expand it. I want to keep this functionality intact and add in a web interface so I can control it from anywhere. I've tried a couple of different things with no success. I have installed apache and I am able to serve the pages with no problem, I can get the data on the page, but I can't figure out how to get the web page to send the data to the running arduino script. My issue stems from the fact that the bot control script needs to run independent of the web page. I want to still keep the same input now from the keyboard, but I also want it to accept the data from the web page. If I invoke the bot controller from the web page each time it will need to re-establish the port connections each time which takes up to 20 seconds...
I am thinking if I create a listening script I can have the website invoke the listener which will run only to receive the data from the web and pass it to the bot controller and back. But I am not sure how to do this or if this is even the best way.
I've looked at websockets, CGI/wsgi, Flask, writing a file, and JSON and I just can't seem to string it all together.
Thanks in advance and apologies if this is not in the right place or has been answered before. Also, I have not included any code as the only solid code is the bot controller. I am hoping someone with some real expertise can help me unravel this.
thanks in advance
KenV
I would say Flask is your best option. A simple example of how you could use it:
from my_robot_stuff import move_forward
#app.route('/move_forward')
def move_forward_flask():
move_forward()
return redirect('/')
Your html would then have a button that says move forward that directs to mysite.com/move_forward. flask would process it, run the code, then redirect back to the root.
Related
I'll try to be as clear as possible with what I'm trying to aim for.
I have a running Python script on my Raspberry Pi and I'd like multiple users to send inputs to the script remotely (through SSH or anything else that might work better).
So for example if I have this script running:
Name = input ("Please type in your name. \n")
type (Name)
print ("Hello there" , Name)
time.sleep(3) # Pause for 3 seconds.
I want users to send names to this script remotely from devices that are connected to the same network as the Raspberry Pi.
If possible, I also want to implement the following functionalities:
Sending the output (aka the printed text) back to the specific device the input came from.
A queuing system: If multiple users send names at the same time, the script will take the names in order, one by one.
I know it's a lot to ask for, but I'd really appreciate if someone could help me get started with this by pointing me in the right direction. I've searched around quite a bit for the past few days but I haven't really come across anything that fits my needs.
Edit: I'm running this on PYTHON 3
Your comment that you would like to communicate (via network) to the script directly, opens up a world of possibilities. You have to modify your Python script a little though, because it won't communicate via stdin/stdout any longer.
I'm still not entirely sure how you want things to work but it does sound to me that a solution based around RPC can possibly work for you. May I suggest you have a look at Pyro4? Basically what that does for you is enable you to do normal Python method calls, but over the network, to code running on another computer.
So you can set up a server on your Pi (that needs to run continuously) which accepts remote calls from other computers, and can then call into your python code on the pi. It can process calls in parallel or in sequence. You didn't say if you need any form of security, but some basic security features are provided (no built-in encryption or communication over TLS yet, sorry).
A simple example is here and lots more are on github so you can have a look to see if this fits your requirements?
Another solution that doesn't require third party libraries is perhaps to write a WSGI http server that calls your script, run this on the pi, and access it via HTTP from your other computers.
Hi everyone I am trying to make a relatively simple home automation system with ifttt and my raspberry pi model b+. My goal is to create a python script which hosts a web server which can be posted to by ifttt maker channel. The pi needs to be able to detect the post by ifttt and then run an action in my case change the color/brightness/state of an RGB LED. I have already tried use email to control actions but that was very slow and whenever wifi dropped out on my pi the script crashed so I also will need a detection system that can detect when wifi is out to prevent crashes. I am currently 11 years old (Shocker) but I need some help because currently, i am struggling to get anywhere close to my goal. Any help will be greatly appreciated.
The RPi side
There are two separate scripts you need:
1) Python script which will host a web-server.
2) Python script which can manipulate RGB data.(Guess you already have this)
On IFTTT side First of all, check out this IFTTT service called Maker Web-hooks.
Basically, IFTTT is able to hit URLs(in your case, your python web-services). So you expose an API, tell IFTTT to listen to a trigger of you choice. And upon trigger, invoke your web API. This should be very fast.
A Few Notes
1) The RPi's server needs to be accessible from the internet, not just the local wi-fi. This is because IFTTT is going to try to reach out to your RPi web-server.
2) For quick message delivery, you can evaluate MQTT. This has been explained in another answer here. The only shortfall is, you need to register(for free) for an MQTT broker service. So there's essentially an additional entity between IFTTT and your RPi.
3) Like #anjsimmo has said, exception handling is a must. You'll need to do it with any sort of code.
I'm running my personal home-automation system with the same RPi model, using MQTT. Publisher is an Android app and subscriber is the RPi. All the best with your project!
I'm making a cmd IRC client in Python. I want to receive data at the same time I can write message, in the previous code I did I could only write 2 messages and then it bugs and I can't write until it receives some kind of data.
The question is, can I have one cmd window running the received data and other one with a constant input waiting for me to write something to send?, maybe with threads?
I've looked through the subprocess library but I don't really know how to code it.
CMD1:
while Connected:
print socket.recv(1024)
CMD2:
while Connected:
text = raw_input("Text to send>> ")
socket.send(text)
(This is a pseudocode not a real one)
This approach you are proposing could be done by making a server like application, and 2 client applications that connect via localhost to send and receive events. So that way you could have 2 terminals open , connected to the same session of the server.
On the other side you should consider a different design approach that include ncurses which allow you to make a terminal ui with input and output at the same terminal (two sections up and down). You can reference: http://gnosis.cx/publish/programming/charming_python_6.html
I'm pretty new to programming and I've been learning python in my spare time. As a challenge to myself, I created a simple text adventure for a class project. This is not for a programming class, so the professor won't know how to compile a raw Python script, let alone have a Python interpreter on their Mac.
That being said, is it possible to run python from a browser? I'm imagining some HTML file that my professor, or anyone, can click that launches a browser and they can play my game from there.
I've learned about something called Django from my research on this subject. However, I have no idea what it is, nor how to implement it. Again, I'm pretty new to programming, so if you could "explain like I'm five", that would be great.
EDIT: I found this other thread where the OP asks a similar question, but I don't fully understand the approved answer:
execution python application from browser
Well, not really. Your basic browser generally supports 1 programming language, javascript.
However, you could use pythonanywhere" which is a hosted python environment.
You could also try skulpt which is a javacript implementation of python. I have never tried this myself.
You can host a website on an internal network and run the program from there. Read more about the Python CGI programming
here to make a form that will execute your script and print the result as a html page
For example you could have a form that will ask for input in textboxes: Name: _, Value: __, SUBMIT
After they press the button, the browser will then send a request to the python program, execute it, and display the result back to the client as a html webpage.
In addition, you do not need to install any other third-party modules if you are using a school computer. However, ask you teacher before hosting the website on the school network.
The problem is that your program is a "text adventure" which requires a lot more input/output management for a CGI program.
You can use this answer for other projects.
Anyway, here are the steps to setup the server:
1) Create a folder for your website and add a "index.html" file (it can be anything)
2) Add a favicon.ico file in the folder (this will speed up the connection) You can download this one
3) Put this python program in the folder (it will be used to host the website)
import BaseHTTPServer
import CGIHTTPServer
import cgitb; cgitb.enable()
from socket import gethostbyname, gethostname
def server(port):
server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
server_address = ("", port)
httpd = server(server_address, handler)
print "Server %s:%s started" % (gethostbyname(gethostname()), str(port))
httpd.serve_forever()
server(4) #You can change this. It is a port number
4) Create a cgi-bin folder
5) To make the website available, execute the program created in the step 3. To stop hosting it, just close the python console.
6) While the program is running, you can go into the browser and type the IP adress : port as the URL. You will see your index.html page and favicon.ico icon. Anyone who is connected to the same network can get to the website. You and only you can also get to the website in a browser by entering http:/localhost:port with "port" being the port you've set
7) The rest you need to manage yourself. I cannot create the full script because I do not know what is in your program. Read the link provided in the beginning and modify your program to make it work in the browser.
FYI: It is possible to host more than one website or an instance of the same website at once using different ports. And, you can set and read cookies using Python CGI
Please comment if something doesn't work because of an error in my answer. I will try to fix it.
All of the answers so far assume that your game is something that can be presented as a web app. You can only do that if you write or covert your program (or part of it) into Javascript, which may not actually work because the existing compilers (e.g. pyjs) are quite limited.
If you made your program in a GUI (using 'Tkinter', 'Pygame', wxPython, PyQt, etc.), your best option is to package your program into a Mac app using py2app or pyinstaller.
Hej,
I have written a little music player like winamp in python. It has a GUI (Songname, Play/Pause, Next, Previous, time progress bar), I can open a folder and the audio files are played one after the other.
Now I really like to add a remote control through a webserver hosted on the same machine. My idea is to have the same buttons and outputs (also a time progress bar) as in the GUI on a webpage.
Scenario: I start my music player on my computer (it also automatically starts a webserver), I choose my folder with songs and skip two songs by clicking on the GUI on my desktop. Now I decide to sit on the couch and read a book. After a while the music annoys me and I want to pause it. I grab my phone, visit the webpage and tap on the pause button. The music stops and also the desktop GUI reacts (stops the time progress bar and displays the play button instead of the pause button).
I know how to create a django server and how to run it, but I do not know how to let the django views communicate with my music player on my desktop.
I have googled and read some stuff but I have no idea which way to go:
signals: don't know if this makes any sense since the two processes are totally detached
communicate over a database, save the state of the music player in a database row and let both processes update the entry whenever a button is pressed: don't like this idea because I'd like the two processes to commuicate without interpreter
maybe use UDP/TCP: but why, the processes are on the same machine
If I had to program it right now, I'd choose the database approach or is there any other solution I haven't stumbled upon yet? Shall I use flask instead of django?
If this is a common question and task, I am sorry for repeating, but I just could not find anything stating how to solve this.
What you are looking for is IPC (inter process communication). My instinct would be to have the music player open a socket, bind to a port, and to listen for commands.
Then in the Django view you open a socket connection to the player, send the command and return a response to the browser.
I you want full two way communication to the browser then you would need to also have a process waiting for output from the music player and sending it back to the browser via a web socket connection. The standard socket tutorial is very handy.