nununo / pycandle2017 Goto Github PK
View Code? Open in Web Editor NEWCandle (2017) in Python
Home Page: https://works.nunogodinho.com/candle/
Candle (2017) in Python
Home Page: https://works.nunogodinho.com/candle/
Including:
inputs.agd.source
is outdated.dbus-daemon
process should also be running.With the change in 074fbbe (argh, a PR would definitely have been cleaner!) the following sequence is now possible:
The last step does not make sense:
Possible fixes:
Player manager general behaviour:
start(self)
:
level(self, new_level, comment='')
:
_player_ended(self, level)
:
The race condition:
level(new_level=X)
called: player unpaused, level X video is played, fades out and player process terminates._player_ended(level=X)
: spawns new level X player.level(new_level=X)
called before just spawned level X player is ready.This would be within acceptable limits if a subsequent level X trigger would work. Unfortunately it does not, so this must be fixed.
Possible fix will need to not only track player termination but also player readiness.
Below is a player.*
debug level log of the occurrence:
18:14:03.001381 [player.mngr#info] new_level=1 comment='network'
18:14:03.003097 [player.each.com.nunogodinho.vela2017-1-01#debug] asking player to play/pause
18:14:03.017497 [player.each.com.nunogodinho.vela2017-1-01#debug] asked player to play/pause
18:14:03.019412 [player.each.com.nunogodinho.vela2017-1-01#info] fade in starting
18:14:03.020830 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 0
18:14:03.058684 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 96.381676197052
18:14:03.099508 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 200.49487352371216
18:14:03.161713 [player.each.com.nunogodinho.vela2017-1-01#info] fade in completed
18:14:05.940658 [player.each.com.nunogodinho.vela2017-1-01#info] fade out starting
18:14:05.942076 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 255
18:14:05.969577 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 240.94610452651978
18:14:06.010768 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 219.9284291267395
18:14:06.040127 [player.mngr#info] new_level=1 comment='network'
18:14:06.052054 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 198.8754916191101
18:14:06.092972 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 178.01369905471802
18:14:06.133929 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 157.1235752105713
18:14:06.175132 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 136.11124992370605
18:14:06.216207 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 115.15485763549805
18:14:06.257382 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 94.16709423065186
18:14:06.298490 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 73.2254147529602
18:14:06.339461 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 52.30732440948486
18:14:06.380493 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 31.374034881591797
18:14:06.391978 [player.mngr#info] new_level=1 comment='network'
18:14:06.421738 [player.each.com.nunogodinho.vela2017-1-01#debug] alpha 10.33787727355957
18:14:06.484176 [player.each.com.nunogodinho.vela2017-1-01#info] fade out completed
18:14:06.567999 [player.dbus#debug] signal data=(':1.24', ':1.24', '')
18:14:06.574260 [player.dbus#debug] signal data=('com.nunogodinho.vela2017-1-01', ':1.23', '')
18:14:06.577890 [player.dbus#debug] signal data=(':1.23', ':1.23', '')
18:14:06.580275 [player.proc.com.nunogodinho.vela2017-1-01#debug] stdout: b'Video codec omx-h264 width 1280 height 720 profile 77 fps 25.000000\nSubtitle count: 0, state: off, index: 1, delay: 0\nV:PortSettingsChanged: [email protected] interlace:0 deinterlace:0 anaglyph:0 par:1.00 display:0 layer:1 alpha:0 aspectMode:0\nhave a nice day ;)\n'
18:14:06.585271 [player.proc.com.nunogodinho.vela2017-1-01#debug] player process ended; exit_code=0
18:14:06.587023 [player.mngr#info] player level=1 ended
18:14:06.588351 [player.mngr#info] creating player level=1
18:14:06.590380 [player.each.com.nunogodinho.vela2017-1-01#info] spawning player 'com.nunogodinho.vela2017-1-01'
18:14:06.591918 [player.dbus#info] tracking dbus player 'com.nunogodinho.vela2017-1-01'
18:14:06.593308 [player.mngr#debug] executable is '/usr/bin/omxplayer.bin'
18:14:06.595053 [player.mngr#debug] executable is '/usr/bin/omxplayer.bin'
18:14:06.603210 [player.proc.com.nunogodinho.vela2017-1-01#debug] player process started
18:14:06.607334 [player.dbus#info] waiting player 'com.nunogodinho.vela2017-1-01' start
18:14:06.712040 [player.mngr#info] new_level=1 comment='network'
18:14:06.713216 [player.each.com.nunogodinho.vela2017-1-01#debug] asking player to play/pause
18:14:06.714924 [twisted.internet.defer#critical] Unhandled error in Deferred:
18:14:06.715876 [twisted.internet.defer#critical]
Traceback (most recent call last):
File "/home/tiago.montes/pyVela2017.venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1532, in unwindGenerator
return _inlineCallbacks(None, gen, Deferred())
File "/home/tiago.montes/pyVela2017.venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
result = g.send(result)
File "/home/tiago.montes/pyVela2017/player/player.py", line 200, in play
yield self.play_pause()
File "/home/tiago.montes/pyVela2017.venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1532, in unwindGenerator
return _inlineCallbacks(None, gen, Deferred())
--- <exception caught here> ---
File "/home/tiago.montes/pyVela2017.venv/lib/python3.4/site-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
result = g.send(result)
File "/home/tiago.montes/pyVela2017/player/player.py", line 190, in play_pause
yield self._dbus_player.callRemote(
builtins.AttributeError: 'NoneType' object has no attribute 'callRemote'
18:14:06.791978 [player.dbus#debug] signal data=(':1.25', '', ':1.25')
18:14:06.794413 [player.dbus#debug] signal data=('com.nunogodinho.vela2017-1-01', '', ':1.25')
18:14:06.795625 [player.dbus#info] player 'com.nunogodinho.vela2017-1-01' started
18:14:06.796671 [player.each.com.nunogodinho.vela2017-1-01#debug] getting dbus player object
18:14:06.797847 [player.each.com.nunogodinho.vela2017-1-01#debug] got dbus player object
18:14:06.801525 [player.dbus#debug] signal data=(':1.26', '', ':1.26')
18:14:06.897648 [player.each.com.nunogodinho.vela2017-1-01#info] duration is 3.52s
18:14:06.899038 [player.each.com.nunogodinho.vela2017-1-01#debug] asking player to play/pause
18:14:06.917616 [player.each.com.nunogodinho.vela2017-1-01#debug] asked player to play/pause
18:14:06.983720 [player.mngr#info] new_level=1 comment='network'
Following up on #30, #31, #32, and playing around with starting, stopping, process relationships and their unexpected exits, found yet another "ugly way" things can fail (as in, it will hang in there for ever).
Reproducing:
dbus-run-session
, dbus-daemon
, python
and 4x omxplayer.bin
.dbus-daemon
suddenly goes away.candle2017.py
to omxplayer.bin
communication is possible:omxplayer.bin
processes to go away from DBus.omxplayer.bin
unexpected stops aren't properly handled: player manager respawns then, but waits forever for them to appear on DBus, thus never pauses them, etc.)Without detecting DBus disconnections, the race condition solution is to implement a timeout on the last step above. Stop will work, albeit somewhat slowly, depending on the timeouts.
Detecting DBus disconnections, there are two possible solutions:
_stop_via_dbus()
and going directly to _stop_via_sigterm()
; this avoids the race condition and ensures a fast stop.DBus disconnections can be detected with:
from txdbus import client
dbus_conn = yield client.connect(...)
dbus_conn.notifyOnDisconnect(callable_receiving_two_args)
Sensors are currently not calibrated. Particularly for level 1.
Notes:
settings.json
file?PS: By the way, should web changed log levels be saved back as well? (not as important, of course)
Convert it instead to a dependency on wires which is mostly the same code, somewhat improved and tested, which I just published on PyPI.
I was driving back home when it struck me that these are commonly available devices useful to:
I investigated a little bit and I guess I have a solution.
While working on #93, I stumbled upon a behaviour I think might need to be reviewed:
player_manager
allow triggering a level 1 clip while a level 2 clip is playing.Implementing #62 will probably lead to some duplication regarding the raw audio input processing, where some variation of the arduino input's "aggregated derivative" will be implemented.
Implementing #62 also brings "challenges" like: how do we get this input's raw/derivative/whatever data plotted via the web?
The general idea about dynamic input wiring is:
settings.json
will tell how to arrange/wire things up, via new output
/input
entries defined in each input.Here's an sketch:
inputs: {
"arduino": {
"device_file": ...,
"baud_rate": ...,
"output": "arduino-raw",
},
"agd": {
"thresholds": [10, 20, 30],
"input": "arduino-raw",
"output": "arduino-agd"
},
"web": {
...
"chart-1-input": "arduino-raw",
"chart-2-input": "arduino-agd",
}
}
With the way the current event manager works, implementing this is trivial.
PS: May need some additional thinking with regards to the web UI's "chart names" and "stuff"!
Once the API is stable the change will be trivial:
Standing by on tmontes/python-wires#24
Once #90 is merged, I'll quickly address this.
Current scenario:
candle2017.py
checks for the DBUS_SESSION_BUS_ADDRESS
variable in the environment.dbus-run-session
.Observation:
dbus-run-session
limitations, this leads to somewhat inelegant clean stops.Idea (after a little investigation):
dbus-run-session
and use dbus-damon
directly instead.player/dbus_manager.py
can handle it all:
dbus-daemon
with the --session
and --print-address
flags.stop
method to stop the spawned dbus-daemon
.Benefits:
Efforts:
Given the multitude of inputs, and the fact that some do not work concurrently, it would be nice to be able to disable them in the configuration instead of having to delete them.
Maybe an "enabled" key per each input entry is enough, taking values true
or false
.
Currently using a collections.deque()
to track the most recent _INPUT_SIZE
readings.
On every new sensor reading:
This is computationally intensive and non-scalable (memory and processor-wise).
Thoughts:
current_agd
), incrementally updating it as in:
current_agd
to 0 and clear the deque().current_agd
and, if len(deque) == _INPUT_SIZE
, subtract its oldest value from current_agd
; then append the reading to the deque().PS: Not that we desperately need those CPU cycles, though. :)
Guarantees that when level N clip ends, we don't get a trailing piece of a level N-1 longer clip!
Scratching an itch, useful for:
Preliminary notes at https://github.com/tmontes/pyVela2017/blob/xplore-asla-input/inputs/alsaaudio/README.md
Status quo:
Idea:
Once done:
TEASER: https://github.com/tmontes/pyVela2017/blob/xplore-asla-input/inputs/alsaaudio/README.md
For correct web based AGD threshold visualisation and changes, the web input must be declared before the AGD input in settings.json
.
This stems from the fact that the input instantiation order is directly sourced from the configuration.
Possible fixes:
I'm in a "make things simpler and with less code" tonic...
Preamble
I have a WIP branch that simplifies the webserver by quite a bit: it mostly throws the http
module away and handles everything in what has been the websocket
module to date (but renamed to server
on that branch).
The benefits are:
That branch is holding on #55 which imposed other types of simplifying changes to websocket.py
.
Result
With such a simpler and now easily configurable web server, maybe we can move it to the inputs
package and take advantage of its ability to "setup" inputs based on the settings.json
configuration.
While the webserver is not strictly an "input", I think it fits nicely along with the other inputs.
Thoughts?
Reproducing steps:
kill SIGTERM <pid>
.Improvement:
player/player.py
handle the TimeOut
condition and try to send a SIGTERM to the associated spawned process, tracking it if needed.README says that stopping can be achieved by sending a SIGTERM to the Python process.
This procedure leaves the spawned omxplayer.bin processes running.
Fixing needs to be done via Twisted event handling.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.