Pin numbering

Following on from #459 ... here's the contentious change I've currently got in the patch: pin numbering.
Yeah, that old chestnut. Funny story...
So, @bennuttall and I are at PyConUK and we bump into @gbaman and get chatting about GPIO Zero. Now, it turns out that @gbaman might be almost as stubborn as I am, to the extent that his local RJam has voted to reject GPIO Zero purely on the basis of its pin numbering (despite acknowledging that it's very nice in most other respects).
Obviously I think this is a bit crazy: why reject plenty of other advantages over the single issue of pin numbering, which arguably isn't that much more complex than board numbering once one takes into account the necessity of still teaching that not all pins are equal.
Nonetheless we get to discussing it, and I make the case that adding mutable global state (a la "GPIO.setmode") is a bad idea because it leaves your script open to the whims of anything you import that might change it (if anyone thinks this is unlikely: go look at early versions of picamera where I had no choice but to force BCM mode to control the camera LED because I couldn't query the mode back then; yes, it most certainly can happen).
However, I then mention the possibility that we could support alternate numberings anyway via an expanded definition of a pin specification. In other words, permit more than just a straight integer GPIO number to be specified. I think I'm right in characterizing his response as "excited" at this possibility :)
So, why acquiesce when I still think their position is, as stated above, "crazy"?

I want to encourage as many as possible to use GPIO Zero, because I'm firmly convinced it's better for teaching physical computing.
I don't have a magic switch I can flip to convince @gbaman to change his mind, and I judge his stubbornness to be akin to my own.
I do have the ability to implement an alternate scheme that he (and hopfully his local RJam) will find acceptable.
If I want to advance point 1 above, the only thing I (or I think we) can do is try point 3. So that's what I'm attempting.

I'm not proposing we remove the current integer GPIO addressing, or that we use these alternate schemes in any of our recipes, or encourage its use in any way (simply to minimize confusion on the part of users). As far as the Recipes chapter is concerned: we use integer GPIO addressing and that's it. However, in the PR for #459 I have added a brief bit under Notes detailing the alternate schemes available anywhere a pin specification is called for.
So, what alternate schemes have I (currently) included in the PR?

Obviously the same old GPIO integer addressing: LED(2)
GPIO and BCM prefixes for the same: LED('GPIO2') or LED('BCM2') are equivalent
wiringPi numbering: LED('WPI8') or LED('WIPI8') are also equivalent (wasn't sure what wiringPi users usually use as an abbreviation)
physical numbering based on the "primary" header (P1 on old Pi's, J8 on new): LED('PHYS3') is the third physical pin on the main header
physical numbering based on a specific header: LED('P1:3'), LED('P5:3'), LED('J8:3') etc.

These are by no means "final" in my head: I think there's too many and some may not "feel" right to people. Have a play, and let me know what you think. Also, these are only used on construction. The specification is always translated internally into a GPIO number (because this is what's required at the register level, and for constructing the pin address) so you'll never see this stuff if you repr() a pin - it'll just read "GPIO2".
BTW, if you think this belongs in an entirely separate PR to deal with once #459 is done, I agree entirely - I'm just too lazy (and knackered!) to pull it out right now. I'll do this next week so this won't get in the way of #459.

Sounding great, and yes I am rather stubborn (the @NIRaspberryJam team will I am sure eagerly confirm that).
One thing to add, not sure on PHYS, is rather long and the S makes reading it with numbers (for example a 2 or 3) a little difficult.
I had rather liked the P3 syntax we had discussed, but do see that then conflicts with using that for headers.
Guess one option could be PIN3, similar to how ScratchGPIO handled it (PIN3 for physical and GPIO3 for BCM)?
Am not right now sure of the best answer for it though...

I had rather liked the P3 syntax we had discussed, but do see that then conflicts with using that for headers.

Yeah, when I got into it I quickly ran across "hang on, P1 is a header on the earlier Pi's" so I took a leaf from wiringPi's various initializers (gpio, phys, and sys) to call it "PHYS". I agree it is a tad clunky though. I was thinking maybe "BOARD3" (to line up with RPi.GPIO's mode) ... but that's even longer.

Guess one option could be PIN3, similar to how ScratchGPIO handled it (PIN3 for physical and GPIO3 for BCM)?

PIN feels a bit ... generic. A bit too confusing given how many other places with use the word "pin".
I kinda like PHY though. Hmmm.

I was thinking maybe "BOARD3" (to line up with RPi.GPIO's mode) ... but that's even longer.

That was the first thing that came to my mind when reading the first comment in this thread :)  Yeah it's a bit long, but it sounds like it's easy to support multiple 'aliases' for the same thing? (PHY3 / BOARD3 / BRD3)
And I guess the idea behind this could also be used to 'fix' #349
Just for reference, #246 is where we'd previously discussed alternative pin-numbering schemes...

That was the first thing that came to my mind when reading the first comment in this thread :) Yeah it's a bit long, but it sounds like it's easy to support multiple 'aliases' for the same thing? (PHY3 / BOARD3 / BRD3)

Hmm, multiple aliases. My internal debate has gone something like this:
"More styles?! Think of the chaos you're encouraging, man!"
"Yes, but if the whole point is to encourage people to use the library, and a style they like isn't present then haven't we failed in the endeavour?"
"But ... CHAOS!"
"Look, just because they have multiple styles at their disposal they'd still be crazy to actual use them in a single script. We can't provide foot shields for every possible foot-shooting scenario"
"Ah ha! But you're always saying 'code is read more than it's written'. By introducing more styles, people reading other people's GPIO Zero scripts potentially have to know more styles to understand the code, or more precisely how to wire the components associated with it"
"Okay, that's actually a good point"
"And besides ... CHAOS!"
"Shut up"
So, I think my position at the moment could be summarised: in favour of permitting (but not encouraging) multiple pin specification schemes, but also in favour of minimizing the number of aliases.
BOARD has familiarity, but not brevity ... but I think familiarity probably trumps brevity. PHY probably has familiarity for some users (wiringPi particularly uses "physical" to describe board numbering). I'm half tempted to remove the "BCMn" prefix ("GPIOn" is already permitted, and that mirrors the text of our pin-out diagram on recipes), but if we permit BOARD should we not also permit BCM as a prefix.
Urgh. The minutiae continue to fuel the internal debate.

And I guess the idea behind this could also be used to 'fix' #349

That thought did indeed occur at the back of my mind as I was writing the translations! Basically the fixed numbering in certain subclasses within boards could simply be done with physical numbers and the board would "just work" on all Pi versions.

Just for reference, #246 is where we'd previously discussed alternative pin-numbering schemes...

Ah, thanks for that link! It all comes flooding back ... black paint, self.kick :)

Haha yeah, I guess there's going to be no "perfect solution" to this. CHAOS.

...and I guess allowing pins to be addressed by their physical number, means we'll need some kind of PinDoesntSupportGPIO exception? ;)

...and I guess allowing pins to be addressed by their physical number, means we'll need some kind of PinDoesntSupportGPIO exception? ;)

Yeah, that's basically done - can't remember exactly what I added for it though (amazing how little remains in my memory from a few days ago!). Let me dig it out...
Ah, here we go - I just re-used PinInvalidPin for it; that's the exception that's already raised when you try and specify an invalid GPIO port (like 60). The relevant bit is here: https://github.com/RPi-Distro/python-gpiozero/pull/468/files#diff-d51cee55d16c76a12beddd2e360b8367R1106 (might need a slightly clearer exception wording there?)
That covers all the physical mappings. For example, wiringPi is basically a physical mapping so the way it's implemented is I convert from, say, WPI8 to J8:3 then recurse to convert J8:3 to a GPIO number. Likewise if you try PHYS1 it'll get converted to J8:1 then recurse and you'll hit that exception when it looks up headers['J8'].pins[1].function and finds it says "3V3" of "GPIOsomething"

Ah, here we go - I just re-used PinInvalidPin for it; that's the exception that's already raised when you try and specify an invalid GPIO port (like 60)

I wonder if it'd actually be worth having two separate exceptions? e.g. 'PHY34' could raise PinInvalidPin on a Model B (which only has 26 pins) but PinNotGPIO (or whatever) on a Model B+ (because it's actually GND).

Yeah, that's a decent idea - descend PinNotGPIO from PinInvalidPin and that'd be nice and clear. I might also refine the error to say something like "{pin} is a {function}, not a GPIO pin" so you'd get something like "PHYS1 is a 3V3, not a GPIO pin". Although there's a little more refinement to do there; because of the recursive lookup at the moment if you try "PHYS1" you'll actually get the error "J8:1 is not a GPIO pin".
Anyway, I'm just in the process of splitting this into separate PRs so we can refine this part a little further.

A couple of comments, if I may...
Do you have any thoughts as to whether @gbaman's stance (which I also think is crazy, maybe even short-sighted) is shared by many, or any, other users? I'd hate to think you're going to all this effort to appease just one person (nothing personal, @gbaman ).
I feel that you need to bear in mind where your users are coming from. I see a lot of them (as is the case with me) using GPIOZero as a first step into Python on the Pi, having used ScratchGPIO previously. I think that if you're going to go down this route, then PIN and GPIO make perfect sense, both to the end user and logically-speaking. You say, 'PIN feels a bit ... generic. A bit too confusing given how many other places with use the word "pin".' What 'other places' is it used within this context?
Anyway, hope that makes sense!

Do you have any thoughts as to whether @gbaman's stance (which I also think is crazy, maybe even short-sighted) is shared by many, or any, other users? I'd hate to think you're going to all this effort to appease just one person (nothing personal, @gbaman ).

Excellent question. Okay, full justification time...
On consistency
If I was certain it was just @gbaman, I'd ignore the issue and carry on (sorry Andrew!).  I'd probably still ignore it. Consistency is a useful trait in education, after all, and progress demands consensus, at least at a certain level (you don't get certain technologies without everyone agreeing the Earth is at least vaguely spherical).
Unfortunately, I'm in the awkward position of firstly knowing that there's a fairly sizeable minority of the community that really hate BCM numbering and are so vehemently opposed that they won't consider anything else (i.e. it's not just @gbaman and his local RJam), and secondly that I've played at least some part in that (although I don't think I'm directly to blame for their opposition)...
Some history
A while back the Pi Foundation (full disclosure: I don't work for them, but I have worked with them on several occasions), decided that having two sets of standards for numbering in their educational resources was a Bad Thing, and that standardizing on one would be a Good Thing. One set of diagrams to distribute, completely consistent numbering between projects, no confusion. It would all be good!
There were strong cases made by both sides for BOARD vs BCM numbering (RPi.GPIO was the only Python implementation on the foundation's radar at the time, so the decisions were based on that, and those are the terms I'll use from here on). Incidentally, this discussion was archived somewhere on a GitHub ticket ... but I can't seem to find it at the moment (if anyone finds it - do please post a link here - it'd be good to refresh my memory!).
What's in a number?
If I had to summarize, the arguments on the BOARD side boiled down to simplicity. I think it's fairly uncontroversial to say that BOARD is the simpler numbering. So if simplicity is your one criteria (and let's be honest, it's a damned important one for education), BOARD wins.
As you've probably guessed, I came down on the BCM side. Given this side can't win on simplicity, it needs to have some damned good counter-arguments. My recollection is too vague to be precise, so I'll just list what my current arguments for this side are (if someone can dig out that ticket, hopefully it'll show some vague consistency in my position :)

Not all GPIOs are physically exposed. If you want to control non-physical GPIOs, therefore, you simply can't use BOARD numbering. So the next question is:
Are there any use-cases for non-physical GPIOs? Two spring to mind: controlling the Pi's camera module LED (I'd released picamera by this point, so obviously this was a keen interest of mine), and controlling the Pi's internal LEDs (an esoteric use-case, admittedly, but quite useful when you want to test with some "known good" LEDs).
Further, BOARD numbering gives the (false) impression that any pin can be used as a GPIO pin. You still have to learn that 1 is "always on", 2 and 4 are "positively dangerous" (sorry ... bad pun ;), 6 is ground, etc. By forcing the student to learn (or at least use) the BCM numbering you make them aware that not all pins are equal.
BOARD vs BCM at the time (at least in RPi.GPIO) involved mutable global state. You could have one or the other. Worse still, the library allowed you to select the mode, but not to query the mode (this was subsequently fixed). Anyway, this caused particular problems in picamera because I needed to control a non-physical GPIO (for the camera LED) but had no way of knowing what mode was selected. My only option was to force BCM mode and hope I didn't blow anyone's circuit up (not a position I was at all comfortable with).

I think 1 and 2 are okay arguments, but that if you have an absolute focus on entry-level (and I'd be a hypocrite if I claimed otherwise, given our recent PyConUK presentation), they're not really applicable to total beginners. Point 3 is not very good: given that not all the pins are GPIO pins, you have to teach this in either system so it doesn't really argue for or against either; just that perhaps BOARD isn't as simple as you'd like.
Point 4 was the clincher for me. The mutable global state meant any script could arbitrarily change your pin numberings, and the inability to query it meant libraries like picamera were left with no option but to arbitrarily change it. However, that's not really applicable to GPIO Zero; we're not talking about having mutable global state. We're talking about having different specifications which are translated into BCM numbers prior to use, so no danger of imports flipping the mode, and no danger of blowing people's circuits up.
So, that's how I saw things. I'd guess it's how some others did as well, given how things played out. Speaking of which...
It's a numbers game
I think I'm right in saying that the BCM side was more popular on the numbers ... but there were a significant number on the BOARD side. Over the next year (ish?) I was involved as a tutor at several Picademy sessions, and occasionally had discussions with attending teachers regarding BOARD vs BCM numbering. Some were perfectly happy with BCM numbering, most I think were happy with "whatever they were presented with", and a small number were fundamentally opposed to anything except straight BOARD numbering. That's the basis of my (admittedly anecdotal, non-rigorous) contention that there's a sizeable minority that simply won't accept BCM numbering.
Which brings us to today. The argument's won: BCM has prevailed, Pi Foundation resources are now written with that as the sole method, nuScratch uses it, GPIO Zero uses it exclusively, etc. Why mess with that?
Well, as @lurch has also mentioned, there's a few addon boards that use physical numbering (in as much as the GPIOs that they use potentially change on older models of Pi). In other words, if you use a LedBorg with GPIO Zero on a really old Pi, it won't work properly (wrong GPIOs).
However, my primary reason is "they're still out there!". BCM might have won, but that didn't automatically convert everyone (you'll have some idea of how naive my understanding of humanity was, that I really thought moving all resources to BCM numbering might eventually bring everyone into line -- hah!). No, there's still plenty out there that will only accept BOARD numbering, and I've come to understand that there's not a hell of a lot I can do to change that.
The problems of others...
To paraphrase one of my favourite scenes:
Now, if it was just them, hey, you pays your money you takes your chances, but it's not just them. The hold-outs are often responsible for numerous other people.
You could argue that it's the hold-outs' problem, but actually it's both parties' problem. Either party could budge and it would benefit new learners; I don't think it matters much to them which moves, only that one does.
My major objection (mutable global state) is gone (at least in the case of GPIO Zero). I acknowledge the issue that permitting multiple pin specifications potentially complicates the understanding of other's scripts; if you've only ever dealt with, say, BOARD numbering and you come across a script using BCM numbering you've got some learning to do. However, it'll be apparent in every pin declaration, not some obscure boiler-plate at the top of the file, and not silently imported from elsewhere; the unfamiliar numberings can be copied and pasted between scripts without harming any existing declarations (unlike global state), and this final argument imagines a user already versed in GPIO Zero, whilst the intended beneficiary here is the complete beginner.
For the existing GPIO Zero user, this change makes no difference to their existing scripts and simply means that in future they may encounter a few odd scripts using different pin specifications. For the beginner, it may mean the difference between them encountering GPIO Zero in their education, or not.
I rest my case.

You say, 'PIN feels a bit ... generic. A bit too confusing given how many other places with use the word "pin".' What 'other places' is it used within this context?

Pretty much everywhere in the documentation (and the code), e.g. https://gpiozero.readthedocs.io/en/v1.3.1/api_output.html#led
And in https://gpiozero.readthedocs.io/en/v1.3.1/api_pins.html
Like @waveform80 I'd definitely be :-1: on having "PIN" as an alias for the physical-pin-numbers. (But then, I've never used ScratchGPIO)

Woah, nice essay @waveform80 :-D
(it was posted at the same time as my previous comment)
Another little point about RPi.GPIO - when the Rev2.0 Model B Pis came out with both a P1 and P5 header, you had to switch to BCM numbering mode if you wanted to control any of the GPIO pins on the P5 header, BOARD mode can only control pins on the P1 header.
Out of curiosity, what does @gbaman and his @NIRaspberryJam think of http://rasp.io/prohat/ (which uses 'BCM' numbers) ?

Okay, I've now got the PRs separated. So, there's the one for remote SPI (#468) which we really ought to review and deal with first. I don't think it's contentious, but it is horrifically long, and the pin numbering PR (#470) branches off it so remote SPI really has to get merged first.

Like @waveform80 I'd definitely be :-1: on having "PIN" as an alias for the physical-pin-numbers. (But then, I've never used ScratchGPIO)

Yeah, I'm afraid PIN is waaay too vague given all the uses of it throughout the docs and code. Sorry!
Having had a think about this, I reckon a decent approach would be: don't dive in with a ton of aliases. Let's start with one prefix for each "numbering system" and see if that brings the hold-outs on board. Adding more aliases later is easy enough, and doesn't break compatibility whilst adding too many up front and then removing them later would break compatibility.
So ... which prefixes? Here's a set I could live with:

'GPIOn' for straight GPIO numbering (i.e. just the current system with a prefix). It's perfectly descriptive of what the pin represents, it mirrors the pin-out diagram's labels, etc.
'PHYn' for physical (board) numbering. It mirrors (ish) what wiringPi calls physical numbering.
'WPIn' for wiringPi numbering (seems like WPI is a more typical contraction of wiringPi than WIPI after I trawled the forums a bit).
'h:n' for explicit header:number; this really has to be present in any system as it's the basis for all physical numberings

Here's another set I could live with, but I think I prefer the first set at the moment:

'BCMn' for straight GPIO numbering. This obviously mirrors RPi.GPIO so this set is fairly obviously appealing to existing RPi.GPIO users.
'BOARDn' for physical numbering. Because this set includes 'BCMn' it makes sense to offer the similar prefix for the physical scheme
'WPIn' for wiringPi numbering. No change here.
'h:n' for the same reasons as above.

Anyway, for now let's concentrate on reviewing and merging the remote SPI stuff. Once that's done, the PR for this will be nice and short and I can tweak it to fit a minimal system like one of the above (or whatever we can all vaguely agree on). We won't please everyone with this, but we don't have to please them ... we merely need to appease them sufficiently ;)

seems like WPI is a more typical contraction of wiringPi than WIPI

Yeah, IMHO WIPI sounds too much like WiFi, and there's also http://uk.farnell.com/element14/wipi/dongle-wifi-usb-for-raspberry/dp/2133900
My only concern with the current prefixes is that it might be easy to mis-read WPI2 as WP12 ? (and could GPIO5 be mis-read as GPI05 or even GP105 ?) Think about people in workshops (e.g. @NIRaspberryJam ) typing in code from printouts...
One way to mitigate that might be to put a separator between the prefixes and the numbers, so that it's clearly only-letters-before-the-separator and only-numbers-after-the-separator e.g.

'GPIO:n'
'PHY:n'
'WPI:n'
'PHY:h=n' (or 'PHY(h):n')

but that obviously risks over-complicating it again :-/
Would a stringified-number i.e. 'n' be interpreted as just an integer n?
The other minor concern I have is that people might expect code using 'P1:11' to work on all models of Pi, whereas I guess it'd have to be changed to 'J8:11' to work on the B+ onwards, with the way you've currently got things?

I'd just provide some translation functions.
So if method x took two GPIO.
x(7, 11) # Broadcom GPIO 7 and 11
x(BOARD(26), BOARD(23)) #  Broadcom GPIO 7 and 11
x(wPi(11), wPi(14)) #  Broadcom GPIO 7 and 11

Wow, that's definitely an in-depth explanation Dave, thanks.
I think I would probably agree that BCM numbering should be the preferred method (definitely from KS2 onwards). As you say, most resources now use that system, and ScratchGPIO can use either. I've just started a new group of kids and I was planning to use pin numbers, but I think I'll try them with BCM tomorrow and see if they grasp it ok.
I like Joan's suggested format, seems quite tidy. If those are the 3 methods, would it be viable to just use G,P(or B),W as prefixes or would that require another level of explanation beforehand?

I suspect that @joan2937 's solution (while it looks neat) wouldn't work with remote-pis being controlled by pigpio?

...although I guess if somebody is vehemently against the 'PHYn' numbering, and is insistent on being able to use the 'PINn' notation from ScratchGPIO, I guess they could do:
def PIN(n):
    return 'PHY%d' % n

at the top of their script, and just use e.g. PIN(5) everywhere in GpioZero that accepts 'PHY5' ;-)
(although we probably shouldn't encourage this)

My tuppence
I must first declare that I've even more for pin numbering than @gbaman :)
But ignoring the big mistake made in a room in Cambridge a long time ago.....
it would be great to let users choose what numbering system to employ in GPIO.zero
However, introducing another word for pin when they are universally known as pins is just not worth it
it'd only be worth it if ubergeeks wanted the pin numbering scheme and they generally don't.
Its the KISS camp that wants/needs pin numbering.
Pin:  Do or do not- no compromise there is
Even though I want pin numbering with every fibre in my body - I wouldn't want ANYONE to have to go thru the whole Calcutta/Mumbai  Peking/Beijing changes word use change.
but why am I bothering saying anything ...... what do I know........ :-)

Innocent question (from a self-confessed ubergeek) : When things like http://rasp.io/prohat/ and http://rasp.io/portsplus/ and http://pinout.xyz/ and https://www.raspberrypi.org/blog/raspberry-leaf/ ( https://github.com/splitbrain/rpibplusleaf ) are available, why are people still so resistant to the BCM numbering scheme?

@cymplecy @lurch
It possibly comes down to the difference between being a developer and being a consumer.
From a developer point of view I didn't have to give any thought to knowing that Broadcom numbering was the appropriate way of defining the GPIO.  All the developer documentation is based on Broadcom GPIO numbering.
From a consumer point of view I'd prefer pin numbering - especially now that the 40 pin expansion header seems stable.
For people who have a foot in both camps like cymplecy and gpiozero it's a bit of a conflict.

@lurch

Yeah, IMHO WIPI sounds too much like WiFi, and there's also http://uk.farnell.com/element14/wipi/dongle-wifi-usb-for-raspberry/dp/2133900

Okay, WIPI's definitely out. WPI's on the list for now. I'll address "W" as a sole prefix a bit below.

One way to mitigate that might be to put a separator between the prefixes and the numbers...

I'm not terribly worried about 0 vs O issue. They must already know the library is "GPIO Zero" or more precisely gpiozero otherwise they wouldn't be able to import it in the first place. We don't use leading zeros in the pin-out diagrams or any prose, so I don't think there's great danger there. As to people using them ("GPIO04"): the code is fairly tolerant - it will happily ignore leading zeros if you happen to use them (but we shouldn't encourage their use - having O and 0 next to each other is pretty awful practice).

Would a stringified-number i.e. 'n' be interpreted as just an integer n?

The current code doesn't (it'll just throw an error), but I wouldn't be averse to adding that case if it makes sense?
@joan2937

I'd just provide some translation functions.

I wish it were that simple. Admittedly at the moment, it is. However, consider the future of supporting IO expanders which incorporate their own (potentially non-sequential) GPIOs (and other sorts of pins). How is the function to know it is being called for the main header, or for an expander, and thus what translation to perform?
@DarrenTownsend

I like Joan's suggested format, seems quite tidy. If those are the 3 methods, would it be viable to just use G,P(or B),W as prefixes or would that require another level of explanation beforehand?

When chatting with @gbaman at PyConUK we were initially discussing Pn, Bn, etc. as a simple scheme. Unfortunately the early Pi models labelled their headers P1 and P5 which instantly throws some confusion into the Pn scheme. The later Pi's use J8 as the primary header's label (J is a more "normal" prefix for this sort of thing).
At the end of the day, if it comes down to a decision between "unambiguous, but longer to type" and "slightly ambiguous, but shorter to type" I'm going to side with the unambiguous option because I'm of the opinion that while having less to type marginally improves ease of use, it's more important that the code is easy to understand than that the code is slightly easier to type.
Sorry - will get back to the rest of the comments later!

"Innocent question (from a self-confessed ubergeek) :why are people still so resistant to the BCM numbering scheme?"

Kids aren't uber-geeks :)
Pin counting doesn't require any learning at all - just counting.  There is a 1:1 correlation between software and hardware that doesn't require ANY explanation (apart from zig-zagging down the connector of course :)

The problem is that uber-geeks actually prefer BCM and are 99% genetically incapable of seeing that it wasn't the way to go forward with teaching resources and lesson plans :)  They weren't able to perform pin abstraction :)
But that war was lost long ago and I assume shortly that @waveform80 will find a "friendly" hand leaning on his shoulder saying - forget about pins :)
But - lets see how far this goes :)

@waveform80

Would a stringified-number i.e. 'n' be interpreted as just an integer n?

The current code doesn't (it'll just throw an error), but I wouldn't be averse to adding that case if it makes sense?

Well, we already do so for the pi_info() function, and IMHO it wouldn't hurt?
Although off the top of my head I can't see any reason why you'd do LED('5') instead of LED(5). Unless of course you're getting the GPIO numbers from some external source, and LED(num) might look neater than LED(int(num)).

I'm going to side with the unambiguous option

Agreed.
@cymplecy
Do kids ever have problems with the "zig-zag counting"? I guess taking the pin-counting-approach to the extreme (Devil's advocate) would end up with two separate single-row headers (a la Arduino). Which in a way is the route that http://rasp.io/prohat/ took.
Ping @raspitv as he had some good comments the last time we were discussing pin-numbering.
And I guess if they're using a case like https://shop.pimoroni.com/products/pibow-coupe-for-raspberry-pi-3 you have to explain that they need to ignore the numbers on the case ;-)
Given that BCM and BOARD pins numbers are both widely used, I guess even if you only teach BOARD numbering, you might have to explain that BCM numbering also exists?

They weren't able to perform pin abstraction :)

@waveform80 does explain above why it wasn't possible to 'universally' use the physical-pin-number abstraction everywhere (which Arduino is able to, where "Digital Pin 10" is really "PB2" under the covers).

But - lets see how far this goes :)

Yup :)

@lurch in relation to why are people still resistant to BCM with all the other boards etc, the point is a kid at our jams shouldn't need one of those boards? I don't want to spend ~£500 on a set of portsplus's, why should we have to when 99.9% of the work they will do will simply use the GPIO pins available as opposed to other weird pins, like camera LED or the extra header on the old Pis.
The kids at our jams won't touch either, basically ever. The advanced uber geeks may someday, but putting them off at the start with even more confusing points right when they start out is not what me or my Raspberry Jam team want to do.
Sure if you have geeks, then fine, explain to them what BCM is and why, or get their parents to buy a £15 board. But for those beginners (which we get a heck of a lot of), abstracting it out like every other board on the planet does (for good reason) is a far better approach. Is this not what gpiozero came along to do in itself? Abstract out a complicated thing for beginners? Why should the 9 year old I am teaching to blink an LED care about what is below? They should just be able to count, instead of looking up a diagram or using an addon board to figure out the number of the pin they want to use from a seemingly random order.
@waveform80 the initial discussion from 2 years ago https://github.com/raspberrypilearning/push-button-stop-motion/issues/5

@gbaman £500 will get you 500 portsplus at wholesale rates. I don't think you need quite that many ;p Incidentally Portplus in its current incarnation has BCM on one side and Pin numbers on the other so you don't need to count when you're using BOARD either. But apparently some people mess up and use the wrong one sometimes. GAH!
I've always used BCM because that was what was on the first board I learnt with - the Gertboard. It's going to be the same for anyone learning. Whatever you learn is "correct" for you and you'll probably want to stick to it. Some favour one, some favour the other and it's actually pointless arguing about it because there will never be agreement.
But there is a strong case, if one scheme is strongly favoured, for only supporting that scheme.
(Just thinking out loud, not saying that's my position on the matter.)
My bugbear is the use of the terminology "pin 14" instead of "GPIO 14" in documentation, because to a BOARD user pin 14 is physical pin 14, but to a BCM user, pin 14 is GPIO 14. That is why I advocate the use of the word "port" in all my RPi.GPIO documentation when I'm talking about ports, and "pin" when I'm talking about physical pins. Makes sense to me. YMMV, but people seem to find my docs fairly clear.
I also hate counting pins and think it is prone to wiring errors. That's why portsplus exists.

Whoops @raspitv, had meant http://rasp.io/prohat/ which @lurch had mentioned few posts back :)

I don't want to spend ~£500 on a set of portsplus's

That's why I also mentioned the 'leaf' printouts ;-)

Whatever you learn is "correct" for you and you'll probably want to stick to it.

True. See also Mac vs. PC... ;-)

That is why I advocate the use of the word "port" in all my RPi.GPIO documentation when I'm talking about ports, and "pin" when I'm talking about physical pins. Makes sense to me.

Yeah, given that everyone is coming from a different direction, and has their own preferences, I guess there's no perfect terminology. "port" could also relate to USB port, Ethernet port, HDMI port, etc.
(I wonder if that's where the 'P' in "header P1" came from?)

I also hate counting pins and think it is prone to wiring errors.

...and surely if you're counting pins, you're more likely to count "5 from the left on the top row", or "3 from the right on the bottom row"? Which of course doesn't have any direct relation to BCM or BOARD numbering.
I guess part of the approach that myself and (perhaps) @waveform80 are looking at is "there are some things you can only do with BCM numbering, and (hopefully) some users of GpioZero may progress from basic to advanced usage, so it makes sense to just teach them one numbering scheme (BCM) from the beginning, rather than having a logical disconnect when the user progresses from basic to advanced usage" ?
Whereas the approach @gbaman is looking at is "the people coming to my Jam will always be basic users, and will never need to know about advanced usage" ?
(but again perhaps that's just my ubergeek PoV)
Just to get some more input, I wonder if @Gadgetoid (author of http://pinout.xyz and https://github.com/WiringPi/WiringPi-Python) has any thoughts? :)
Apologies if I'm coming across as antagonistic - that's not my intention, I'm just trying to understand people's reasoning.
I fully support the multiple-ways-to-specify-pins that @waveform80 is suggesting in this issue. (apologies if I've accidentally dragged this discussion too far off-topic from the original intention!)

Hi All!
It would like to request that GPIOZero supported (at least a basic subset of) board agnostic pin names/aliases, and by ‘board’ I’m not limiting gpiozero to Pi boards.
"Why?"  Well..
Because, I’ve ported (a subset of) gpiozero and also the Python BluetoothLE module ‘bluezero’ to a port of MicroPython for: nrf51 (e.g. micro:bit),  nrf52 (new Arduino’s, RuuviTag and more) devices.
With the port I’ve created it’s possible to write Python code that can control an LED via BluetoothLE and that the Python code will run unmodified across:  Raspberry Pi’s, micro:bit’s, Arduino’s (ARM-cortex devices) and many Nordic BLE SoC based devices.
I’ve had interest from various educational related folks and it would be very convenient from a learning. documentation and maintenance perspective, to be able to create many more types of example that would not need modifying, because of variations in board pinouts, by using these aliases.
I’m not expecting to be able to cover every possible gpio use cases, but the basics to support simple experimentation on different sorts of hardware should be easy.
There are some examples for the current implementation here:  https://thebubbleworks.com/bubblepy-examples
For what I’m requesting the GPIOZero implementation (for the board gpiozero is installed on) would map these (example only) names to board specific pins at runtime:
D0 .. Dn			(digital)
A0 .. An			(analog)
LED_0 .. LED_n
LED_BLINK_PIN	(e.g.  maps to 13 on Arduino ARM based boards, pin 17 on some BLE modules, etc.)
BTN_0 .. BTN_n
SDA		(default)
SCL		(default)
SDA_0 .. SDA_n
SCL_0 .. SDC_n
ADC0 would have no meaning on a Pi    (unless a default add-on is assumed or has been setup perhaps, a seperate 'device registry’ topic perhaps.)
Also, could pi_info() be aliased as board_info() please? That would also be vurra nice too :)
Thanks
Wayne

lurch said "...although I guess if somebody is vehemently against the 'PHYn' numbering, and is insistent on being able to use the 'PINn' notation from ScratchGPIO, I guess they could do:
def PIN(n):
return 'PHY%d' % n
at the top of their script, and just use e.g. PIN(5) everywhere in GpioZero that accepts 'PHY5' ;-)
(although we probably shouldn't encourage this)"
Is this any different from 'import StupidlyLongName as Name' ? Why would it be frowned upon?
@gbaman "Sure if you have geeks, then fine, explain to them what BCM is and why, or get their parents to buy a £15 board. But for those beginners (which we get a heck of a lot of), abstracting it out like every other board on the planet does (for good reason) is a far better approach. Is this not what gpiozero came along to do in itself? Abstract out a complicated thing for beginners? Why should the 9 year old I am teaching to blink an LED care about what is below? They should just be able to count, instead of looking up a diagram or using an addon board to figure out the number of the pin they want to use from a seemingly random order."
THIS!
I think it all boils down to who you feel your users are. In my opinion, it is ideal for Upper KS2/KS3 moving on from Scratch on the Pi and making their first steps in Python, or using it because they want to do something that is not possible, or too cumbersome, in Scratch.
I also think that there is a danger of going the same way as NuScratch, in trying to build in support for every add-on out there, but forgetting that your target market (kids, schools) does not have the money or need for these extras.

(although we probably shouldn't encourage this)

Is this any different from 'import StupidlyLongName as Name' ? Why would it be frowned upon?

I was only suggesting that it shouldn't be encouraged, because the more different naming schemes that are being used, the harder it is to copy'n'paste snippets of code out of other peoples' gpiozero scripts into the gpiozero script you're currently working on. (which seems to be the way lots of beginners operate)

I also think that there is a danger of going the same way as NuScratch, in trying to build in support for every add-on out there, but forgetting that your target market (kids, schools) does not have the money or need for these extras.

Not sure I follow? Just because something supports a particular feature or add-on board, doesn't mean you have to use that feature or add-on board?

Not sure I follow? Just because something supports a particular feature or add-on board, doesn't mean you have to use that feature or add-on board?

Agreed, as long as trying to provide support for some random add-on, or trying to develop something that suits everybody (even with the best intentions), doesn't end up alienating your primary audience.

For what my opinion is worth (which in coding GPIO Zero is nothing, but in terms of using the thing might be worth something)... I know it might be a royal PITA to implement, but having both numbering systems just seems like the right thing to do. It certainly won't affect take-up negatively, and think of all the possible positive effects it might have. Just imagine, having BOARD numbering in there might just encourage someone who is on the borderline between enthusiasm and abject terror to try stuff out. I'm not advocating that anyone should use anything other than BCM, God forbid, but if counting pins is what we need to engage those with less ability to cope with the abstraction, go for it! 👍
Love what you're doing with GPIO Zero, guys. 😀

"someone who is on the BOARDerline..." ? ;-)
(sorry)

@recantha - yup, that's pretty much my stance (as hopefully comes across from my excessive verbiage above).
@WayneKeenan - right now I'd like to concentrate on just getting the alternate specs in for the Pi. As mentioned above I'd rather do minimal additions now and leave room to add more later than add too much now and have to look at removing stuff later. On pi_info() vs board_info(): it is something that crossed my mind when constructing the pin factories, but I'm not sure what form the result should take if it's to cover a wide variety of boards in the future. So for the time being, I'm going to stick with pi_info() which returns a very pi-specific structure; in future we may we add a more generic board_info() method which returns something more generic (and re-factor pi_info so it becomes a stub that calls that, or something else). It is something we're thinking about though!
To everyone else - I haven't forgotten about this, but I need to get the remote SPI stuff in first as this PR builds on that one. @lurch has very kindly spending some time reviewing that PR (and picked up several things I've been addressing); anyway, once that's complete I'll rebase this one and we can get something merged.

I've done some reading up, but I can't help but feel like I'm a little behind the curve still so forgive me for trundling in like a blind elephant and trumpeting out my ill-informed opinions.
Both WiringPi and RPi.GPIO demand that you "set up" the GPIO before use, explicitly declaring which numbering scheme you're going to be using. What's the reason for using constant-defined, or string-named prefix schemes versus just doing this? Even in documentation, it's easier to communicate "This uses scheme X" and then simply write the numbers as numbers, than mangle everything with prefixes. A prefix system only serves to encourage people to mix different schemes, which would be a sin much worse than using WiringPi numbering :D
TLDR: What's the technical reason for:
do_stuff_with_pin(GPIO14)

versus:
use_scheme(GPIO)
do_stuff_with_pin(14)

As for the merit of physical numbering; as much as "counting pins" may be the path of least resistance, I'd venture that it's not a method which has any real practical use beyond the Pi. I've found few micro-controllers, for example, where the designer has felt it prudent to number pins in any fashion other than apparently at random.
Being able to read, understand and relate to a pinout diagram and translate that information to a physical piece of hardware is, in and of itself, a valuable skill. Supplying text instructions to communicate the location of pin 1, and the practise of counting pins is, arguably, as convoluted, but less widely applicable than such a skill. Of course, as one of the pinout.xyz maintainers I'm a little biased :P
I'm particularly interested in the nomenclature being put forward here, since pinout.xyz should reflect the consensus of the community.

TLDR: What's the technical reason for:...

Mutable global state. I've covered it above, but I admit this thread's too long to skim. The issue with making pin numbering dependent upon global state is that innocently importing any module which tampers with that state can break your script (not to mention your circuit).
In case anyone thinks "surely that's unlikely to happen" (i.e. I'm just spouting hypotheticals) bear in mind that historically one couldn't query RPi.GPIO's numbering mode so in older versions of picamera where I needed BCM mode to control the camera LED (because it's a non-physical GPIO so you can't address it from BOARD mode) I had no option but to force the mode to BCM and hope I didn't blow up anyone's stuff. In other words, this isn't just theoretical. People can, and have, simply forced the GPIO numbering scheme in libraries that users are likely to import (without necessarily reading the docs and the associated warning boxes).
This also means that people can copy'n'paste between scripts which use entirely different numbering schemes and things will still work (although their code will have a distinctly schizophrenic feel to it).
Still, that's a minor benefit: the major objection is mutable global state. It's evil :)

Mutable global state.

I should have guessed that one. Also it was in the first post. I'm a tool ;)
I can totally understand why that's a no no. An unfortunate side-effect of being able to use the GPIO module as imported, rather than having boilerplate where you create a class instance.
I think strings are ugly. If numerical pin addressing is still supported, I suppose there's nothing to stop me creating "constant" definitions like: GPIO2 = 3 and GPIO3 = 5. Sadly Python doesn't make importing a set of constants particularly compelling, either from Whatever.Pins import * or import Whateverand thenWhaever.Pins.GPIO2`. Ugh.
Anyway, I'm just mumbling. My main reason for being here is Pinout, and how it could be changed to better reflect the "one true way."  I shall make a note of this thread!

Is there any further update on this? We are still keen to use GPIO Zero at the NI Jams, but as a team we made the decision that for the activities we do, Physical layout is far better for our kids so are unable to use GPIO Zero as of yet.
We are in the process of designing activities for next term and it would be perfect if we could use GPIO Zero.

@gbaman and waveform80 I read through a good portion of this thread last night and I appreciate the challenges presented.
What I don't understand is why isn't @gbaman's use case easily solved with a set of variables that maps physical pins to BCM integers? From a beginner's and teaching point of view, it's no different than defining variables for RGB values when introducing color. Think RGBLEDs.
The list of variables wouldn't even have to be part of the official library. They could be in a stand alone module that gets loaded by groups wanting to use board numbering.
What am I missing?

If you were to support both ways, but one would be default, it would not be more complicated.
In addition, I am interested in how to support the older versions of Raspberry Pi, which have a different labeling without changes.

Great news - GPIO Zero v1.5 now supports BOARD numbering :grinning:


Argument comments

Feature request:
This may be out of scope of this project, but
how about adding the ability comment under someone's else vote?
possible restrictions to avoid clutter:

no nested comments, only 1 level .
1 comment per user for other user's argument.

At work we sometimes use google docs to continue arguments. There you can mark words and create a comment list from it. One recent relevant example where this could be useful:

this proposal puts forward messy syntax that isn't clear

"messy syntax" here is not very precise. It would be nice to create a comment from those words and ask for clarification. :) Just my 2 cents. ^^

Work in progress update:

ArgumentComment is a thing now
Comments are hidden by default, but can be shown on a per-argument basis
I want to keep comments as plain as possible, that means no markdown support.

Todos

[ ] Creating a comment
[ ] Should comments always be shown?
[ ] Styling
[ ] Being able to edit or delete your comment (or as an admin)
[ ] Styling
[ ] Add a way to visualise whether there are new comments? Or at least have a way that notifies users when there are new comments on their arguments, and when an argument you've commented on, received a new comment

Branch is here, btw: https://github.com/brendt/rfc-vote/tree/argument-comments

FWIW, I think from the perspective of an RFC author, it's important to be able to comment on comments (and have them always shown). For example to clear up confusion/misunderstanding or notify that a certain concern has been addressed by an edit in the RFC text.

Makes sense to always show them. Though I'm afraid the list will grow way too big. Maybe there's a compromise where we show comments for argument you've voted on, or always show the first comment

One idea:

Show max 3 first comments with a link-button to view more
Add an option to always hide comments

Too much work?

No, sounds like a good idea 👍


Delete validate dep check in unified pipelines

Eg - azure-sdk-tools use the same unified pipelines but we don't want to run dep check for them

verify if dep check is still required in the release side  for mono-repo
if yes then figure how to disable this step for other repos?

Changed the title to "delete" instead of "disable" since this is redundant with what's already happening in the analyze step of the pipeline.

https://dev.azure.com/azure-sdk/internal/_git/azure-sdk-build-tools/pullrequest/138?_a=overview


Micromenu tabs issue

Hi! Thank you for the addon!
There are two tabs with the same image in the micromenu (Atlas and PvP tabs)
Client - Client WoW Cata

Hey,
this is kind of intended, but more so because retail doesn't have a fitting Icon for the PVP button:

Tried to find something else in this style, but so far nothing.

Same with the World Map Button on Era, but some guy on Curseforge made one for me 😂

Ok, thank you! Good luck!

Perfect!

Pressed button state is not perfect yet, but good for now: 9a48f499bc0171e5822f90be3a0d9b932b9c8423


Alfoa/ga fucntions constants

Pull Request Description
What issue does this change request address? (Use "#" before the issue to link it, i.e., #42.)
Closes #1665
What are the significant changes in functionality due to this change request?
Added support for constants/functions etc. for batching system.
A new issue should be opened since the Restart capability does not work with batching

For Change Control Board: Change Request Review
The following review must be completed by an authorized member of the Change Control Board.

[x] 1. Review all computer code.
[x] 2. If any changes occur to the input syntax, there must be an accompanying change to the user manual and xsd schema. If the input syntax change deprecates existing input files, a conversion script needs to be added (see Conversion Scripts).
[x] 3. Make sure the Python code and commenting standards are respected (camelBack, etc.) - See on the wiki for details.
[x] 4. Automated Tests should pass, including run_tests, pylint, manual building and xsd tests. If there are changes to Simulation.py or JobHandler.py the qsub tests must pass.
[x] 5. If significant functionality is added, there must  be tests added to check this. Tests should cover all possible options.  Multiple short tests are preferred over one large test. If new development on the internal JobHandler parallel system is performed, a cluster test must be added setting, in  XML block, the node <internalParallel> to True.
[x] 6. If the change modifies or adds a requirement or a requirement based test case, the Change Control Board's Chair or designee also needs to approve the change.  The requirements and the requirements test shall be in sync.
[x] 7. The merge request must reference an issue.  If the issue is closed, the issue close checklist shall be done.
[x] 8. If an analytic test is changed/added is the the analytic documentation updated/added?
[x] 9. If any test used as a basis for documentation examples (currently found in raven/tests/framework/user_guide and raven/docs/workshop) have been changed, the associated documentation must be reviewed and assured the text matches the example.

This PR is good and checklist is satisfied. An email is needed to send to the users. @aalfonsi

@wangcj05 created issue at #1668


Ionic v4: Re-add compareWith property to ion-select

Bug Report
Ionic Info
Run ionic info from a terminal/cmd prompt and paste the output below.
cli packages: (/usr/local/lib/node_modules)

   @ionic/cli-utils  : 2.0.0-rc.6
   ionic (Ionic CLI) : 4.0.0-rc.6

local packages:

   @angular-devkit/core       : 0.6.8
   @angular-devkit/schematics : 0.6.8
   @angular/cli               : 6.0.8
   @ionic/schematics-angular  : 1.0.0-rc.6
   Ionic Framework            : @ionic/angular 4.0.0-alpha.7

System:

   NodeJS : v8.11.1
   npm    : 6.1.0
   OS     : macOS High Sierra

Describe the Bug
ion-select is missing the compareWith Angular property in ionic-angular v4, previously working in v3 with PR #11965.
Steps to Reproduce
Steps to reproduce the behavior:

Add an <ion-select> element with [compareWith]="compareFunction".
The following error is thrown in the console:

Can't bind to 'compareWith' since it isn't a known property of 'ion-select'.
1. If 'ion-select' is an Angular component and it has 'compareWith' input, then verify that it is part of this module.
2. If 'ion-select' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the<EMAIL_ADDRESS>of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the<EMAIL_ADDRESS>of this component.

Related Code
If you are able to illustrate the bug with an example, please provide a sample application via an online code collaborator such as StackBlitz, or GitHub.
Expected Behavior
To be able to bind to compareWith in an ion-select.
Additional Context
Angular docs for compareWith

Just go over this file : https://github.com/ionic-team/ionic/blob/master/core/src/components/select/select.tsx
and set:
  @Prop()
compareWith(fn: (o1: any, o2: any) => boolean) {
  if (typeof fn !== 'function') {
    throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
  }
  this._compareWith = fn;
}

Then build again the core with the npm run build.dev.core command and you're done! 👍

same problem, need compareWith to work with objects!

Has there been any more work on this? I too need compareWith to work with objects. @FdezRomero are you saying izio38 solution won't work? If not did you find a work around, do you mind sharing it?

Thanks for the prompt response. I looked at Angular Material, did you mean you gave up on Ionic all together or use import Angular Material's form components into your Ionic app?

@bkarv Not disappointing at all. That's what betas are made for! Finding things that are missing or not working as expected and reporting them 😄
I didn't drop Ionic at all, I just replaced inputs and selects for the ones in Angular Material, since the drop-down select style suited by app better anyway.

@FdezRomero sorry misunderstood! Ok well fingers crossed a solution is found.

@FdezRomero @izio38 @matheusdavidson
I needed compareWith because had an array of objects as my select options eg {id: string, name: string}[]
After digging around I found this post where we can used trackBy instead
https://github.com/ionic-team/ionic/pull/6627
Tried it in Ionic 4 -beta 8 and it works like a charm! If anything trackBy feature is better than compareWith as I don't have to define the function. Here is a working example below:
Controller
  name: {id: string, name: string} = null; // question 1
  list: {id: string, name: string}[] = [{id: '1', name: 'John'}, {id: '2', name:'Peter'}, {id: '3', name: 'David'}];

Html
<ion-select  trackBy="id"  placeholder="Choose Name" [(ngModel)]="name" >
          <ion-select-option *ngFor="let item of list"  class="word-wrap" [value]="item">{{item.name}}
          </ion-select-option>
</ion-select>

Same problem! And the trackBy suggested by @bkarv is not working on beta15.

Put in a PR for this finally.

When will this be merged?

Hi everyone,
This has been fixed by #17358 and will be in the next release of Ionic. Thanks for your patience!


Significant number of ANRs with v1.2.5

The last release of my app (Chronus) included an update to v1.2.5 of the android-job library.  No other changes were made to the functionality of the jobs in our app. I am noticing a huge spike in ANRs reported on the Play store with many thousands of users affected and many thousands of ANRs reported.
ANR reports as follows:
https://pastebin.com/XWULuQX5
https://pastebin.com/AchuQWhi
Could it be caused by the the new 'Race condition' fix?

Yes, likely. It's probably also caused by how you're using the library. Are you synchronizing to access to your job object somewhere? I mean you either use a synchronized method in your job class or use a synchronized block with the job instance as monitor? This thread is holding the lock
"NewsFeedUpdateTask" prio=5 tid=18 Native
  | group="main" sCount=1 dsCount=0 obj=0x32c05940 self=0xe803c100
  | sysTid=4255 nice=0 cgrp=default sched=0/0 handle=0xcf9ff920
  | state=S schedstat=( 0 0 0 ) utm=1166 stm=22 core=3 HZ=100
  | stack=0xcf8fd000-0xcf8ff000 stackSize=1038KB
  | held mutexes=
  #00  pc<PHONE_NUMBER>017530  /system/lib/libc.so (syscall+28)
  #01  pc<PHONE_NUMBER>0b69a1  /system/lib/libart.so (_ZN3art17ConditionVariable16WaitHoldingLocksEPNS_6ThreadE+92)
  #02  pc<PHONE_NUMBER>271891  /system/lib/libart.so (_ZN3art3JNI11GetIntFieldEP7_JNIEnvP8_jobjectP9_jfieldID+212)
  #03  pc<PHONE_NUMBER>012c7d  /system/lib/libjavacrypto.so (???)
  #04  pc<PHONE_NUMBER>012cf7  /system/lib/libjavacrypto.so (???)
  #05  pc<PHONE_NUMBER>00f225  /system/lib/libjavacrypto.so (???)
  #06  pc<PHONE_NUMBER>00e4ed  /system/framework/arm/boot-conscrypt.oat (Java_com_android_org_conscrypt_NativeCrypto_SSL_1read__JLjava_io_FileDescriptor_2Lcom_android_org_conscrypt_NativeCrypto_00024SSLHandshakeCallbacks_2_3BIII+192)
  at com.android.org.conscrypt.NativeCrypto.SSL_read (Native method)
  at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read (OpenSSLSocketImpl.java:789)
- locked <0x03d86a6e> (a java.lang.Object)
  at com.android.okhttp.okio.Okio$2.read (Okio.java:141)
  at com.android.okhttp.okio.AsyncTimeout$2.read (AsyncTimeout.java:211)
  at com.android.okhttp.okio.RealBufferedSource.read (RealBufferedSource.java:60)
  at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read (HttpConnection.java:466)
  at com.android.okhttp.okio.RealBufferedSource$1.read (RealBufferedSource.java:396)
  at java.io.BufferedInputStream.fill (BufferedInputStream.java:235)
  at java.io.BufferedInputStream.read1 (BufferedInputStream.java:275)
  at java.io.BufferedInputStream.read (BufferedInputStream.java:334)
- locked <0x02a7050f> (a java.io.BufferedInputStream)
  at com.dvtonder.chronus.misc.i.a (SourceFile:216)
  at com.dvtonder.chronus.news.d.a (SourceFile:333)
  at com.dvtonder.chronus.news.b.a (SourceFile:693)
  at com.dvtonder.chronus.news.b.a (SourceFile:378)
  at com.dvtonder.chronus.news.f.a (SourceFile:336)
  at com.dvtonder.chronus.news.f.onRunJob (SourceFile:171)
- locked <0x0674353b> (a com.dvtonder.chronus.news.f)
  at com.evernote.android.job.Job.runJob (SourceFile:132)
  at com.evernote.android.job.JobExecutor$JobCallable.runJob (SourceFile:191)
  at com.evernote.android.job.JobExecutor$JobCallable.call (SourceFile:176)
  at com.evernote.android.job.JobExecutor$JobCallable.call (SourceFile:159)
  at java.util.concurrent.FutureTask.run (FutureTask.java:237)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
  at java.lang.Thread.run (Thread.java:762

This can be fixed in the library, though. I just want to make sure that this is really the reason.

Yes, I have my onRunJob() method set as synchronized.
public class NewsFeedUpdateJob extends Job {
public static class Creator implements JobCreator {
@Override
public Job create(String tag) {
switch (tag) {
case JOB_TAG_PERIODIC:
case JOB_TAG_MANUAL:
case JOB_TAG_MARK_ALL_AS_READ:
return new NewsFeedUpdateJob();
}
return null;
}
}
@NonNull
@Override
protected synchronized Result onRunJob(Params params) {
	// Job code runs in here

	// When the job processing is done ...
    if (hasFailure) {
        return manual ? Result.FAILURE : Result.RESCHEDULE;
    }
    return Result.SUCCESS;
}

public static void scheduleManualUpdate(Context context, int widgetId, boolean force, boolean clearCache) {
    PersistableBundleCompat extras = new PersistableBundleCompat();
    extras.putBoolean(EXTRA_FORCE, force);
    extras.putBoolean(EXTRA_MANUAL, true);
    extras.putInt(EXTRA_WIDGET_ID, widgetId);
    extras.putBoolean(EXTRA_CLEAR_CACHE, clearCache);
    new JobRequest.Builder(JOB_TAG_MANUAL)
            .setUpdateCurrent(true)
            .startNow()
            .setExtras(extras)
            .build()
            .scheduleAsync(new JobRequest.JobScheduledCallback() {
                @Override
                public void onJobScheduled(int jobId, @NonNull String tag, @Nullable Exception exception) {
                    if (DebugFlags.NEWS_DEBUG) {
                        Log.d(TAG, "Scheduled a manual News feed sync job with id = " + jobId);
                    }
                }
            });
}

public static void schedulePeriodicUpdate(Context context) {
    long interval = Preferences.newsFeedRefreshIntervalInMs(context);
    boolean wifiOnly = Preferences.newsFeedDownloadOverWiFiOnly(context);
    new JobRequest.Builder(JOB_TAG_PERIODIC)
            .setRequiredNetworkType(wifiOnly
                    ? JobRequest.NetworkType.UNMETERED
                    : JobRequest.NetworkType.CONNECTED)
            .setRequirementsEnforced(true)
            .setUpdateCurrent(true)
            .setPeriodic(interval, interval / 2)
            .build()
            .scheduleAsync(new JobRequest.JobScheduledCallback() {
                @Override
                public void onJobScheduled(int jobId, @NonNull String tag, @Nullable Exception exception) {
                    Log.v(TAG, "Scheduled a periodic News feed sync job with id = " + jobId);
                }
            });
}

}

Got it, then this makes sense. Thanks for bringing the issue up.

Quick question: if I remove the synchronized from my onRunJob() method, would it address the issue and allow me to use 1.2.5?

Yes, it would. Unfortunately, I didn't have time to work on this, yet.

That's now fixed in version https://github.com/evernote/android-job/releases/tag/v1.2.6


Initial hlk-sw16 relay switch support

Description:
This PR adds initial support for controlling the HLK-SW16. I plan to use this for controlling a multi-zone hot water heating system in addition to possible other low voltage devices such as sprinklers.
The MCU reference code for the device is available here. The device does have an internal timer feature as well but I'm not sure if there's a reason to add support for that in home-assistant.
Currently I have implemented/tested toggling all 16 relays individually in addition to reading their current state on startup, I'm looking to see if my general approach looks correct and how I might best expose the individual switch controls and how I would best configure this for controlling hot water zone valves. I'm still working on cleaning things up.
Documentation PR: home-assistant/home-assistant.io#7250
Example entry for configuration.yaml (if applicable):
hlk_sw16:
  host: <IP_ADDRESS>
  port: 8080
  switches:
    0:
      name: relay0
    1:
      name: relay1
    2:
      name: relay2
    3:
      name: relay3
    4:
      name: relay4
    5:
      name: relay5
    6:
      name: relay6
    7:
      name: relay7
    8:
      name: relay8
    9:
      name: relay9
    a:
      name: relaya
    b:
      name: relayb
    c:
      name: relayc
    d:
      name: relayd
    e:
      name: relaye
    f:
      name: relayf

Checklist:

[x] The code change is tested and works locally.
[ ] Local tests pass with tox. Your PR cannot be merged unless tests pass

If user exposed functionality or configuration variables are added/changed:

[x] Documentation added/updated in home-assistant.io

If the code communicates with devices, web services, or third-party tools:

[x] New dependencies have been added to the REQUIREMENTS variable (example).
[x] New dependencies are only imported inside functions that use them (example).
[x] New or updated dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
[x] New files were added to .coveragerc.

If the code does not interact with devices:

[x] Tests have been added to verify that the new code works.

Hi @jameshilliard,
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!

Could not find a related PR in our documentation repository. Adding docs-missing label.

I've moved the protocol implementation into a separate package, there's a few things in particular that still need review:

The device protocol should be able to push switch state changes, however I'm not exactly sure how to best implement this. Currently I only read the switch state when first connecting to the device.

State responses from the device at the protocol level always provide the state of all 16 relays and should always be up to date unless the tcp connection fails, should the state for all 16 be pushed to the home-assistant switch entities by the protocol or should they be filtered by the protocol to the specific entity relay? I partially implemented an event_callback but I'm not entirely sure where to wire this up to the individual entities.

The device sends a keep alive message every second with an internal timestamp from the device, should I be using this for anything such as detecting timeouts or connection failures quicker than waiting for the tcp connection to fail?

I'm unsure of the best way to generate the unique id as the device has no serial or mac that can be easily queried over the relay control interface. Would having something like {host}-{port}-{relay} make sense for the unique id's?

A callback from the device to push state changes sounds good. Eg allow to register one or more callback handler functions. On new state event call handlers with new state etc.
Probably pass an id of the relay that changed state together with the rest of the state info when calling the callback handler. If we can store the relay id in the entity when that is created, the entity can be notified of only corresponding state changes. The state event message could be a custom instance or perhaps a dict. Attributes of the instance or the keys of the dict represent the different parts of the info we need to send to the callback handler. Use our dispatch handler to signal the correct entity from the component that has the connection to the device if we have a central callback handler function. If we go for distributed callback handling then each entity could register its own callback handler and be notified directly.
The keep alive message can be monitored and used to set the available property on entities. This notifies the user if entities become unavailable due to connection issues. We don't want to store the keep alive timestamp in the state machine since that would be spam.
Unique_id needs to be  persistent besides unique. Host and port, if network properties, might change, right?

Unique_id needs to be persistent besides unique. Host and port, if network properties, might change, right?

Yes they can change, however I haven't found any other viable options, the relay control TCP interface is quite limited as it's implemented as a ser2net pass-through to a simple MCU(I've looked through the MCU code and wasn't able to find anything unique that can be queried).

If we go for distributed callback handling then each entity could register its own callback handler and be notified directly.

This sounds to me like the best option, I think I can probably just add a relay specific state change callback registration function to my protocol implementation. I'm mostly just confused in regards to from which function in my component I should actually call do this registration from, I think it needs to be before the entity populates the initial state so as to avoid missing any state updates(I use a queue mechanism within my protocol to avoid command races). Would having it within my async_update function make sense?

Callbacks in entities should be registered in entity coroutine method async_added_to_hass. This will make sure the entity has been added to home assistant and can schedule a state update when a state event come in.

Uniqueness and persistence are required properties of unique_id. If we can't control those we can't implement unique_id.
https://developers.home-assistant.io/docs/en/entity_registry_index.html#unique-id-requirements

From now, please don't squash commits, since review has started. This will make it easier to track changes. We will squash when merging.

This will make sure the entity has been added to home assistant and can schedule a state update when a state event comes in.

Ok, so async_added_to_hass will always be executed before the async_update which queries the state right? The device only pushes state when explicitly queried so it's important that the callback is registered before self._protocol.status() is called I think.

Uniqueness and persistence are required properties of unique_id. If we can't control those we can't implement unique_id.

Oh, so unique_id is actually something that's not required to be supported by components at all? So I should just remove any references to unique_id then?

Shouldn't querying, if necessary, be handled in the library? The library then pushes state events as they happen. It doesn't sound right that the app both needs to take care of querying the device and register callbacks. Why would we need callbacks then?

Yes, unique_id is not required, but it is very good to implement if possible.

If we ask the entity platform helper to update state when adding entities, the first call to async_update will happen before async_added_to_hass. But this is optional.

Shouldn't querying, if necessary, be handled in the library?

It more or less is.

It doesn't sound right that the app both needs to take care of querying the device and register callbacks. Why would we need callbacks then?

Well the query would be to establish existing state since callback's would happen trigger if there is a state change(such as one initiated by an entirely different device talking to the HLK-SW16 at the same time).

If we ask the entity platform helper to update state when adding entities, the first call to async_update will happen before async_added_to_hass. But this is optional.

Hmm, I do want it to call update but only after the callback is registered. Is there any reason it wouldn't work having the callback registration within async_update but before the protocol gets queried for state? Is there somewhere else it might make sense to have so that the update gets called only after the registration?

If we don't need to query regularly, maybe we don't need to implement async_update but just do the initial query in async_added_to_hass after the callback is registered?

From what I can tell with how the device works you should never need to query again once you have the initial state since the device should always push state changes if there is an open TCP connection(I'm designing the protocol with this assumption).

maybe we don't need to implement async_update but just do the initial query in async_added_to_hass after the callback is registered

Sounds like this might be the best option, I'll give it a try and see how it goes.

If we don't need to query regularly, maybe we don't need to implement async_update but just do the initial query in async_added_to_hass after the callback is registered?

This seems to work reliably, the switch state changes update even if I trigger the relays via an external script instead of home-assistant.

I've refactored this in order to make it possible to configure multiple hlk-sw16 devices, does my config example in the OP seem sensible?

Is it possible to discover the relays automatically somehow on the host? Or could the host push presentation of relays to home assistant? It would be nice if the user just needs to configure a host.

Is it possible to discover the relays automatically somehow on the host?

So each HLK-SW16 device has its own IP/port and exactly 16 available switchable relays(although the user may not need all of them). The 16 individual relays can be used for arbitrary functions so they need to be nameable at least and there's no device side relay naming capability(they are internally only identified/controllable by their fixed hex byte id which also corresponds to the printed relay labels) so I don't think any auto-discovery is really possible.

I've refactored the client library here.

Current connection resumption behavior is now for the client to process the queue from where it last left off from so that commands executed while offline are not missed.

Consider limiting processing of queue to last state. Stale state changes that are applied later might be bad, eg if state is flipped back and forth multiple times.

Consider limiting processing of queue to last state.

That would be tricky I think with how I designed the protocol implementation. The calls themselves eg await self._client.turn_on(self._device_port) however are await'd until actual confirmed execution so it should be possible in theory for the callers to know not to call again until there is successful execution.

Stale state changes that are applied later might be bad, eg if state is flipped back and forth multiple times.

Well the device itself shouldn't really have trouble handling that, it processes the commands and returns responses quite quickly.

I've added timeouts here which should result in the device getting marked as unavailable within 10 seconds of connection loss. Hopefully that should prevent home-assistant from trying to queue too many state changes.

removed those now

Great! Can be merged when build passes.


DRAFT: chore: change internal logic, remove V4 suffix internally

This PR is part of the 3 part pull request:
chore: change internal logic, remove base, V2, and V4 suffix internally

I'll close the PR for a bit until my tests pass locally again.


Translate the rain section into French

Thank you Michel. I will merge this into the next release.


[Request Feature] Change resolution for Game Window

Because I want to know how it render on mobile resolution

This bug has been fixed


Local path following dynamic obstacle near to the goal

Dear all,
first of all, thanks for your contribution to the robotics community with this local planner.
We are experiencing an strange issue of the TEB local planner where the computed trajectory tries to "follow" a moving obstacle (in this case a person) instead of being recomputed to obtain a shorter path towards the goal.
We observed that this issue appears specially close to the goal. To explain this better, we share here this video:
https://drive.google.com/file/d/13bAjEJ8FIvoU8gy4QJpgZoRpuFeG3td_/view?usp=sharing
In the video you can see the teb plan surrounding the person when the goal is just placed in straight line (green straight line is the global plan). Around 0:43 we give another goal close to the previous one and the local plan is not recomputed. Then, around 0:55 we give a new goal further than the current one and then this time, the local plan is recomputed correctly in straight line.
Ideally we would not like to send different goals to solve this situation and the first "people following" should not happen. I guess this is an issue with the optimizer, that becomes far from the optimal solution and it takes as initial guess the previous deformed one.
Have you experienced this issue? Could you help in how to tune the TEB so this does not happen or how to detect this situation to "reset" it?
Best,
Mayte.

I also encountered the same problem. Have you solved this problem？ @mtlazaro

Hi,
I'm afraid we haven't.
Maybe one could detect that the differences in length between the computed teb plan and the local or global plan is high. But I don't know how we could later reset the planner since resending the same goal takes no effect.

Hi,
I'm afraid we haven't.
Maybe one could detect that the differences in length between the computed teb plan and the local or global plan is high. But I don't know how we could later reset the planner since resending the same goal takes no effect.

Thank you for your reply, and I will try to continue to solve this problem. I hope that our new progress can be synchronized here. Thanks


Feature/addKotlinCodegen

Summary
This PR adds Generators for Kotlin to Codegen.
Since Kotlin can interopt with Java seamlessly, the generation of the Kotlin Code is not necessary to use Kotlin for Module-Implementation, but i think it would be nice to have just Kotlin-Code.

Changelog

[Internal] [Added] - add Generators for Kotlin to Codegen

cc @RSNara

Hi @SimonErm, I'm excited to see these contributions to the codegen! I think that, for now, it would be best if Kotlin support is provided through a generator in a separate package that exists outside of the core RN repository. I do recognize that we need to provide better support for custom generators, we just haven't gotten to working on that yet.

Thanks for your feedback @hramos :-) i fully agree with you, i just didn't thought about that before the implementation :-D


Contact Form Broken

Nothing I do can get the contact form to work. Have change the line in the PHP file with an email account that isn't gmail/hotmail. Form submits but never receive mail.

Interesting the form seems to be working elsewhere. This might be an issue with your web host. Also, the form wont work at all if you're hosting on GitHub pages.

I've tried on a local XAMPP server as well as a blank LAMP stack on Digital Ocean. I highly doubt my host(s) have anything to do with it.

You've got a mail server running locally and everything?

I am not seeing any issues with the form, and I'm not getting any other issues from other users. If you moved the files around make sure you fix the path in the contact_me.js file, but other than that I can't really think of anything else to try at this point...


global flags not shown on --help

preevy --help should show all global flags (e.g, --debug)

Can I work on this?

can someone explain what's going on here

Assigning @Abhi5Pande since they were first.
Oclif's notion of "global flags" attaches flags to specific commands, so this may prove trickier than it seems. If you need to make compatibility breaking-changes LMK. You're invited discuss this further on our Slack.

@Abhi5Pande any progress?

Yes @royra , experimenting with custom help class and figuring out how we can get the list of global flags


fixes for unit tests and uninstall code

pls review on commit bases
ideally first 2 commits should fix the issue however 3rd commit is the one which made me to realise the issue
so i'd also like 3rd commit in as well

will raise separate pr for getCSVByPrefix fix


variables of associations are not accessible in subclasses

Please consider the following example,
class A{
  0..1 sth-- * B;
}
class B{
}
class D{
  isA A;
  0..1 sth -- * B;
}

It generates the following code
  public B getB_B(int index)
  {
    B aB = (B)bs.get(index);
    return aB;
  }

The variable bs is not accessible in the class D, so there is an error. It's a private varibale in the superclass A.
There several other errors in other APIs in association with the variable bs

The solution is likely to change the direct variable access to bs to instead call the getbs method.
When solving this probem search for other cases, and add tests for all cases found.

One case I found difficult to fix is the adder function generated from the example given above, in class D, we have:
public boolean addB(B aB) { boolean wasAdded = false; if (bs.contains(aB)) { return false; } D existingSth = aB.getSth(); if (existingSth == null) { aB.clear_sth(); aB.addSth(this); } else if (!this.equals(existingSth)) { existingSth.removeB(aB); addB(aB); } else { bs.add(aB); } wasAdded = true; return wasAdded; }
The issues are:

Class D has no access to bs.
method getBs() does not return the reference to bs, but a duplicate of it.
method addB() is overriden, so calling addB() in D invokes the method itself, rather than the addB() defined in class A.

Yikes. Tricky. These kinds of issues seem to be getting more and more complex.
In an ideal design, the addB method in B should continue to work, and not be overridden, with only calls to any necessary 'checks' made by it (e.g. for verifying multiplicity bounds) being overridden in subclasses.
I notice only trivial details that differ for the addB method in the subclass D as compared to A. Not sure why the 'clear_sth()' is needed in D, for example. Perhaps this could be put into the superclass'es method (i.e. present in all add methods) and then the override is not necessary.
Another thought would be to add a necessary protected service methods into the superclass that the subclass can use to do operations on the private variable (and not a copy of it). But that increases complexity, where as the solution above decreases complexity.
The particular case here is  a bit degenerate: The association in the subclass is identical to the association in the superclass. That would imply that actually it could be ignored (as it inherits anyway). The interesting cases are where the association with is modified to have a slightly different multiplicity (e.g. a Vehicle has any number of wheels, but in the subclass Car it is modified to have a maximum of 4 wheels -- allowing for three-wheelers!), Whatever we do, we need to test for such cases too.

One question that is blocking me right now is that in Umple's Java Generator, when generating the code of a particular class, how could I access the information regarding the base class of this class (should it be a subclass). And if there exists an association in the subclass, how can I see whether its parent class also has associations of the same type or multiplicity?

I have encountered another tricky case.
Given two snippets of Umple code
class A {
  1 -- * C;
}
class B {
  isA A;
  1 -- * C;
}
class C {
}

and
class A {
  1 sth -- * C;
}
class B {
  isA A;
  1 sth -- * C;
}
class C {
}

The only difference is that in the second case, the association between A/B and C is named with one single name and in the first case the association is not named. However, they result in different behaviors in code generation. In the first case, class B has a field cs (a list of class C objects) overriding the cs inherited from A. However in the second case there is no such overriding.
My question is, are these two examples supposed to produce the same output? And if so, which behavior is expected?

The examples should produce the same output except that in the first case a variable on the 1 side would be aB, and on the other side it would be sth. The expected behaviour, however, is that overidding association in B would be ignored since it is identical to the inherited association. Code in subclass should only change if the multiplicities change, and multiplicities are the only thing that should change (otherwise it is a different association).

In the last comment avoid the word 'attribute', we are talking about 'variables' here, not attributes. Attributes are at the UML modeling level. Variables are in the generated code.
So right "neither of the two cases should have a separate cs in class B" is true.
However the second part should be "and in class C, there should only be one variable anA, instead of both anA  and aB". This is different from what you wrote in a couple of ways.
As for the example the last comment, it should generate error 19 for the same reason that the code below should generate error 19. A totally separate association is created as soon as any role name differs. But there need to be differences on both sides.
class A {
}
class B {
  isA A;
  1 sth1 -- * C;
  1 sth2 -- * C;
}
class C {
}

So we have agreed that the rules are:
a) If an association in a subclass has identical role names on both sides (either explicit role names or the names of classes), then
i. if the multiplicities are the same too, then it is the same association, and can be ignored (inherited methods will all work)
ii. If a multiplicity is different, then it is an overiding association and specialization templates can be used.
b) else if the association has one different role name, then error 19 should be raised
c) else it is a completely different association

I have implemented a fix for the above mentioned case a) i.
The idea is: Find the association to be ignored, and delete both the Association and the AssociationVariable from the classes at both ends of the association so that relevant code will not be generated. For Association objects this idea works fine, but the difficulty is with AssociationVariables. In UmpleClass, the getAssociationVariables method returns an unmodifiable collection, which makes it impossible to make any modification to the AssociationVariable method.
One possible solution is to add an "ignoredAssociationVariable" list into the UmpleClass object, and then check the list during the generation phase. Is there any other suggested solution?

There is API generated to remove links of any association. So even though you get an unmodifiable collection, you can still delete a link by calling the right API. That would be the best solution. Think 'Umple' not 'Java'.
Your idea of creating an 'ignoredAssociationVariable' list is problematic in several ways. Firstly it would require all generators to be aware of it, including diagram generators. Secondly, you would add an association not a list!

I am finalizing my fix for this case:
class A {
  1 -- * C;
}
class B {
  isA A;
  1 -- * C;
}
class C {
}

One thing I am not sure: in this case, the association in class B should be ignored, but what about in class C, in the generated Java code of class C, should there be attribute "private B b;" and corresponding methods?  If there are those methods, how do we trigger "setB" if only class A has setC"?

The short answer: What should appear in class C is what would appear if class B did not exist.
In other words class C would have "private A a" as it does now. Since B is a subclass of A, any B can be put into this variable at runtime.
Class A has 'addC', but class B can do that too, as it is inherited. Class C has 'setA', and if it needs to set a B, it calls setA since any B can be used wherever and A is specified.
In conclusion. Ignoring the association in class B that is identical to the inherited association means truly ignoring it.

There is a problem with this solution, the case mentioned before is parsed equivalently with this form:
class A {
}
class B {
  isA A;
}
class C {
  * -- 1 A;
  * -- 1 B;
}

Then as the solution mentioned above, the association between B and C would be ignored. However, in umple compiler, this is the exact case happening in class UmpleClass, which has association with both ConstraintTree and Precondition, where class Precondition extends ConstraintTree. And class UmpleClass would require the method "getPrecondition()", which would not be generated if the ignored association is removed.

Refactor the compiler first to add a role name for b case. Am travelling so can’t analyse in more detail
Timothy C Lethbridge
Sent from my mobile

On Mar 10, 2018, at 14:07, Yuan Bowei<EMAIL_ADDRESS>wrote:
There is a problem with this solution, the case mentioned before is parsed equivalently with this form:
class A {
}
class B {
isA A;
}
class C {

-- 1 A;
-- 1 B;
}
Then as the solution mentioned above, the association between B and C would be ignored. However, in umple compiler, this is the exact case happening in class UmpleClass, which has association with both ConstraintTree and Precondition, where class Precondition extends ConstraintTree. And class UmpleClass would require the method "getPrecondition()", which would not be generated if the ignored association is removed.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

One more point. Given the above you should ensure a warning is issued when ignoring duplicate associations.
Association matches an inherited association. Use a different role name if you need a new association for another purpose.
Timothy C Lethbridge
Sent from my mobile

On Mar 10, 2018, at 15:06, Timothy Lethbridge<EMAIL_ADDRESS>wrote:
Refactor the compiler first to add a role name for b case. Am travelling so can’t analyse in more detail
Timothy C Lethbridge
Sent from my mobile

On Mar 10, 2018, at 14:07, Yuan Bowei<EMAIL_ADDRESS>wrote:
There is a problem with this solution, the case mentioned before is parsed equivalently with this form:
class A {
}
class B {
isA A;
}
class C {

-- 1 A;
-- 1 B;
}
Then as the solution mentioned above, the association between B and C would be ignored. However, in umple compiler, this is the exact case happening in class UmpleClass, which has association with both ConstraintTree and Precondition, where class Precondition extends ConstraintTree. And class UmpleClass would require the method "getPrecondition()", which would not be generated if the ignored association is removed.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

While working on the case a) ii. I found another issue with association, therefore I created another issue issue#1238 and provided fix PR@1239

Regarding the rules we have previously agreed on, the progress is reported as below:
a) If an association in a subclass has identical role names on both sides (either explicit role names or the names of classes), then
i. if the multiplicities are the same too, then it is the same association, and can be ignored (inherited methods will all work)
Progress: Resolved by PR1236
ii. If a multiplicity is different, then it is an overiding association and specialization templates can be used.
Progress:
1. A bug was discovered while my investigation, explained in issue#1238, fixed by PR#1239.
2. There are some extra work needs to be done for this rule, which will be committed after the CI is fixed and other rules to be completed.
b) else if the association has one different role name, then error 19 should be raised
Progress:
Addressed by PR1237, which was merged then resulted in failures, because some umple source code violates this rule. Either should we revise this rule or modify the violating code.
c) else it is a completely different association
Progress: nothing needs to be done.

Another bug with specialized association is found, regarding rule a) ii issue#1245.

Some error 19 cases are being raised PR #1243 from the UmpleToRTCPP templates (after fixing the build in PR #1247 and #1248). Options for part b in the last comment are
b-i) To ignore cases where there is an overriding association where only one end has a different variable. Drawback for this is that is can hide bugs and would be generally confusing
b-ii) To refactor the associations in UmpleToRTCpp where this problem exists.
It was agreed to investigate the latter for now.

Progress as of March 25:
The rules that we have previously agreed on have been fixed, other than one exception:
a) If an association in a subclass has identical role names on both sides (either explicit role names or the names of classes), then if a multiplicity is different, then it is an overiding association and specialization templates can be used.
Here the condition if a multiplicity is different is wrong according to Umple's definition of "specialization", a specialization makes sense only when the association in the subclass has a more specific multiplicity.
Now most of the specialization templates are no long called in an error-causing situation. The next step is to write some comprehensive test cases that covers all possible specialization cases and check the get methods.

Right. The Liskov Substitution Principle says that instances of a subclass must be able to be used wherever a parent class is used. So if Car isA GroundVehicle and GroundVehicle has * wheels, and Car has 4 wheels, this is valid as a specialization (more restrictive multiplicity). But the reverse is not. I think there should be a warning issued where the subclass actually broadens the constraint:
"Multiplicity {0}  in the specialization association between {1} and {2} is less restrictive than multiplicity {4} in the inherited association with class {5}. This violates the Liskov Substitution Principle".
The code generated would still work, so this should only be a warning. But it would be a useful warning  in practice and for educational purposes.

What blocks me now is the definition of "specialization" and "relatedSpecialization". And when each of these templates should be instantiated.

To figure this out take a look at the logic that determines which templates will be emitted. For example, the relatedSpecialization templates to be emitted are determined in UmpleToJava/UmpleTLTemplates/association_set_specialization_reqCommonCode.ump
(ignore the .jet, just look at the prefix for the includefile and includefile2 to determine what will be emitted.
The above in turn is invoked by JavaSpecGenerator.ump

Progress April 13, 2018:

The issue that in some classes the wrong templates are trigger is fixed by this pull request:
PR1258

As PR1258 is merged. This issue can be identified as fully resolved and can be closed.


LaTeX3/expl3 syntax highlight fails in environments

A clear and concise description of what the bug is.
LaTeX3/expl3 syntax highlight fails in environments.
A minimal example to reproduce the issue
With this code snippet:
\int_case:nn
\begin{center}
  \int_case:nn
\end{center}

the output is

VS Code Version: 1.88.1 (Universal)
OS Version: macOS Sonoma 14.4.1
LaTeX-Workshop version if you use it: latest

This is related to the fix of #83. This is a tricky issue.
Consider the above example: the latex3 grammar calls the latex grammar and we would the content of an environment to be matched against the base grammar (latex3).
When latex is embedded in markdown for instance, we want the content of an environment to be matched against the latex grammar and not the base grammar (markdown)
I can think of two solutions

Duplicate the latex grammar to define the latex3 grammar but this is no good for maintenance
Integrate the specificity of latex3 into latex and use the same grammar all the time.

I think 2 is best. @James-Yu any opinion?

I would vote for the second option 😄

The LaTeX3 functions and variables are not matched by the standard LaTeX grammar.
Note that in the previous LaTeX3 dedicated grammar, functions were assigned the keyword.control.expl.latex scope, which was wrong. Now, we use the scope support.function.general.tex as for other LaTeX macros.

Hi@jlelong Currently the syntax highlighting is still wrong. The last updated time of the extension is 2024-04-21, 19:09:54.

And the syntax highlighting of  dtx files is also strange and  wrong. See this screenshot:

I do not know what the last updated time refers to but the fix has not been released yet. Version 9.20.0 was released a week ago. Using the development version of the extension

How to use the development version?

You can download the .zip artifact https://github.com/James-Yu/LaTeX-Workshop/actions/runs/8767494435/artifacts/1432332965. You can install the contained .vsix package, using Extensions: Install from VSIX.

Thanks for the guide. After installing from VSIX, there is some problems.

\__module_foo:nn is not highlighted correctly.
And another strange phenomenon:

The LaTeX3 grammar is built from the conventions described in section 1.1 of https://ctan.math.illinois.edu/macros/latex/contrib/l3kernel/interface3.pdf
In particular, it is written that Each function name starts with the module to which it belongs. So a function should not start with a double _, but it could be changed.
This issue on the .dtx file is most likely related to the fix of #83 https://github.com/jlelong/vscode-latex-basics/commit/4f8b49bca02b0bfde6e46252c209396ba6c567f9. Can you open a new issue on this? Thanks

The expl3.pdf says that:

To allow clear separation of these two cases, the following convention is used. To denote a private function or a private variable (of the module), two _ characters are used in front of the module name, e.g.
\module_foo:nnn

is a public function which should be documented while
\__module_foo:nnn

is private to the module, and should not be used outside of that module.

So it is reasonable for a function name to be started with \__.

This issue on the .dtx file is most likely related to the fix of https://github.com/jlelong/vscode-latex-basics/issues/83 https://github.com/jlelong/vscode-latex-basics/commit/4f8b49bca02b0bfde6e46252c209396ba6c567f9. Can you open a new issue on this? Thanks

OK. I'll open a new issue.


Release 0.13.0 of ROI

We need to release roi because:
tagged this 22 days ago · 13 commits to master since this tag
and this:
https://github.com/bucharest-gold/roi/issues/15

https://www.npmjs.com/package/roi


Expire clip thumbnails when cache is filled

Ensure that transcoded thumbnail clips are also expired from the cache like all other media. Fixes a bug where they could be left orphaned.

Codecov Report

Merging #170 (df3443f) into main (dc68c93) will increase coverage by 0.11%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #170      +/-   ##
==========================================
+ Coverage   92.03%   92.14%   +0.11%
==========================================
  Files          17       17
  Lines        1870     1872       +2
==========================================
+ Hits         1721     1725       +4
+ Misses        149      147       -2

Impacted Files
Coverage Δ

google_nest_sdm/event_media.py
95.28% <100.00%> (+0.44%)
:arrow_up:

google_nest_sdm/google_nest_subscriber.py
62.33% <0.00%> (-0.17%)
:arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update dc68c93...df3443f. Read the comment docs.


slight run with 0 capabilities

Description of the bug
When slight is run using a slightfile with 0 capabilities, slight will error out.
To Reproduce
Create a slightfile with 0 capabilities and run the app.

https://github.com/deislabs/spiderlightning/pull/342#pullrequestreview-1331529545

This is related to #358


fix(remove-parent-modules): only filter runtime chunk

Summary
When removing parent modules, filter runtime chunk properly

Test Plan

Require Documentation?

[ ] No
[ ] Yes, the corresponding rspack-website PR is __

!canary

!bench