forked from community/device-mgt-plugins
parent
e05906fed5
commit
971185decf
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
|
||||||
|
|
||||||
|
public class BeaconMonitoringActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private BluetoothLeScanner mScanner;
|
||||||
|
private BluetoothUtils mBluetoothUtils;
|
||||||
|
private LeDeviceListAdapter mLeDeviceListAdapter;
|
||||||
|
private BluetoothLeDeviceStore mDeviceStore;
|
||||||
|
|
||||||
|
protected ListView mList;
|
||||||
|
|
||||||
|
public static final int MINIMUM_DISTANCE = -70;
|
||||||
|
|
||||||
|
public static Map itemMap;
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_beacon_monitoring);
|
||||||
|
|
||||||
|
itemMap = new HashMap<String, String>();
|
||||||
|
itemMap.put("DC:5F:BD:68:88:D5", "Noodles");
|
||||||
|
itemMap.put("EF:0F:50:D5:BA:A1", "Vegetables");
|
||||||
|
itemMap.put("FA:F2:CF:84:C2:F7", "Oil");
|
||||||
|
|
||||||
|
mList = (ListView) this.findViewById(android.R.id.list);
|
||||||
|
|
||||||
|
mDeviceStore = new BluetoothLeDeviceStore();
|
||||||
|
mBluetoothUtils = new BluetoothUtils(this);
|
||||||
|
mScanner = new BluetoothLeScanner(mLeScanCallback, mBluetoothUtils);
|
||||||
|
startScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||||
|
@Override
|
||||||
|
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
|
||||||
|
final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device, rssi, scanRecord, System.currentTimeMillis());
|
||||||
|
if(deviceLe!= null && deviceLe.getName()!= null && !deviceLe.getName().equals("Unknown Device")){
|
||||||
|
mDeviceStore.addDevice(deviceLe);
|
||||||
|
|
||||||
|
if(deviceLe.getRssi() > MINIMUM_DISTANCE){
|
||||||
|
Object[] objects = new Object[4];
|
||||||
|
objects[0] = deviceLe.getName();
|
||||||
|
objects[1] = deviceLe.getAddress();
|
||||||
|
objects[2] = deviceLe.getRssi();
|
||||||
|
objects[3] = itemMap.get(device.getAddress());
|
||||||
|
|
||||||
|
new SendToSiddi().execute(objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final EasyObjectCursor<BluetoothLeDevice> c = mDeviceStore.getDeviceCursor();
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mLeDeviceListAdapter.swapCursor(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void startScan() {
|
||||||
|
|
||||||
|
mLeDeviceListAdapter = new LeDeviceListAdapter(this, mDeviceStore.getDeviceCursor());
|
||||||
|
mList.setAdapter(mLeDeviceListAdapter);
|
||||||
|
|
||||||
|
final boolean mIsBluetoothOn = mBluetoothUtils.isBluetoothOn();
|
||||||
|
final boolean mIsBluetoothLePresent = mBluetoothUtils.isBluetoothLeSupported();
|
||||||
|
mBluetoothUtils.askUserToEnableBluetoothIfNeeded();
|
||||||
|
if (mIsBluetoothOn && mIsBluetoothLePresent) {
|
||||||
|
mScanner.scanLeDevice(-1, true);
|
||||||
|
invalidateOptionsMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SendToSiddi extends AsyncTask<Object, Object, Void>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Object... objects) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice;
|
||||||
|
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||||
|
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
|
||||||
|
|
||||||
|
public class BluetoothLeDeviceStore {
|
||||||
|
private final Map<String, BluetoothLeDevice> mDeviceMap;
|
||||||
|
|
||||||
|
|
||||||
|
public BluetoothLeDeviceStore() {
|
||||||
|
mDeviceMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDevice(final BluetoothLeDevice device) {
|
||||||
|
if (mDeviceMap.containsKey(device.getAddress())) {
|
||||||
|
mDeviceMap.get(device.getAddress()).updateRssiReading(device.getTimestamp(), device.getRssi());
|
||||||
|
} else {
|
||||||
|
mDeviceMap.put(device.getAddress(), device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
mDeviceMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyObjectCursor<BluetoothLeDevice> getDeviceCursor() {
|
||||||
|
return new EasyObjectCursor<>(
|
||||||
|
BluetoothLeDevice.class,
|
||||||
|
getDeviceList(),
|
||||||
|
"address");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BluetoothLeDevice> getDeviceList() {
|
||||||
|
final List<BluetoothLeDevice> methodResult = new ArrayList<>(mDeviceMap.values());
|
||||||
|
|
||||||
|
Collections.sort(methodResult, new Comparator<BluetoothLeDevice>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(final BluetoothLeDevice arg0, final BluetoothLeDevice arg1) {
|
||||||
|
return arg0.getAddress().compareToIgnoreCase(arg1.getAddress());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return methodResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getListAsCsv() {
|
||||||
|
final List<BluetoothLeDevice> list = getDeviceList();
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(CsvWriterHelper.addStuff("mac"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("name"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("firstTimestamp"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("firstRssi"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("currentTimestamp"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("currentRssi"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("adRecord"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("iBeacon"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("uuid"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("major"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("minor"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("txPower"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("distance"));
|
||||||
|
sb.append(CsvWriterHelper.addStuff("accuracy"));
|
||||||
|
sb.append('\n');
|
||||||
|
|
||||||
|
for (final BluetoothLeDevice device : list) {
|
||||||
|
sb.append(CsvWriterHelper.addStuff(device.getAddress()));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(device.getName()));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getFirstTimestamp())));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(device.getFirstRssi()));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(TimeFormatter.getIsoDateTime(device.getTimestamp())));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(device.getRssi()));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(ByteUtils.byteArrayToHexString(device.getScanRecord())));
|
||||||
|
final boolean isIBeacon = BeaconUtils.getBeaconType(device) == BeaconType.IBEACON;
|
||||||
|
final String uuid;
|
||||||
|
final String minor;
|
||||||
|
final String major;
|
||||||
|
final String txPower;
|
||||||
|
final String distance;
|
||||||
|
final String accuracy;
|
||||||
|
|
||||||
|
if (isIBeacon) {
|
||||||
|
final IBeaconDevice beacon = new IBeaconDevice(device);
|
||||||
|
uuid = String.valueOf(beacon.getUUID());
|
||||||
|
minor = String.valueOf(beacon.getMinor());
|
||||||
|
major = String.valueOf(beacon.getMajor());
|
||||||
|
txPower = String.valueOf(beacon.getCalibratedTxPower());
|
||||||
|
distance = beacon.getDistanceDescriptor().toString().toLowerCase(Locale.US);
|
||||||
|
accuracy = String.valueOf(beacon.getAccuracy());
|
||||||
|
} else {
|
||||||
|
uuid = "";
|
||||||
|
minor = "";
|
||||||
|
major = "";
|
||||||
|
txPower = "";
|
||||||
|
distance = "";
|
||||||
|
accuracy = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(CsvWriterHelper.addStuff(isIBeacon));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(uuid));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(minor));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(major));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(txPower));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(distance));
|
||||||
|
sb.append(CsvWriterHelper.addStuff(accuracy));
|
||||||
|
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shareDataAsEmail(final Context context) {
|
||||||
|
final long timeInMillis = System.currentTimeMillis();
|
||||||
|
|
||||||
|
final String to = null;
|
||||||
|
final String subject = "";
|
||||||
|
|
||||||
|
final String message = "";
|
||||||
|
|
||||||
|
final Intent i = new Intent(Intent.ACTION_SEND);
|
||||||
|
i.setType("plain/text");
|
||||||
|
try {
|
||||||
|
final File outputDir = context.getCacheDir();
|
||||||
|
final File outputFile = File.createTempFile("bluetooth_le_" + timeInMillis, ".csv", outputDir);
|
||||||
|
outputFile.setReadable(true, false);
|
||||||
|
generateFile(outputFile, getListAsCsv());
|
||||||
|
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(outputFile));
|
||||||
|
i.putExtra(Intent.EXTRA_EMAIL, new String[]{to});
|
||||||
|
i.putExtra(Intent.EXTRA_SUBJECT, subject);
|
||||||
|
i.putExtra(Intent.EXTRA_TEXT, message);
|
||||||
|
context.startActivity(Intent.createChooser(i, "Email Subject"));
|
||||||
|
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileWriter generateFile(final File file, final String contents) {
|
||||||
|
FileWriter writer = null;
|
||||||
|
try {
|
||||||
|
writer = new FileWriter(file);
|
||||||
|
writer.append(contents);
|
||||||
|
writer.flush();
|
||||||
|
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
writer.close();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class BluetoothLeScanner {
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final BluetoothAdapter.LeScanCallback mLeScanCallback;
|
||||||
|
private final BluetoothUtils mBluetoothUtils;
|
||||||
|
private boolean mScanning;
|
||||||
|
|
||||||
|
public BluetoothLeScanner(final BluetoothAdapter.LeScanCallback leScanCallback, final BluetoothUtils bluetoothUtils) {
|
||||||
|
mHandler = new Handler();
|
||||||
|
mLeScanCallback = leScanCallback;
|
||||||
|
mBluetoothUtils = bluetoothUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScanning() {
|
||||||
|
return mScanning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scanLeDevice(final int duration, final boolean enable) {
|
||||||
|
if (enable) {
|
||||||
|
if (mScanning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.d("TAG", "~ Starting Scan");
|
||||||
|
// Stops scanning after a pre-defined scan period.
|
||||||
|
if (duration > 0) {
|
||||||
|
mHandler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Log.d("TAG", "~ Stopping Scan (timeout)");
|
||||||
|
mScanning = false;
|
||||||
|
mBluetoothUtils.getBluetoothAdapter().stopLeScan(mLeScanCallback);
|
||||||
|
}
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
mScanning = true;
|
||||||
|
mBluetoothUtils.getBluetoothAdapter().startLeScan(mLeScanCallback);
|
||||||
|
} else {
|
||||||
|
Log.d("TAG", "~ Stopping Scan");
|
||||||
|
mScanning = false;
|
||||||
|
mBluetoothUtils.getBluetoothAdapter().stopLeScan(mLeScanCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
|
public final class BluetoothUtils {
|
||||||
|
public final static int REQUEST_ENABLE_BT = 2001;
|
||||||
|
private final Activity mActivity;
|
||||||
|
private final BluetoothAdapter mBluetoothAdapter;
|
||||||
|
|
||||||
|
public BluetoothUtils(final Activity activity) {
|
||||||
|
mActivity = activity;
|
||||||
|
final BluetoothManager btManager = (BluetoothManager) mActivity.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||||
|
mBluetoothAdapter = btManager.getAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void askUserToEnableBluetoothIfNeeded() {
|
||||||
|
if (isBluetoothLeSupported() && (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())) {
|
||||||
|
final Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||||
|
mActivity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BluetoothAdapter getBluetoothAdapter() {
|
||||||
|
return mBluetoothAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBluetoothLeSupported() {
|
||||||
|
return mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBluetoothOn() {
|
||||||
|
if (mBluetoothAdapter == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return mBluetoothAdapter.isEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
public class CsvWriterHelper {
|
||||||
|
private static final String QUOTE = "\"";
|
||||||
|
|
||||||
|
public static String addStuff(final Integer text) {
|
||||||
|
return QUOTE + text + QUOTE + ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String addStuff(final Long text) {
|
||||||
|
return QUOTE + text + QUOTE + ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String addStuff(final boolean value) {
|
||||||
|
return QUOTE + value + QUOTE + ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String addStuff(String text) {
|
||||||
|
if (text == null) {
|
||||||
|
text = "<blank>";
|
||||||
|
}
|
||||||
|
text = text.replace(QUOTE, "'");
|
||||||
|
|
||||||
|
return QUOTE + text.trim() + QUOTE + ",";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.support.v4.widget.SimpleCursorAdapter;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
|
||||||
|
import uk.co.alt236.bluetoothlelib.device.beacon.ibeacon.IBeaconDevice;
|
||||||
|
import uk.co.alt236.easycursor.objectcursor.EasyObjectCursor;
|
||||||
|
|
||||||
|
public class LeDeviceListAdapter extends SimpleCursorAdapter {
|
||||||
|
private final LayoutInflater mInflator;
|
||||||
|
private final Activity mActivity;
|
||||||
|
|
||||||
|
public static final DecimalFormat DOUBLE_TWO_DIGIT_ACCURACY = new DecimalFormat("#.##");
|
||||||
|
public static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
public LeDeviceListAdapter(final Activity activity, final EasyObjectCursor<BluetoothLeDevice> cursor) {
|
||||||
|
super(activity, R.layout.list_item_device, cursor, new String[0], new int[0], 0);
|
||||||
|
mInflator = activity.getLayoutInflater();
|
||||||
|
mActivity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public EasyObjectCursor<BluetoothLeDevice> getCursor() {
|
||||||
|
return ((EasyObjectCursor<BluetoothLeDevice>) super.getCursor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BluetoothLeDevice getItem(final int i) {
|
||||||
|
return getCursor().getItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(final int i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(final int i, View view, final ViewGroup viewGroup) {
|
||||||
|
final ViewHolder viewHolder;
|
||||||
|
// General ListView optimization code.
|
||||||
|
if (view == null) {
|
||||||
|
view = mInflator.inflate(R.layout.list_item_device, null);
|
||||||
|
viewHolder = new ViewHolder();
|
||||||
|
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
|
||||||
|
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
|
||||||
|
viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
|
||||||
|
viewHolder.deviceIcon = (ImageView) view.findViewById(R.id.device_icon);
|
||||||
|
viewHolder.deviceLastUpdated = (TextView) view.findViewById(R.id.device_last_update);
|
||||||
|
viewHolder.ibeaconMajor = (TextView) view.findViewById(R.id.ibeacon_major);
|
||||||
|
viewHolder.ibeaconMinor = (TextView) view.findViewById(R.id.ibeacon_minor);
|
||||||
|
viewHolder.ibeaconDistance = (TextView) view.findViewById(R.id.ibeacon_distance);
|
||||||
|
viewHolder.ibeaconUUID = (TextView) view.findViewById(R.id.ibeacon_uuid);
|
||||||
|
viewHolder.ibeaconTxPower = (TextView) view.findViewById(R.id.ibeacon_tx_power);
|
||||||
|
viewHolder.ibeaconSection = view.findViewById(R.id.ibeacon_section);
|
||||||
|
viewHolder.ibeaconDistanceDescriptor = (TextView) view.findViewById(R.id.ibeacon_distance_descriptor);
|
||||||
|
view.setTag(viewHolder);
|
||||||
|
} else {
|
||||||
|
viewHolder = (ViewHolder) view.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
final BluetoothLeDevice device = getCursor().getItem(i);
|
||||||
|
final String deviceName = device.getName();
|
||||||
|
|
||||||
|
final double rssi = device.getRssi();
|
||||||
|
|
||||||
|
if (deviceName != null && deviceName.length() > 0) {
|
||||||
|
viewHolder.deviceName.setText(deviceName + " (" + BeaconMonitoringActivity.itemMap.get(device.getAddress()) + ")");
|
||||||
|
} else {
|
||||||
|
viewHolder.deviceName.setText(R.string.unknown_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (BeaconUtils.getBeaconType(device) == BeaconType.IBEACON) {
|
||||||
|
final IBeaconDevice iBeacon = new IBeaconDevice(device);
|
||||||
|
final String accuracy = DOUBLE_TWO_DIGIT_ACCURACY.format(iBeacon.getAccuracy());
|
||||||
|
|
||||||
|
viewHolder.deviceIcon.setImageResource(R.drawable.beacon);
|
||||||
|
viewHolder.ibeaconSection.setVisibility(View.VISIBLE);
|
||||||
|
viewHolder.ibeaconMajor.setText(String.valueOf(iBeacon.getMajor()));
|
||||||
|
viewHolder.ibeaconMinor.setText(String.valueOf(iBeacon.getMinor()));
|
||||||
|
viewHolder.ibeaconTxPower.setText(String.valueOf(iBeacon.getCalibratedTxPower()));
|
||||||
|
viewHolder.ibeaconUUID.setText(iBeacon.getUUID());
|
||||||
|
viewHolder.ibeaconDistance.setText(
|
||||||
|
mActivity.getString(R.string.formatter_meters, accuracy));
|
||||||
|
viewHolder.ibeaconDistanceDescriptor.setText(iBeacon.getDistanceDescriptor().toString());
|
||||||
|
} else {
|
||||||
|
if(device.getRssi() > BeaconMonitoringActivity.MINIMUM_DISTANCE){
|
||||||
|
viewHolder.deviceIcon.setImageResource(R.drawable.beacon_red);
|
||||||
|
}else{
|
||||||
|
viewHolder.deviceIcon.setImageResource(R.drawable.beacon);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewHolder.ibeaconSection.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final String rssiString =
|
||||||
|
mActivity.getString(R.string.formatter_db, String.valueOf(rssi));
|
||||||
|
final String runningAverageRssiString =
|
||||||
|
mActivity.getString(R.string.formatter_db, String.valueOf(device.getRunningAverageRssi()));
|
||||||
|
|
||||||
|
viewHolder.deviceLastUpdated.setText(
|
||||||
|
android.text.format.DateFormat.format(
|
||||||
|
TIME_FORMAT, new java.util.Date(device.getTimestamp())));
|
||||||
|
viewHolder.deviceAddress.setText(device.getAddress());
|
||||||
|
viewHolder.deviceRssi.setText(rssiString + " / " + runningAverageRssiString);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ViewHolder {
|
||||||
|
TextView deviceName;
|
||||||
|
TextView deviceAddress;
|
||||||
|
TextView deviceRssi;
|
||||||
|
TextView ibeaconUUID;
|
||||||
|
TextView ibeaconMajor;
|
||||||
|
TextView ibeaconMinor;
|
||||||
|
TextView ibeaconTxPower;
|
||||||
|
TextView ibeaconDistance;
|
||||||
|
TextView ibeaconDistanceDescriptor;
|
||||||
|
TextView deviceLastUpdated;
|
||||||
|
View ibeaconSection;
|
||||||
|
ImageView deviceIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class TimeFormatter {
|
||||||
|
private final static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
|
||||||
|
private final static SimpleDateFormat ISO_FORMATTER = new UtcDateFormatter(ISO_FORMAT, Locale.US);
|
||||||
|
|
||||||
|
public static String getIsoDateTime(final Date date) {
|
||||||
|
return ISO_FORMATTER.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getIsoDateTime(final long millis) {
|
||||||
|
return getIsoDateTime(new Date(millis));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* ****************************************************************************
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
||||||
|
* <p/>
|
||||||
|
* GenieConnect Ltd. ("COMPANY") CONFIDENTIAL
|
||||||
|
* Unpublished Copyright (c) 2010-2013 GenieConnect Ltd., All Rights Reserved.
|
||||||
|
* <p/>
|
||||||
|
* NOTICE:
|
||||||
|
* All information contained herein is, and remains the property of COMPANY.
|
||||||
|
* The intellectual and technical concepts contained herein are proprietary to
|
||||||
|
* COMPANY and may be covered by U.S. and Foreign Patents, patents in process, and
|
||||||
|
* are protected by trade secret or copyright law. Dissemination of this
|
||||||
|
* information or reproduction of this material is strictly forbidden unless prior
|
||||||
|
* written permission is obtained from COMPANY. Access to the source code
|
||||||
|
* contained herein is hereby forbidden to anyone except current COMPANY employees,
|
||||||
|
* managers or contractors who have executed Confidentiality and Non-disclosure
|
||||||
|
* agreements explicitly covering such access.
|
||||||
|
* <p/>
|
||||||
|
* The copyright notice above does not evidence any actual or intended publication
|
||||||
|
* or disclosure of this source code, which includes information that is
|
||||||
|
* confidential and/or proprietary, and is a trade secret, of COMPANY.
|
||||||
|
* <p/>
|
||||||
|
* ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, OR PUBLIC
|
||||||
|
* DISPLAY OF OR THROUGH USE OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN
|
||||||
|
* CONSENT OF COMPANY IS STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS
|
||||||
|
* AND INTERNATIONAL TREATIES. THE RECEIPT OR POSSESSION OF THIS SOURCE CODE
|
||||||
|
* AND/OR RELATED INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE,
|
||||||
|
* DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING
|
||||||
|
* THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
package org.wso2.carbon.iot.android.sense.bmonitor;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
|
import java.text.DateFormatSymbols;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
public class UtcDateFormatter extends java.text.SimpleDateFormat {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String TIME_ZONE_STRING = "UTC";
|
||||||
|
private static final TimeZone TIME_ZONE_UTC = TimeZone.getTimeZone(TIME_ZONE_STRING);
|
||||||
|
|
||||||
|
@SuppressLint("SimpleDateFormat")
|
||||||
|
public UtcDateFormatter(final String template) {
|
||||||
|
super(template);
|
||||||
|
super.setTimeZone(TIME_ZONE_UTC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SimpleDateFormat")
|
||||||
|
public UtcDateFormatter(final String template, final DateFormatSymbols symbols) {
|
||||||
|
super(template, symbols);
|
||||||
|
super.setTimeZone(TIME_ZONE_UTC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UtcDateFormatter(final String template, final Locale locale) {
|
||||||
|
super(template, locale);
|
||||||
|
super.setTimeZone(TIME_ZONE_UTC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function will throw an UnsupportedOperationException.
|
||||||
|
* You are not be able to change the TimeZone of this object
|
||||||
|
*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.text.DateFormat#setTimeZone(java.util.TimeZone)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setTimeZone(final TimeZone timezone) {
|
||||||
|
throw new UnsupportedOperationException("This SimpleDateFormat can only be in " + TIME_ZONE_STRING);
|
||||||
|
}
|
||||||
|
}
|
@ -1,55 +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.siddhi.dto;
|
|
||||||
|
|
||||||
public class BLE {
|
|
||||||
int id;
|
|
||||||
long timeStamp;
|
|
||||||
String location;
|
|
||||||
|
|
||||||
public BLE(int id, String location){
|
|
||||||
this.id = id;
|
|
||||||
this.location = location;
|
|
||||||
timeStamp = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeStamp() {
|
|
||||||
return timeStamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimeStamp(long timeStamp) {
|
|
||||||
this.timeStamp = timeStamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(String location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,136 +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.siddhi.eventprocessor.core;
|
|
||||||
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.dto.BLE;
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.eventprocessor.wrapper.SidhdhiWrapper;
|
|
||||||
import org.wso2.siddhi.core.SiddhiManager;
|
|
||||||
import org.wso2.siddhi.core.event.Event;
|
|
||||||
import org.wso2.siddhi.core.stream.input.InputHandler;
|
|
||||||
import org.wso2.siddhi.core.ExecutionPlanRuntime;
|
|
||||||
import org.wso2.siddhi.core.stream.output.StreamCallback;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
|
|
||||||
|
|
||||||
public class SidhdhiQueryExecutor implements Runnable {
|
|
||||||
|
|
||||||
protected String query = null;
|
|
||||||
private static SiddhiManager siddhiManager = new SiddhiManager();
|
|
||||||
private static final int INTERVAL = 3000;
|
|
||||||
|
|
||||||
public volatile Thread sidhdiThread;
|
|
||||||
private ReadWriteLock rwlock = new ReentrantReadWriteLock();
|
|
||||||
|
|
||||||
//TODO have another array initialized so that a list of callbacks can be stored, String[] callbackList
|
|
||||||
public SidhdhiQueryExecutor(String query){
|
|
||||||
this.query = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run(){
|
|
||||||
//TODO the array of callbacks needs to be passed to invoke
|
|
||||||
//TODO what is retruned should be a map of callbacks and outputs
|
|
||||||
ExecutionPlan executionPlan = new ExecutionPlan().invoke();
|
|
||||||
|
|
||||||
Thread thisThread = Thread.currentThread();
|
|
||||||
|
|
||||||
while (sidhdiThread == thisThread) {
|
|
||||||
InputHandler inputHandler = executionPlan.getInputHandler();
|
|
||||||
|
|
||||||
//Sending events to Siddhi
|
|
||||||
try {
|
|
||||||
List<BLE> bleReadings = read();
|
|
||||||
for(BLE ble : bleReadings){
|
|
||||||
System.out.println("Publishing data...");
|
|
||||||
inputHandler.send(new Object[]{ble.getId(), ble.getTimeStamp(), ble.getLocation()});
|
|
||||||
}
|
|
||||||
|
|
||||||
thisThread.sleep(INTERVAL);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BLE> read()
|
|
||||||
{
|
|
||||||
List<BLE> bleData;
|
|
||||||
rwlock.readLock().lock();
|
|
||||||
try {
|
|
||||||
//TODO Reading BLE VALUES
|
|
||||||
bleData = SidhdhiWrapper.getBleData();
|
|
||||||
} finally {
|
|
||||||
rwlock.readLock().unlock();
|
|
||||||
}
|
|
||||||
return bleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop(){
|
|
||||||
sidhdiThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(){
|
|
||||||
sidhdiThread = new Thread(this);
|
|
||||||
sidhdiThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ExecutionPlan {
|
|
||||||
|
|
||||||
private InputHandler inputHandler;
|
|
||||||
|
|
||||||
public InputHandler getInputHandler() {
|
|
||||||
return inputHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO should expect an array of callbacks
|
|
||||||
public ExecutionPlan invoke() {
|
|
||||||
|
|
||||||
//Generating runtime
|
|
||||||
ExecutionPlanRuntime runtime = siddhiManager.createExecutionPlanRuntime(query);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO logic needs to be revised so that array of callbacks are processed
|
|
||||||
runtime.addCallback("dataOut", new StreamCallback() {
|
|
||||||
@Override
|
|
||||||
public void receive(Event[] events) {
|
|
||||||
System.out.println("Location Match event initiated.");
|
|
||||||
if (events.length > 0) {
|
|
||||||
//TODO Configure Event here!
|
|
||||||
System.out.println("Firing location match event...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//Retrieving InputHandler to push events into Siddhi
|
|
||||||
inputHandler = runtime.getInputHandler("dataIn");
|
|
||||||
|
|
||||||
//Starting event processing
|
|
||||||
runtime.start();
|
|
||||||
System.out.println("Execution Plan Started!");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,59 +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.siddhi.eventprocessor.wrapper;
|
|
||||||
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.dto.BLE;
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.eventprocessor.core.SidhdhiQueryExecutor;
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.reader.BLEReader;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
public class SidhdhiWrapper {
|
|
||||||
|
|
||||||
private static List<BLE> bleData;
|
|
||||||
|
|
||||||
public static List<BLE> getBleData() {
|
|
||||||
return bleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setBleData(List<BLE> bleData) {
|
|
||||||
SidhdhiWrapper.bleData = bleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String args[]){
|
|
||||||
String query = "@Import('iot.sample.input:1.0.0')\n" +
|
|
||||||
"define stream dataIn (id int, timestamp long, location string);\n" +
|
|
||||||
"\n" +
|
|
||||||
"@Export('iot.sample.output:1.0.0')\n" +
|
|
||||||
"define stream dataOut (action string, timestamp long);\n" +
|
|
||||||
"\n" +
|
|
||||||
"from every e1=dataIn[location=='loc_1'] -> e2=dataIn[location=='loc_2'] -> e3=dataIn[location=='loc_3']\n" +
|
|
||||||
"select 'x' as action, e3.timestamp\n" +
|
|
||||||
"insert into dataOut;";
|
|
||||||
|
|
||||||
BLEReader blEReader = new BLEReader();
|
|
||||||
blEReader.start();
|
|
||||||
|
|
||||||
SidhdhiQueryExecutor queryExecutor = new SidhdhiQueryExecutor(query);
|
|
||||||
queryExecutor.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,71 +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.siddhi.reader;
|
|
||||||
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.dto.BLE;
|
|
||||||
import org.wso2.carbon.iot.android.sense.siddhi.eventprocessor.wrapper.SidhdhiWrapper;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
|
|
||||||
public class BLEReader implements Runnable{
|
|
||||||
|
|
||||||
private ReadWriteLock rwlock = new ReentrantReadWriteLock();
|
|
||||||
List<BLE> bleData = new ArrayList<BLE>();
|
|
||||||
public volatile Thread bleReader;
|
|
||||||
private static final int INTERVAL = 2000;
|
|
||||||
|
|
||||||
public void run(){
|
|
||||||
Thread thisThread = Thread.currentThread();
|
|
||||||
while (bleReader == thisThread) {
|
|
||||||
write();
|
|
||||||
try {
|
|
||||||
thisThread.sleep(INTERVAL);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop(){
|
|
||||||
bleReader = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(){
|
|
||||||
bleReader = new Thread(this);
|
|
||||||
bleReader.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write()
|
|
||||||
{
|
|
||||||
rwlock.writeLock().lock();
|
|
||||||
try {
|
|
||||||
bleData.add(new BLE(123, "loc_1"));
|
|
||||||
bleData.add(new BLE(123, "loc_2"));
|
|
||||||
bleData.add(new BLE(123, "loc_3"));
|
|
||||||
SidhdhiWrapper.setBleData(bleData);
|
|
||||||
} finally {
|
|
||||||
rwlock.writeLock().unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
After Width: | Height: | Size: 19 KiB |
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/listContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/empty"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical|center_horizontal"
|
||||||
|
android:text="@string/no_data"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,203 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2013 The Android Open Source Project
|
||||||
|
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="top"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/device_icon"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:src="@drawable/beacon"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="24sp"/>
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:columnCount="2">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_mac"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_address"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:typeface="monospace"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_updated"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_last_update"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_rssi"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/device_rssi"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
</GridLayout>
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:id="@+id/ibeacon_section"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:columnCount="4">
|
||||||
|
|
||||||
|
<!-- ROW 1 -->
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_uuid"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ibeacon_uuid"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_columnSpan="3"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<!-- ROW 2 -->
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_major"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ibeacon_major"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_minor"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ibeacon_minor"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<!-- ROW 3 -->
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_tx_power"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ibeacon_tx_power"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_distance"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ibeacon_distance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
|
<!-- ROW 4 -->
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:text="@string/label_decriptor"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ibeacon_distance_descriptor"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_columnSpan="3"
|
||||||
|
android:paddingRight="5dp"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
</GridLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
Reference in new issue