Are You Okay? Widget
What The Software Does (Agent)
The goal of the agent software is to send user messages if the device fails in some way. For debugging, it is often easier to get messages when something does happen. Thus, there are two output message methodologies.
Settings
When debugging, you don’t necessarily want to flood your debug mechanism. If you keep tapping on the unit because you are fine tuning the color of the LED, you don’t want to get 1000 emails or twitter messages.
These next settings control how often you get messages and prevent message flurries:
language:JavaScript
// debug output frequency: these prevent twitter flurries where you
// get the same message 10 times because you are tapping the device
const dtDebugMessageMotionDetected = 80; // seconds
const dtDebugMessageBatteryUpdateDetected = 600; // seconds
The next setting is the most important.
language:JavaScript
// This is how long the device will go without an update from the
// user before it cries for help
const dtNoMotionDetected = 129600;
These should be set according to how often your device needs attention before it sends you email. If you set it to be too frequent, the person you are monitoring will find it intrusive. If you set it too long, you may not be able to alleviate your worry. Here are some settings I like:
User needs to move it | Hours | dtNoMotionDetected Setting |
---|---|---|
Three times a day | 12 | 43200 |
Every day | 36 | 129600 |
Every couple days | 60 | 216000 |
With the most frequent setting, remember the user needs to sleep so 12 hours represents a couple hours on either side of night’s rest. As for “every day”, it isn’t 24 hours because that would require the user to interact with the device every day at the same time (or a minute earlier). Using 36 hours instead means that one day can be 8am but the next can be 8pm. The “every couple days” has a similar buffer.
The next setting configures how long the device can fail to communicate before you get an error message. This is likely because the device has lost power or its WiFi is not available.
language:JavaScript
const dtNoBatteryUpdate = 21600; // seconds (21600 ==> 6 hours)
Peace of mind sometimes means knowing that everything is still working. I updated my system to send a note every few days to say everything is ok.
language:JavaScript
const dtEverythingFineUpdate = 432000; // seconds (432000 ==> 5 days)
Actually, everything may be working fine but you should know the device’s batteries are getting low. To that end, we have to decide when the “everything is fine” messages should include “but my battery is getting low”:
language:JavaScript
const MIN_GOOD_STATE_OF_CHARGE = 25; // percent
Communicating With the Caregiver
The different ways to communicate with the device require permissions. Electric Imp has example code for a number of web services: Xively, Twillio, Twitter, etc. I used the agent code from their repository. For twitter, you’ll need to use the Twitter Developer Center. Then you’ll need the keys to work:
language:JavaScript
_CONSUMER_KEY <- "YOUR KEY"
_CONSUMER_SECRET <- "YOUR SECRET"
_ACCESS_TOKEN <- "YOUR TOKEN"
_ACCESS_SECRET <- "YOUR SECRET"
These are at the top of my agent.nut
but the code is a little further down (marked with a section break). It’s relevant function is twitter.Tweet(string)
.
Note: if you have trouble with twitter, modify the twitterDebug
function to output messages to the Electric Imp server.log
. Those messages get tedious to look at but are nice when starting out.
Monitoring Multiple Devices
Once you have one of these devices, you may want another. Right after the Settings sections, there is an area to help with monitoring multiple devices:
language:JavaScript
/******************** Handle setting the device's name ******************************/
If you only want one unit, and you want to skip the next steps, edit the code directly and fix the name of the unit and where to send caregiver messages.
language:JavaScript
settings <- {
name = "Maxwell", // name of the unit
attn = "@logicalelegance" // who to send messages to
};
The other way to set these server-stored variables is to set up your unit the first time by putting the information in a URL of the form:
language:JavaScript
https://agent.electricimp.com/{agentUrl}/settings?name={nameValue}&attn={attnValue}
If you look at the top of the Imp editor for you agent URL, you'll see something like:
Copy the URL from the editor and add the necessary information in place of the curly braces, so it looks like: https://agent.electricimp.com/abcd1234/settings?name={Maxwell}&attn={@logicalelegance}
.
Again, Maxwell
is the name of the unit and @logicalelegance
is where I want messages to be sent.
Once the agent code is running, put that URL into a browser and it will write the information into server storage. The next block of code handles the HTTP interaction. After that is the twitter-handling code.
Messages to the User
As noted above, there are two types of output: debugMessage
and userMessage
. You may turn off debugMessage
entirely once you are happy with how it is working.
For me, debug messages go to the server log and to my general account at twitter. User messages are called out in the server log (prefaced with "!!!!") and go to the attn
in twitter.
Since these functions are separated, it is straightforward to modify them to email, text, or use another media to inform you of events.
Device Handling
There are three asynchronous timers, each monitoring for things to happen (or not):
- Battery update -- If this times out, we received no battery update: something is wrong since the device isn’t communicating.
- Motion update -- If this times out, the user has not moved the device: send a message to the caregiver to check on their loved one.
- Everything is fine -- If this times out, no errors occurred: send a reassurance message to the caregiver that all is working normally.
These all have the same elements:
- Modifiable timeout from the settings section on the top of the file (
dtNoMotionDetected
). - Timer variable used to start and stop the timer (
motionUpdateFromDeviceTimer
). - Function that is called when something happens that resets the timer, such as a motion is received from the device (
motionOnDevice
), this often causes a debug message. - Callback when the timer expires (
noMotionFromDevice
), this causes a user message. - Timer creation (
motionUpdateFromDeviceTimer = imp.wakeup(dtNoMotionDetected, noMotionFromDevice);
).
Once you see the symmetry between them, it is less of an impenetrable wall of code