-
Notifications
You must be signed in to change notification settings - Fork 143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blinkenlights #1591
Blinkenlights #1591
Conversation
The purpose of blinkenlights are to allow multiple modes to be able to control the same RGB light. In this way, if multiple modes share the same shot, those modes can each add their own color to the light for that shot, and the shot will flash all the different colors to let the player know that the same shot will be scored for multiple modes. (For example, a multiball and a mode sharing the same ramp shot.) Modes can add colors to a blinkenlight with the blinkenlight_player, and the blinkenlight will cycle through all the colors that have been added. Modes can also remove colors, or remove all colors, effectively turning the blinkenlight off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it. Some small nits and some thoughts about sync.
mpf/devices/blinkenlight.py
Outdated
|
||
@property | ||
def num_colors(self): | ||
# I would prefer this to be a calculated value (i.e., just return len(self._colors)), but then there's no setter involved so things like mpf monitor won't know when this value gets updated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some magic methods on DeviceMonitor to notify it about changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to find the magic methods you mentioned but I don't see any on DeviceMonitor aside from __init__
and __call__
. I know __setattr__
is used to notify subscribers when a variable is changed, but how can I notifiy subscribers without creating a fake variable like this?
Guess we are good to land this. Some small coding style changes to fix and we can merge this:
|
Looking good. Well I haven't had time to look at mine any further, and you have already solved the problems, so I'll bow out here on fixes. I think it is looking great with Jan's comments there. Jan, how do we pull this down to run against our local machine? I'd love to pull it down and test it out with Monitor to see how its works. Or do we have to have it merged before that can be done? |
I roughly explained this in my video on the IDE setup. Short:
There are other ways with multiple remotes in one checkout but those are a bit tricky to use unless you are very familiar with the inner workings of git. |
Haven't watched that one yet (in my saved for later on YouTube), and I love the content!!! I will check it out to make sure I understand the ins and outs. But basically same as getting my local, just swapping the steps for Dave, and then do mine to switch back. Makes perfect sense! |
So here's an example of some of the "weirdness" that might happen: Let's say the blinkenlight has
If green color is added to the blinkenlight (this assumes
Then a third color (blue) is added:
Note that each color now is only 1/3 of a second long, since there are three of them per cycle now. Now, let's say blue is removed from the blinkenlight, while the blinkenlight is currently showing a blue color:
Notice how blue is displayed when the color is removed, and the light immediately switches to green, since green should be displayed at that point in time now that the blinkenlight only has 2 colors. So the end result is green "flashes" very briefly before red is displayed again and the red/green cycle starts. I hope this makes sense. It's predictable, and I think if I was playing the game and saw this happen I would understand what happened and why the color change occurred like that. |
Agreed. It definitely works this way :-). I guess we should add the ordering by priority in |
I think this is ready to go. |
@densminger Looks like it needs a couple of cleanup items to pass the Travis CI build test. All looks like general formatting and consistency stuff. Once that's cleaned up, it should pass all three tests and get the green check mark. Great work!
|
Green check! |
Sweet!!! |
I've been playing with this, and I have a question. Right now, a Edit: I just realized that the Edit2: I've marked this PR as draft. I want to get this working before it gets merged. |
I was looking at the same thing when I saw your edit. Agreed, just need to use that to cancel when mode ends there and it clears the stack for it's called keys. As for starting back up, is there a scenario where it would need to do that? I would assume my shot would be in a state that it's profile calls a specific show. So if the shot is in that state when the mode starts again, it should automatically be calling the show, and adding it back to the stack. |
Good point. I think it's ok to not remember state. I have it working so that when mode ends it removes the mode's colors automatically. I changed the Thanks for your input, it helps a lot! I'll push these changes shortly. |
We already got a way to handle this. It is called "clear_context“. That is called when modes are unloaded, shows are stopped and in any other case. You can have a look at LightPlayer. It is similar to your approach but covers aboslutely everything in MPF. Also you probably do need the change in Blinkenlight with that. |
Got it. Thanks, Jan. I changed it to use I also renamed the |
mpf/devices/blinkenlight.py
Outdated
self.info_log('All colors removed') | ||
self._restart() | ||
|
||
def remove_color_with_label(self, label): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs changed to private _remove_color_with_label (or if it needs to be public, line 92 needs changed to remove the underscore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blinkenlight_player calls this, so it looks like the call on 92 needs to be global.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. That would have been a runtime error. Made me realize I didn't have a unit test for this. I've fixed it and added a test. Will push in next update.
mpf/config_spec.yaml
Outdated
__type__: config_player | ||
action: single|enum(add,remove,remove_mode,remove_all)|add | ||
label: single|str|None | ||
color: single|color|ffffff |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be changed to: color: single|str|white
This will allow tokens to be passed in, in addition to color names of color codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. This would change to single|color_or_token|white
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you are right. This does not yet exist. I guess we should create it (as we have it for floats or ints). That will move str parsing out of runtime in most cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't publish changes, but here's what they are.
Update 347 to: color: single|color_or_token|ffffff.
Then in config_validator:
Add line 81: "color_or_token": self._validate_type_or_token(self._validate_type_color),
Line 669: Swap above the two lines of comments (#) for the following:
def _validate_type_color(self, item, validation_failure_info, param=None):
assert not param
if item is not None:
try:
if isinstance(item, tuple):
if len(item) != 3:
self.validation_error(item, validation_failure_info, "Color needs three components")
return item
except ValueError:
self.validation_error(item, validation_failure_info, "Cannot convert value to color.", 11)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of param=None
and assert not param
? These aren't in my version of config_validator and I'm not sure the purpose. I'm not sure what's going on here in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jan would have to answer the specifics for you here. But we switched to allowing tokens, and it runs through the token validated to see is it a token on a color, in this case. If it's a token, we know that, so we stop before the validation breaks. If it's not a token, we go through. Without this argument it breaks here as it expects three arguments, but gets 4 due to the token validation.
This is based on the other token_or_xx methods here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok. I'll take a look when I get home and push the changes later tonight.
…. Also, fixed a bug if a blinkenlight color was added that already exists. Also added tests for both of these.
@atummons Ok, both of your fixes have been pushed. I changed the |
Renamed |
Awesome work! I'll get latest on your repo and continue to play around with my test machine. |
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Everything works on my end. It's ready to go as far as I'm concerned.
Edit: So it looks like the "stop/remove" express config option will only remove colors that were added without a key (that is, colors that were added with the express config method, or colors that were added without specifying a key). This makes sense, I just need to update the documentation to reflect that.
Thanks for testing and confirming. This has been an awesome collaboration! Thanks @densminger @atummons .
Yeah exactly. My theory is that 99% of the users will have maximum one color per mode. |
Blinkenlights feature, as discussed in issue #766