# Advanced eGauge Operation # USB thumb-drive functionality eGauge Core/Pro have USB and thumb-drive storage functionality # Automated USB Export and Upgrade scripting file # Introduction Starting with [firmware](https://www.egauge.net/revs/) v3.4, eGauge firmware supports USB Mass-Storage devices on hardware with USB ports (e.g., EG4015 (Core) and EG4030 (Pro)). Both Windows VFAT and Linux EXT3 filesystems are supported. When the eGauge device detects a valid storage device, it will automatically bring up a USB Storage menu on the LCD screen. From there, it is possible to select various operations, such as: - [Creating a backup](https://kb.egauge.net/books/general/page/how-do-i-perform-a-backup-and-restore-of-the-egauge-data "How do I perform a backup and restore of the eGauge data?") of all eGauge data - Exporting data to a CSV (comma-separated-values) file. - Updating the device firmware. - Ejecting (unmounting) the storage device so it can be removed safely. For flexibility and to simplify operations when it is necessary to perform the same USB Storage task on multiple devices, the firmware also supports a script file called auto.run. When this file is present in the top-level directory (root folder) of the USB storage device, it will be executed as soon as the USB storage device is detected by the firmware. The details of how this file is executed are specified below. # Scripting Language The auto.run file consists of a sequence of text lines, each line containing a command. Commands are executed in sequence, one by one. If a command fails for any reason, script execution stops and the most recent error is displayed on the LCD screen. The operator needs to acknowledge the error by pushing the multiswitch button and, once that is done, the USB Storage menu is displayed. In the absence of errors, script execution stops upon reaching the end of the script file or after execution of an "eject" command (see below). After reaching the end of the script, the USB storage menu is displayed on the LCD. After an "eject" command, the LCD screen reverts to normal operation. The USB storage device is then no longer accessible until the USB storage device is removed and reinserted into the USB port or the device is rebooted (e.g., power cycled or rebooted via firmware). Script files may contain line-comments that start with a hash character (#). The hash character and any following characters up to the end of the line are ignored. ## Script Commands In the following descriptions, square brackets are used to indicate optional parts of a command. Italics is used as place-holders for variable content. --- > backup \[FILENAME\_TEMPLATE\] Backup the eGauge device data to the file specified by FILENAME\_TEMPLATE. This string may contain references to variables that are expanded as follows:
Variable Reference | Expands to | Example |
${DEVNAME} | eGauge device name | eGauge1234 |
${SN} | eGauge serial number | 1701260002 |
${TIME} | current date and time | 20180411-1310 |
Variable Reference | Expands to | Example |
${PERIOD} | export time-period | ytd |
${GRAN} | export granularity | hour |
Period specified | Time range covered |
day | Most recent 24 hours of data are exported. |
month | Most recent 31 days of data are exported. |
year | Most recent 366 days of data are exported. |
all | All data is exported. |
dtd | day-to-date: export data from midnight up to current time |
mtd | month-to-date: export data from start of month up to current time |
ytd | year-to-date: export data from start of year up to current time |
Granularity specified | Resolution |
sec | Second resolution (or best available). |
min | Minute resolution (or best available). |
quarter | 15-minute resolution (or best available). |
hour | Hour resolution (or best available). |
day | Day resolution. |
These instructions may not work for all versions of Windows and are provided as-is. eGauge Support cannot provide additional troubleshooting or support on formatting USB sticks. An adequate understanding of using the Windows operating system and file explorer may be necessary to complete these instructions.
This **will permanently erase all data** on the selected drive or USB stick. Incorrect usage can cause permanent data loss on the wrong drive.
1\) Connect a USB stick to a PC running the latest version of Windows 10. 2\) Click on the Start Menu and type in "this pc" and open the "This PC" app. [![image-1622141210699.png](https://kb.egauge.net/uploads/images/gallery/2021-05/scaled-1680-/image-1622141210699.png)](https://kb.egauge.net/uploads/images/gallery/2021-05/image-1622141210699.png) 3\) In the "This PC" window, right-click the USB stick and choose "Format..." [![image-1622141320231.png](https://kb.egauge.net/uploads/images/gallery/2021-05/scaled-1680-/image-1622141320231.png)](https://kb.egauge.net/uploads/images/gallery/2021-05/image-1622141320231.png) 4\) Ensure the "File system" is set to FAT32, and "Quick Format" is checked. The "Volume label" does not matter. Press "Start". [![image-1622141347791.png](https://kb.egauge.net/uploads/images/gallery/2021-05/scaled-1680-/image-1622141347791.png)](https://kb.egauge.net/uploads/images/gallery/2021-05/image-1622141347791.png) 5\) When complete, the USB stick is ready for use with an eGauge. If copying files such as auto.run and fw.bin, open another explorer window to where the files are downloaded on your computer, and open the USB drive. Select the file(s) and drag the files to the explorer window of the USB stick. [![image-1622141555421.png](https://kb.egauge.net/uploads/images/gallery/2021-05/scaled-1680-/image-1622141555421.png)](https://kb.egauge.net/uploads/images/gallery/2021-05/image-1622141555421.png) 6\) After the files are copied, click the "back" button on the USB stick window, right-click the USB stick drive and choose "Eject". [![image-1622141610887.png](https://kb.egauge.net/uploads/images/gallery/2021-05/scaled-1680-/image-1622141610887.png)](https://kb.egauge.net/uploads/images/gallery/2021-05/image-1622141610887.png) 7\) Remove the USB stick. It is now ready for use with the eGauge meter. # Alerts All about eGauge Alert functionality # Alerts and Email Gateway with SendGrid # IntroductionIf delivering email to only one recipient, consider using the [eGuard Alert Service](https://kb.egauge.net/link/217#bkmrk-eguard-alert-service) to send device alerts as it is the easiest method for delivering email alerts.
You will need your own website's email address to send email from; Gmail, Yahoo, AOL and other public email services may not work with this method.
Compatibility Notice: Beginning in June 2023, only EG4xxx will be compatible with the SendGrid SMTP gateway. Legacy meters such as EG30xx and eGauge2 will fail to send alerts via the SendGrid SMTP gateway.
SendGrid is a free third party service unaffiliated with eGauge which provides a consistent outbound email delivery service. It can be used for eGauge alert delivery, and is more reliable than not specifying an "Email Gateway". Without an "Email Gateway" configured, alert emails may be rejected, dropped, or fail inconsistently. It is intended as a commercial service for businesses rather than individual end users. SendGrid allows **up to 100 emails daily** with the **free plan**. SendGrid provides delivery information and monitoring such as email delivery failures, number of emails sent and other features. # Disclaimer SendGrid is a third party email delivery service with no affiliation with eGauge Systems. eGauge Systems cannot guarantee email delivery, uptime, or security of using SendGrid. Information on this page will be updated on best effort level. Information including pricing, set up instructions, screenshots, and locations of items are not guaranteed to be up to date or consistent. eGauge Systems does not provide any support for SendGrid's services, and cannot assist with account creation, password recovery, or similar issues. # Pre-setup notes[Ensure the eGauge meter used is on firmware v4.0 or greater, click here for information on checking and upgrading firmware](https://kb.egauge.net/books/egauge-meter-ui/page/checking-and-upgrading-firmware).
Email can be delivered from the eGauge meter using SMTP server `smtp.sendgrid.com` and a sendgrid API key. If using alerts on multiple devices, it is advised to set up a unique API key for each one, so that if the key becomes compromised or the meter becomes inaccessible and alerts cannot be disabled, the API key can be revoked for only that meter. API keys are passwords and are displayed only once after creation. # Setup 1. Set up API keys: [Initial account creation and setup wizard for first email](#wizard) **or** [Adding a second API key, or adding without the wizard from the main dashboard](#manual) 2. [Verify a sender identity](#bkmrk-verify-sender-identi) 3. [Configure the eGauge meter](#bkmrk-configure-the-egauge) ## Initial account creation and setup wizard for first email 1. Create an account at [https://sendgrid.com/](https://sendgrid.com/) 2. Click "Start" to the right of "Integrate using our Web API or SMTP relay"![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012226519/original/c8aucuOvBbXygSFda8uAjP0lu7prKCIdTQ.png?1563901180) 3. In "Choose a setup method", choose "SMTP relay" ![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012226541/original/b-bM_ZmtL1TpODcyuq72DRzZnqanKKY0Vg.png?1563901296) 4. Give the API key a name, like "eGauge Alerts Emails" and press "Create Key" ![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012226552/original/kBZs-S_--ZF8z4QdfPtuoI3V6r6ATQXTDg.png?1563901347) 5. You will now be given the SMTP server (smtp.sendgrid.net), the username (apikey), and password (hidden). This is the only time the password will be displayed, it should be saved somewhere securely like an encrypted keychain if it will be used more than once. Keep this page open or copy the password as it will be used in a later step. ![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012226566/original/CMsnC3SxrMd4L6-UFXh-JhOKIigJBrtcQA.png?1563901461) --- ## Adding a second API key, or adding without the wizard from the main dashboard 1. In the main dashboard on the left-side menubar, expand Settings and click API keys. [![image-1657573543458.png](https://kb.egauge.net/uploads/images/gallery/2022-07/scaled-1680-/image-1657573543458.png)](https://kb.egauge.net/uploads/images/gallery/2022-07/image-1657573543458.png) 2. Click "Create API Key" in the upper right-hand corner: [![image-1657573663515.png](https://kb.egauge.net/uploads/images/gallery/2022-07/scaled-1680-/image-1657573663515.png)](https://kb.egauge.net/uploads/images/gallery/2022-07/image-1657573663515.png) 3. Choose "Restricted Access" as the API key permissions, expand the "Mail Send" section, and click the dot on the right side of the bar next to "Mail Send" to grant that permission ![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012227001/original/pJWCPx6Oqc2OqYSgXgAiJX7JZwHHPdmTVQ.png?1563903098) 4. Click "Create and View", and copy the API key displayed on the next screen. This will be used to configure the eGauge meter in a later step. ![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012227038/original/-3ejHcL2QCIPH0FX4JyMM1psf5--SQ58Eg.png?1563903327) ## Verify Sender Identity You will need to set up Sender Authentication so the receiving email server trusts and accepts the email the eGauge meter delivers. Follow the instructions for [Single Sender Authentication](https://docs.sendgrid.com/ui/sending-email/sender-verification) (simple: sends an email link to verify email address) or [Domain Authentication](https://docs.sendgrid.com/ui/account-and-settings/how-to-set-up-domain-authentication) (advanced: requires modifying DNS entries on your website). Without sender authentication, you will see an error such as `The from address does not match a verified Sender Identity` when sending a test email without verification completed. It will contain a link with information to set up sender authentication. The email address you verify will be used in the `Custom "From" address` setting in the eGauge meter alert settings. ## Configure the eGauge Meter 1. Navigate to Settings -> Alerts, ensure "Alert Provider" is set to "SMTP Gateway" and click on "View/Edit Gateway & Alert Destinations". Enter the mail server hostname (`smtp.sendgrid.com`), username (`apikey`), and the API key / password that was created previously. For the Custom "From" Address, enter an email identity verified in the previous step. [![image-1657575198734.png](https://kb.egauge.net/uploads/images/gallery/2022-07/scaled-1680-/image-1657575198734.png)](https://kb.egauge.net/uploads/images/gallery/2022-07/image-1657575198734.png) 2. Enter the email address(es) that should receive alerts from the meter under Alert Destinations. [![image-1657575742987.png](https://kb.egauge.net/uploads/images/gallery/2022-07/scaled-1680-/image-1657575742987.png)](https://kb.egauge.net/uploads/images/gallery/2022-07/image-1657575742987.png) 3. Press "Save" at the bottom of the page, and then "Send Test Message" to the right of each Alert Destination to ensure the delivery works. ![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25012227090/original/JlGbI0PPLxr5GwkkU21wIGCvnZHptHGxGg.png?1563903498) # Configuring eGauge Alerts ### Overview The eGauge can be configured to send alerts based on a variety of trigger conditions. Alerts must be configured through the eGauge interface, and the eGauge needs to be powered on and connected to the internet in order to send alerts. There are three possible alert destinations: SMTP (email or SMS-capable phone numbers via an email-to-SMS gateway if the cellular provider supports), the eGuard alert service, or a custom URI for a JSON POST (advanced users). SMTP emails credentials may be supplied, and the eGauge will use this email account to generate alerts. Some services such as Gmail may restrict logins to browsers, or disallow the login if devices in different locations are attempting to all log in to send alerts. For large larger deployments a [service such as SendGrid](https://kb.egauge.net/books/advanced-egauge-operation/page/alerts-and-email-gateway-with-sendgrid) may be used. The [eGuard Alert Service](https://kb.egauge.net/link/217#bkmrk-eguard-alert-service) is a more simplified email alert delivery service and only requires you have an eGauge.net account. The following article covers basic alert configuration and provides some sample alerts. Additional information is available on an eGauge-specific basis by navigating to http://**DEVNAME**.egaug.es/fundoc.html?alert where **DEVNAME** is the [device name](https://kb.egauge.net/books/general/page/where-can-i-find-my-device-name "Where can I find my device name?") of your specific eGauge. To take advantage of all alert features, the eGauge should be on the [latest firmware](https://www.egauge.net/revs/).For meters shipped after January 1, 2024 this information may be found at: http://**DEVNAME**.egauge.io/fundoc.html?alert
### Contents [Alert Basics](#bkmrk-alert-basics) [Configuring the Alert Service Provider](#bkmrk-configuring-the-aler-0) [SMTP Gateway](#bkmrk-smtp-gateway) [Using SendGrid](#bkmrk-using-sendgrid) [eGuard Alert Service](#bkmrk-eguard-alert-service) [Custom Alert Destinations](#bkmrk-custom-alert-destina) [Configuring Alerts](#bkmrk-configuring-alerts-0) [System Alerts](#bkmrk-system-alerts) [User Defined Alerts](#bkmrk-user-defined-alerts) [Viewing and Acknowledging Alerts](#bkmrk-viewing-and-acknowle-0) [User-defined Alert Examples](#bkmrk-user-defined-alert-e-0) [Example and description of POST data](#bkmrk-example-and-descript-0) ### Alert Basics Alerts may be configured from the **Settings → Alerts** page and viewed from **View → Alerts**. There are two types of alerts: system alerts and user-defined alerts. System alerts can report conditions such as when the device configuration is changed or when the connection to a remote device has been established. User-defined alerts are built arbitrary conditions that, when true, trigger the alert. For example, you could define an alert that triggers when solar production for a period is below a certain threshold value, or an alert that triggers when the register monitoring Oven usage has been above a certain value for a certain time. More examples are **available here**. ### Configuring the Alert Service Provider Choose the View/Edit Gateway & Alert Destinations button from the top of the Alerts page to configure how alerts are sent. The page will request credentials in order to make changes if none have been previously cached. ##### SMTP GatewayLegacy meters (eGauge2 and EG30xx series) support TLS 1.1, while newer meters (such as EG4xxx) support TLS 1.2.
[![image-1598029453892.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598029453892.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598029453892.png) The SMTP Gateway Alert Service Provider allows the eGauge to send alerts directly to email addresses, SMS-enabled phones, or a mixture of the two. This functionality requires an internet connection, but *does not* require the eGauge to be connected to the proxy server at d.egauge.net. The following fields are required: **Hostname of mail server** Normally, eGauge attempts to deliver email directly to the destination address. Similarly, it attempts to deliver SMS directly to an SMS-gateway. However, if a firewall prevents the device from directly establishing such connections, as is commonly the case for consumer-grade Internet-service, you will have to set the value of this setting to the hostname of a mail server which can forward the messages to the final destination. The mail server may either be a host on the same LAN (e.g., within a company or school network) that will accept email delivery without authentication or it may be am external mail server where you have a valid user account. By specifying the username and password for that account, the device is then able to deliver email through that mail server (ie, the alert messages from the eGauge will originate from your username on that mail server). As an example, if you have a Gmail account, you can set the hostname to smtp.gmail.com. By specifying your Google account’s username and password, you can then have alerts delivered via Gmail. **Username for mail server** When non-empty, this setting specifies the username the device uses to authenticate itself to the mail server. If empty, mail is delivered without authentication or encryption. Note that this option is required for almost all mail servers. **Password for mail server** This setting specifies the password the device uses to authenticate itself to the mail server. It is used only if Username is not empty.Caution: on legacy meters (eGauge2 and EG30xx series) the password is transmitted to the eGauge over an unencrypted channel. Only change this password from a computer that’s connected to the same LAN as the eGauge and only after clicking on the **LAN Access** link on the eGauge main page. As an added security measure, create a dedicate email account at the mail server for sending eGauge alerts.
##### Using SendGridCompatibility Notice: Beginning in June 2023, only EG4xxx will be compatible with the SendGrid SMTP gateway. Legacy meters such as EG30xx and eGauge2 will fail to send alerts via the SendGrid SMTP gateway.
SendGrid credentials are entered in the SMTP Alert Service Provider fields. For more information on using SendGrid or a similar service, please refer to [this article](https://kb.egauge.net/books/advanced-egauge-operation/page/alerts-and-email-gateway-with-sendgrid). ##### Setting Alert Destinations [![image-1598030888514.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598030888514.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598030888514.png) Message Format: select the appropriate SMS carrier or email format. Email address or phone number: enter the appropriate destination for the alert. Min. Alert Prio (Minimum Alert Priority): minimum level of alerts this destination should receive (see below). Up to four alert-destinations can be defined. Alerts are prioritized. For each alert-destination, a **minimum priority** can be defined. Only alerts whose priority is equal to or greater than the minimum priority are reported to an alert-destination. Once an alert-destination has been notified, only alerts of higher priority result in a new notification to that destination until the alert has been acknowledged or deleted via the alerts page, or after 24 hours have passed. ##### eGuard Alert ServiceLegacy meters (eGauge2 and EG30xx) require **[HTTPS certificate validation to be disabled](https://kb.egauge.net/link/369#bkmrk-disabling-certificat)** to activate the eGuard Alert Service. This is due to a bug with an older SSL library used on legacy meters and the eGauge.net certificate provider. This should only be used if the alert information being sent is not sensitive.
[![image-1598030496087.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598030496087.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598030496087.png) The eGuard alert service provides an alternative to configuring the eGauge with SMTP credentials. This is especially useful for users with a large number of devices. The meter must be in an eGuard group controlled by the user. More information on eGuard is [available here](https://kb.egauge.net/books/eguard-porfolio-manager/page/eguard-overview). Also note that eGuard features built-in alerts - those are covered in [this article](https://kb.egauge.net/books/eguard-porfolio-manager/page/eguard-alerts). To use the eGuard Alert Service, simply select "eGuard Alert Service" and click the "Activate" button. A new window will open, and you will be prompted to log in to eGuard. Once logged in (or if you are already logged in), eGuard will confirm you want to register this device for alerts. Click "Register for Alerts" to confirm. [![image-1598030729373.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598030729373.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598030729373.png) **Minimum priority to report:** Setting this to a value other than zero will omit any alerts with a priority set lower than that value. This can be useful when certain alerts are not required (eg, set all system alerts to zero, set minimum priority to report to 1, then set all user-defined alerts to 1). ##### Custom Alert Destinations [![image-1598031072095.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598031072095.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598031072095.png) Custom alerts may be utilized by advanced users to send JSON-formatted data as a POST to a user-provided URI (alert destination). **Alert Provider**: Must be set to "custom". **URI**: The URI to send the JSON POST to. Should be unique to the device, such as with a GET token to uniquely identify the device making the POST. **Options**: A comma separated list of options available below: - deflate: Use "deflate" content-encoding when posting alerts. - gzip: Use "gzip" content-encoding when posting alerts. - secure: For HTTPS connections, fail if the alert provider server's certificate cannot be verified as being valid.Do not use multiple compression schema, i.e., do not use gzip AND deflate on the same device.
**Minimum priority to report**: All alerts with a priority level equal to or greater than this will be POSTed to the URI when triggered. To prevent some or all system alerts from being reported, this may be set to "1" or greater. When alerts below the minimum priority level are triggered, they are only logged on the device locally and do not create a POST.An example of the JSON post contents is [available here](#bkmrk-example-and-descript).
### Configuring Alerts Alerts are reported with a delay of approximately 30 seconds and are automatically acknowledged 24 hours after reporting them. These rules ensure you will be promptly informed of any alert conditions for a device without a deluge of SMS or email messages. Alerts of higher priority are reported even if there are pending alerts of a lower priority. There are two types of alerts: System alerts and User-defined alerts ##### System Alerts System alerts are predefined but you can choose the priority with which they are reported. This allows control over which recipients receives which system alerts (if any) and which alerts are more important. To set an alert priority, use the dropdowns in the "Prio" column. If there are certain system-alerts that you do not wish to have reported at all, select priority 0 and ensure that all alert destinations have a minimum alert priority of at least 1. Note that alerts with a priority of 0 will still be logged on the Alerts page, but no notifications will be sent for those alerts if all alert destination priorities are higher than 1. [![image-1598035794750.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598035794750.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598035794750.png) Proxy-connection established/lost: tracks when a connection to the proxy server at d.egauge.net is opened or closed. If this occurs frequently it can indicate an unstable network connection. Device-configuration changed: reports when a device’s configuration is changed, and which account has made the modification. Date and/or Time changed: reports when the device date or time is changed (either by the user or automatically). Device running hot: reports if the eGauge’s internal temperature reaches a significantly high temperature. Device temperature OK: reports when the eGauge’s temperature returns to a safe level. Remote-device connected: tracks when a connection is established to a remote device (including Modbus devices and remote eGauges). Remote-device lost: tracks when a connection to a remote device is lost (including Modbus devices and remote eGauges). Failed to push data: reports if a data push is set, and the eGauge is unable to successfully push data. Device up and running/Device rebooted by firmware: tracks when the meter is rebooted, and when the meter comes back online from a reboot or power outage. Network interface changed: tracks when the meter switches from an Ethernet (ETH) to HomePlug (PLC) connection. This may happen immediately after a reboot and can generally be ignored. Database error: typically reports when the device configuration is changed. The occasional database error is considered normal, but if this alert triggers multiple times per day and no configuration changes are being made it may indicate an issue. If this happens, contact eGauge support atChoose the lowest check frequency possible as evaluating too many conditions too often may slow down the device. If a slow-running condition (eg, a condition using the peak\_risk() function) is evaluated, evaluation of other conditions may be delayed until the evaluation of that condition is completed.
**Msg (Message):** use this field to define a custom-message to be displayed along with the alert name. If left empty, a default message is included which shows the value of the lhs, the operator, and the rhs of the trigger-condition. A well-written message will explain the alert - for example, on a "Low Production" alert the message might be "Caution: Low production on Inverter 1 (north side)". The placeholders `%l` and `%r` can be used in the message field to include the calculated value for the lhs and rhs of the equation.Examples of user-defined alerts are available in the [User-defined Alert Examples](#h_98585608921598384978268) section near the end of this document. Click [here](#h_98585608921598384978268) to jump to that section.
### Viewing and Acknowledging Alerts You can view and acknowledge alerts on your device under **View → Alerts**. By default, a list of triggered alerts will be visible. For more information on each alert and the option to acknowledge or delete an alert, click the "View Privileged Details" button. [![image-1598384378068.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598384378068.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598384378068.png) **Ack (Acknowledged):** indicates if this alert has been acknowledged. Once acknowledged, the alert will be reported again should it reoccur and its priority is sufficiently high. Alerts are automatically acknowledged after 24 hours. To ensure new alerts are reported, alerts should be acknowledged when they are received. **Prio (Priority):** the priority of the corresponding alert. **Time:** date and time of the most recent occurrence of the alert. **\#:** number of times this alert has occurred (note that this isn't necessarily the number of times the alert has occurred since the device was installed). **Name:** name of the alert. **Last Reported:** date and time when the alert was last reported to at least one of the alert-destinations. To view detailed alert information as well as acknowledge and delete reported alerts, click the "View Privileged Details" button. Valid credentials are required to see this information and acknowledge/delete alerts. [![image-1598384643646.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598384643646.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598384643646.png) The **Detail** column contains additional information about each alert. For example, one instance of the "Network interface changed" alert provides the additional detail that the network interface was changed from "none" to "eth0" (this happens immediately after a reboot) while the other (newer) instance of the "Network interface changed" alert provides the additional detail that the network interface changed from eth0 to qca0. This happened very quickly (within the same minute), and is normal behavior for a meter coming back online after a reboot. To modify alerts, check off any alerts you wish to delete or acknowledge, and click the appropriate button. Deleting alerts here will remove them from the reported alert page until it occurs again. ### User-defined Alert ExamplesFor available functions on your particular firmware version, visit http://**DEVNAME**/fundoc.html?alert where DEVNAME is your eGauge [device name](https://kb.egauge.net/books/general/page/where-can-i-find-my-device-name "Where can I find my device name?").
##### General Notes `$"REG NAME"` returns the instantaneous value of the register REG NAME, while `"REG NAME"` points a function at a specific register (but doesn't necessarily return the register's value). When using functions such as avg() or others listed in the function documentation, **do not** include the dollar sign. When creating a message (Msg), there are several shortcuts which can be used to include values from the alert condition itself: `%l` will return the value of the left–hand–side `%L `will return the formula of the left–hand–side `%r` will return the value of the right–hand–side `%R` will return the formula of the right–hand–side `%%` will return a single percent sign (eg, %l %% would read as <value from left side of the comparison> %) ##### Basic Examples In the following example, "Grid Average" will return the daily average of the Grid register if that value is less than or equal to 5000W, while "Grid Instantaneous Usage" will return the instantaneous reading of the Grid register if that value is less than or equal to 1000W. [![image-1598385221466.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598385221466.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598385221466.png) The next example will trigger if the value of the L1 voltage register is greater than or equal to 130V (which could indicate a dangerous condition for devices connected to that service). [![image-1598388200742.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598388200742.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598388200742.png) More complex math can also be performed on either side of the alert expression. For example, the following alert obtains the average voltage from two references, and triggers if that value is greater than or equal to 130V. [![image-1598388449822.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598388449822.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598388449822.png) It's also possible to calculate cumulative values (kWh) over a period and trigger an alert based on those values. In the following example, let's assume an outdoor hot tub has a 6kW pump/heater, which cycles every 3 hours for 30 minutes at a time. Thus, every 6 hours there should be 6 kWh of energy used. Any less could indicate a pump or heater failure, and the hot tub could freeze. `(avg("Hot Tub Pump/Heat",360)*6) / 1000` will take the average power (W) read on the register Hot Tub Pump/Heat over the last 360 minutes (60 minutes in an hour, 6 hours). Then, the average power is multiplied by 6 hours to get Wh, the total energy used over the 6 hour period. Finally, we divide by 1000 to convert Wh to kWh. That value is then compared to the value on the right-hand-side, in this case 6. If the alert is triggered the alert will be sent. [![image-1646775756987.png](https://kb.egauge.net/uploads/images/gallery/2022-03/scaled-1680-/image-1646775756987.png)](https://kb.egauge.net/uploads/images/gallery/2022-03/image-1646775756987.png) ##### Ternary operator The syntax of the “?” ternary operator (also referred to as a conditional or conditional test) is `condition?value_if_true:value_if_false` and can be nested. This is a fundamental component of many alerts, especially more complex alerts. ##### Boolean expressions Simple boolean expressions may be used within an alert: `(5 > 4)` will return 1. Conversely, `(5 < 4)` will return 0. The boolean value can be multiplied by another value (including a register value). For example, `($"Grid" < 7000) * $"Grid"` returns the value of “Grid” if “Grid” is greater than 7000 W, and returns 0 if the value of "Grid" is less than 7000W. To break this down: if `$"Grid" < 7000` is true, it will return a 1. `1 * $"Grid"` returns the value for the "Grid" register. If `$"Grid" < 7000` is false, it will return a 0. `0 * $"Grid"` is 0. Remember, `$"REGNAME"` returns the instantaneous value of the register. Let's look at how the `time()` function can be used with the ternary operator and boolean expressions to trigger an alert at a specific time: [![image-1598387960751.png](https://kb.egauge.net/uploads/images/gallery/2020-08/scaled-1680-/image-1598387960751.png)](https://kb.egauge.net/uploads/images/gallery/2020-08/image-1598387960751.png) These two alerts work together to trigger if the Grid value is greater than 5000W during daytime hours and greater than 3000 during nighttime hours. time() returns the current time as a number from 0 up to (but not including) 24 with minutes as a fractional value. For example, 11:30am would be 11.5. We use two booleans here: `time() > 8 * time() < 18` If the time is > 8 (8am) and less than 18 (6pm), the booleans work out to 1 \* 1 or 1. If either boolean is false, the output from the booleans is 0. 0 \* 1 or 1 \* 0 both equal 0. This gives us a ternary expression of either `1 ? $"Grid" : 0` or `0 ? $"Grid" : 0` (remember ternary expressions work out as `condition?value_if_true:value_if_false`). Thus, if the booleans evaluate to 1, the left side of the formula returns the value of $"Grid". If the booleans evaluate to 0, the left side of the formula returns 0. Moving on to the alert expression: if the booleans work out to zero (ie, if the time range is not correct), the left side of the alert returns 0. This can never be greater than 5000, so the alert never triggers. If the booleans work out to 1, the left side of the alert returns the value of the "Grid" register. If the value of the "Grid" register is >= 5000, the alert triggers. ## Example and description of POST data ```generic { "now": "1568419537.35", "alerts": [ { "id": 1804290019, "priority": 7, "occurrences": 12, "first_occurence": 4462.5, "last_occurence": 389.31, "name": "Device-configuration changed", "detail": "By owner." }, { "id": 1804290035, "priority": 0, "occurrences": 1, "first_occurence": 0, "last_occurence": 0, "name": "Device rebooted by firmware", "detail": "Howdy do?" } ] } ```[![](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/25001040454/original/gf6x4YhiU4unyRb2v8Bf5HdR5-5fqWTqEQ.png?1495551560)](https://www.egauge.net/media/support/docs/egauge-tutorial-article-7-IE10-11.pdf) [IE 10/11 PROXY SETTINGS](https://www.egauge.net/media/support/docs/egauge-tutorial-article-7-IE10-11.pdf) |
Warning: Systems greater than 600V phase-to-phase are not fully supported by eGauge Systems. Supported CTs are rated for up to 600Vac, systems at higher voltages will need to source alternate CTs.
Amperage-output CTs (e.g., 5A output, or 100:5 ratio, etc) can cause serious shock or electrocution. Use appropriate protection when installing and handling equipment. **Amperage-output CTs must not be connected directly to the eGauge meter and may cause damage**.
#### Monitoring High Voltage SystemseGauge Systems cannot guarantee meter accuracy when third party potential transformers are used. It is recommended to use the **[EV1000 high voltage sensor](https://kb.egauge.net/books/egauge-hardware-product-pages/page/egauge-high-voltage-sensor-ev1000)** when measuring a system with higher voltage than the eGauge meter rating, or on a different side of a transformer from where the eGauge voltage taps are connected.
As with all physical registers, a monetary register will only record values from the time it is created moving forward.
### Creating a monetary register formulaIt's strongly recommended to use a plain text editor (notepad, nano, vim, etc). Other software may add formatting characters which can cause issues.
At the most basic level, a monetary register multiplies the value of an arbitrary power register or set of power registers against one or more cost per kWh values. The monetary register is expressed in terms of currency units per second (eg, dollars, pounds, euros, etc). To convert from currency per kWh to currency per second, the final step of any monetary register calculation is to divide by 3.6e6 (or 3600000). Here's a basic example: `($"Grid"*.25)/3.6e6` This example would effectively be the same thing as setting the "Average cost of 1kWh of electricity" to .25, except you can use *any arbitrary register* in the calculation (meaning you're not limited to using the Usage totaling register). For example, you could add two registers together: `(($"Subpanel1"+$"Subpanel2")*.25)/3.6e6` or multiply by some additional value: `(($"Grid"*2)*.25)/3.6e6` Monetary register formulas can also utilize some of the built-in eGauge functions (specifically time(), wday(), mday(), and month()) for tiered billing structures. For more information on these functions, refer to the function documentation on your specific meter by appending /fundoc.html? to the end of your meter URL (for example, DEVNAME.d.egauge.net/fundoc.html? where DEVNAME is the [device name](https://kb.egauge.net/books/general/page/where-can-i-find-my-device-name) of your meter).Available functions will vary from meter to meter depending on meter firmware version. It may be necessary to [update meter firmware](https://kb.egauge.net/books/egauge-meter-ui/page/checking-and-upgrading-firmware) to get access to certain functions. On meters connecting to eGauge.io this information will be available at: DEVNAME.egauge.io/fundoc.html
#### Basic Examples Let's start with a basic example - tiered billing with a higher peak rate between 5pm and 9pm. Standard 12am to 5pm; 9pm to 12am - $.15 / kWh Peak 5pm to 9pm - $.25 / kWh The eGauge features a full variety of comparison operators (=, <, >, <=, >=), so we'll use those along with the time() function.The time() function is based on the time zone set under **Settings -> Date & Time**
A comparison operator will return a 1 if true, or a 0 if false. Thus, we can use the following to test for the time range between 5pm and 9pm: `(time()>17)*(time<21)` If both conditions are met, the result is 1\*1. If either condition is false, the result is 0\*1 or 1\*0 (0 either way). Next, we'll use a conditional to return a value based on the time comparisons (expressed as C ? T : F where C is the condition, T is the value returned if true, and F is the value returned if false).Spaces in the formula are optional, and are ignored. In the examples below, spaces are used to improve readability.
`((time()>17)*(time<21) ? ($"Grid"*.25) : ($"Grid"*.15))/3.6e6` This is the complete formula - we'll get the value of the "Grid" register multiplied by .25 and divided by 3.6e6 if the time is between 5pm and 9pm, and the value of the "Grid" register multiplied by .15 and divided by 3.6e6 if the time is outside of that range. #### Intermediate Example Moving on to a more complex example - it's possible to nest conditionals to perform more complex comparisons. Here's an example using time of day and day of week: Peak - 5pm-9pm M-F $.25 Peak Weekend - 4pm-10pm S-S $.32 Off Peak - 12am - 5pm; 9pm-12am M-F $.15 Off Peak Weekend - 12am-4pm; 10pm-12am S-S $.18 `((wday()<=4) ? ((time()>17)*(time<21) ? ($"Grid"*.25) : ($"Grid"*.15)) : ((time()>16)*(time<22) ? ($"Grid"*.32) : ($"Grid"*.18)))/3.6e6` Here, we've created a conditional which uses a comparison to see if wday()<=4 (corresponding to a weekday). If it is a weekday, the first nested conditional runs to check the time and return a value based on the time; if it's a weekend, the second conditional runs a different time check and returns a different value based on the time. Finally, we divide by 3.6e6 at the end, which is always required. The following flowchart may better illustrate the logic behind this formula: [![image-1623866302534.png](https://kb.egauge.net/uploads/images/gallery/2021-06/scaled-1680-/image-1623866302534.png)](https://kb.egauge.net/uploads/images/gallery/2021-06/image-1623866302534.png)Formula registers have a finite length, meaning that extremely intricate billing schemes may not be supportable.
#### Advanced Example Building off of the previous example, let's say the utility also has an additional per-kWh charge from November thru May, and an additional flat daily rate: Peak - 5pm-9pm M-F $.25 Peak Weekend - 4pm-10pm S-S $.32 Off Peak - 12am - 5pm; 9pm-12am M-F $.15 Off Peak Weekend - 12am-4pm; 10pm-12am S-S $.18 Winter Peak Charge - Nov-May, $.08 per kWh Daily surcharge of $1.23 `((((month()<10)*(month()>4)) ? ((wday()<=4) ? ((time()>17)*(time<21) ? ($"Grid"*.25) : ($"Grid"*.15)) : ((time()>16)*(time<22) ? ($"Grid"*.32) : ($"Grid"*.18))) : ((wday()<=4) ? ((time()>17)*(time<21) ? ($"Grid"*.33) : ($"Grid"*.23)) : ((time()>16)*(time<22) ? ($"Grid"*.40) : ($"Grid"*.26))))+(1.23/86400))/3.6e6` We're building off of the previous formula in this example. We've used another conditional to test for the month of the year - if the month is > 4 (ie, June 1) or < 10 (ie, Nov 1) the meter uses the original formula in the Intermediate Example. If the month *isn't* within that range, the meter uses a modified version of the formula in the Intermediate Example (with rates adjusted upward by $.08 per kWh). Once a cost per kWh value is calculated, we take the calculated value multiplied by the actual register measurement and add 1.23/86400. We have a daily charge of $1.23, but the monetary value register expects *dollars per second*, not dollars per day. To convert $/s to $/d, we can divide by the number of seconds in a day (86400). The following flowchart may better illustrate the logic behind this formula: [![image-1624394505672.png](https://kb.egauge.net/uploads/images/gallery/2021-06/scaled-1680-/image-1624394505672.png)](https://kb.egauge.net/uploads/images/gallery/2021-06/image-1624394505672.png) ### Using the monetary register Once a monetary register has been created and saved, navigate back to **Settings -> Preferences**. Scroll down to "Money used register" or "Money earned register" (based on whether the monetary register is used for consumption or generation billing) and select the appropriate register from the dropdown menu. [![image-1623866640275.png](https://kb.egauge.net/uploads/images/gallery/2021-06/scaled-1680-/image-1623866640275.png)](https://kb.egauge.net/uploads/images/gallery/2021-06/image-1623866640275.png) Make sure to click "Save" at the bottom of the page to apply these changes. It's also possible to view the cumulative total (ie, cost) recorded by a monetary register by displaying that register in the [Mobile-Friendly Dashboard UI](https://kb.egauge.net/books/egauge-meter-ui/page/dashboard). To do this, create a new "Summary Table" dashlet (or add a new register to an existing dashlet). Leave the Type as "Register value", name the dashlet as desired, select the monetary register in the "Register to display" field, and leave the unit as "auto". It may be necessary to flip the polarity of the reading to get a positive dollar value (using the "Flip sign of the value" option). This should result in something similar to the following: [![image-1649168885469.png](https://kb.egauge.net/uploads/images/gallery/2022-04/scaled-1680-/image-1649168885469.png)](https://kb.egauge.net/uploads/images/gallery/2022-04/image-1649168885469.png) # Lua Scripting # Lua Scripting OverviewLua scripting is an advanced topic. eGauge Support cannot review code and has limited support for troubleshooting Lua scripts.
# Introduction Support for eGauge Script (eScript) was introduced in firmware v1.1, allowing limited scripting through the use of [formula registers](https://kb.egauge.net/books/advanced-egauge-operation/page/formula-registers-and-remote-devices). eScript was designed for calculating basic and common mathematical formulas such basic arithmetic operations, comparisons, and conditionals, along with the ability to call library routines (functions). Firmware v4.1 introduced [Lua v5.3](https://www.lua.org/manual/5.3/) support. To ensure safe operation, Lua execution is guarded with timeouts to protect against infinite loops or unacceptably long execution times. Additionally, a restricted set of standard libraries is supported. To maintain backwards compatibility, firmware transparently translates eScript expressions to Lua scripts before execution and the Lua execution environment provides all the functions available within eScript. # Lua Primer ## Lexical Conventions Names may consist of any letters, digits, or underscores but may not start with a digit. Numeric values use the same conventions as in most other languages, including the ability to write hexadecimal values with a prefix of 0x. The two boolean literal values are true and false. A variable with an undefined value is nil. Strings may be enclosed in double or single quotes. Characters within a string may be escaped with a backslash. Comments start with a double-dash (--) and extend to the end of the line. Statements may be terminated with a semicolon but, generally, semicolons are not required (even when there are multiple statements on a single line). The only exception to this rule is that a semicolon is required if the following statement starts with a left parenthesis. ## Variables Variables are global unless explicitly declared as local. For example: ```lua x = 10 -- global variable local y = 42 -- local variable ``` ## Operators Lua provides a normal set of operators for arithmetic operations and comparisons. A bit unusual is that the inequality operator is ~= rather than the more typical !=. Logical operators use keywords like in Python: and, or, and not. The length of a string or a table (see [Structured Data](https://docs.google.com/document/d/17NXpUaK4-43_vgHUIjUSDugHxkx9iGFTnqBTszToJ0c/edit#heading=h.5kbztt1c5hpd)) is obtained by prefixing the string or table name with a hash mark. \#'hi' would return 2, for example. Strings can be concatenated with the double-dot operator. 'yell'..'ow' would yield 'yellow', for example. ## Control Structures The syntax for the various control structures is: ```lua for index=initial,step,final do block end -- numeric for loop ``` ```lua for var in iterator do block end -- iterator for loop ``` ```lua while cond do block end -- while loop ``` ```lua repeat block until cond -- do while loop ``` ```lua if cond then block else block end -- conditional statement ``` You can use break to exit a loop but, unlike in C and other languages, there is no continue that would allow you to skip to the next iteration. ## Structured Data Lua uses tables to represent both arrays and hash tables (Python dictionaries, Javascript objects). For example: ```lua local a = {'a', 'b', 'c'} ``` assigns an array containing the strings 'a', 'b', and 'c' to local variable a. Unlike in most other languages, the array base index is 1, so a\[1\] would yield the first element or 'a' in our example. Dictionary literal values can be written like this: ```lua local d = {['k1']='v1', ['k2']='v2'} ``` and indexed with square brackets such that d\['k2'\] would yield 'v2', for example. If the keys for a dictionary happen to be valid Lua names, the square brackets and quotes around the key strings can be omitted. For example, the above example could be simplified to: ```lua local d = {k1='v1', k2='v2'} ``` For such key values, it is also possible to access their values using member-name syntax. For example, d.k1 would yield 'v1', just as d\['k1'\] would. # Migrating from eScript to Lua Most of eScript has a direct equivalent in Lua. eScript has full support for a single numeric type (IEEE754 double precision float) and limited support for strings. As configured for the eGauge firmware, Lua has the same numeric type but also supports 32-bit integers and has full support for strings, boolean values, and tables. The most important differences between eScript and Lua are as follows: - In eScript, the value of a register is obtained with $"register\_name", whereas in Lua, the equivalent expression is \_\_r("register\_name"). - Lua boolean values cannot directly be used as numeric values, whereas eScript uses 0 to represent false and any non-zero value for true. - Lua does not provide a direct analog for the conditional operator ``` cond ? if_true_expr : if_false_expr ``` Instead, Lua uses the logical expression ```lua cond and if_true_expr or if_false_expr ``` This works quite similarly to the eScript conditional because of the way the and and or operators are defined. Specifically, and returns false if the left-hand side is nil or false or the right-hand side's value otherwise. Operator or returns the value of the left-hand side if it is not nil or false and the value of the right-hand side otherwise. Both operators short-circuit evaluation and operator and has higher precedence than or. - eScript automatically propagates NaN (Not-a-Number) values. For example, if any function is called with a NaN value, the returned result is also NaN. Similarly, if the condition of the conditional operator is NaN, then the result of the conditional expression is also NaN. Given the similarities between eScript and Lua, most eScript expressions trivially translate to Lua. The non-trivial translations are shown in the table below:Lua scripting is an advanced topic. eGauge Support cannot review code and has limited support for troubleshooting Lua scripts.
eGauge meters in firmware 4.1 and later have built-in Lua scripting functionality. The eGauge Lua script editor may be accessed from the Mobile Friendly interface. Refer to the [Lua Scripting Overview](https://kb.egauge.net/books/advanced-egauge-operation/page/lua-scripting-overview) article for full details about the meter's Lua scripting interface. #### Formulas script Creating lua functions in the Formulas script editor will allow the functions to be used in a formula register. For example, here are two functions made in the Lua Formulas script editor that will return the min or max of two numbers: [![](https://kb.egauge.net/uploads/images/gallery/2023-02/scaled-1680-/image-1676406949779.png)](https://kb.egauge.net/uploads/images/gallery/2023-02/image-1676406949779.png) They may then be used in a formula register: [![](https://kb.egauge.net/uploads/images/gallery/2023-02/scaled-1680-/image-1676407153301.png)](https://kb.egauge.net/uploads/images/gallery/2023-02/image-1676407153301.png) And we may see the registers work as defined by the script functions: [![](https://kb.egauge.net/uploads/images/gallery/2023-02/scaled-1680-/image-1676407218019.png)](https://kb.egauge.net/uploads/images/gallery/2023-02/image-1676407218019.png) #### Tariff script Advanced time-of-use or tiered billing may be performed in this Lua scrript. A tariff script should provide (at least) a cost(register, negate, schedule) function which calculates the incremental cost based on the energy-use recorded by register. _negate_ can be set to true if the register's value counts down for power consumption. _schedule_ is optional and can be set to the (non-default) name of the schedule to use when calculating the cost. A formula register of type "monetary" would be used with the `cost()` function. For an example billing script, from the classic interface: 1. Navigate to Settings -> Billing. 2. Choose Xcel Colorado as the tariff provider. 3. Click "OK" to save and go back to the main settings page. 4. Go back to Settings -> Billing. 5. Change the tariff providert to "custom" 6. Click the "Customize tariff script" button, which will open a copy of the Xcel Colorado billing tariff in the Lua script editor. #### Alerts script Alerts scripts work the same as Formula scripts, but are used in eGauge meter alerts, configured in Settings -> Alerts. #### Control scriptSee the main Lua Scripting Overview Control Scripts section for additional Lua Control environment information.
There is high risk of damaging external equipment using control scripts. Only skilled Lua developers familiar with the eGauge meter and software should attempt to use Lua control scripts.
Control scripts can be used to confrol supported equipment such as the eGauge Power Relay Module (PRM3). For example, the following script reads the instantaneous value of a register called "Temperature" and controls a PRM3 relay contact. If the temperature is lower than 21 C, relay number 0 of the PRM3 is closed (activated), otherwise it opens (turns off) relay number 0. It then sleeps for 15 minutes before checking again. In the real world, the control script should be more advanceddev = ctrl:dev({interface='relay'})
relay = dev:interface('relay')
while true do
print("Temperature is currently: " .. __r("Temperature"))
if __r("Temperature") < 21 then
relay:close(0)
else
relay:open(0)
end
sleep(60*15)
end
#### Persistent variables See the main [Lua Scripting Overview](https://kb.egauge.net/link/321#bkmrk-module-persistent) section on Persistent variables. Persistent variables are variables that are preserved between reboots or power cycles. The following Formula script creates and updates a peristent variables with a given name and number passed to it in a formula register, and prints debug to the output log:
function persistent_variable_example(name, number)
obj = persistent:new(name, number, "Variable stored by formula function persistent_variable_example")
current_value = obj:get()
print(name .. " currently has value " .. current_value)
print("updating " .. name .. "to new value " .. number)
obj:set(number)
end
A register is configured to run the formula script:
[![](https://kb.egauge.net/uploads/images/gallery/2023-02/scaled-1680-/image-1676411385422.png)](https://kb.egauge.net/uploads/images/gallery/2023-02/image-1676411385422.png)
This creates or updates a persistent variable called "variable test 1" with the current time.
The Formula script editor shows the print debug as the variable is updated once a second
as the formula register is run:
```
15:26:28.168 variable test 1 currently has value 22.043333333333
15:26:28.168 updating variable test 1 to new value 22.043611111111
15:26:29.171 variable test 1 currently has value 22.043611111111
15:26:29.172 updating variable test 1 to new value 22.043888888889
15:26:30.168 variable test 1 currently has value 22.043888888889
15:26:30.168 updating variable test 1 to new value 22.044166666667
15:26:31.168 variable test 1 currently has value 22.044166666667
15:26:31.168 updating variable test 1 to new value 22.044444444444
```
While this particular example is rather pointless, persistent variables may be used in any Lua scripts. Control scripts are executed continuously, and a formula register would not need to be created to run it.