Merge pull request #459 from menakaj/release-3.0.x

Android Sense stabilization
merge-requests/1/head
Charitha Goonetilleke 8 years ago committed by GitHub
commit 34fb3cad0b

@ -50,6 +50,12 @@
android:label="@string/app_name" >
</service>
<service
android:name="org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryReaderService"
android:enabled="true"
android:label="@string/app_name" >
</service>
<service android:name="org.wso2.carbon.iot.android.sense.event.streams.activity.ActivityReceiver"/>
<receiver android:name="org.wso2.carbon.iot.android.sense.event.SenseScheduleReceiver" >

@ -18,16 +18,18 @@ import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* This creates and AlarmManagerService that triggers the data uploader service with a 30 seconds interval.
*/
public class DataPublisherReceiver extends BroadcastReceiver {
private static int ALARM_INTERVAL = 30000;
private static int ALARM_INTERVAL = 1000;
@Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Log.i("Data Publisher", "triggered");
Intent i = new Intent(context, DataPublisherService.class);
PendingIntent pending = PendingIntent.getService(context, 0, i, 0);
service.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ALARM_INTERVAL, pending);

@ -25,7 +25,7 @@ import java.util.Calendar;
* This is a service which triggers to collect
*/
public class SenseScheduleReceiver extends BroadcastReceiver {
private static final int ALARM_INTERVAL = 5000;
private static final int ALARM_INTERVAL = 1000;
@Override
public void onReceive(Context context, Intent intent) {
@ -35,7 +35,7 @@ public class SenseScheduleReceiver extends BroadcastReceiver {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
cal.add(Calendar.SECOND, 10);
service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), ALARM_INTERVAL, pending);
}

@ -56,7 +56,7 @@ public class SenseService extends Service {
SenseDataReceiverManager.registerActivityDataReceiver(this);
SenseDataReceiverManager.registerSmsDataReceiver(this);
SenseDataReceiverManager.registerAppDataReceiver(this);
SenseDataReceiverManager.registerNetworkDataReceiver(this);
SenseDataReceiverManager.registerNetworkDataReader(this);
//service will not be stopped until we manually stop the service
return Service.START_NOT_STICKY;
@ -70,7 +70,7 @@ public class SenseService extends Service {
SenseDataReceiverManager.unregisterActivityDataReceiver(this);
SenseDataReceiverManager.unregisterSmsDataReceiver(this);
SenseDataReceiverManager.unregisterAppDataReceiver(this);
SenseDataReceiverManager.unregisterNetworkDataReceiver(this);
SenseDataReceiverManager.unregisterNetworkDataReader();
SenseWakeLock.releaseCPUWakeLock();
super.onDestroy();

@ -13,10 +13,15 @@
*/
package org.wso2.carbon.iot.android.sense.event.streams.battery;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import android.util.Log;
import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherService;
import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
/**
@ -24,21 +29,20 @@ import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
*/
public class BatteryDataReceiver extends BroadcastReceiver {
private final long ALARM_INTERVAL = 1000;
/**
* when the data is retreived then its added to a inmemory map.
* When the data is retrieved then its added to a in memory map.
*
* @param context of the reciever.
* @param intent of the reciver
* @param context of the receiver.
* @param intent of the receiver
*/
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BATTERY_OKAY.equals(intent.getAction())) {
SenseDataHolder.getBatteryDataHolder().add(new BatteryData(BatteryData.State.OK));
} else if (Intent.ACTION_BATTERY_LOW.equals(intent.getAction())) {
SenseDataHolder.getBatteryDataHolder().add(new BatteryData(BatteryData.State.LOW));
} else {
SenseDataHolder.getBatteryDataHolder().add(new BatteryData(intent));
}
AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Log.i("Battery Data Receiver", "Triggered");
Intent i = new Intent(context, BatteryReaderService.class);
PendingIntent pending = PendingIntent.getService(context, 0, i, 0);
service.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ALARM_INTERVAL, pending);
}
}

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.iot.android.sense.event.streams.battery;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
public class BatteryReaderService extends IntentService {
private Context context;
public BatteryReaderService() {
super("BatteryReaderService");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void onHandleIntent(Intent intent) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
intentFilter.addAction(Intent.ACTION_BATTERY_OKAY);
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
Intent intent1 = registerReceiver(null, intentFilter);
Log.i("Battery Data", String.valueOf(intent1.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)));
if (Intent.ACTION_BATTERY_OKAY.equals(intent.getAction())) {
SenseDataHolder.getBatteryDataHolder().add(new BatteryData(BatteryData.State.OK));
} else if (Intent.ACTION_BATTERY_LOW.equals(intent.getAction())) {
SenseDataHolder.getBatteryDataHolder().add(new BatteryData(BatteryData.State.LOW));
} else {
SenseDataHolder.getBatteryDataHolder().add(new BatteryData(intent1));
}
}
}

@ -23,19 +23,16 @@ import java.util.Date;
public class NetworkData {
//Mobile or Wifi
private String DATA_TYPE;
private String type;
private long dataReceived;
private long dataSent;
private long timeStamp;
public NetworkData(long received, long sent) {
this.dataReceived = received;
this.dataSent = sent;
this.timeStamp = new Date().getTime();
public NetworkData() {
}
public String getDataType() {
return DATA_TYPE;
return type;
}
public long getDataReceived() {
@ -57,4 +54,16 @@ public class NetworkData {
public long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(long timeStamp) {
this.timeStamp = timeStamp;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

@ -0,0 +1,96 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.iot.android.sense.event.streams.data;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.TrafficStats;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
import java.util.Date;
/**
* Class to read data sent and received by the device.
*/
public class NetworkDataReader extends AsyncTask<Void, Void, Long> {
private NetworkData networkData;
private Context context;
private Handler mHandler = new Handler();
private long mStartRX = 0;
private long mStartTX = 0;
private final String WIFI = "WIFI";
private final String MOBILE = "MOBILE";
private String connectionType;
public NetworkDataReader(Context context) {
this.context = context;
}
@Override
protected Long doInBackground(Void... voids) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
networkData = new NetworkData();
if (getConnectionType(connectivityManager, ConnectivityManager.TYPE_WIFI)) {
connectionType = WIFI;
} else if (getConnectionType(connectivityManager, ConnectivityManager.TYPE_MOBILE)) {
connectionType = MOBILE;
}
mStartRX = TrafficStats.getTotalRxBytes();
mStartTX = TrafficStats.getTotalTxBytes();
if (mStartRX == TrafficStats.UNSUPPORTED || mStartTX == TrafficStats.UNSUPPORTED) {
Log.e("ERROR", "Not connected.");
} else {
mHandler.postDelayed(mRunnable, 10000);
}
return null;
}
/**
* Collect data sent and received with in 10 second time frames.
*/
private final Runnable mRunnable = new Runnable() {
public void run() {
long rxBytes = TrafficStats.getTotalRxBytes()- mStartRX;
long txBytes = TrafficStats.getTotalTxBytes()- mStartTX;
Log.i("Usage: ", String.valueOf(rxBytes) + " " + String.valueOf(txBytes) + " " + System.currentTimeMillis());
networkData.setType(connectionType);
networkData.setTimeStamp(new Date().getTime());
networkData.setDataSent(txBytes);
networkData.setDataReceived(rxBytes);
SenseDataHolder.getNetworkDataHolder().add(networkData);
mHandler.postDelayed(mRunnable, 10000);
}
};
/**
* Get the type of the connection currently have.
*/
private boolean getConnectionType(ConnectivityManager manager, Integer type) {
NetworkInfo networkInfo = manager.getNetworkInfo(type);
return networkInfo.isConnected();
}

@ -1,42 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.iot.android.sense.event.streams.data;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
public class NetworkDataReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
long sent = android.net.TrafficStats.getTotalTxBytes();
long received = android.net.TrafficStats.getTotalRxBytes();
Log.d("NetworkData :", "Received: " + sent + " Received : " + received);
NetworkData networkData = new NetworkData(received, sent);
SenseDataHolder.getNetworkDataHolder().add(networkData);
}
}

@ -56,6 +56,7 @@ public class SenseClientAsyncExecutor extends AsyncTask<String, Void, Map<String
private final static String TAG = "SenseService Client";
private static final String STATUS = "status";
private final String PASSWORD_GRANT_TYPE = "password";
private final static String DEVICE_NAME = Build.MANUFACTURER + " " + Build.MODEL;
private Context context;
@ -116,7 +117,7 @@ public class SenseClientAsyncExecutor extends AsyncTask<String, Void, Map<String
new BasicAuthRequestInterceptor(apiApplicationKey.getConsumerKey(), apiApplicationKey.getConsumerSecret()))
.contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
.target(TokenIssuerService.class, endpoint + SenseConstants.TOKEN_ISSUER_CONTEXT);
accessTokenInfo = tokenIssuerService.getToken("password", username, password, "device_" + deviceId);
accessTokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password, "device_" + deviceId);
//DeviceRegister
AndroidSenseManagerService androidSenseManagerService = Feign.builder().client(disableHostnameVerification)

@ -35,7 +35,7 @@ import org.wso2.carbon.iot.android.sense.event.streams.activity.ActivityReceiver
import org.wso2.carbon.iot.android.sense.event.streams.application.ApplicationDataReceiver;
import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryDataReceiver;
import org.wso2.carbon.iot.android.sense.event.streams.call.CallDataReceiver;
import org.wso2.carbon.iot.android.sense.event.streams.data.NetworkDataReceiver;
import org.wso2.carbon.iot.android.sense.event.streams.data.NetworkDataReader;
import org.wso2.carbon.iot.android.sense.event.streams.screen.ScreenDataReceiver;
import org.wso2.carbon.iot.android.sense.event.streams.sms.SmsDataReceiver;
@ -52,7 +52,7 @@ public class SenseDataReceiverManager {
private static ApplicationDataReceiver appDataReceiver;
private static NetworkDataReceiver networkDataReceiver;
private static NetworkDataReader networkDataReader;
private SenseDataReceiverManager() {
@ -174,20 +174,20 @@ public class SenseDataReceiverManager {
context.unregisterReceiver(appDataReceiver);
appDataReceiver = null;
}
} public static void registerNetworkDataReceiver(Context context) {
if (networkDataReceiver == null) {
networkDataReceiver = new NetworkDataReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_MANAGE_NETWORK_USAGE);
context.registerReceiver(networkDataReceiver, intentFilter);
}
public static void registerNetworkDataReader(Context context) {
if (networkDataReader == null) {
networkDataReader = new NetworkDataReader(context);
networkDataReader.execute();
}
}
public static void unregisterNetworkDataReceiver(Context context) {
if (networkDataReceiver != null) {
context.unregisterReceiver(networkDataReceiver);
public static void unregisterNetworkDataReader() {
if (networkDataReader != null) {
networkDataReader.cancel(true);
}
networkDataReceiver = null;
networkDataReader = null;
}

@ -21,7 +21,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
/**
* This hold the api defintion that is used as a contract with netflix feign.
* This hold the api definition that is used as a contract with netflix feign.
*/
@Path("/token")
public interface TokenIssuerService {
@ -30,4 +30,10 @@ public interface TokenIssuerService {
@Produces(MediaType.APPLICATION_JSON)
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
@QueryParam("password") String password, @QueryParam("deviceId") String deviceId);
@POST
@Produces(MediaType.APPLICATION_JSON)
AccessTokenInfo getRefreshToken(@QueryParam("grant_type") String grantType, @QueryParam("refreshToken") String refreshToken);
}

@ -0,0 +1,19 @@
@Plan:name('Android-Battery-ExecutionPlan')
@Plan:description('Find the battery status of the android device.')
@Import('org.wso2.iot.android.battery:1.0.0')
define stream BatteryStream (meta_owner string, meta_deviceId string, meta_timestamp long, level int, state string, status string, temperature int);
@Export('org.wso2.iot.android.battery.stats:1.0.0')
define stream BatteryStatsStream (meta_owner string, meta_deviceId string, meta_timestamp long, level int, state
string, status string, temperature int, year int, month int, day int, hour int, minute int);
partition with (meta_deviceId of BatteryStream)
begin
from BatteryStream
select meta_owner, meta_deviceId, meta_timestamp, level, state, status, temperature, time:extract(preState.meta_timestamp, 'year') as year, time:extract(preState.meta_timestamp, 'month') as month, time:extract(preState.meta_timestamp, 'day') as day, time:extract(preState.meta_timestamp, 'hour') as hour, time:extract(preState.meta_timestamp, 'minute') as minute
insert into BatteryStatsStream;
end;

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name= "android_android_battery_executionplan" version="1.0.0" type="event/execution-plan"
serverRole="DataAnalyticsServer">
<file>Android-Battery-ExecutionPlan.siddhiql</file>
</artifact>

@ -11,7 +11,7 @@ define stream CallStatsStream (meta_owner string, meta_deviceId string, meta_tim
partition with (meta_deviceId of CallStream)
begin
from CallStream[type == 'INCOMING' OR type == 'OUTGOING']
from CallStream
select meta_owner, meta_deviceId, meta_timestamp, number, type, (endTime - startTime) as duration, time:extract(meta_timestamp, 'year') as year, time:extract(meta_timestamp, 'month') as month, time:extract(meta_timestamp, 'day') as day, time:extract(meta_timestamp, 'hour') as hour, time:extract(meta_timestamp, 'minute') as minute
insert into CallStatsStream;
end;

@ -1,17 +1,19 @@
{
"provider-conf": {
"streamName": "org.wso2.iot.android.battery:1.0.0",
"provider-name": "realtime"
"tableName": "ORG_WSO2_IOT_ANDROID_BATTERY_STATS",
"query": "",
"limit": "",
"provider-name": "batch"
},
"chart-conf": {
"x": "TIMESTAMP",
"x": "meta_timestamp",
"xType": "time",
"y": "level",
"yType": "number",
"color": "None",
"mode": "stack",
"maxLength": "30",
"gadget-name": "Android Battery Level Chart",
"gadget-name": "Battery History",
"chart-name": "area-chart"
}
}

@ -0,0 +1,9 @@
{
"id": "Android_Battery_History_Chart",
"title": "Battery History",
"type": "gadget",
"thumbnail": "gadget/Android_Battery_History_Chart/thumbnail.png",
"data": {
"url": "gadget/Android_Battery_History_Chart/gadget.xml"
}
}

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Android Battery Level Chart" description="This is a template gadget">
<ModulePrefs title="Battery History" description="This is a template gadget">
<Require feature="dynamic-height"/>
<Require feature="wso2-gadgets-identity"/>
</ModulePrefs>
<UserPref name="windowSize"
display_name="Window Size"
default_value="10"/>
<UserPref name="refreshInterval"
display_name="Refresh Interval"
default_value="1000000"/>
<Content type="html">
<![CDATA[
<head>
@ -25,15 +25,13 @@
<script src="/portal/libs/jquery_1.11.0/jquery-1.11.3.min.js"></script>
<!-- provider libs -->
<script src="js/provider-libs/ws-client.js"></script>
<!-- shared libs -->
<script src="/portal/libs/analytics-wso2-2.0.0/d3.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/vega.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/VizGrammar_2.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/VizGrammar.min.js"></script>
<script src="/portal/libs/analytics-wso2-2.0.0/wso2gadgets.js"></script>
@ -45,8 +43,6 @@
<!--scripts copied by framework -->
<script src="js/core/provider-client.js"></script>
<script src="js/core/gadget-util.js"></script>
<script src="js/core/area-chart-api.js"></script>
<script src="js/core/gadget-core.js"></script>

@ -0,0 +1,190 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush;
(function() {
var PROVIDERS_LOCATION = '/extensions/providers/';
var PROVIDER_NAME = 'batch';
var TYPE = "type";
var TABLE_NAME = "tableName";
var HTTPS_TRANSPORT = "https";
var CONTENT_TYPE_JSON = "application/json";
var AUTHORIZATION_HEADER = "Authorization";
var USER_TOKEN = "user";
var TENANT_DOMAIN = "domain";
var CONST_AT = "@";
var USERNAME = "username";
var HTTP_USER_NOT_AUTHENTICATED = 403;
var JS_MAX_VALUE = "9007199254740992";
var JS_MIN_VALUE = "-9007199254740992";
var typeMap = {
"bool" : "string",
"boolean" : "string",
"string" : "string",
"int" : "number",
"integer" : "number",
"long" : "number",
"double" : "number",
"float" : "number",
"time": "time"
};
var log = new Log();
var carbon = require('carbon');
var configs = require('/configs/designer.json');
var utils = require('/modules/utils.js');
var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils;
var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector;
var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache;
var cacheTimeoutSeconds = 5;
var loggedInUser = null;
if (configs.cacheTimeoutSeconds) {
cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds);
}
var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB
if (configs.cacheSizeBytes) {
cacheSizeBytes = parseInt(configs.cacheSizeBytes);
}
response.contentType = CONTENT_TYPE_JSON;
var authParam = request.getHeader(AUTHORIZATION_HEADER);
if (authParam != null) {
credentials = JSUtils.authenticate(authParam);
loggedInUser = credentials[0];
} else {
var token = session.get(USER_TOKEN);
if (token != null) {
loggedInUser = token[USERNAME] + CONST_AT + token[TENANT_DOMAIN];
} else {
log.error("user is not authenticated!");
response.status = HTTP_USER_NOT_AUTHENTICATED;
print('{ "status": "Failed", "message": "User is not authenticated." }');
return;
}
}
var cache = application.get("AnalyticsWebServiceCache");
if (cache == null) {
cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes);
application.put("AnalyticsWebServiceCache", cache);
}
var connector = new AnalyticsCachedJSServiceConnector(cache);
/**
* require the existing config.json and push any dynamic fields that needs to be populated in the UI
*/
getConfig = function() {
var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json');
var tables;
try {
tables = JSON.parse(connector.getTableList(loggedInUser).getMessage());
} catch (e) {
log.error(e);
}
var configs = formConfig.config;
configs.forEach(function(config) {
if (config.fieldName === TABLE_NAME) {
config.valueSet = tables;
}
});
return formConfig;
}
/**
* validate the user input of provider configuration
* @param providerConfig
*/
validate = function(providerConfig) {
/*
validate the form and return
*/
return true;
}
/**
* returns the data mode either push or pull
*/
getMode = function() {
return "PULL";
}
/**
* returns an array of column names & types
* @param providerConfig
*/
getSchema = function(providerConfig) {
var schema = [];
var tableName = providerConfig["tableName"];
var result = connector.getTableSchema(loggedInUser, tableName).getMessage();
result = JSON.parse(result);
var columns = result.columns;
Object.getOwnPropertyNames(columns).forEach(function(name, idx, array) {
var type = "ordinal";
if(columns[name]['type']) {
type = columns[name]['type'];
}
schema.push({
fieldName: name,
fieldType: typeMap[type.toLowerCase()]
});
});
// log.info(schema);
return schema;
};
/**
* returns the actual data
* @param providerConfig
* @param limit
*/
getData = function(providerConfig, limit) {
var tableName = providerConfig.tableName;
var query = providerConfig.query;
var limit = 100;
if (providerConfig.limit) {
limit = providerConfig.limit;
}
var result;
//if there's a filter present, we should perform a Lucene search instead of reading the table
if (query) {
var filter = {
"query": query,
"start": 0,
"count": limit
};
result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage();
} else {
var from = JS_MIN_VALUE;
var to = JS_MAX_VALUE;
result = connector.getRecordsByRange(loggedInUser, tableName, from, to, 0, limit, null).getMessage();
}
result = JSON.parse(result);
var data = [];
for (var i = 0; i < result.length; i++) {
var values = result[i].values;
data.push(values);
}
return data;
};
}());

@ -19,9 +19,14 @@ $(function () {
var schema;
var pref = new gadgets.Prefs();
var refreshInterval;
var providerData;
var CHART_CONF = 'chart-conf';
var PROVIDER_CONF = 'provider-conf';
var REFRESH_INTERVAL = 'refreshInterval';
var init = function () {
$.ajax({
url: gadgetLocation + '/conf.json',
@ -41,17 +46,33 @@ var init = function () {
}
});
getProviderData();
}
});
};
var getProviderData = function (){
$.ajax({
url: gadgetLocation + '/gadget-controller.jag?action=getData',
method: "POST",
data: JSON.stringify(conf),
contentType: "application/json",
async: false,
success: function (data) {
providerData = data;
}
});
return providerData;
};
var drawGadget = function (){
draw('#canvas', conf[CHART_CONF], schema, null);
registerCallBackforPush(conf[PROVIDER_CONF], schema, function(providerData) {
update(providerData);
});
draw('#canvas', conf[CHART_CONF], schema, providerData);
setInterval(function() {
draw('#canvas', conf[CHART_CONF], schema, getProviderData());
},pref.getInt(REFRESH_INTERVAL));
};

@ -14,7 +14,7 @@
* limitations under the License.
*/
var getGadgetLocation = function (callback) {
var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Battery_Level_Chart";
var gadgetLocation = "/portal/store/carbon.super/fs/gadget/Android_Battery_History_Chart";
var PATH_SEPERATOR = "/";
if (gadgetLocation.search("store") != -1) {
wso2.gadgets.identity.getTenantDomain(function (tenantDomain) {

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name= "android_battery_history_chart_gadget" version="1.0.0" type="dashboards/gadget"
serverRole="DataAnalyticsServer">
<file>Android_Battery_History_Chart</file>
</artifact>

@ -1,9 +0,0 @@
{
"id": "Android_Battery_Level_Chart",
"title": "Android Battery Level Chart",
"type": "gadget",
"thumbnail": "gadget/Android_Battery_Level_Chart/thumbnail.png",
"data": {
"url": "gadget/Android_Battery_Level_Chart/gadget.xml"
}
}

@ -1,51 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// var registerCallBackforPush;
(function() {
var callback;
/**
* TODO Need to read hostname,port, and tenantId from providerConfig
* @param providerConfig
* @param schema
*/
registerCallBackforPush = function(providerConfig, schema, _callback) {
var streamId = providerConfig['streamName'];
var hostname = window.parent.location.hostname;
var port = window.parent.location.port;
subscribe(streamId.split(":")[0], streamId.split(":")[1],
'10',
onData, onError,
hostname,
port,
'WEBSOCKET'
);
callback = _callback;
};
function onData(streamId, data) {
callback(data);
};
function onError(error) {
console.error(error);
};
}());

@ -1,154 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush;
(function() {
var PROVIDERS_LOCATION = '/extensions/providers/';
var PROVIDER_NAME = 'realtime';
var log = new Log();
var utils = require('/modules/utils.js');
var carbon = require("carbon");
var EventPublisherConstants = Packages.org.wso2.carbon.event.publisher.core.config.EventPublisherConstants;
var eventPublisherService = carbon.server.osgiService('org.wso2.carbon.event.publisher.core.EventPublisherService');
var eventStreamService = carbon.server.osgiService('org.wso2.carbon.event.stream.core.EventStreamService');
var typeMap = {
"bool": "string",
"boolean": "string",
"string": "string",
"int": "number",
"integer": "number",
"long": "number",
"double": "number",
"float": "number",
"time": "time"
};
getConfig = function() {
var formConfig = require(PROVIDERS_LOCATION + '/' + PROVIDER_NAME + '/config.json');
var datasources = [];
try {
var eventPublisherConfigurationList = eventPublisherService.getAllActiveEventPublisherConfigurations();
for (var i = 0; i < eventPublisherConfigurationList.size(); i++) {
var eventPublisherConfiguration = eventPublisherService.getActiveEventPublisherConfiguration(
eventPublisherConfigurationList.get(i).getEventPublisherName());;
var mappingTypeIsWso2 = eventPublisherConfiguration.getOutputMapping()
.getMappingType().equals(EventPublisherConstants.EF_WSO2EVENT_MAPPING_TYPE);
var adapterType = null;
if (eventPublisherConfiguration.getToAdapterConfiguration() != null) {
adapterType = eventPublisherConfiguration.getToAdapterConfiguration().getType();
}
if (mappingTypeIsWso2 && adapterType.trim() == "ui") {
var streamName = eventPublisherConfiguration.getFromStreamName();
var streamVersion = eventPublisherConfiguration.getFromStreamVersion();
var streamId = streamName + ":" + streamVersion;
datasources.push(streamId);
}
}
var datasourceCfg = {
"fieldLabel": "Event Stream",
"fieldName": "streamName",
"fieldType": "dropDown"
};
datasourceCfg['valueSet'] = datasources;
} catch (e) {
log.error(e);
}
formConfig.config.push(datasourceCfg);
return formConfig;
};
/**
* validate the user input of provider configuration
* @param providerConfig
*/
validate = function(providerConfig) {
/*
validate the form and return
*/
return true;
};
/**
* returns the data mode either push or pull
*/
getMode = function() {
return 'push';
};
/**
* returns an array of column names & types
* @param providerConfig
*/
getSchema = function(providerConfig) {
var streamId = providerConfig["streamName"];
var output = [];
output.push({
fieldName: "TIMESTAMP",
fieldType: "time"
});
if (eventStreamService != null) {
var eventStreamConfiguration = eventStreamService.getEventStreamConfiguration(streamId);
if (eventStreamConfiguration != null) {
var metaData = eventStreamConfiguration.getStreamDefinition().getMetaData();
var correlationData = eventStreamConfiguration.getStreamDefinition().getCorrelationData();
var payloadData = eventStreamConfiguration.getStreamDefinition().getPayloadData();
if (metaData != null) {
for (var i = 0; i < metaData.size(); i++) {
var type = metaData.get(i).getType().toString().toLowerCase();
output.push({
fieldName: metaData.get(i).getName(),
fieldType: typeMap[type.toLowerCase()]
});
}
}
if (correlationData != null) {
for (var i = 0; i < correlationData.size(); i++) {
var type = correlationData.get(i).getType().toString().toLowerCase();
output.push({
fieldName: correlationData.get(i).getName(),
fieldType: typeMap[type.toLowerCase()]
});
}
}
if (payloadData != null) {
for (var i = 0; i < payloadData.size(); i++) {
var type = payloadData.get(i).getType().toString().toLowerCase();
output.push({
fieldName: payloadData.get(i).getName(),
fieldType: typeMap[type.toLowerCase()]
});
}
}
}
}
return output;
};
getData = function(providerConfig,limit) {
var data = [];
return data;
};
}());

@ -1,262 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var CONSTANTS = {
urlSeperator: '/',
queryParamStreamName : '?streamname=',
queryParamStreamVersion : '&version=',
queryParamLastUpdatedTime : '&lastUpdatedTime=',
urlSecureTransportWebsocket : 'wss://',
urlSecureTransportHttp : 'https://',
colon : ':',
defaultIntervalTime : 10 * 1000,
defaultHostName : 'localhost',
defaultSecurePortNumber : '9443',
defaultMode : 'AUTO',
processModeHTTP : 'HTTP',
processModeWebSocket : 'WEBSOCKET',
processModeAuto : 'AUTO',
numThousand : 1000,
websocketTimeAppender : 400,
websocketSubscriptionEndpoint : 'portal/uipublisher/websocketSubscriptionEndpoint.jag',
httpEventRetrievalEndpoint : 'portal/uipublisher/httpEventRetrievalEndpoint.jag'
};
var websocket = null;
var webSocketUrl;
var httpUrl;
var cepHostName;
var cepPortNumber;
var isErrorOccured = false;
var lastUpdatedtime = -1;
var polingInterval;
var stream;
var streamVersion;
var firstPollingAttempt;
var processMode;
var onSuccessFunction;
var onErrorFunction;
var terminateWebsocketInstance = false;
var pollingContinue = true;
function subscribe(streamName,version,intervalTime,
listeningFuncSuccessData,listeningFuncErrorData,cepHost,cepPort,mode){
stopPollingProcesses();
stream = streamName;
streamVersion = version;
onSuccessFunction = listeningFuncSuccessData;
onErrorFunction = listeningFuncErrorData;
if(intervalTime == null || intervalTime == ""){
polingInterval = CONSTANTS.defaultIntervalTime;
} else{
polingInterval = intervalTime * CONSTANTS.numThousand;
}
if(cepHost == null || cepHost == ""){
cepHostName = CONSTANTS.defaultHostName;
} else{
cepHostName = cepHost;
}
if(cepPort == null || cepPort == ""){
cepPortNumber = CONSTANTS.defaultSecurePortNumber;
} else{
cepPortNumber = cepPort;
}
if(mode == null || mode == ""){
processMode = CONSTANTS.defaultMode;
} else{
processMode = mode;
}
webSocketUrl = CONSTANTS.urlSecureTransportWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber +
CONSTANTS.urlSeperator + CONSTANTS.websocketSubscriptionEndpoint;
if(processMode == CONSTANTS.processModeHTTP){
firstPollingAttempt = true;
pollingContinue = true;
startPoll();
} else{
initializeWebSocket(webSocketUrl);
}
}
/**
* Initializing Web Socket
*/
function initializeWebSocket(webSocketUrl){
websocket = new WebSocket(webSocketUrl);
websocket.onopen = webSocketOnOpen;
websocket.onmessage = webSocketOnMessage;
websocket.onclose = webSocketOnClose;
websocket.onerror = webSocketOnError;
}
function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProperties, streamValues) {
if (streamProperties.length === streamValues.length) {
var message = {};
message.streamName = streamName;
message.streamVersion = streamVersion;
var i;
for (i = 0; i < streamProperties.length; i++) {
message.filterProps = [];
message.filterProps.push({
'name': streamProperties[i],
'value': streamValues[i]
});
}
return JSON.stringify(message);
} else {
console.log('stream properties and values are not in equal size');
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/
var webSocketOnMessage = function (evt) {
var event = evt.data;
var array = JSON.parse(event);
constructPayload(array);
};
/**
* On server close
*/
var webSocketOnClose =function (e) {
if(isErrorOccured){
if(processMode != CONSTANTS.processModeWebSocket){
firstPollingAttempt = true;
pollingContinue = true;
startPoll();
}
} else{
if(!terminateWebsocketInstance){
waitForSocketConnection(websocket);
} else{
terminateWebsocketInstance = false;
}
}
};
/**
* On server Error
*/
var webSocketOnError = function (err) {
var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!";
onErrorFunction(error);
isErrorOccured = true;
};
/**
* Gracefully increments the connection retry
*/
var waitTime = CONSTANTS.numThousand;
function waitForSocketConnection(socket, callback){
setTimeout(
function () {
if (socket.readyState === 1) {
initializeWebSocket(webSocketUrl);
console.log("Connection is made");
if(callback != null){
callback();
}
return;
} else {
websocket = new WebSocket(webSocketUrl);
waitTime += CONSTANTS.websocketTimeAppender;
waitForSocketConnection(websocket, callback);
}
}, waitTime);
}
/**
* Polling to retrieve events from http request periodically
*/
function startPoll(){
(function poll(){
setTimeout(function(){
httpUrl = CONSTANTS.urlSecureTransportHttp + cepHostName + CONSTANTS.colon + cepPortNumber +
CONSTANTS.urlSeperator + CONSTANTS.httpEventRetrievalEndpoint + CONSTANTS.queryParamStreamName + stream +
CONSTANTS.queryParamStreamVersion + streamVersion + CONSTANTS.queryParamLastUpdatedTime + lastUpdatedtime;;
$.getJSON(httpUrl, function(responseText) {
if(firstPollingAttempt){
/*var data = $("textarea#idConsole").val();
$("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/
firstPollingAttempt = false;
}
var eventList = $.parseJSON(responseText.events);
if(eventList.length != 0){
lastUpdatedtime = responseText.lastEventTime;
for(var i=0;i<eventList.length;i++){
var arr = eventList[i];
constructPayload(arr);
}
}
if(pollingContinue){
startPoll();
}
})
.fail(function(errorData) {
var errorData = JSON.parse(errorData.responseText);
onErrorFunction(errorData.error);
});
}, polingInterval);
})()
}
function stopPollingProcesses(){
//stopping the Websocket
if(websocket != null){
terminateWebsocketInstance = true;
websocket.close();
}
//stopping the HTTPS Request
pollingContinue = false;
}
function constructPayload(eventsArray){
var streamId = stream + CONSTANTS.colon + streamVersion;
var twoDimentionalArray = [eventsArray];
onSuccessFunction(streamId,twoDimentionalArray);
}

@ -130,13 +130,40 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Analytics>
<Editable>true</Editable>
<Name>AndriodCallScript</Name>
<Script> CREATE TEMPORARY TABLE AndroidBatteryData USING CarbonAnalytics OPTIONS(tableName
"ORG_WSO2_IOT_ANDROID_BATTERY_STATS", incrementalParams "ORG_WSO2_IOT_ANDROID_BATTERY_STATS, DAY");
CREATE TEMPORARY TABLE Android_Battery_Stat_Per_Day USING CarbonAnalytics
OPTIONS (tableName "Android_Battery_Stat_Per_Day",
schema "owner STRING, deviceId STRING, type STRING, level INT -i, year INT -i, month INT -i, day INT -i,
timestamp STRING", primaryKeys "year, month, day, deviceId, owner, type", mergeSchema "false");
INSERT INTO TABLE Android_Battery_Stat_Per_Day
SELECT meta_owner as owner, meta_deviceId as deviceId, type, avg(level) as level, year, month, day,
getDateStartingTime(year, month, day) as timestamp
FROM AndroidBatteryData
GROUP BY year, month, day, meta_deviceId, meta_owner, type ORDER BY timestamp DESC;
INCREMENTAL_TABLE_COMMIT ORG_WSO2_IOT_ANDROID_BATTERY_STATS;
</Script>
<CronExpression>0 0/5 * * * ?</CronExpression>
</Analytics>

@ -17,7 +17,7 @@
~ under the License.
-->
<artifact name= "android_battery_level_chart_gadget" version="1.0.0" type="dashboards/gadget" serverRole="DataAnalyticsServer">
<file>Android_Battery_Level_Chart</file>
<artifact name= "android_battery_script" version="1.0.0" type="analytics/spark" serverRole="DataAnalyticsServer">
<file>AndroidBatteryScript.xml</file>
</artifact>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name= "android_battery_stats_event_sink" version="1.0.0" type="analytics/eventstore"
serverRole="DataAnalyticsServer">
<file>org_wso2_iot_android_battery_stats.xml</file>
</artifact>

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EventStoreConfiguration>
<TableSchema>
<ColumnDefinition>
<Name>meta_owner</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>meta_deviceId</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>meta_timestamp</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>LONG</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>level</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>state</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>status</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>LONG</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>temperature</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>year</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>month</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>day</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>hour</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>minute</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>INTEGER</Type>
</ColumnDefinition>
</TableSchema>
<Source>
<StreamId>org.wso2.iot.android.battery.stats:1.0.0</StreamId>
</Source>
<MergeSchema>false</MergeSchema>
<RecordStoreName>PROCESSED_DATA_STORE</RecordStoreName>
</EventStoreConfiguration>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name= "android_battery_stats_streams" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
<file>org.wso2.iot.android.battery.stats_1.0.0.json</file>
</artifact>

@ -0,0 +1,58 @@
{
"name": "org.wso2.iot.android.battery.stats",
"version": "1.0.0",
"nickName": "",
"description": "",
"metaData": [
{
"name": "owner",
"type": "STRING"
},
{
"name": "deviceId",
"type": "STRING"
},
{
"name": "timestamp",
"type": "LONG"
}
],
"payloadData": [
{
"name": "level",
"type": "INT"
},
{
"name": "state",
"type": "STRING"
},
{
"name": "status",
"type": "STRING"
},
{
"name": "temperature",
"type": "INT"
},
{
"name": "year",
"type": "INT"
},
{
"name": "month",
"type": "INT"
},
{
"name": "day",
"type": "INT"
},
{
"name": "hour",
"type": "INT"
},
{
"name": "minute",
"type": "INT"
}
]
}

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name= "android_battery_stats_ui_event_publisher" version="1.0.0" type="event/publisher"
serverRole="DataAnalyticsServer">
<file>org.wso2.iot.android.battery.stats.ui.publisher.xml</file>
</artifact>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<eventPublisher name="org.wso2.iot.android.battery.stats.ui.publisher"
processing="enable" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventpublisher">
<from streamName="org.wso2.iot.android.battery.stats" version="1.0.0"/>
<mapping customMapping="disable" type="wso2event"/>
<to eventAdapterType="ui"/>
</eventPublisher>

@ -130,18 +130,45 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, [], []);
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params != null) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -130,18 +130,44 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -130,18 +130,44 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -130,18 +130,44 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -130,18 +130,44 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -130,18 +130,44 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -130,18 +130,44 @@ function getWebsocketSubscriptionMessage(streamName, streamVersion, streamProper
}
}
/**
* Get the parameters as query parameters.
* This method parses those parameters and returns.
* */
function getAllQueryParamsFromURL() {
var queryParamList = {}, qParam;
var urlQueryString = decodeURIComponent(window.top.location.search.substring(1));
if (urlQueryString) {
var queryStringPairs = urlQueryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
qParam = queryStringPairs[i].split('=');
queryParamList[qParam[0]] = qParam[1];
}
return queryParamList;
} else {
return null;
}
}
/**
* Web socket On Open
*/
var webSocketOnOpen = function () {
var filterPropNames = ["meta_deviceId"];
var filterPropVals = ["htc"];
var params = getAllQueryParamsFromURL();
var deviceId;
var owner;
if (params) {
owner = params["owner"];
deviceId = params["deviceId"];
}
var filterPropNames = ["meta_owner", "meta_deviceId"];
var filterPropVals = [owner, deviceId];
var data = getWebsocketSubscriptionMessage(stream, streamVersion, filterPropNames, filterPropVals);
websocket.send(data);
};
/**
* On server sends a message
*/

@ -586,9 +586,9 @@
{
"content": {
"data": {
"url": "fs://gadget/Android_Battery_Level_Chart/gadget.xml"
"url": "fs://gadget/Android_Battery_History_Chart/gadget.xml"
},
"id": "Android_Battery_Level_Chart",
"id": "Android_Battery_History_Chart",
"locale_titles": {
"en-US": "History"
},
@ -611,11 +611,11 @@
"title": "History",
"titlePosition": "center"
},
"thumbnail": "fs://gadget/Android_Battery_Level_Chart/thumbnail.png",
"title": "Android Battery Level Chart",
"thumbnail": "fs://gadget/Android_Battery_History_Chart/thumbnail.png",
"title": "Android Battery Hisory Chart",
"type": "gadget"
},
"id": "Android_Battery_Level_Chart-0"
"id": "Android_Battery_History_Chart-0"
}
],
"e": [

@ -38,6 +38,8 @@
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_android_audio_executionplan" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_android_battery_executionplan" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_android_call_executionplan" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_android_data_executionplan" version="1.0.0" include="true"
@ -54,11 +56,20 @@
<dependency artifact="android_audio_streams" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_level_chart_gadget" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_history_chart_gadget" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_percentage_chart_gadget" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_script" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_stats_event_sink" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_stats_streams" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_streams" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_ui_event_publisher" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_battery_stats_ui_event_publisher" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="android_call_script" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="android_call_stats_event_sink" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>

@ -280,11 +280,7 @@ public class AndroidSenseServiceImpl implements AndroidSenseService {
if (added) {
AndroidConfiguration androidConfiguration = new AndroidConfiguration();
androidConfiguration.setTenantDomain(APIUtil.getAuthenticatedUserTenantDomain());
String mqttEndpoint = DEFAULT_MQTT_ENDPOINT;
if (mqttEndpoint.contains(AndroidSenseConstants.LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(AndroidSenseConstants.LOCALHOST, APIUtil.getServerUrl());
}
androidConfiguration.setMqttEndpoint(mqttEndpoint);
androidConfiguration.setMqttEndpoint(APIUtil.getMqttEndpoint());
return Response.ok(androidConfiguration.toString()).build();
} else {
return Response.status(Response.Status.NOT_ACCEPTABLE.getStatusCode()).entity(false).build();

@ -17,26 +17,9 @@
*/
function onRequest(context) {
var devices = context.unit.params.devices;
var deviceType = context.uriParams.deviceType;
var user = context.user;
var deviceId = request.getParameter("deviceId");
if (devices) {
return {
"devices": stringify(devices),
"backendApiUri": "/android_sense/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {
"device": device.content,
"backendApiUrl": "/android_sense/stats/" + deviceId + "/sensors/"
};
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit();
}
}
//Redirects to the portal app as we do not use the old analytics view.
response.sendRedirect(context.app.conf["portalURL"] + "/portal/dashboards/android-iot/real-time?owner=" + user.username + "&deviceId=" + deviceId);
}

@ -41,8 +41,6 @@
data-toggle="tab" aria-controls="device_statistics">Device
Statistics</a>
</li>
<li><a class="list-group-item" href="#device_location" role="tab" data-toggle="tab"
aria-controls="device_location">Device Location</a></li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>
{{/zone}}
@ -53,15 +51,6 @@
<div class="panel-heading">Device Statistics</div>
{{unit "cdmf.unit.device.type.android_sense.realtime.analytics-view" device=device}}
</div>
<div class="panel panel-default tab-pane" id="device_location" role="tabpanel"
aria-labelledby="device_location">
<div class="panel-heading">Device Location</div>
<div class="panel-body">
<div id="map" style="height: 400px;">
</div>
<br class="c-both"/>
</div>
</div>
<div class="panel panel-default tab-pane" id="event_log" role="tabpanel"
aria-labelledby="event_log">
<div class="panel-heading">Operations Log <span><a href="#"
@ -85,9 +74,3 @@
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
<script async defer
src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&callback=initMap">
</script>
{{/zone}}

@ -19,98 +19,7 @@
<div id="chartWrapper">
</div>
<div id="div-chart" data-websocketurl="{{websocketEndpoint}}">
<div id="chartWrapper-battery" class="chartWrapper">
<div id="y_axis-battery" class="custom_y_axis" style="margin-top: -20px;">Battery</div>
<div class="legend_container-battery">
<div id="smoother-battery" title="Smoothing"></div>
<div id="legend-battery"></div>
</div>
<div id="chart-battery" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-light" class="chartWrapper">
<div id="y_axis-light" class="custom_y_axis" style="margin-top: -20px;">Light</div>
<div class="legend_container-light">
<div id="smoother-light" title="Smoothing"></div>
<div id="legend-light"></div>
</div>
<div id="chart-light" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-pressure" class="chartWrapper">
<div id="y_axis-pressure" class="custom_y_axis" style="margin-top: -20px;">Pressure</div>
<div class="legend_container-pressure">
<div id="smoother-pressure" title="Smoothing"></div>
<div id="legend-pressure"></div>
</div>
<div id="chart-pressure" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-proximity" class="chartWrapper">
<div id="y_axis-proximity" class="custom_y_axis" style="margin-top: -20px;">Proximity</div>
<div class="legend_container-proximity">
<div id="smoother-proximity" title="Smoothing"></div>
<div id="legend-proximity"></div>
</div>
<div id="chart-proximity" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-accelerometer" class="chartWrapper">
<div id="y_axis-accelerometer" class="custom_y_axis" style="margin-top: -20px;">Accelerometer</div>
<div class="legend_container-accelerometer">
<div id="smoother-accelerometer" title="Smoothing"></div>
<div id="legend-accelerometer"></div>
</div>
<div id="chart-accelerometer" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-magnetic" class="chartWrapper">
<div id="y_axis-magnetic" class="custom_y_axis" style="margin-top: -20px;">Magnetic</div>
<div class="legend_container-magnetic">
<div id="smoother-magnetic" title="Smoothing"></div>
<div id="legend-magnetic"></div>
</div>
<div id="chart-magnetic" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-rotation" class="chartWrapper">
<div id="y_axis-rotation" class="custom_y_axis" style="margin-top: -20px;">Rotation</div>
<div class="legend_container-rotation">
<div id="smoother-rotation" title="Smoothing"></div>
<div id="legend-rotation"></div>
</div>
<div id="chart-rotation" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-gyroscope" class="chartWrapper">
<div id="y_axis-gyroscope" class="custom_y_axis" style="margin-top: -20px;">Gyroscope</div>
<div class="legend_container-gyroscope">
<div id="smoother-gyroscope" title="Smoothing"></div>
<div id="legend-gyroscope"></div>
</div>
<div id="chart-gyroscope" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
<div id="chartWrapper-gravity" class="chartWrapper">
<div id="y_axis-gravity" class="custom_y_axis" style="margin-top: -20px;">Gravity</div>
<div class="legend_container-gravity">
<div id="smoother-gravity" title="Smoothing"></div>
<div id="legend-gravity"></div>
</div>
<div id="chart-gravity" class="custom_rickshaw_graph"></div>
<div class="custom_x_axis">Time</div>
</div>
</div>
<a class="padding-left"
href="{{@app.context}}/device/{{device.type}}/analytics?deviceId={{device.deviceIdentifier}}&deviceName={{device.name}}">
<span class="fw-stack">

Loading…
Cancel
Save