To add to this, I understand this is a third party module created by Paul, but if we're creating functions that are in the realm of possibility for the base ignition platform, shouldn't these just be developed into ignition? I also wonder what happens when features get added in here that really should be in the base ignition and the platform ends up with hidden knowledge of "yeah you should really install Ignition Extensions for any new project".
I do agree with you here. I think a lot of these functions should make it into Ignition. The good thing however with this module is that Paul can very kindly add requested functions usually a lot faster than these would be added into Ignition. Into Ignition, it has to go through all of IA's processes for selecting things to add, then through dev and rigorous testing. This module bypasses all of that, but the changes made I would assume are extremely unlikely to break something.
That is definitely a major blessing of this module, but I think it's also a curse. If all of the QA is being bypassed and we can all get our delicious candy straight away I can see this getting out of hand quite quickly as we decide to get new features through this process rather than going through the channels that IA already has.
these arent really new features, they are just convenient scripts
I think you’ve got a good instinct here.
I don’t know if Paul just wasn’t around yet or doesn’t remember, but I’ve been watching with a mix of amusement and dismay as this module of his follows a parallel path to the “IA Labs” module horror show. The only difference is instead of a bunch of Design Services guys adding functions whenever they needed it for a project it’s Paul responding to customers, and hopefully the quality is a little better.
But it’s still receiving no design review, no QA, no promise of ever being integrated into Ignition, and ya’ll are getting hooked and adding this as a dependency anyway.
Meh. Public code that anyone can build and carry forward.
@Michael.Smith has made a similar comment about my EtherNet/IP module being a third party product, but at least that one was justified by its commercial status.
Modules developed outside IA's process do not have to follow IA's schedule, and do not have to set the minimum Ignition version to the latest release, and can therefore provide features for older Ignition versions with low risk. My current set of modules work in the entire v8.1.x line.
IA's rigid versioning inhibits one of the key advantages of a modular platform: small changes (module installs) for incremental gains.
Does IA do design review or QA of other modules that are available in the module showcase? I don't know what the vetting process is. Is Paul's module distinct in that?
No.
Good points but I still think it's a value add in the context that this module is a collection of potentially useful scripts and not an IA product that has gone through the QA process.
Sure, I'm not disputing that. Use it. Or don't.
I'm just amused by history repeating itself.
I love a good spicy breakfast in the morning, thanks y'all
So, for me, this module serves a few purposes; in no particular order:
- It's a fun distraction. I like writing Kotlin much more than Python, and most of what's in this module at the moment are basically just nice-to-have utility methods, but packaged under the system namespace because modules are allowed to do this. Basically zero maintenance burden or risk, because they're just operating on the public contract of things like datasets.
- It's an educational exercise; for me, and for the community. This is, as far as I know, the only publicly available example of a 'modern' CI stack for an Ignition module. It's even got automated releasing and signing via Github Actions. It's also a good opportunity to demonstrate a "real" module, rather than the closer to toy examples in the
sdk-examples
project. - It's an experimentation ground for me. Maybe I have an idea for a function (that could eventually end up in Ignition) but I have no idea what the API should be. Or if it's even going to be useful to folks. With no QA process, no guarantees of future compatibility, and a big scary warning every time you autocomplete the function, I figure risk of someone blindly relying on this "in the wild" is pretty minimal.
- Most of these functions don't belong in the platform for every single end user. Sure, anyone familiar with Python or functional programming in general is going to grok
system.dataset.filter/map
pretty immediately. But many folks coming to Ignition have never programmed in anything besides ladder, or VBA, or Excel formulas. Trying to explain the idea of a 'pure' function to someone who can't yet distinguish expressions from scripts? Sounds like a bad time.- Similarly, nothing I'm doing here is anything you can't just do yourself from scripting, with sufficient motivation. It's a lot easier now, sure, but the only truly "unsafe" thing exposed here, in terms of deep reflection or reliance on non-public internals are
system.project.save()
andsystem.project.update()
.
- Similarly, nothing I'm doing here is anything you can't just do yourself from scripting, with sufficient motivation. It's a lot easier now, sure, but the only truly "unsafe" thing exposed here, in terms of deep reflection or reliance on non-public internals are
It's also not just my project. I'm open to PRs from everyone, and I took steps to divorce it from my name/namespace on Github. If anyone wants to step up and maintain it going forward, or if I fall off the face of the earth... they can! No big deal.
I'm very aware of the birth (and ignoble death) of the IA labs concept (https://forum.inductiveautomation.com/t/useful-common-script-extensions/64538?u=pgriffith) - it was top of mind when I started this project. That's precisely why I made sure to make nothing about this 'special' to me, or blessed by IA in any official capacity. It's intended to be a community effort; it's just that so far nobody's stepped up to learn enough Kotlin to contribute
I'm very aware of the birth (and ignoble death) of the IA labs concept (https://forum.inductiveautomation.com/t/useful-common-script-extensions/64538?u=pgriffith)
Link is broken fyi
Not broken, it's just in the special 'Lounge' area the forum software hasn't decided you get to see yet. It's not very exciting, I promise.
I spend my spare time in embedded Rust programming. Seems like I saw you had written something in Rust , I think I was browsing your Github profile a while back and stumbled upon it
Ahh gotcha. Disregard then!
To be clear, I don't have anything against third party modules and I think that they serve a purpose where IA doesn't have the knowledge/expertise/willpower/desire to develop a product in line with their standards. My comment to you previously was more of a curiosity about how it achieves magnitudes better performance than the base driver.
I think many of these features probably do belong in ignition at a base level as they are within the scope of the base ignition platform, particularly the fromExcel function and Logic expression functions.
I wouldn't be so sure of this assumption, I would suspect a great deal of the user base are familiar with basic programming concepts. Many people coming to ignition have probably never touched SQL, but those features are available to all users.
Not trying to rain on anyone's parade, and the other points you raised are valid, but at some point I think it is worth checking and saying "Should ignition just do this already?"
Maybe I'm biased since I made the suggestion, but I definitely feel the isAvailable
function should become part of the Ignition base. The alternative without it is so overly convoluted in the expression language if you're wanting to hide components based on the availability of tags (exist and not disabled). I install this module for all projects almost purely for this function alone! Although I do find many of the other python functions convenient as well, however as Paul said, these at least are replicable without the module. Expression functions however, aren't, and if I tell a newcomer that in order to hide a component, they have to use this expression below, they will look at me like I'm insane
indexOf(toStr(qualityOf({tag})), 'Bad_NotFound') = -1 &&
indexOf(toStr(qualityOf({tag})), 'Bad_Disabled') = -1
I'm curious, why do you need the indexOf()
and toStr()
portions of that expression? I would have thought that the expression below would work, but I'm guessing I'm missing something important:
qualityOf({tag}) != 'Bad_NotFound' &&
qualityOf({tag}) != 'Bad_Disabled'