Last active
January 18, 2017 13:46
-
-
Save lbrenman/474ec7f013380ba24dbd to your computer and use it in GitHub Desktop.
Appcelerator Titanium, Appcelerator mBaaS, Raspberry Pi - Full Stack JavaScript iOT Example to use mobile app to control RPi through mBaaS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Cloud = require('ti.cloud'); | |
exports.ACSLogin = function(u,p,o){ | |
Ti.API.debug("ACS: ACSLogin()"); | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
alert("No Network. Please try again later."); | |
if (o.error) { o.error("ACSLogin(): No Network"); }; | |
return; | |
} | |
Ti.API.debug("ACS: ACSLogin - Logging in to ACS with username = "+u+", password = "+p); | |
Cloud.Users.login({ | |
login : u, | |
password: p, | |
}, function(e) { | |
if (e.success) { | |
Ti.API.debug("ACS: ACSLogin - Log in to ACS successful"); | |
Ti.API.debug("ACS: ACSLogin - Session ID = "+Cloud.sessionId); | |
var user = e.users[0]; | |
// uid = user.id; | |
Alloy.Globals.user_id = Alloy.Globals.user_id; | |
// sessionid = Cloud.sessionId; | |
if (o.success) { o.success(e); }; | |
} else { | |
Ti.API.debug('ACS: ACSLogin - Login Error:' +((e.error && e.message) || JSON.stringify(e))); | |
// alert("Unable to login"); | |
if (o.error) { o.error(e); }; | |
} | |
}); | |
}; | |
exports.ACSResetPushBadgeCount = function(deviceToken){ | |
Ti.API.debug("ACS: ACSResetPushBadgeCount()"); | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
Ti.API.debug("ACS: ACSResetPushBadgeCount(): No Network"); | |
return; | |
} | |
if ((Titanium.Platform.model === 'Simulator')&&((Titanium.Platform.osname === 'iphone')||(Titanium.Platform.osname === 'ipad'))) { | |
Ti.API.debug("ACS: ACSResetPushBadgeCount(): cannot reset badges on iOS simulator"); | |
return; | |
} | |
if(!deviceToken) { | |
Ti.API.debug("ACS: ACSResetPushBadgeCount(): Device Token is null!!!"); | |
return; | |
} | |
Cloud.PushNotifications.resetBadge({ | |
device_token: deviceToken.value | |
}, function (e) { | |
if (e.success) { | |
Ti.API.debug("ACS: ACSResetPushBadgeCount(): Badge Reset success"); | |
Ti.API.debug(e); | |
} else { | |
Ti.API.debug("ACS: ACSResetPushBadgeCount(): Badge Reset, e: " +((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var push = require('push'); | |
var acs = require('ACS'); | |
var buttonIsOn = false; | |
function getState(o) { | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
Ti.API.debug("No Network"); | |
if (o.error) { o.error("No Network"); }; | |
return; | |
} | |
var xhr = Ti.Network.createHTTPClient({ | |
onload: function(e) { | |
Ti.API.debug(this.responseText); | |
var response = JSON.parse(this.responseText); | |
Ti.API.debug(response.value); | |
if (o.success) { o.success(response); } | |
}, | |
onerror: function(e) { | |
Ti.API.debug("httpclient error = "+e.error); | |
if (o.error) { o.error(e.error); } | |
}, | |
timeout:10000 | |
}); | |
xhr.open("GET", "https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/getVal"); | |
xhr.send(); | |
} | |
function getHeartBeat(o) { | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
Ti.API.debug("No Network"); | |
if (o.error) { o.error("No Network"); }; | |
return; | |
} | |
var xhr = Ti.Network.createHTTPClient({ | |
onload: function(e) { | |
Ti.API.debug(this.responseText); | |
var response = JSON.parse(this.responseText); | |
Ti.API.debug(response.heartbeat); | |
if (o.success) { o.success(response); } | |
}, | |
onerror: function(e) { | |
Ti.API.debug("httpclient error = "+e.error); | |
if (o.error) { o.error(e.error); } | |
}, | |
timeout:10000 | |
}); | |
xhr.open("GET", "https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/getHeartBeat"); | |
xhr.send(); | |
} | |
function turnOn(o) { | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
Ti.API.debug("No Network"); | |
if (o.error) { o.error("No Network"); }; | |
return; | |
} | |
var xhr = Ti.Network.createHTTPClient({ | |
onload: function(e) { | |
Ti.API.debug(this.responseText); | |
var response = JSON.parse(this.responseText); | |
Ti.API.debug(response.value); | |
if (o.success) { o.success(response); } | |
}, | |
onerror: function(e) { | |
Ti.API.debug("httpclient error = "+e.error); | |
if (o.error) { o.error(e.error); } | |
}, | |
timeout:10000 | |
}); | |
xhr.open("GET", "https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/setValOn"); | |
xhr.send(); | |
} | |
function turnOff(o) { | |
if(Titanium.Network.networkType == Titanium.Network.NETWORK_NONE){ | |
Ti.API.debug("No Network"); | |
if (o.error) { o.error("No Network"); }; | |
return; | |
} | |
var xhr = Ti.Network.createHTTPClient({ | |
onload: function(e) { | |
Ti.API.debug(this.responseText); | |
var response = JSON.parse(this.responseText); | |
Ti.API.debug(response.value); | |
if (o.success) { o.success(response); } | |
}, | |
onerror: function(e) { | |
Ti.API.debug("httpclient error = "+e.error); | |
if (o.error) { o.error(e.error); } | |
}, | |
timeout:10000 | |
}); | |
xhr.open("GET", "https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/setValOff"); | |
xhr.send(); | |
} | |
function toggleButtonClicked() { | |
if(buttonIsOn) { | |
turnOff({ | |
success: function(e){ | |
$.toggleBTN.title = "Turn On"; | |
buttonIsOn = false; | |
}, | |
error: function(e){ | |
alert("Cannot turn off, please try again"); | |
} | |
}); | |
} else { | |
turnOn({ | |
success: function(e){ | |
$.toggleBTN.title = "Turn off"; | |
buttonIsOn = true; | |
}, | |
error: function(e){ | |
alert("Cannot turn on, please try again"); | |
} | |
}); | |
} | |
} | |
$.index.open(); | |
Ti.API.debug("index.open()"); | |
Ti.API.debug("buttonIsOn is "+buttonIsOn); | |
getState({ | |
success: function(e){ | |
Ti.API.debug("getState success, e= "+e); | |
if(e.value==0) { | |
$.toggleBTN.title = "Turn On"; | |
buttonIsOn = false; | |
Ti.API.debug("buttonIsOn is "+buttonIsOn); | |
} else { | |
$.toggleBTN.title = "Turn Off"; | |
buttonIsOn = true; | |
Ti.API.debug("buttonIsOn is "+buttonIsOn); | |
} | |
}, | |
error: function(e){ | |
alert("error"); | |
} | |
}); | |
function callGetHeartBeat() { | |
getHeartBeat({ | |
success: function(e){ | |
Ti.API.debug("getHeartBeat success, e= "+e); | |
if(e.heartbeat) { | |
$.deviceStatusLBL.text = "Device is connected"; | |
$.toggleBTN.enabled=true; | |
} else { | |
$.deviceStatusLBL.text = "Device is disconnected"; | |
$.toggleBTN.enabled=false; | |
} | |
}, | |
error: function(e){ | |
alert("error"); | |
} | |
}); | |
} | |
push.getPushToken(); | |
callGetHeartBeat(); | |
setInterval(callGetHeartBeat,30000); | |
acs.ACSLogin("a", "1234",{ | |
error: function(e) { | |
// activityInidcatorHide(); | |
Ti.API.debug(e); | |
alert("Login failed; please try again"); | |
}, | |
success: function(e) { | |
// activityInidcatorHide(); | |
Ti.API.debug(e); | |
push.subscribeToChannel(); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Alloy> | |
<Window class="container" layout="vertical"> | |
<Label id="deviceStatusLBL" top="50"/> | |
<Button id="toggleBTN" width="40%" top="50" onClick="toggleButtonClicked"/> | |
</Window> | |
</Alloy> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var https = require('https'); | |
var ACS = require('acs-node'); | |
ACS.init('U0WThrb8BBh4v57RmGOQW0ypxtRZvf8U'); | |
// From acs new --framework none | |
// var http = require('http'); | |
// http.createServer(function (req, res) { | |
// res.writeHead(200, {'Content-Type': 'text/plain'}); | |
// res.end('Welcome to Node.ACS! non MVC'); | |
// }).listen(process.env.PORT || 8080); | |
// From the expressjs hello world exanple | |
var express = require('express'); | |
var app = express(); | |
var val=0; //val is set either on (1) or off (0) and represents the desired state of the LED on RPi | |
var isOn=false; //heartbeat for RPi - is it connected to the Node.ACS server | |
var heartBeatTimer=setInterval(function() { | |
console.log("heartBeat timer fired, device is not connected") | |
isOn=false | |
}, 60000); | |
var server = app.listen(8080, function () { | |
var host = server.address().address | |
var port = server.address().port | |
console.log('Example app listening at http://%s:%s', host, port) | |
}) | |
app.get('/getVal', function (req, res) { | |
var o={'value':val}; | |
res.send(o); | |
}); | |
app.get('/setValOn', function (req, res) { | |
val=1; | |
var o={'value':val}; | |
res.send(o); | |
}); | |
app.get('/setValOff', function (req, res) { | |
val=0; | |
var o={'value':val}; | |
res.send(o); | |
}); | |
app.get('/heartBeat', function (req, res) { | |
console.log("heartBeat called, device is connected, reset timer") | |
isOn=true; | |
res.send({"status":"OK"}); | |
clearInterval(heartBeatTimer); | |
heartBeatTimer=setInterval(function() { | |
console.log("heartBeat timer fired, device is not connected") | |
isOn=false | |
}, 60000); | |
}); | |
app.get('/getHeartBeat', function (req, res) { | |
var o={'heartbeat':isOn}; | |
res.send(o); | |
}); | |
app.get('/buttonClicked', function (req, res) { | |
console.log("Button clicked on RPi") | |
res.send({"status":"OK"}); | |
ACSSendPush(); | |
}); | |
function ACSLogin() { | |
var data = { | |
login: "a", | |
password: "1234" | |
}; | |
ACS.Users.login(data, function(response){ | |
if(response.success) { | |
console.log("Successful login."); | |
console.log("UserInfo: " + JSON.stringify(response.users[0], null, 2)) | |
} else { | |
console.log("Error to login: " + response.message); | |
} | |
}); | |
} | |
// function ACSSendPush(){ | |
// console.log("ACSSendPush() called"); | |
// var url='https://api.cloud.appcelerator.com/v1/push_notification/notify.json?key=U0WThrb8BBh4v57RmGOQW0ypxtRZvf8U&pretty_json=true&channel=iot&payload=RPiAlert'; | |
// var str=''; | |
// var myreq = https.get(url, function(r) { | |
// r.setEncoding('utf8'); | |
// r.on('data', function (chunk) { | |
// str += chunk; | |
// }); | |
// r.on('end', function () { | |
// // console.log("ACS Send Push success, response = "+JSON.parse(str)); | |
// }); | |
// }); | |
// myreq.end(); | |
// myreq.on('error', function(e){ | |
// console.log("ACS Send Push error, e = "+e); | |
// }); | |
// } | |
function ACSSendPush(){ | |
ACS.PushNotifications.notify({ | |
channel: 'iot', | |
payload: 'iot notification', | |
to_ids: 'everyone' | |
}, function (e) { | |
if (e.success) { | |
console.log("Successful Push"); | |
} else { | |
console.log('Error:\n' + | |
((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
} | |
ACSLogin(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Cloud = require('ti.cloud'); | |
var acs = require('ACS'); | |
var deviceToken = null; | |
exports.getPushToken = function(){ | |
Ti.API.debug('push: getPushToken()'); | |
//http://docs.appcelerator.com/titanium/latest/#!/guide/Subscribing_to_push_notifications-section-37551717_Subscribingtopushnotifications-Obtainingadevicetoken | |
if(OS_ANDROID) { | |
// Require the module | |
var CloudPush = require('ti.cloudpush'); | |
// Initialize the module | |
CloudPush.retrieveDeviceToken({ | |
success: deviceTokenSuccess, | |
error: deviceTokenError | |
}); | |
// Enable push notifications for this device | |
// Save the device token for subsequent API calls | |
function deviceTokenSuccess(e) { | |
Ti.API.debug('push: deviceTokenSuccess()'); | |
deviceToken = e.deviceToken; | |
Alloy.Globals.deviceToken = deviceToken; | |
} | |
function deviceTokenError(e) { | |
// alert('Failed to register for push notifications! ' + e.error); | |
Ti.API.debug('push: deviceTokenError()' + e.error); | |
} | |
// Process incoming push notifications | |
CloudPush.addEventListener('callback', function (evt) { | |
// alert("Notification received: " + evt.payload); | |
Ti.API.debug("push: Notification received: " + evt.payload); | |
acs.ACSResetPushBadgeCount(Alloy.Globals.deviceToken); | |
}); | |
} | |
if(OS_IOS) { | |
// Check if the device is running iOS 8 or later | |
if (Ti.Platform.name == "iPhone OS" && parseInt(Ti.Platform.version.split(".")[0]) >= 8) { | |
Ti.API.debug('push: getPushToken() - iOS8 or later detected'); | |
// Wait for user settings to be registered before registering for push notifications | |
Ti.App.iOS.addEventListener('usernotificationsettings', function registerForPush() { | |
Ti.API.debug('push: getPushToken() - usernotificationsettings callback'); | |
// Remove event listener once registered for push notifications | |
Ti.App.iOS.removeEventListener('usernotificationsettings', registerForPush); | |
Ti.Network.registerForPushNotifications({ | |
success: deviceTokenSuccess, | |
error: deviceTokenError, | |
callback: receivePush | |
}); | |
}); | |
// Register notification types to use | |
Ti.App.iOS.registerUserNotificationSettings({ | |
types: [ | |
Ti.App.iOS.USER_NOTIFICATION_TYPE_ALERT, | |
Ti.App.iOS.USER_NOTIFICATION_TYPE_SOUND, | |
Ti.App.iOS.USER_NOTIFICATION_TYPE_BADGE | |
] | |
}); | |
} | |
// For iOS 7 and earlier | |
else { | |
Ti.API.debug('push: getPushToken() - iOS7 or earlier detected'); | |
Ti.Network.registerForPushNotifications({ | |
// Specifies which notifications to receive | |
types: [ | |
Ti.Network.NOTIFICATION_TYPE_BADGE, | |
Ti.Network.NOTIFICATION_TYPE_ALERT, | |
Ti.Network.NOTIFICATION_TYPE_SOUND | |
], | |
success: deviceTokenSuccess, | |
error: deviceTokenError, | |
callback: receivePush | |
}); | |
} | |
// Process incoming push notifications | |
function receivePush(e) { | |
// alert('Received push: ' + JSON.stringify(e)); | |
Ti.API.debug('push: Received push: ' + JSON.stringify(e)); | |
acs.ACSResetPushBadgeCount(Alloy.Globals.deviceToken); | |
Ti.UI.iPhone.appBadge=null; | |
} | |
// Save the device token for subsequent API calls | |
function deviceTokenSuccess(e) { | |
Ti.API.debug('push: deviceTokenSuccess()'); | |
deviceToken = e.deviceToken; | |
Alloy.Globals.deviceToken = deviceToken; | |
} | |
function deviceTokenError(e) { | |
Ti.API.debug('push: deviceTokenError()' + e.error); | |
// alert('Failed to register for push notifications! ' + e.error); | |
} | |
} | |
}; | |
exports.subscribeToChannel = function(){ | |
Ti.API.debug("push: subscribeToChannel, deviceToken = "+deviceToken); | |
Cloud.PushNotifications.subscribe({ | |
channel: "iot", | |
device_token: deviceToken, | |
type: Ti.Platform.name == 'android' ? 'android' : 'ios' | |
}, function (e) { | |
if (e.success) { | |
// alert('Subscribed'); | |
Ti.API.debug('push: Subscribed'); | |
} else { | |
// alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e))); | |
Ti.API.debug('push: Error:\n' + ((e.error && e.message) || JSON.stringify(e))); | |
} | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var https = require('https'); | |
var Gpio = require("onoff").Gpio; | |
var led = new Gpio(7,'out'); | |
button = new Gpio(2, 'in', 'rising'); | |
var buttonTimer; | |
var btnClickCount=0; | |
led.write(1); | |
function getVal(){ | |
var url='https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/getVal'; | |
var myreq = https.get(url, function(r) { | |
r.setEncoding('utf8'); | |
r.on('data', function (chunk) { | |
var o={}, d = JSON.parse(chunk); | |
if(d.value==0) { | |
console.log("Server set OFF"); | |
led.write(1); | |
} else { | |
console.log("Server set ON"); | |
led.write(0); | |
} | |
}); | |
}); | |
myreq.end(); | |
myreq.on('error', function(e){ | |
console.log("getVal https request error = "+e); | |
}); | |
} | |
function heartBeat(){ | |
var url='https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/heartBeat'; | |
var myreq = https.get(url, function(r) { | |
// do nothing | |
}); | |
myreq.end(); | |
myreq.on('error', function(e){ | |
console.log("getVal https request error = "+e); | |
}); | |
} | |
button.watch(function (err, value) { | |
if (err) { | |
throw err; | |
} | |
btnClickCount++; | |
if(btnClickCount<=1) { | |
// console.log("Button pressed"); | |
buttonClicked(); | |
setTimeout(function () {btnClickCount=0}, 5000); | |
} | |
}); | |
function buttonClicked() { | |
console.log("Button pressed"); | |
var url='https://62255494ad0f3182e868013ebd6c8d454797fa06.cloudapp-enterprise.appcelerator.com/buttonClicked'; | |
var myreq = https.get(url, function(r) { | |
// do nothing | |
}); | |
myreq.end(); | |
myreq.on('error', function(e){ | |
console.log("getVal https request error = "+e); | |
}); | |
} | |
function exit() { | |
led.unexport(); | |
button.unexport(); | |
process.exit(); | |
} | |
process.on('SIGINT', exit); | |
setInterval(getVal, 15000); //fetch LED setting from server | |
setInterval(heartBeat, 30000); //call heartBeat to let server know RPi is connected | |
heartBeat(); | |
getVal(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment