Device types: how can a device alert/alarm/notify of critical problems?

(There’s actually a proposed solution in the latter half of this post - the first half is just describing a problem, and then trying to emphasize how serious it is.)

If it’s not obvious from my recent postings, I’m playing around with device type code. One issue I see over and over is that a device might experience a serious problem that a human being REALLY needs to be informed about, but there doesn’t seem to be any way for a device type to send a notification or alarm.

For example, let’s say you get this new wiz-bang auto-magic does everything ESP enabled door lock. This thing can detect if a burglar is even THINKING about breaking into your house!

So, you add it as a new z-wave device, see that ST can lock/unlock it, and you go off to work. Then, while you’re at work, a burglar just happens to come by and breaks into your house. ST doesn’t notify you. You come home to find that you’ve been robbed blind (but at least the burglar left behind the ST hub that didn’t tell you about the event.)

Here’s the sad thing: The door lock detects that the door was forced, and the device type code for the lock actually does get an alarm event. However, the device code has no way to cause a notification of any type to be sent to the user. The absolute best you can hope is that the device type code causes something to show up in the activity stream (but you can’t even assume that!)

So much for a “smart thing” in a “smart home.”

BTW, as an irony, if the battery in the door lock gets low, you’ll probably get a notification for that (assuming the default for the low battery option isn’t changed.)

The reason for all this is that device types have no way to push to anything except for the activity log or to smart apps. The devices do this by calling createEvent (or sendEvent) to send information out to “whoever is listening.” However, there doesn’t seem to be anything “listening” on a global scale for any kind of alarms!


The same flaw exists for a door lock, a water sensor, etc.

A user could install a smartapp to listen for certain events and send notifications. However, in the case of the door lock being forced, there’s nothing specific to subscribe to. Here’s the event used when if the door lock is disassembled:

map = [ descriptionText: “$device.displayName front escutcheon removed”, isStateChange: true ]

No name or value. Just a description. With no attribute (name), how can this be subscribed to? Is the subscriber supposed to parse the description text for everything? Really?

Is the lock’s bolt jammed? That would be pretty important… here’s the event:
map = [ name: “lock”, value: “unknown”, descriptionText: “$device.displayName bolt is jammed” ]

At least there’s an attribute (lock), but the value is quite a bit less significant than the description!

The z-wave garage door code is just as bad… jammed, stuck, car drove though it, nuclear explosions… all send events that are generally ignored.

Okay, enough ranting about what’s broken. Now a proposed fix. @Ben , I’ve referenced you so that (hopefully) you can call this to the proper person’s attention. This isn’t a “we need another device” proposal. This is a MAJOR shortcoming of the ST product that should be addressed quickly (and should be fairly simple to address.)

The simple way would be to add a way for device types to send notifications to users. I somehow doubt that would be added. It just doesn’t “fit” with the existing system. Then again, it might be the easiest and quickest “solution.” Considering that everyone is probably working on v2, this might be the best we can hope for.

A more elegant solution would be to have the ST recognize a boolean attribute in the ‘Event’ class called “urgent”. If true, the event is of an urgent nature and should generate a notification REGARDLESS of any smartapps that may or may not be running. This would act in the same way as an event with a name of “battery” and a value of “1” (but with no time restrictions.) If this is used, then the above sample (with actually exists in the z-wave door lock code) would be changed to:

map = [ urgent: true, descriptionText: “$device.displayName front escutcheon removed”, isStateChange: true ]

When that event was sent, it would immediately generate a pushed notification to all ST mobile apps (for that account) with the text of “Front door front escutcheon removed!”

If either of these ideas (or any other) is implemented, the device code for z-wave garage doors and z-wave door locks should REALLY be updated to make use of the solution.

Take care

1 Like

@garyd9 I’m not sure I understand, why would you want to couple the action with the definition of a device? If you have a separate SmartApp you can notify as many people as you want, instead of having only one notification in the device type. You can couple it w/ other devices to create more reliable notifications, if the door is opened but the lock is still locked?

From a platform architecture perspective, I don’t see why you would want to so tightly couple the device definition (device type) - it knows about the device and how to interact with it, with the actions (SmartApp) you would like to perform.

1 Like

I agree. While I understand @garyd9’s sentiment here and applaud this Topic, I slightly (?) disagree with the proposed implementation.

My recommendation:

  • Security related devices could indeed provide a new capability: “capability.urgentAlert” (I’m not married to the term “urgent”; but some standard new capability is desirable. It would have no commands, just “attribute: urgentAlert - [true, false]”.

  • Device Type Handlers that are able to parse out urgent alert information can offer this capability. Gary’s examples are great, and there are plenty more. A smoke detector whose battery is ultra-low might consider this an “urgentAlert”, since it can no longer report on a fire.

  • Worth noting here: The Device Type Handler is absolutely an abstraction of the physical device; this means that the “dead battery” condition could actually be detected and handled by the Device Type Handler even if the physical device is no longer reporting to the hub: The Device Type Handler for certain classes of devices could have a “pollingFailed()” callback method which can be handled in various ways, optionally including issuing an urgentAlert Event.

  • The normal SmartApp system can subscribe to the events that set urgentAlert on the Devices associated with each SmartApp, if the SmartApp chooses to do so, along with the desired Actions.

  • SmartThings might choose to implement various “global” SmartApps (similar to the somewhat unique SmartApps that are in the Dashboard panels); and one such “global” SmartApp could be the “Urgent Alert” SmartApp which just offers the user the option to subscribe to all urgentAlerts across a long list of devices with capability.urgentAlert.

NB: This last bullet is significant, as this piece essentially implements Gary’s idea that there should be some ability to easily handle “global” (hub or account-wide) status events; while maintaining the distinction between Devices (which only respond to commands and issue attribute state events to SmartApps) and SmartApps which decide which events to handle and how.

Hey… SmartThings already has a global SmartApp… “Low Battery Warning”
Just noticed / recalled that there already is a global (location-scale) SmartApp which must be tied to capability.battery; so adding another that is tied to capability.urgentAlert should be trivial.

…CP / Terry.


That’s a problem. IF there is a separate smartapp… John Doe isn’t going to know that they have to install a separate smartApp to know about these critical issues. Actually, as the device types stand right now, they can install dozens of smartapps, but nothing is going to be able to subscribe to an event that has no event (or if they can, there’s no consistent mechanism to determine if an event is just descriptive spam or something that’s really critical.)

[quote=“thrash99er, post:2, topic:9483”]
From a platform architecture perspective, I don’t see why you would want to so tightly couple the device definition (device type) - it knows about the device and how to interact with it, with the actions (SmartApp) you would like to perform.
[/quote]So don’t tightly couple it. That was why I offered two solutions… The first was a blunt mechanism that would probably be trivial for ST to implement. The second was a bit more complex, but fits into the existing architecture. It gives a mechanism that’s VERY similar to how any device can force a “low battery” notification to be pushed to the user (but relies on ST supporting a capability similar to “battery”, and relies on ST to force notifications on these critical events.)

Keep in mind that I’m not bringing this up for elegant code, pretty architecture, etc. This topic was to point out something that is, in my opinion, a CRITICAL FLAW in ST. Someone is breaking into my house, my door lock knows about it, and is SCREAMING to the hub that something is terribly wrong… but the door lock’s device type has no mechanism to get that critical information to the user (and doesn’t even have a standard mechanism to tell a ST app that something Really Bad is happening.) So, it’s doing the ONLY thing it can do: sending events that are useless (unless you’re a geek such as myself that stares at the logging while in meetings at work.)

Take care

That would work too. Personally, I prefer using the extra attribute… which would allow events to have more definition. The difference would only really be that you could have categories of “urgent” events. A “battery” event might be urgent if the battery was dead enough.

Consider these:

battery: 10, descriptionText: “battery low” // not urgent…
battery: 1, descriptionText: “battery level critical”, urgent: true // urgent? perhaps, because the next step is:
battery: 0, descriptionText: “battery too low to operate lock”, urgent: true // this is pretty urgent

You know that both of these are battery related without parsing the text description… On the other hand, the same device can also spit these out:

(This is interesting because there are no defined values for a door’s lock attribute. I’ve seen only “locked”, “unlocked” and “unknown” in the code. The other events coming from the lock don’t send the “lock” attribute)

descriptionText: “detected failed user code attempt.” // might be just one mistake?
descriptionText: “front escutcheon removed”, urgent: true // someone is taking the lock apart!!!

One of the ideas (I believe) of the ST architecture is to be as future-proof as possible. With that in mind, it’s possible that a smartapp could cause some “urgent” event to be handled, thereby rendering it no longer urgent. Think of it as OOP exception handling… it’s only an error if it’s not handled. In order for an app to handle it, it has to know what to subscribe to… which means we need that other part (and I can’t think of the name of it… it’s the attribute part of the cap.)

So, the following would typically be urgent:

battery: 1, descriptionText: “you’re screwed”, urgent: true

However, let’s guess that some future smart device could re-route power via a microwave beam to that device with the low battery to recharge it. In that case, a smartApp for that “power re-router” would do:

subscribe (somedevice, “battery”, …)

The handler would “handle” the event. Once handled, the event is rendered non-urgent. (How does it indicate if it’s handled? probably with a return code, or something. I’m not familiar with the smartapp side of things to make a suggestion here.)

Again, however, I feel the need to point out that HOW this is dealt with isn’t nearly as important as just dealing with it in SOME manner. Quickly! It’s PATHETIC that ST can turn on a siren if a contact sensor is opened, but has no mechanism in place to deal with a “smart” lock telling the hub that there’s a security breach.

Talking about the most elegant solution is nice. Honestly, I’d rather some quick and dirty hack it put in NOW to resolve the critical issue, and then we can chat about the best way to clean up the hack to be elegant. Bad code in a functional product is much better than elegant code in a non-functional product.

Yes, as someone who spends over 89% of my time dealing with issues in legacy code, I know the pitfalls of that. I also know the reality of software development. I believe this is one of those cases where some quick and dirty fix should be made, and then cleaned up later.


In my view, there’s two distinct issues in play here, actually, one of which I brought up to the last “Developers Office Hours Call” (and some private discussions with ST folks)…

  1. Event “descriptionText” should never be essential information:

I believe (strongly) that all of the critical parts of a Device Type must be expressed through it’s Capabilities. In turn, the Capabilities must be standardized and represent a mandatory interface to instances of the Device Type which offer that Capability. They could offer completely optional and non-critical / non-essential information through additional events or optional attributes – but even this violates the strict concept of an interface. An interface in Java, for example, lists method prototypes, and anything that implements this interface must fill in the code for those methods (no more, and no less). In the case of SmartThings capabilities, my definition is to extend Java interface with mandatory attributes and events – i.e., exactly all attributes of the capability must be set by the Device Type. The Capabilities Reference Table does not define standard events; but let’s say that there should be at least an event for each attribute.

It is up to the Device Type Handler to parse all the low level messages from the physical device and convert them to meaningful attributes. As your examples prove, it is ambiguous, confusing, and risky to expect SmartApps and other users of a Device Instance to interpret descriptionText.

So without using the descriptionText for any essential information (including critically “urgent” information), I believe that ST can handle this sufficiently using attributes, it’s just that the documentation for Capabilities is currently a bit weak and/or is not enforced by the system (as discussed with @Ben and @Jim).

If the Capabilities Reference is maintained, fully fleshed out, and strictly enforced, then we can be assured that all SmartDevice Types can be relied upon to delivery their capabilities in a consistent manner. Subsequently, all SmartApps (global, shortcut, manually installed) and external apps which select Devices based on capability preferences reference name, can trust the interface of the capability, and are solidly isolated from the hardware abstraction layer and physical hardware (i.e., physical devices of the same capability must be 100% interchangeable, regardless of vendor, model, or who wrote the Device Type Handler.

Concluding this Section #1: The goal of the last paragraph is impossible to achieve if Device Type Handlers do not distill (parse) essential information out of free form text fields and into strict attributes.

The sample descriptionText’s you gave, very likely differ greatly from one vendor to another:

To meet your desire to ensure these messages can be reliably interpreted, the Device Type Handler for a lock, therefore, must have some standard attributes to convey these type of lock states in a standard manner. It must interpret and distill the text into attributes that can be common across ALL locks with similar urgent conditions reported. I think we are in fully in agreement of this requirement; but I’d like to emphasize my preferred implementation as it fits into ST’s existing model.

  1. Device Types Can Provide “global” (or near-global) Capabilities:

I don’t want this to sound particularly novel, nor is my terminology necessarily accurate … but, let’s try this by example

capability.battery is a great example of a capability that very many Device Types implement; and, presumably, the Device Types implement it properly, by providing attribute: battery [0% to 100%], using the necessary parse() or sendEvent() logic. Because it is so common, because it can be considered critical information when value is low, and because it is consistently implemented (through attribute, not via an unparsed descriptionText, SmartThings has been able to provide the global SmartApp Low Battery Notification; and places the configuration of this SmartApp right in the “Hello Home” Page.

Now you have present a valid point: What battery level is urgent or critical? Even if we standardize attribute: battery and insist we should not use descriptionText for more information, it is a fallacy to assume a certain battery numeric value is not-critical; some devices can’t function below 40%, perhaps.

  • Your proposed solution is to add a sub-attribute (again, set by the standard Device Type Class methods of parse() or sendEvent()): battery.urgent - [true, false] or perhaps battery.urgency - [low, warning, critical].

  • The simpler alternative, perhaps, is to have Device Types normalize the battery levels they set. In other words, set a standard such that a Device Type must set the value of battery to 0 if it is below reliable function level, regardless of the actual hardware voltage reading.

  • A third option is to add one or more new attributes (by adding attributes to the existing capability.battery or adding new capabilities, e.g. capability.batteryStatus): such as attribute: batteryWarning - [safe, warn, critical], or a catch-all for various urgent conditions that I mentioned in first post: capability.urgentAlert with attribute: urgentAlertLevel - [safe, warn, critical].

  • A balance must be struck between adding new capabilities, new attributes, and overloading information into existing attributes. Every time a new attribute is added or overloaded on an existing capability, all SmartApps and external users of that capability might need to be refactored; well – adding attributes and values is pretty safe; removing is dangerous. But every time we add a brand new capability, we also want to review all SmartApps to see if they “should” use this capability; again, this is not critical, since new or “global” SmartApps can handle the new capability, and, indeed, deleting a capability is a much more impactful.

    • Now to your specific examples (aside from “battery”…). How to handle:
      • “Detected failed user code attempt”? At first, it seems like this should be just another attribute of capability.lock, except that we really should keep the scope of each capability as simple and small as possible, to ensure maximum compatibility. You’ll notice from the existing Capabilities, that capability.lock and capability.lockCodes are separate (but, combinable) interfaces. The first one covers basic lock functionality (command: lock/unlock, and attributes: lock - [state: locked/unlocked, I presume, but not documented]). The latter one actually overlaps these command and attributes – I think this is improper, but currently unavoidable, since ST does not implement inheritance of capabilities (grrrr!!! :grimacing:). The lack of inheritance means that you can’t just add attributes and functionality to a base interface (lock) and have it automatically be reflected in more complex classes (lockCodes).
        • Options: (a) overload attribute: lock with additional status values such as failed attempt. Messy.
        • (b) add attribute: failedUnlockAttempts - [count] and attribute: lockIntegrity - [secure, unsecure] to capability.lock and capability.lockCodes; pretty clean, but all existing DeviceTypes that provide capability.lock/lockCodes are now obligated to provide some value for these 2 new attributes (if we are as strict as I believe we should be.
        • (c) add a new capability that can optionally be added to existing SmartApps or used by “global” SmartApps, such as “capability.lockAttemptCount”; this seems to be the most practical option when we are adding important new attributes that are not likely to be universal across all devices of more basic capabilities (e.g., some electronic locks have no keypad, and thus, a lockAttemptCount is unlikely to be provided by the physical device – unless it happens to count key insertions or NFC swipes, I guess).
    • “Front Escutcheon removed”?
      • Again, I recommend (c): Add “capability.lockIntegrityReport” to SmartThings, with corresponding attributes and desired global and/or non-global SmartApps.

Can this “quickly” address the urgent flaw that you express as:

? … :ballot_box_with_check: YES! …

  1. Add the two or three new Capabilities suggested above to better handle critical battery, failed input attempts, and lock front-panel integrity. NB: Critical battery probably doesn’t include completely failed or removed battery, unless the hub can offer a callback to a “pollingFailed()” method or some other workaround.

  2. Replicate the existing “global” SmartApp called “Low Battery Notification - Low battery warnings…” to do the exact same kind of multi-Device event subscription against Device Types that implement one or more of the new Capabilities per #1.

Whew … (dang… no “tired face” emoji?)…

The reason for the long answer is that I feel very passionately that SmartThings has the “right idea” when it comes to the entire paradigm of Capabilities; though I also feel, and mentioned, that I think they should go a bit further and make these much more rigorous and more similar to the Object-Oriented concepts of Interfaces (and related powerful options like Inheritance and more).

I’m optimistic that the foundation is in place for this additional rigor, but even without such enhancements, the existing paradigm can, IMHO, meet the needs that you expressed, Gary (@garyd9); and by using the existing paradigm we avoid the “tight coupling” that @thrash99er observed, and that is because I think my recommended solutions fit into the SmartThings Architecture.

Thanks for letting me present/discuss these ideas with y’all. As always, all questions and feedback are welcome; including Private Messages and/or telephone - chat time if you want to brainstorm. I am in San Francisco, California.

…CP / Terry.


A request:

I started this post to raise the alarm about a critical problem with ST’s. I offered a couple of possibly solutions that could handle the problem quickly (meaning little effort by ST.)

I feel like the thread moving from the “oh, crap - there’s a problem… how can we fix or work around it QUICKLY?” into a “How can we re-design the language used for device types to better handle critical problems?”

The first is an alarm to ST to fix something. The second is more of a theoretical discussion that, while needed, is diluting the alarm. (Seriously - if you read the entire thread, its easy to lose track of the fact that critical events are parsed and then completely ignored by the ST system.)

Can we start a new thread for the theory and “long term” proposals, and keep this thread focused on it’s intent? (Which is to hopefully get ST to fix the problem in any form for now.)

Re-designing the language to support inheritance is a long-term. Adding limitless capabilities for every possible urgent attribute wouldn’t be feasible in the short term (and probably not in the long term.) If “descriptionText” should or shouldn’t be essential information is irrelevant for the short-term. It’s there already.

No, it doesn’t.

It addresses only those specific issues I brought up or that someone at ST has time to write new capability code for AND to handle those specific capability events in some kind of global handler. It’s assuming that ST devs have time to weed through all the existing device types to identify every possible critical event, create a new capability for that specific event, add the definitions for that new cap, and change some global handler to subscribe to all of those events.

It falls on its face the second that someone realizes that they missed a critical message from a garage door opener that doesn’t fit into one of the added caps… or the moment that we need a new device type that has a critical event that doesn’t fit one of the existing caps… because then ST has to add yet another cap (even if they aren’t authoring the device type) because they ALSO have to add a subscription to the global smart app which sends the notifications.

A fix has to be quick to the customers, and extensible so that any device type handler can hook into it without requiring ST to make further code changes to their in-house dev.

I know some of my answer was off-focus, but stand firm on my summarized conclusion that I think the existing architecture is sufficient to resolve the problem you present, just in my opinion, not associated with SmartThings in any way.

My recommendation can be simplified for quickest implementation, if a new catch-all capability is introduced (e.g., “capability.deviceAlert”) instead of multiple new capabilities and attributes tailored for each Device Type.

The Community Forum, however, is meant for asking questions, sharing and discussing ideas and soliciting feedback. That doesn’t always result in a single clear solution, or even any satisfactory solution or recommendations.

But this Topic is new and there’s lots of folks who can chime in. I’m interested in the range of ideas, refinement, debate or concurrence.

If you want an urgent resolution, especially if broad changes to ST may be required, we’re always reminded that the effective channel is

Keep me posted? I definitely share your concern regarding critical device messages (despite my tangential architecture tweaking passions).

… Terry.

This is an interesting discussion. As far as I understand the SmartThings architecture, events are not guaranteed to be handled in the order they are created. We also have seen delays in schedules are scheduled at common times like on the hour.

This makes me wonder whether the events need a form QOS?

I sent a message to support@ - here was the response: (I’m including the entire response as it includes references to people who might be able to assist with an interim solution.) I think the last line of the response is amusing. The support guy is assuming I’m patient. :wink:

Hi Gary,

I will flag your feedback for the development team as a feature recommendation to include with the locks. In the meantime, you may want to ping @ben, @gilbert, and @mager on the thread and ask them to chime in as they may be able to provide more direct feedback and tips for implementing a custom integration for these features.

Thanks for the patience.

1 Like

A (delayed) response to the message that support sent me: I’m extremely disappointed that ST doesn’t consider it a BUG that alarms from the lock don’t notify a user. Instead, having the ST system inform a user that their smart-lock is alarming goes under “feature recommendation.”

ST is starting to sound more and more like “samsung.” I once sent Samsung a message about a massive security problem on their galaxy S3 phone. They refused to call it a bug, and told me that it would be a feature request. Duh.

One man’s “bug” is another’s “missing feature” (or, sometimes the bug is the feature, as the cliché goes).

I wouldn’t take the wording in the response email from support to be an official final declaration that this isn’t a bug… It is just as likely imprecise unintentional miswording from the front lines.

On the other hand, in my personal opinion, a reasonable distinction between “bug fix” and “feature requests” is that any bug with a practical “workaround” isn’t necessarily a bug. It is “just a feature request”.

I don’t know anything about your Samsung case, but, well… I’ve made it pretty clear earlier in this Thread that I believe that the issue has a very workable and architecturally appropriate “workaround”.

A response from the aforementioned dev team, will hopefully give you a more positive view that your concern is officially understood and in the queue to be addressed.

… CP / Terry.

Really? I’m not talking about code-level changes, etc. This is about a consumer product that doesn’t work.

There’s no “workaround” unless the architecture is modified. Speaking more directly, there’s no way to “work around” the issue without making code changes. (A device type can’t send notifications, and a smart app can’t subscribe to events that aren’t associated with a capability.)

Said a different way:

Using that ST provided device types (as the door lock is a supported device), there’s no possible way to get notified of alarms, as the device type doesn’t create the events with anything that can be subscribed to. As well, there’s no ST provided smartapp that would push those notifications even if it could subscribe to them.

However, being more general (and more like a “consumer”):

Here are advertised features of SmartThings that aren’t working in this regard:

The door lock is specifically listed on the “works with smartthings” page, and the only note is that custom key codes aren’t supported.

So, if a device that claims to provide instant alerts if there’s unexpected entry, and claims that it works with a lock that provides an event in the case of unexpected entry, it’s perfectly reasonable to expect that device to provide an instant alert when there’s unexpected entry. It doesn’t. Hence, it’s a bug.

All the talk back and forth about ways to work around the bug are just that - ways to work around A BUG. When you start saying it’s not a bug because there could be a work around in code, you’re starting to sound like a marketing person (or sales person.) Or worse, like a politician. :wink:

BTW, I have a very good understanding of what a “bug” is vs what a feature request is. I’ve been doing software development for over 25 years. A “bug” is something that doesn’t work as reasonably expected. A “feature request” is a modification of expected behavior.

Okay… you don’t consider it a bug. Of course, Ford Motor Corporation didn’t consider it a bug that some of their engines were catching on fire. Until the NTSB forced them to do a recall, it was listed on customer invoices as “works by design.” Guess what? Bugs aren’t limited to just code implementations. Design bugs are also bugs.

(disclaimer: if I seem to be frustrated, it’s because I am. For the second day in a row, ST just completely stopped working and I’m watching what seems to be ST support people ignoring or deflecting the issue. At the same time, I don’t see them fixing any of the stuff they’ve promised to fix, etc… and then I send support a message about what seems to be an obvious problem, and they call it a “feature” request.)

Balancing the promises of Marketing, the visions of Engineering, the implementations of Development, the limitations of Operations, and the duties of Support (among all the other areas and profit goal of the business), is, indeed a highly imperfect and political science.

I agree that you’ve discovered an oversight in the product as delivered. And you know that this is only one of a mountain of imperfections in ST.

There’s really not much more I can say; but reiterate that I, and the Community, does find STs responses to us to be interesting, even if frequently not satisfying.

I think the discussions here must be very different from those at the purely “consumer level”. ST faces a unique challenge and opportunity balancing their product and service priorities between developers, power users, and basic consumers.

Most companies in this industry to date have avoided this challenge by various means; primarily by choosing to sell only through professional VARS or limiting third-party development and essential hiding issues and limitations experienced by consumers, but not both.

ST represents an interesting choice of business model. I think it is preferable to the alternatives, but not sure how this plays out in the long term.

I mostly side with the camp that believes marketplace success does not require perfect execution, and that profitable success is essential to product and service improvement rather than vice versa.

In other words, this feature request will become a bug fix eventually… But not until many people have contributed to STs bottom line despite this and other issues… Visible or otherwise.

I presume you’re not holding your breath. Nothing wrong with having high expectations, however.