Introducing KumoApp
KumoApps are rules that run on the cloud ("くも"/kumo in Japanese). They work instantly without delay. Everything from as simple as "turn off AC when a window is open", to some of the very complex ones, can be configured with a few taps from your smartphone and tablets. Choose from tens of existing ones or define your own in just a few lines of code in Javascript.Reed KumoSensor, a contact based door/window sensor used together with WeMo LED bulb and a KumoApp (Instructions on how to link your WeMo LEDs, Swtiches and Maker).
Why KumoApp
It is amazing the variety of feature requests we receive since the release of Motion Sensor Tags in 2012. Some user wants to receive push notification every x minutes until door is closed, another user wants to receive notification when no motion is detected for y minute. With integration of WeMo switches and LED, Dropcam and Nest Thermostat, there will be even wider variety of possible features that are useful to some, but not to everyone to make it worthwhile to add more buttons/options to the already busy app screen. It is almost inevitable that we ended up with KumoApp.With KumoApp, anyone can implement these variety of features very quickly with a few lines of Javascript code. Thanks to the KumoApp configuration interface, end-users can immediately enable/disable them from the app interface with a few taps, as if they were integrated features.
Not only is it quick to use, but also it is quick to write your own KumoApp. It is designed such that people can help themselves by writing their own full-fledged algorithms with only basic knowledge of Javascript.
KumoApp is different from the Web Service JSON API, which is a lower level API on which our iOS and Web Apps are built. Some key benefits of KumoApp are
- While our Web Service API is uni-directional (except you can define URL callbacks), KumoApp is natively event-driven with "actions" and "events".
- The actions and events in KumoApp are readily available from JavaScript, so that you can write your algorithm in just a few lines of code without knowing anything about AJAX/HTTP/JSON etc. You have tens of existing examples to start from.
- We host your KumoApps 24/7 on our Cloud server, so you can define event triggers and scheduled tasks, without having a computer always turned on that runs your programs to receive URL callbacks or run scheduled tasks.
- We store the log output of your App in our database so that you can download it anytime to analyze data.
- We automatically store some global variables (those begins with "$") of your app in our database and restore them the next time it runs, so complicated algorithms that span over multiple events can be defined. This allows implementing an integration in feedback algorithm, and apps with learning, adaptive and statistics/report generation that is not possible with "stateless" system such as IFTTT.
Advantages over IFTTT
Native to Wireless Sensor Tags, KumoApp is faster and more flexible than IFTTT for those tasks that it supports.You can extend your IFTTT recipe to take advantages of the flexibility in KumoApp through the WirelessTag IFTTT channel's "New KumoApp message" IFTTT trigger and "Run a KumoApp" IFTTT action. In one example, you can install a KumoApp that turns on specific group of WeMo switches, and call it a certain name like "turn on all lights on second floor". Then use IFTTT action "Run a KumoApp" to run that app to achieve the effect IFTTT cannot achieve with a single recipe. In another example, you can write a KumoApp that logs a message using KumoApp.Log function when more than specified number of window or door is open. Then use IFTTT trigger "New KumoApp message" to trigger some IFTTT action.
IFTTT | KumoApp | |
---|---|---|
Delay | Events are polled every 15 minutes; realtime channels have typical delay of 7~8 seconds | Natively event driven. Delay is determined by network latency only, typically < 1 second |
Logic | Only if(this){that} where "this" and "that" often must be a single item. | Every logic Javascript provides, such as: and, or, if, forEach, some, switch, average, for loops, recursive function calls, binary search, Math.*, deviation, .... |
Supported triggers | Many types of Internet based events. | Motion, temperature too low/too high/change, humidity too low/too high/change, door/window open/close, PIR sensor detection/timeout, iOS device entering/exiting a location, water detection, and any trigger from IFTTT using the "Run a KumoApp" IFTTT action. |
Supported actions | Many types of Internet based actions. | Turning on/off WeMo switches, taking photos from DropCam, Setting Nest thermostat home/away modes/temperature/fan timer, arming/disarming temperature/motion sensors, beeping a tag, sending push notifications to iOS/Android devices, sending Emails, posting a Tweet, and activating other network connected devices that support HTTP, such as Phillips Hue Lamp, using the KumoApp.httpCall action. Triggering an IFTTT recipe using KumoApp.Log function + "New KumoApp message" IFTTT trigger |
Statistics/logging | IFTTT generated format | Any format you define using Javascript and utility functions, given to KumoApp.Log function |
Learning/adaptive algorithms | Cannot be defined with the "if(this){that}" logic | Everything is possible. See below time to temperature KumoApp for example |
Getting Started
Here is a simple example for the KumoApp "When any of the window or door is opened, turn off AC/heat."
var sensors = <#door or window_[12|52|53]_N#>; sensors.forEach( function (sensor) { sensor.opened = function () { <#thermostat_[62]_1#>.turnoff(); }; });
Standard Javascript language features are all supported. In this example, for each of the specified tag object, a property "opened" is assigned a call back function instance, where the specified thermostat's method "turnoff" is called.
The region inside "<" and ">" is called a "place holder". They are like a blank box that the KumoApp user will fill in through the iOS and Web interface. The first part inside the place holder, e.g. "door or window" is the description that appears in the configuration interface. The next part [12|52|53] limits the type of tags that can be configured, and the last part "N" or "1" specifies if multiple or a single tag needs to be set for this place holder. "..._N" becomes a Javascript array (e.g. [tag1, tag2]) while "..._1" becomes a single object.
For example, if you write "<#Infra-red sensors_[72]_N#>" and "<#the thermostat_[62]_1#>" in your code, the configuration screen for iOS/web app would look like below, allowing user to pick one or more tags with accepted tag types.
The complete app for this is just a few lines:
<#infra-red sensors_[72]_N#>.forEach( function (sensor) { sensor.detected = function () { <#the thermostat_[62]_N#>.target = sensor; }; });
This is a the code for the KumoApp "Send push when no motion is detected for x minute".
var target = <#motion sensor_[12]_1#>; function notify() { <~devices to send notification~>.push(target.name + "is not moved for too long"); } var timeout=<%interval (seconds)_N%>*1000; var timer=KumoApp.setTimeout(notify, timeout); target.moved=function(t){ KumoApp.stopTimer(timer); timer=KumoApp.setTimeout(notify, timeout); }
All global variables are saved and loaded automatically between each event call, and those starting with "$" will survive app re-starts. For example, below app will print 1, 2, 3, ... each time you stop it and then start it again.
var $i=1;
KumoApp.Log($i++);
The automatic state-persistence is vital in order to allow any kind of feedback to regulate some sensor value. For example, to control dimmable LED such as WeMo, Hue or LIFX based on ambient light sensor reading, you must remember what dimming level you have set last time, so that you can adjust it higher or lower.
var wemo=<%WeMo LED_[82]_1%>; var $current_bri=0.0; <#light sensors_[26]_1#>.brightnessChange = function () { var diff = <%Target Brightness (lux)_N%> - sensor.lux; var new_bri = Math.min(100.0, Math.max(0.0, $current_bri + diff/8.0)); wemo.dimLED(new_bri, 1); $current_bri=new_bri; };
Because the automatic state-persistence, you can also implement learning/adaptive logic that spans over multiple events. Below is a KumoApp that notifies on your iOS/android devices whenever you set temperature on the specified Kumostat, estimated time to reach the set temperature based on historical statistics.
var Normal=1, TooHigh=2, TooLow=3; var kumostat = <#Kumostat_[72]_1#>; var setTime, tempToRaise, tempToCool; var $averageTimeToHeatPerDeg, $averageTimeToCoolPerDeg; var devices = <~devices to send estimate~>; kumostat.target.lowThSet=function(target){ if(target.tempState==TooLow && kumostat.hvacOn) { setTime=KumoApp.Tick; tempToRaise=target.th_low-target.temperature; tempToCool=0; if($averageTimeToHeatPerDeg>0){ devices.push("Expected to take " + KumoApp.UserFriendlyTimeSpan($averageTimeToHeatPerDeg*tempToRaise) + " to reach " + target.th_low); } } } kumostat.target.highThSet=function(target){ if(target.tempState==TooHigh && kumostat.hvacOn) { setTime=KumoApp.Tick; tempToCool=target.temperature-target.th_high; tempToRaise=0; if($averageTimeToCoolPerDeg>0){ devices.push("Expected to take " + KumoApp.UserFriendlyTimeSpan($averageTimeToCoolPerDeg*tempToCool) + " to reach " + target.th_high); } } } kumostat.target.temperatureCross=function(target){ if(target.tempState=Normal && kumostat.hvacOn){ if(tempToCool>0){ if($averageTimeToCoolPerDeg==undefined)$averageTimeToCoolPerDeg=(KumoApp.Tick-setTime)/tempToCool; else $averageTimeToCoolPerDeg=(KumoApp.Tick-setTime)/tempToCool/2+$averageTimeToCoolPerDeg/2; } else if(tempToRaise>0){ if($averageTimeToHeatPerDeg==undefined)$averageTimeToHeatPerDeg=(KumoApp.Tick-setTime)/tempToRaise; else $averageTimeToHeatPerDeg=(KumoApp.Tick-setTime)/tempToRaise/2+$averageTimeToHeatPerDeg/2; } } }
Use AppCoder see other examples and try out your idea today.
Place Holders
- Tags, KumoSensors, Kumostats: <#...#>
- Days of the week, time of the day: <@...@>
- Region: <_..._>
- Texts and numbers: <%...%>
- Mobile devices: <~...~>
The Global KumoApp Object
- KumoApp.setTimeout
- KumoApp.setInterval
- KumoApp.stopTimer
- KumoApp.Log
- KumoApp.Tick
- KumoApp.FormatDateTime
- KumoApp.UserFriendlyTimeSpan
- KumoApp.Wp
- KumoApp.WpPostTitle
- KumoApp.httpCall
- KumoApp.httpCallExternal
- KumoApp.Tweet
- KumoApp.Email
- KumoApp.OnStop
- KumoApp.armMultiple
- KumoApp.disarmMultiple