Adding preference option to existing driver/app

Yes, that.

Neat. But I like to keep things simple. It's easier for me to read when each line does one or two things. For me, it's not about condensing the code down to minimal lines, but keeping it easy to read, so I avoid nesting, but also those sort of "tricks". Maybe I'm just not adept and/or a bit slow, but to each their own on that, and/or the ternary operators.

No, some people really hate ternary operators. Like with a fiery passion.

I understand why, but it doesn't bother me at all.

So to read a ternary you have to sorta read it forward and backward at the same time. Especially if you're doing a 'ternary return' like I have above.

You're reading return this and thinking "ok, we're returning that", then you get to != null ? and now what you just read is no longer true, you're not returning that at all, it's an expression to determine which thing you're returning, the stuff after the ? or :

So I totally understand that some people hate them.

But in this example case here, it's really clear that these are all a bunch of null check ternary. Some languages have ways to do explicit null check returns, something like this:

return myValue ?: defaultValue

Groovy has this too... except it uses "Groovy truth" which like I said above sometimes fails in ways you aren't expecting. If you use the "Elvis operator" in groovy, then the above would return defaultValue if myValue is null (what we want), but also if it's 0, false, etc, which is probably not what we want.

There's other languages where the above "Elvis operator" or similar constructs ONLY check against null. That's a lot more useful IMO.

2 Likes

I just got caught up on this and wanted to say I love using ternary, especially when I can use the "Elvis" (TIL ?: = Elvis).

Perfect explanation of that and the "truthiness" complications. I just got bit by that not too long ago trying to check for null using the ?: and forgot that 0 would be a valid value.... Had to make it a little less pretty and add in the != null like what you did above.

Also... was totally not aware you could use the actual symbol in groovy but not really that surprised. Is that common in other languages? I will just stick with the good old != though.

1 Like

Honestly, that should always be how to do it. It’s a fair bit faster because Groovy knows exactly what it needs to do. if(myVar != null && myVar != ‘’) is much faster than if(myVar).

Make everything explicit, with static typing, casting as needed, and put @CompileStatic on everything. It’s drastically faster. I’ve got a bunch of helpers in my code specifically to handle things that I can’t get into @CompileStatic, such as sending events, getting device DNI, etc. Little 1-2 line helper functions, getters/setters, etc, that can’t use @CompileStatic so I can use it with everything else.

It’s a little more work up front, but you end up with much faster, less buggy code. And when you come back to the code a year down the road, it’s a LOT better seeing ArrayList<LinkedHashMap<String, String> and knowing exactly what you’re dealing with at that point in your code rather than def. So if you factor in the amount of time saved down the road trying to remember/figure out what type an object is when you’re making some code changes, it’s really not any more work overall, and you get a ‘free’ benefit of faster code. def is just awful and I hate it.

Yeah I agree there as well, I have been getting rid of def in my borrowed code (from old ported drivers mostly) as I go through it more.

1 Like

That's how the power monitoring plug driver I'm working on right now can process 43,500 incoming messages while using almost no resources:

3.3ms per count, or 141 seconds to handle 43,509 messages, on a C7. I do miss the old Device Stats/App Stats page where I didn't need to break out a calculator to see the milliseconds per count stat.

Most drivers I see are around 10x that much resource usage for the same.

Example.. using the "Generic ZigBee Outlet" driver for my Sonoff Zb Lite plug uses 12 seconds of CPU on my C8-Pro, or 3.3ms per message, and that's not doing any power monitoring, on a CPU that's 2x faster.

My Zooz Zen20 using your driver uses 35ms per count, on a C8-Pro. :wink:

I have a bunch of other stuff going on in there like checking hi and low limits, etc... Also need to pull up the child device and forward the event to it. But if you see something that could be optimized I am open to suggestions.

You can define them on separate lines. It’s more readable and allows strict typing.

2 Likes