I have been working on a Raspberry Pi powered photobooth that is controlled via a web interface on a user's smartphone as my first RPi project.
The booth itself has a built in display that has a pygame view to give an animated guide and countdown when taking pictures. It uses flask-socketio (http://flask-socketio.readthedocs.org/en/latest/) to handle client connections and input events from the user via the smartphone.
Pygame needs to be on the app's main thread, and so does socketio, so my problem is that I can't get socketio to work if displaying the pygame view.
My original logic was to have socketio events create an event like so:
#socketio.on('connect', namespace'/photo')
def client_connect():
evnt = pygame.event.Event(gui.INFOEVENT, msg="client_connect")
pygame.event.post(evnt)
and then catch this event in the pygame thread:
running = True
while running:
for event in pygame.event.get():
if (event.type is gui.INFOEVENT and event.msg == "client_connect"):
# welcome client on photobooth screen and start guide
Note: I haven't checked the syntax on this and it might be wrong.
Does anyone know how I might achieve this? And if so, is my logic half-way there?
I am struggling to get my head around threads and queues and whilst I have learned a tonne, this 'fun' project is slowly wearing me down! Very grateful for any help.
-Andrew
Three problems:
pygame.event.Event instances don't have a tpe attribute. I think you mean:
if (event.type is gui.INFOEVENT and event.type == client_connect):
A pygame event (or any other python object)'s type attribute can't simultaneously point to gui.INFOEVENT and client_connect at the same time, unless the two values are the same (which makes the second check redundant).
client_connect as a variable is never declared anywhere. I think you mean "client_connect".
However, pygame events can have arbitary attributes associated with them, so you can solve problem two by changing the second use of event.type (that stores client_connect) to any other value.
Note: I am not Familiar with socketio
In the end I couldn't find an answer to this but here's what I decided to do.
Instead of creating a GUI on the photobooth itself using a separate lib such as pygame with all the intricacies of threads and whatnot, I decided to create a separate route within my socketio app which I will load within a kiosk mode browser on the Raspberry Pi itself at runtime.
From there, my intention is that as the user interacts with the booth using their smartphone (via the index route) and events are fired back to the server (RPi), the server will deal with those interactions and additionally emit events to the local GUI via a different namespace.
These events can trigger animations, transitions or a countdown etc. on the 'local GUI'.
The only issues might be with performance and smooth animations as the interface requires a browser to be running, and an issue to work out when there is more than one user connected to the booth (though there could be a hardware issue in itself there if two clients try to access the camera at the same time, but that's another story!)
Best
Andrew
Related
i am working on a game project and i decide to go with twisted for the server part.
its a multiplayer shooting game.
now i want to integrate a main loop into the game (on server side) to process input and physics(for bullets and players).The inputs are recieved from the clients through websockets.
i want the game loop to run game at lets say. 50 fps.
if i follow the method for implementing a game loop mentioned in this atricle. i have this code below
previous = getCurrentTime()
def loop():
double lag = 0.0
while True:
current = getCurrentTime()
elapsed = current - previous
previous = current
lag += elapsed
processInput()
while (lag >= MS_PER_UPDATE):
update()
lag -= MS_PER_UPDATE
send_state_to_connected_clients()
In the article it mentions that:
If you’re making a game that runs in a web browser, you pretty much can’t write your own classic game loop. The browser’s event-based nature precludes it
Now i am having a difficult time understanding it as this applies to Twisted as it's also event based.(i think what it says is the while true statement will block the reactor forever.so what can we do to implement our own loop in twisted given its even based)
in the same article towards the bottom it mentions these points:
Use the platform’s event loop:
1. It’s simple. You don’t have to worry about writing and optimizing the core loop of the game
2. It plays nice with the platform. You don’t have to worry about explicitly giving the host time to process its own events, caching events, or otherwise managing the impedance mismatch between the platform’s input model and yours.
What i am looking for is a general approach towards implementing a game loop in twisted(for a networked multiplayer game).
should i use the inbuilt reactor by using the LoopingCall to call
my Loop? how does then it handles the issues
mentioned in the article.
should i create my own loop somehow? (ex by using threads/processes or some other construct to run the game loop seperate from reactor)
should i create my own reactor implementation somehow?
If I understand the problem accurately, you will have a Python server and players will play a real-time FPS in the browser. You will have to:
display the game in real-time
handle user events in the browser
send browser-event results to the server
parse the results on the server
send server events to the browser
handle server events in the browser
We already know that you are going to use WebSockets.
Display the game in real-time
You will need to display the graphics somewhere, maybe inside a canvas. You will need to implement lots of functions, like update health bar, display changes and so on. These will be triggered when you handle responses from the server.
Handle user events in the browser
If we assume that clicking is shooting, space is activate and so on, you will need some event handlers for those. In the browser you will need a browser-level validation. For instance, if the player intends to shoot, but there is no more ammo, then you do not even have to send a message to the server, maybe display a sound effect of the gun which signifies that shooting was unsuccessful. If, according to the data you have in the browser you have ammo, then the direction you shoot at should be sent to the server.
Send browser-event results to the server
When an event occurs in the browser and is evaluated, then the results in many cases will be sent to the server, which will handle them and eventually send a response to the browser.
Parse the results on the server
The server will have an event loop and will receive WebSocket messages from the browsers of the players. For example if the server receives a shoot event, then it will get the current coordinates of the player and the direction, calculate where the bullet goes and send a message to the players' browser. If someone is hit, then damage is to be calculated and determined whether the player dies, subsequently players will get WebSocket messages from the server and subsequently the sound of the bullet will be displayed along with the bullet's graphical display and potentially some blood, falling players and so on.
Send server events to the browser
The browsers will listen to WebSocket messages from the server and handle those.
Handle server events in the browser
We cannot trust user events, because some cheating could be involved, so when you shoot, the browser will handle the event and the server will receive a message. When the server sends a WebSocket message, the browsers will "believe" that the server sent an accurate response.
Technical needs
You will need a graphics API, user event listeners and WebSocket listeners in the browsers. On the server you will listen to client WebSocket messages.
I am trying to create a window in python where I will be displaying the status of a large system, a bunch of numbers or some LEDs. The idea is that the system sends messages to the display thread and the thread updates different parts of the window, like displaying a number or turning the color of a field. More importantly, the user interacts with system via command line of python interpreter, e.g. executing commands or updating variables.
One may simply suggest that I need to use one of the GUI packages, like pyqt or xwpython. But these modules are designed to build GUIs, that means they have plenty of resources to handle events moues clicks and so on, which I don't need. Also, these modules run a event loop which is a waste of resources as well as in many cases they block the python shell.
I tried to use pyqt without running the main loop. But when I do this windows thinks my application is not responding, and I get a bunch of problems. For example the close button on the window does not work, and any effort on closing it crashes my python session.
Any ideas on how I can implement my application?
Maybe you should consider to use the Apache's Superset dashboard.
Check this up:
https://superset.incubator.apache.org/installation.html
It makes amazing dashboards incredibly easy and useful.
So I'm trying to get a Python script to detect if I've pressed insert and if I have it should print the clipboard to a file.
I've got most of it working but it seems the game eats up my keyboard detection.
I currently have:
keyboard.add_hotkey('k',writeToFile,args=[])
using the keyboard module, but it does nothing when in game. Outside the game it works fine.
As the README says:
Other applications, such as some games, may register hooks that swallow all key events. In this case keyboard will be unable to report events.
If keyboard can't report the events, it can't use them to trigger a hotkey.
It may be possible to get around it by just waiting until the game has started, and only then starting your script. If there's no way to tab out of the game without quitting, of course, this is obviously a non-starter—but even if you can do that, it still may not work.
And if not, you just can't hook keyboard events with a global event hook. Which means there's nothing keyboard can do for you.
But, since you're dealing with an 18-year-old game here, there might be a workaround: You may be able to run the game inside an emulator or virtual machine, smoothly enough to be perfectly playable. If so, the game should only be able to globally hook events inside the emulator/VM, not on the real system, so your hook may be able to catch events first. (You may still need to run your script last, or you may need to configure your Wine/VMware/whatever settings, but it may just work out of the box.)
I am writing a simple Mac application designed to run in the background and perform certain actions whenever the user clicks the mouse button. The app is written in Python using PyObjC. I am using addGlobalMonitorForEventsMatchingMask to watch for NSLeftMouseDown events:
NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSLeftMouseDownMask, handler)
This code works perfectly when running in the terminal. However, when I bundle it as a standalone app (using py2app) and then launch it, the app doesn't receive any events at first. (Or at least, if it does, it doesn't run the code in my handler method.) Only when I click on the app in the Dock does it start receiving events, and after that, it continues to receive events even after it returns to the background. But it doesn't receive anything until activated once.
My question is: How can I get my app to start receiving events as soon as it is launched, without having to be activated first by clicking the Dock icon? Is this some known quirk of NSEvents, or is there perhaps something wrong with my run loop in PyObjC?
Any help or guidance is greatly appreciated!
Edit: Upon further testing, it seems that, in fact, my app spontaneously starts receiving notifications about ten seconds after launch, regardless of whether I activate it. Which is slightly annoying, but fine.
However, if I run the app with either LSUIElement = true or LSBackgroundOnly = true in my Info.plist (which I ultimately want to do, since this app should only run in the background and never appear in the Dock), I never receive notifications. So I am still stuck.
As you said "Only when I click on the app in the Dock does it start receiving events" , that means the handler gets registered after you click on the app in the Dock.
So it depends on at which point in the code you are calling this : NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSLeftMouseDownMask, handler) ,
that is registering the handler.
You should register the handler in appdidfinishlaunching function.
I am creating a script in Python to integrate Pidgin with Unity (Ubuntu 12.04), I've managed to do the counting notifications system using the Unity API, but i dont know what event or signal that is activated when the conversation window gains focus(To clear the message counter)...
I've tried some of the signals available on the documentation of Pidgin (https://developer.pidgin.im/wiki/DbusHowto) but none of them worked, is there any GTK(or anything) event that is triggered when the window chat gets focus?
Conversation UI signals are listed here those might be more helpful for what you are trying to do.
Though I don't know that I understand what you meant by your comment about the counter being wiped instantly when you tried some of the other signals. That sounds like it might be a coding error to me.