Giter Site home page Giter Site logo

missionpinball / mpf-monitor Goto Github PK

View Code? Open in Web Editor NEW
11.0 8.0 10.0 973 KB

Graphical utilty which connects to MPF to let you visually control, troubleshoot, and see the status of the machine

Home Page: http://missionpinball.org

License: MIT License

Python 100.00%
mpf mission-pinball-framework debugger

mpf-monitor's Introduction

MPF Monitor (mpf-monitor)

This package is for the Mission Pinball Framework (MPF) Monitor (mpf-monitor).

The MPF monitor is a graphical app that connects to a live running instance of MPF and shows the status of various devices. (LEDs, switches, ball locks, etc.). You can add a picture of your playfield and drag-and-drop devices to their proper locations so you can interact with your machine when you're not near your physical machine.

The MPF Monitor can run on Windows, Mac, and Linux. It uses PyQt6 (Python bindings for Qt6) for its visual framework.

Installation & Instructions

Full instructions for installing and using the MPF monitor are included in the MPF documentation here: https://missionpinball.org/

Support

MPF is open source and has no official support. Some MPF users follow the MPF-users Google group: https://groups.google.com/forum/#!forum/mpf-users. Individual hardware providers may provide additional support for users of their hardware.

Contributing

MPF is a passion project created and maintained by volunteers. If you're a Python coder, documentation writer, or pinball maker, feel free to make a change and submit a pull request. For more information about contributing see the Contributing Code and Contributing Documentation pages.

License

MPF and related projects are released under the MIT License. Refer to the LICENSE file for details. Docs are released under Creative Commons CC BY 4.0.

mpf-monitor's People

Contributors

atummons avatar avanwinkle avatar blackbaud-johnmarsh avatar jabdoa2 avatar kylenahas avatar qcapen avatar toomanybrians avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mpf-monitor's Issues

MPF Monitor crashing

MPF Monitor is crashing for me, I have now tried on two Windows 11 computers. The second one I went with a completely new installation of Windows, Python and mpf (Python 3.9.13) , and configuration files. Used the installation instructions on the homepage.
It start as it should but as soon I move a switch to my playfield it crashes. If I then restart with mpf monitor it crashes again until I remove the configuration file that mpf monitor creates. Monitor.yaml only saves the location for the switch I just placed on the playfield. Exact same issue and error message on both computers.

Traceback (most recent call last):
File "C:\Users\Johan.local\pipx\venvs\mpf\lib\site-packages\mpfmonitor\core\playfield.py", line 198, in paint
painter.setRenderHint(QPainter.Antialiasing, True)
AttributeError: type object 'QPainter' has no attribute 'Antialiasing'

Move window storage to monitor.yaml file

Different games may need different window layouts, and the current scheme only restores from the last open instance of monitor. Saving the window layout with the game ensures it's presented how the designer intended.

Placing a device twice crashes Monitor

I accidentally dragged over a switch that I'd already placed on the playfield picture and Monitor crashed. Here's the log: https://github.com/missionpinball/mpf-monitor/files/3235561/2019-05-30-00-32-57-monitor-Gabes-MBP-2.log.

The crash from the Terminal window is below.

It's good to be back :)

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mpfmonitor/core/mpfmon.py", line 620, in dropEvent
drop_y)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mpfmonitor/core/mpfmon.py", line 625, in create_pf_widget
drop_y, save)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mpfmonitor/core/mpfmon.py", line 635, in init
widget.set_change_callback(self.notify)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mpfmonitor/core/mpfmon.py", line 44, in set_change_callback
raise AssertionError("Can only have one callback")
AssertionError: Can only have one callback
INFO : root : MPF Monitor run loop ended.
INFO : root : Stopping child threads... (2 remaining)
INFO : root : All child threads stopped.

List device attributes

Show all attributes pushed by MPF in the device tree. Very helpful for debugging and for building placeholders/templates

Run monitor from any folder

Look in the local folder for the config files, then maybe a /monitor folder. Also add command line option to specify config location.

MPF Monitor slows down greatly when large device tree is expanded

This seems to be an issue with lots of devices on the playfield.

To recreate, open a MPF Monitor project with lots of devices on the playfield (Demo Man example works), and expand the "light" device tree. MPF Monitor slows incredibly. Collapsing the large tree returns speed to normal.

I am not sure of the root cause, but it may be related to storing the data for playfield devices in the tree's model. In theory this issue also existed before my changes to the treeview rendering, but I'm not positive. I can test on an older version if wanted.

Potentially we could separate the data for the playfield devices from the tree model, but I'm not sure if that's the way to go.

Add monitor version to window (or about box)

There is currently no easy way to determine the version of the monitor running (except for pip list). It would be nice to put the version in the main window or create an about box. Also add the version to the log file.

PyQt and PyQt-Qt Version Errors

When there is a mismatch between versions, it throws the following error: from PyQt6.QtCore import *
ImportError: DLL load failed while importing QtCore: The specified procedure could not be found.

They can easily be fixed by running an install targeting the matching version.

It would be great to add to dependencies to make them match. I looked and couldn't find syntax to set them equal or use environmental variable in pyproject.toml

@toomanybrians any idea about how to set them to matching versions? If not do we just pin them both to 6.6.1 as dependencies to ensure they match and just increment manually as needed?

Render diverters

Render diverters as a shape on the playfield (just like switches or lights but another shape). Turn them purple when active.

Create integration test with MPF

Add some test to run the monitor with some minimal config on Travis. It should at least start. Currently, we sometimes break it without noticing.

Flipper Shape Unresponsive

Flipper shapes become unresponsive when device inspector is toggled which results with not being able to select it again (clicks on the object do not register)

Moving a switch toggles it

Not a huge deal, but when trying to position a switch on the playfield image by left-clicking and dragging, the switch is toggled to the opposite state that it was in. It's as if you right-clicked on it to move it.

Steps to recreate:

Place switch on to playfield image.
Left click + drag switch to a new location.

You have to right-click it to toggle it back off again.

Feature request: remove old events from mpf monitor

Hi,

when testing it sometimes would be helpful to start again with an empty list of events. Would be nice if the mpf monitor event list has a button "clear" which removes from that view all events posted so far. Maybe it would as well be helpful to have an additional column which shows the timestamp of the event posted. I know they are ordered as received, but seeing the time difference might be helpful to understand what action has posted such an event.

Thanks for the great tool!

Add recent events

I know it's opening up a ton of chatter, but it would be cool to see a list of recent events to Monitor. I think it would be implemented as a text box with checkboxes for different kind of events that make it into the list.

For example, I want to see events about shots, but I'm not sure what the full event is that I want to hook (like, is it shot_group_my_group_active_hit or shot_my_shot_flashing_hit or whatever). I'd have to run with -v and check the logs now.

Not sure if Monitor is just reading logs, but I suspect not, so if it saves me from stopping my game, running -v, and then filtering the logs, that would be a huge time saver when you add up 30 secs times 1000 different events I need to find.

Thoughts? I was thinking a UI like this:

O Shot events ร˜ Mode events O Logic Block events O Timer events O ...


2016-10-05 22:24:04,714 : DEBUG : Events : ^^^^ Posted event 'mode_attract_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.attract>>, Args: {}
2016-10-05 22:24:04,716 : DEBUG : Events : ^^^^ Posted event 'mode_attract_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.attract>>, Args: {}
2016-10-05 22:24:11,912 : DEBUG : Events : ^^^^ Posted event 'mode_game_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.game>>, Args: {}
2016-10-05 22:24:11,913 : DEBUG : Events : ^^^^ Posted event 'mode_attract_stopping'. Type: queue, Callback: <bound method Mode._stopped of <Mode.attract>>, Args: {}
2016-10-05 22:24:11,924 : DEBUG : Events : ^^^^ Posted event 'mode_attract_stopped'. Type: None, Callback: <bound method Mode._mode_stopped_callback of <Mode.attract>>, Args: {}
2016-10-05 22:24:11,925 : DEBUG : Events : ^^^^ Posted event 'mode_game_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.game>>, Args: {}
2016-10-05 22:24:11,965 : DEBUG : Events : ^^^^ Posted event 'mode_wizard_advance_lit_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.wizard_advance_lit>>, Args: {}
2016-10-05 22:24:11,970 : DEBUG : Events : ^^^^ Posted event 'mode_managers_choice_base_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.managers_choice_base>>, Args: {}
2016-10-05 22:24:11,975 : DEBUG : Events : ^^^^ Posted event 'mode_skill_shot_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.skill_shot>>, Args: {}
2016-10-05 22:24:12,031 : DEBUG : Events : ^^^^ Posted event 'mode_base_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.base>>, Args: {}
2016-10-05 22:24:12,057 : DEBUG : Events : ^^^^ Posted event 'mode_base_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.base>>, Args: {}
2016-10-05 22:24:12,060 : DEBUG : Events : ^^^^ Posted event 'mode_light_mission_select_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.light_mission_select>>, Args: {}
2016-10-05 22:24:12,061 : DEBUG : Events : ^^^^ Posted event 'mode_light_mission_select_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.light_mission_select>>, Args: {}
2016-10-05 22:24:12,065 : DEBUG : Events : ^^^^ Posted event 'mode_skill_shot_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.skill_shot>>, Args: {}
2016-10-05 22:24:12,079 : DEBUG : Events : ^^^^ Posted event 'mode_managers_choice_lit_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.managers_choice_lit>>, Args: {}
2016-10-05 22:24:12,080 : DEBUG : Events : ^^^^ Posted event 'mode_managers_choice_lit_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.managers_choice_lit>>, Args: {}
2016-10-05 22:24:12,082 : DEBUG : Events : ^^^^ Posted event 'mode_managers_choice_base_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.managers_choice_base>>, Args: {}
2016-10-05 22:24:12,083 : DEBUG : Events : ^^^^ Posted event 'mode_wizard_advance_lit_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.wizard_advance_lit>>, Args: {}
2016-10-05 22:24:12,106 : DEBUG : Events : ^^^^ Posted event 'mode_mystery_lit_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.mystery_lit>>, Args: {}
2016-10-05 22:24:12,110 : DEBUG : Events : ^^^^ Posted event 'mode_mystery_lit_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.mystery_lit>>, Args: {}
2016-10-05 22:24:16,269 : DEBUG : Events : ^^^^ Posted event 'mode_base_score_score'. Type: None, Callback: None, Args: {'change': 0, 'prev_value': 10, 'value': 10}
2016-10-05 22:24:16,275 : DEBUG : Events : ^^^^ Posted event 'mode_skill_shot_stopping'. Type: queue, Callback: <bound method Mode._stopped of <Mode.skill_shot>>, Args: {}
2016-10-05 22:24:16,291 : DEBUG : Events : ^^^^ Posted event 'mode_skill_shot_stopped'. Type: None, Callback: <bound method Mode._mode_stopped_callback of <Mode.skill_shot>>, Args: {}
2016-10-05 22:24:16,660 : DEBUG : Events : ^^^^ Posted event 'mode_base_score_score'. Type: None, Callback: None, Args: {'change': 0, 'prev_value': 10, 'value': 10}
2016-10-05 22:24:17,325 : DEBUG : Events : ^^^^ Posted event 'mode_base_score_score'. Type: None, Callback: None, Args: {'change': 0, 'prev_value': 10, 'value': 10}
2016-10-05 22:24:17,812 : DEBUG : Events : ^^^^ Posted event 'mode_base_score_score'. Type: None, Callback: None, Args: {'change': 0, 'prev_value': 10, 'value': 10}
2016-10-05 22:24:18,741 : DEBUG : Events : ^^^^ Posted event 'mode_base_score_score'. Type: None, Callback: None, Args: {'change': 0, 'prev_value': 10, 'value': 10}
2016-10-05 22:24:20,464 : DEBUG : Events : ^^^^ Posted event 'mode_light_mission_select_stopping'. Type: queue, Callback: <bound method Mode._stopped of <Mode.light_mission_select>>, Args: {}
2016-10-05 22:24:20,489 : DEBUG : Events : ^^^^ Posted event 'mode_mission_rotator_starting'. Type: queue, Callback: <bound method Mode._started of <Mode.mission_rotator>>, Args: {}
2016-10-05 22:24:20,491 : DEBUG : Events : ^^^^ Posted event 'mode_mission_rotator_started'. Type: None, Callback: <bound method Mode._mode_started_callback of <Mode.mission_rotator>>, Args: {}
2016-10-05 22:24:20,504 : DEBUG : Events : ^^^^ Posted event 'mode_light_mission_select_stopped'. Type: None, Callback: <bound method Mode._mode_stopped_callback of <Mode.light_mission_select>>, Args: {}

ModuleNotFoundError: No module named 'sip'

On execution of mpf monitor, the following error is displayed:

Traceback (most recent call last):
  File "/home/pinball/mpf/mpf-venv/bin/mpf", line 33, in <module>
    sys.exit(load_entry_point('mpf', 'console_scripts', 'mpf')())
  File "/home/pinball/mpf/pinball.mpf.git/mpf/commands/__init__.py", line 175, in run_from_command_line
    CommandLineUtility(path).execute()
  File "/home/pinball/mpf/pinball.mpf.git/mpf/commands/__init__.py", line 151, in execute
    *self.parse_args())
  File "/home/pinball/mpf/pinball.mpf-monitor.git/mpfmonitor/commands/monitor.py", line 100, in __init__
    from mpfmonitor.core.mpfmon import run
  File "/home/pinball/mpf/pinball.mpf-monitor.git/mpfmonitor/core/mpfmon.py", line 10, in <module>
    from PyQt5.QtCore import *
ModuleNotFoundError: No module named 'sip'

An MPF Virtual Environment is being used, and the following are installed with pip3:

(mpf-venv) pinball@lister:~$ pip3 list
Package          Version      Location
---------------- ------------ -----------------------------------------
asciimatics      1.11.0
certifi          2020.12.5
chardet          3.0.4
docutils         0.16
ffpyplayer       4.3.1
future           0.18.2
grpcio           1.31.0
grpcio-tools     1.31.0
idna             2.10
Kivy             1.11.1
Kivy-Garden      0.1.4
lxml             4.6.3
mpf              0.54.0.dev78 /home/pinball/mpf/pinball.mpf.git
mpf-mc           0.54.0.dev20 /home/pinball/mpf/pinball.mpf-mc.git
mpf-monitor      0.54.0.dev7  /home/pinball/mpf/pinball.mpf-monitor.git
packaging        20.9
Pillow           8.0.1
pip              21.0.1
pkg-resources    0.0.0
prompt-toolkit   3.0.8
protobuf         3.13.0
psutil           5.7.0
pyfiglet         0.8.post1
Pygments         2.3.1
pyparsing        2.4.7
PyQt5            5.15.4
PyQt5-Qt5        5.15.2
PyQt5-sip        12.9.0
PyQt5-stubs      5.15.2.0
pyserial         3.4
pyserial-asyncio 0.4
requests         2.25.0
ruamel.yaml      0.15.100
setuptools       54.2.0
six              1.15.0
sortedcontainers 2.1.0
terminaltables   3.1.0
toml             0.10.2
typing           3.7.4.3
urllib3          1.26.2
wcwidth          0.2.5
wheel            0.36.2

I also have python3-pyqt5 and python3-sip installed via apt.

System: Devuan v3 (beowulf)

Crash with Python 3.11, is PyQt6 compatible with 3.11?

I just updated the dev branch to v0.57.0.devXX and added Python 3.10 and 3.11 to the project as supported versions (and tests via GitHub).

Running on my Mac on Python 3.11 alongside MPF 0.57, I get crashes in MPF Monitor like this:

Traceback (most recent call last):
  File "/Users/brian/git/mpf-monitor/mpfmonitor/core/playfield.py", line 326, in mousePressEvent
    self.send_to_inspector_window()
  File "/Users/brian/git/mpf-monitor/mpfmonitor/core/playfield.py", line 396, in send_to_inspector_window
    self.mpfmon.inspector_window_last_selected_cb(pf_widget=self)
  File "/Users/brian/git/mpf-monitor/mpfmonitor/core/inspector.py", line 101, in update_last_selected
    self.ui.size_slider.setValue(self.last_pf_widget.size * 100)
TypeError: setValue(self, a0: int): argument 1 has unexpected type 'float'

The lines in question are here.

Obviously a simple fix is to wrap it in int(), but that leads to the next similar error (line 128), which leads to the next... I played with this but then the slider is wonky and doesn't really work. Plus it doesn't really match what the comments say.

So, I'm not sure what's happening. Searching the web, I can't even figure out if Python 3.11 is actually supported by PyQt6? So, dunno, someone needs to look into this I guess.

In the meantime, if I run on Python 3.9, even with the latest PyQt6 version 6.5.2, it works fine. So I think it's a Python 3.11 thing. (I didn't try on 3.10.)

People can still run this with MPF 0.57. If MPF is on Python 3.11 then they'll just need to have a separate install of 3.9 (again, or maybe 3.10?) to run monitor.

I'm not going to investigate this further at the moment, but if someone wants to take a look, that would be great.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.