Skip to content

Instantly share code, notes, and snippets.

@lbrenman
Last active January 18, 2017 13:46
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save lbrenman/474ec7f013380ba24dbd to your computer and use it in GitHub Desktop.
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
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)));
}
});
};
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();
}
});
<Alloy>
<Window class="container" layout="vertical">
<Label id="deviceStatusLBL" top="50"/>
<Button id="toggleBTN" width="40%" top="50" onClick="toggleButtonClicked"/>
</Window>
</Alloy>
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();
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)));
}
});
};
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