Skip to content

Instantly share code, notes, and snippets.

@domadev812
Forked from shyampurk/pubnubheartrate-algo
Last active November 15, 2017 21:05
Show Gist options
  • Select an option

  • Save domadev812/3272e78ad0cd779aade1cf19d04a5c8b to your computer and use it in GitHub Desktop.

Select an option

Save domadev812/3272e78ad0cd779aade1cf19d04a5c8b to your computer and use it in GitHub Desktop.
Heartrate monitoring using PubNub
private static PreviewCallback previewCallback = new PreviewCallback() {
/**
* {@inheritDoc}
*/
@Override
public void onPreviewFrame(byte[] data, Camera cam) {
if (data == null) throw new NullPointerException();
Camera.Size size = cam.getParameters().getPreviewSize();
if (size == null) throw new NullPointerException();
if (!processing.compareAndSet(false, true)) return;
int width = size.width;
int height = size.height;
int imgAvg = ImageProcessing.decodeYUV420SPtoRedAvg(data.clone(), height, width);
// Log.i(TAG, "imgAvg="+imgAvg);
if (imgAvg == 0 || imgAvg == 255) {
processing.set(false);
return;
}
int averageArrayAvg = 0;
int averageArrayCnt = 0;
for (int i = 0; i < averageArray.length; i++) {
if (averageArray[i] > 0) {
averageArrayAvg += averageArray[i];
averageArrayCnt++;
}
}
int rollingAverage = (averageArrayCnt > 0) ? (averageArrayAvg / averageArrayCnt) : 0;
TYPE newType = currentType;
if (imgAvg < rollingAverage) {
newType = TYPE.RED;
if (newType != currentType) {
beats++;
// Log.d(TAG, "BEAT!! beats="+beats);
}
} else if (imgAvg > rollingAverage) {
newType = TYPE.GREEN;
}
if (averageIndex == averageArraySize) averageIndex = 0;
averageArray[averageIndex] = imgAvg;
averageIndex++;
// Transitioned from one state to another to the same
if (newType != currentType) {
currentType = newType;
image.postInvalidate();
}
long endTime = System.currentTimeMillis();
double totalTimeInSecs = (endTime - startTime) / 1000d;
if (totalTimeInSecs >= 10) {
double bps = (beats / totalTimeInSecs);
int dpm = (int) (bps * 60d);
if (dpm < 30 || dpm > 180) {
startTime = System.currentTimeMillis();
beats = 0;
processing.set(false);
return;
}
// Log.d(TAG,
// "totalTimeInSecs="+totalTimeInSecs+" beats="+beats);
if (beatsIndex == beatsArraySize) beatsIndex = 0;
beatsArray[beatsIndex] = dpm;
beatsIndex++;
int beatsArrayAvg = 0;
int beatsArrayCnt = 0;
for (int i = 0; i < beatsArray.length; i++) {
if (beatsArray[i] > 0) {
beatsArrayAvg += beatsArray[i];
beatsArrayCnt++;
}
}
int beatsAvg = (beatsArrayAvg / beatsArrayCnt);
text.setText(String.valueOf(beatsAvg));
beatsPerMinuteValue=String.valueOf(beatsAvg);
makePhoneVibrate();
dispatchPubNubEvent(String.valueOf(beatsAvg));
showReadingCompleteDialog();
startTime = System.currentTimeMillis();
beats = 0;
}
processing.set(false);
}
};
private void saveDoctorId(){
mSharedPreferences
.edit()
.putString("doc_id", mEdtxtDoctorId.getText().toString())
.commit();
}
function getChannelHistory(){
PUBNUB_demo.history()
.channel(DOCTOR_ID+'heartbeat_alert') // where to fetch history from
.count(100) // how many items to fetch
.async(new PNCallback<PNHistoryResult>() {
@Override
public void onResponse(PNHistoryResult result, PNStatus status) {
}
});
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
v = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
parentReference=this;
strSavedDoctorID= HeartRateMonitor.this.getSharedPreferences("app_prefs", MODE_PRIVATE)
.getString("doc_id", "---");
preview = (SurfaceView) findViewById(R.id.preview);
previewHolder = preview.getHolder();
mTxtVwStopWatch=(TextView)findViewById(R.id.txtvwStopWatch);
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
image = findViewById(R.id.image);
text = (TextView) findViewById(R.id.text);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey(PUBNUB_SUBSCRIBE_KEY);
pnConfiguration.setPublishKey(PUBNUB_PUBLISH_KEY);
PubNub pubnub = new PubNub(pnConfiguration);
prepareCountDownTimer();
configurePubNubClient();
pubnubSubscribe();
}
private void pubnubSubscribe(){
pubnub.addListener(new SubscribeCallback() {
@Override
public void status(PubNub pubnub, PNStatus status) {
switch (status.getOperation()) {
// let's combine unsubscribe and subscribe handling for ease of use
case PNSubscribeOperation:
case PNUnsubscribeOperation:
// note: subscribe statuses never have traditional
// errors, they just have categories to represent the
// different issues or successes that occur as part of subscribe
switch (status.getCategory()) {
case PNConnectedCategory:
// this is expected for a subscribe, this means there is no error or issue whatsoever
case PNReconnectedCategory:
// this usually occurs if subscribe temporarily fails but reconnects. This means
// there was an error but there is no longer any issue
case PNDisconnectedCategory:
// this is the expected category for an unsubscribe. This means there
// was no error in unsubscribing from everything
case PNUnexpectedDisconnectCategory:
// this is usually an issue with the internet connection, this is an error, handle appropriately
case PNAccessDeniedCategory:
// this means that PAM does allow this client to subscribe to this
// channel and channel group configuration. This is another explicit error
default:
// More errors can be directly specified by creating explicit cases for other
// error categories of `PNStatusCategory` such as `PNTimeoutCategory` or `PNMalformedFilterExpressionCategory` or `PNDecryptionErrorCategory`
}
case PNHeartbeatOperation:
// heartbeat operations can in fact have errors, so it is important to check first for an error.
// For more information on how to configure heartbeat notifications through the status
// PNObjectEventListener callback, consult <link to the PNCONFIGURATION heartbeart config>
if (status.isError()) {
// There was an error with the heartbeat operation, handle here
} else {
// heartbeat operation was successful
}
default: {
// Encountered unknown status type
}
}
}
@Override
public void message(PubNub pubnub, PNMessageResult message) {
}
@Override
public void presence(PubNub pubnub, PNPresenceEventResult presence) {
}
});
}
private static void pubnubPublish(String message){
pubnub.publish().channel(strSavedDoctorID+"heartbeat_alert").message( "Heart beat alert at :: "+message+" for Test User @ "+date).async(new PNCallback<PNPublishResult>() {
@Override
public void onResponse(PNPublishResult result, PNStatus status) {
// Check whether request successfully completed or not.
if (!status.isError()) {
// Message successfully published to specified channel.
}
// Request processing failed.
else {
// Handle message publish error. Check 'category' property to find out possible issue
// because of which request did fail.
//
// Request can be resent using: [status retry];
}
}
});
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSharedPreferences= MainActivity.this.getSharedPreferences("app_prefs", MODE_PRIVATE);
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("demo");
pnConfiguration.setPublishKey("demo");
PubNub pubnub = new PubNub(pnConfiguration);
setContentView(R.layout.activity_main);
initializeLayout();
configurePubNubClient();
pubnubSubscribe();
}
function getDoctorId(){
var doctorId = document.getElementById("doctorID").value;
DOCTOR_ID=doctorId;
if(doctorId){
$("#historyAnchor").removeClass("disabled");
$("#clearHistoryAnchor").removeClass("disabled");
PUBNUB_demo.subscribe().channels(doctorId+'heartbeat_alert').message(function(message){
console.log(message);
console.log(new Date());
DOCTOR_ID=doctorId;
var payload= "<h3>"+'<br>'+message+"</h3>";
document.getElementById("latestNotificationDiv").innerHTML = payload;
ALERT_COUNT++;
document.getElementById("alertCountbOX").innerHTML ="<h3>CRITICAL-TRIGGERS:: " +ALERT_COUNT+"</h3>";
});
}else{
alert("please enter doctor id");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment