Hardware components | ||||||
| × | 2 | ||||
| × | 1 | ||||
| × | 6 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 2 |
The surge in single-person households is a global phenomenon, and in 2020, one out of six households in the world is a single-person household.It is expected that the proportion of single-person households in 28 member countries of the European Union (EU) also ranges from 31% in 2010 to 2017 in 2017.It is showing an increasing pattern to 34% (Eurosta, 2019). (The Latest Trends of Single-person Households Related P
olicy
In U.S.A,
International Society Security Review 2019 Winter issue, Soonhee Jung) According to the academic data cited earlier, the number of single-person households is increasing not only in the United States but also around the world. In addition, the population with pets is also increasing. Therefore, this project will be planned and prototyped to encourage pet ticket culture so that people and pets can coexist and live together.
http://203.253.128.177:7579/Mobius/walwal
- motion package streaming service
- Image classification model
- Raspberrypi dog train classfier
- Raspberrypi dog train classfier_2
- Dog feed machine.
- Ultrasonic sensor dog food remaining amount of TAS app.js code.
- Ultrasonic sensor nCube conf.js code for remaining dog feed.
- Whether dogs eat food or not. TAS conf.xml code of ultrasonic sensor.
- Whether dogs eat food or not. TAS app.js code of ultrasonic sensor.
- Ultrasonic sensor dog food remaining amount of TAS conf.xml code.
- eat or not nCube conf.js code
- Whether dogs eat food or not. nCube conf.js code of ultrasonic sensor.
- GPS alarm
- nCube 'conf.js' for Training Machine
- "http_app.js" file for training machines.
- 'instruct.py' file for training machine
- 'TotalTraining.ino' code for actual device startup.
- Android MainActivity.java for Mobius App
- Android strings.xml for Mobius App
- Android activity_main.xml for Mobius App
- Android AndroidManifest.xml for Mobius App
sudo apt-get install motion
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.applications import ResNet50
import pandas as pd
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
width_shift_range=0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True
)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('C:/Users/hjhhi\OneDrive - sch.ac.kr\LectureCode\mobius\downloads',
target_size = (200, 200),
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('C:/Users\hjhhi\OneDrive - sch.ac.kr\LectureCode\mobius/test',
target_size = (200, 200),
class_mode = 'binary')
model = tf.keras.models.Sequential()
model.add(ResNet50(include_top=True, weights=None, input_shape=(200, 200, 3), classes=2))
model.summary()
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'],
)
history = model.fit_generator(training_set, epochs=100, validation_data=test_set)
model.save('model_last_1.h5')
model = tf.keras.models.load_model('model_last_1.h5')
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
### Test code before export Raspberrypi
#open("model.tflite","wb").write(tflite_model)
#last_set = test_datagen.flow_from_directory('C:/Users/hjhhi\OneDrive - sch.ac.kr\LectureCode\mobius\instance',
# target_size = (200, 200),
# batch_size = 32,
# class_mode = 'binary')
##percentage for class will printed
## sit = 0, standing = 1
#model.predict_generator(last_set)
Raspberrypi dog train classfier
PythonIt can print percentage of dog is sitting or standing.
import requests
import tensorflow as tf
import os
import sys
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
test_datagen = ImageDataGenerator(rescale = 1./255)
os.system('fswebcam ./sample/instance/image.jpg')
test_set = test_datagen.flow_from_directory('./sample',
target_size = (200, 200),
# batch_size = 32,
class_mode = 'binary')
interpreter = tf.lite.Interpreter(model_path="model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
input_image = test_set
#X_train, y_train = next(input_image)
X_train = np.asarray(input_image[0][0])
X_train.shape
interpreter.set_tensor(input_details[0]['index'], X_train)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
output = np.argmax(output_data)
return_value = output == 1
mobius_data = int(return_value)
url = 'http://203.253.128.177:7579/Mobius/walwal/success'
headers = {
'Accept':'application/json',
'X-M2M-RI':'12345',
'X-M2M-Origin':'XXXXXXXXXXX', # change to your aei
'Content-Type':'application/vnd.onem2m-res+json; ty=4'
}
data = {
"m2m:cin": {
"con": mobius_data
}
}
r = requests.post(url, headers=headers, json=data)
print("END OF SIT")
try:
r.raise_for_status()
print(r)
except Exception as exc:
print('There was a problem: %s' % (exc))
Raspberrypi dog train classfier_2
PythonIt can print percentage of dog is wating or moving.
import tensorflow as tf
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import pandas as pd
import requests
import time
import os
test_datagen = ImageDataGenerator(rescale = 1./255)
os.system('fswebcam ./sample2/instance/image_1.jpg')
time.sleep(3)
os.system('fswebcam ./sample2/instance/image_2.jpg')
test_set = test_datagen.flow_from_directory('./sample2',
target_size = (200, 200),
# batch_size = 32,
class_mode = 'binary')
input_image = test_set
X_train = np.asarray(input_image[0][0])
count=0
for i in (X_train[0]*0.9 <= X_train[1]) & (X_train[1] <= X_train[0]*1.1):
j = pd.DataFrame(i)
if (len(j[j[0].values == True])) < 150:
count = count+1
return_value = count > 100
mobius_data = int(return_value)
print("END OF WAIT")
print("END OF WAIT")
url = 'http://203.253.128.177:7579/Mobius/walwal/success'
headers = {
'Accept':'application/json',
'X-M2M-RI':'12345',
'X-M2M-Origin':'XXXXXXXXXXX', # change to your aei
'Content-Type':'application/vnd.onem2m-res+json; ty=4'
}
data = {
"m2m:cin": {
"con": mobius_data
}
}
r = requests.post(url, headers=headers, json=data)
try:
r.raise_for_status()
print(r)
except Exception as exc:
print('There was a problem: %s' % (exc))
Dog feed machine.
Pythonimport RPi.GPIO as GPIO
import time
import datetime as dt
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
SERVO_PIN = 16
GPIO.setup(SERVO_PIN, GPIO.OUT)
servo = GPIO.PWM(SERVO_PIN, 50)
servo.start(0)
try:
while True:
now = dt.datetime.now()
now_hour = now.hour
now_min = now.minute
print(now)
if( now_hour == 8 and now_min == 00)or(now_hour == 20 and now_min == 00):
servo.ChangeDutyCycle(7.5)
time.sleep(4)
servo.ChangeDutyCycle(12.5)
time.sleep(57)
print("Feeding Now!!!")
except KeyboardInterrupt:
servo.stop( )
GPIO.cleanup( )
Ultrasonic sensor dog food remaining amount of TAS app.js code.
JavaScriptvar net = require('net');
var util = require('util');
var fs = require('fs');
var xml2js = require('xml2js');
var wdt = require('./wdt');
var useparentport = '';
var useparenthostname = '';
var upload_arr = [];
var download_arr = [];
var conf = {};
// This is an async file read
fs.readFile('conf.xml', 'utf-8', function (err, data) {
if (err) {
console.log("FATAL An error occurred trying to read in the file: " + err);
console.log("error : set to default for configuration")
}
else {
var parser = new xml2js.Parser({explicitArray: false});
parser.parseString(data, function (err, result) {
if (err) {
console.log("Parsing An error occurred trying to read in the file: " + err);
console.log("error : set to default for configuration")
}
else {
var jsonString = JSON.stringify(result);
conf = JSON.parse(jsonString)['m2m:conf'];
useparenthostname = conf.tas.parenthostname;
useparentport = conf.tas.parentport;
if (conf.upload != null) {
if (conf.upload['ctname'] != null) {
upload_arr[0] = conf.upload;
}
else {
upload_arr = conf.upload;
}
}
if (conf.download != null) {
if (conf.download['ctname'] != null) {
download_arr[0] = conf.download;
}
else {
download_arr = conf.download;
}
}
}
});
}
});
var tas_state = 'init';
var upload_client = null;
var t_count = 0;
var tas_download_count = 0;
function on_receive(data) {
if (tas_state == 'connect' || tas_state == 'reconnect' || tas_state == 'upload') {
var data_arr = data.toString().split('<EOF>');
if (data_arr.length >= 2) {
for (var i = 0; i < data_arr.length - 1; i++) {
var line = data_arr[i];
var sink_str = util.format('%s', line.toString());
var sink_obj = JSON.parse(sink_str);
if (sink_obj.ctname == null || sink_obj.con == null) {
console.log('Received: data format mismatch');
}
else {
if (sink_obj.con == 'hello') {
console.log('Received: ' + line);
if (++tas_download_count >= download_arr.length) {
tas_state = 'upload';
}
}
else {
for (var j = 0; j < upload_arr.length; j++) {
if (upload_arr[j].ctname == sink_obj.ctname) {
console.log('ACK : ' + line + ' <----');
break;
}
}
for (j = 0; j < download_arr.length; j++) {
if (download_arr[j].ctname == sink_obj.ctname) {
g_down_buf = JSON.stringify({id: download_arr[i].id, con: sink_obj.con});
console.log(g_down_buf + ' <----');
break;
}
}
}
}
}
}
}
}
function tas_watchdog() {
if (tas_state == 'init') {
upload_client = new net.Socket();
upload_client.on('data', on_receive);
upload_client.on('error', function(err) {
console.log(err);
tas_state = 'reconnect';
});
upload_client.on('close', function() {
console.log('Connection closed');
upload_client.destroy();
tas_state = 'reconnect';
});
if (upload_client) {
console.log('tas init ok');
tas_state = 'init_thing';
}
}
else if (tas_state == 'init_thing') {
// init things
tas_state = 'connect';
}
else if (tas_state == 'connect' || tas_state == 'reconnect') {
upload_client.connect(useparentport, useparenthostname, function() {
console.log('upload Connected');
tas_download_count = 0;
for (var i = 0; i < download_arr.length; i++) {
console.log('download Connected - ' + download_arr[i].ctname + ' hello');
var cin = {ctname: download_arr[i].ctname, con: 'hello'};
upload_client.write(JSON.stringify(cin) + '<EOF>');
}
if (tas_download_count >= download_arr.length) {
tas_state = 'upload';
}
});
}
}
// Every 3 seconds, check if the TAS is not working
wdt.set_wdt(require('shortid').generate(), 3, tas_watchdog);
const Gpio = require('pigpio').Gpio;
// The number of microseconds it takes sound to travel 1cm at 20 degrees celcius
const MICROSECDONDS_PER_CM = 1e6/34321;
const trigger = new Gpio(20, {mode: Gpio.OUTPUT}); // GPIO20: trigger pin
const echo = new Gpio(21, {mode: Gpio.INPUT, alert: true}); // GPIO21: echo pin
const range_max = 600; // maximum range for detection
const range_min = 0; // minimum range for detection
var dist_0 = 0;
var dist_1 = 0;
var ultrasonic_update = true;
trigger.digitalWrite(0);
const watchHCSR04 = () => {
let startTick;
echo.on('alert', (level, tick) => {
if (level == 1) {
startTick = tick;
} else {
const endTick = tick;
const diff = (endTick >> 0) - (startTick >> 0); // Unsigned 32 bit arithmetic
// console.log(diff / 2 / MICROSECDONDS_PER_CM);
dist_1 = (diff / 2 / MICROSECDONDS_PER_CM).toFixed(2);
if (dist_1 >= range_max || dist_1 <= range_min)
dist_1 = -1;
}
});
};
watchHCSR04();
setInterval(() => {
trigger.trigger(10, 1);
if (ultrasonic_update) {
if (tas_state=='upload') {
for(var i = 0; i < upload_arr.length; i++) {
Percent = Math.round(100-(dist_1/18*100))
if(upload_arr[i].id != "ultrasound") {
var cin = {ctname: upload_arr[i].ctname, con: Percent};
console.log("SEND : " + JSON.stringify(cin) + ' ---->')
upload_client.write(JSON.stringify(cin) + '<EOF>');
break;
}
}
}
dist_0 = dist_1;
}
}, 1000);
Ultrasonic sensor nCube conf.js code for remaining dog feed.
JavaScript/**
* Created by Il Yeup, Ahn in KETI on 2017-02-23.
*/
/**
* Copyright (c) 2018, OCEAN
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var ip = require("ip");
var conf = {};
var cse = {};
var ae = {};
var cnt_arr = [];
var sub_arr = [];
var acp = {};
conf.useprotocol = 'http'; // select one for 'http' or 'mqtt' or 'coap' or 'ws'
// build cse
cse.host = '203.253.128.177';
cse.port = '7579';
cse.name = 'Mobius';
cse.id = '/Mobius2';
cse.mqttport = '1883';
cse.wsport = '7577';
// build ae
ae.name = 'walwal';
ae.id = 'SgkP2YGD89v';
ae.parent = '/' + cse.name;
ae.appid = 'measure_co2';
ae.port = '9727';
ae.bodytype = 'json'; // select 'json' or 'xml' or 'cbor'
ae.tasport = '3105';
// build cnt
var count = 0;
cnt_arr[count] = {};
cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
cnt_arr[count++].name = 'remains';
// build sub
count = 0;
// --------
sub_arr[count] = {};
sub_arr[count].parent = '/' + cse.name + '/' + ae.name + '/' + cnt_arr[0].name;
sub_arr[count].name = 'sub';
sub_arr[count++].nu = 'mqtt://' + cse.host + '/' + ae.id + '?ct=' + ae.bodytype; // mqtt
// build acp: not complete
acp.parent = '/' + cse.name + '/' + ae.name;
acp.name = 'acp-' + ae.name;
acp.id = ae.id;
conf.usesecure = 'disable';
if(conf.usesecure === 'enable') {
cse.mqttport = '8883';
}
conf.cse = cse;
conf.ae = ae;
conf.cnt = cnt_arr;
conf.sub = sub_arr;
conf.acp = acp;
module.exports = conf;
Whether dogs eat food or not. TAS conf.xml code of ultrasonic sensor.
XML<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<m2m:conf xmlns:m2m="http://www.onem2m.org/xml/protocols" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tas>
<parenthostname>localhost</parenthostname>
<parentport>3105</parentport>
</tas>
<upload>
<ctname>eat</ctname>
<id>eat#1</id>
</upload>
</m2m:conf>
Whether dogs eat food or not. TAS app.js code of ultrasonic sensor.
JavaScriptvar net = require('net');
var util = require('util');
var fs = require('fs');
var xml2js = require('xml2js');
var wdt = require('./wdt');
var useparentport = '';
var useparenthostname = '';
var upload_arr = [];
var download_arr = [];
var conf = {};
// This is an async file read
fs.readFile('conf.xml', 'utf-8', function (err, data) {
if (err) {
console.log("FATAL An error occurred trying to read in the file: " + err);
console.log("error : set to default for configuration")
}
else {
var parser = new xml2js.Parser({explicitArray: false});
parser.parseString(data, function (err, result) {
if (err) {
console.log("Parsing An error occurred trying to read in the file: " + err);
console.log("error : set to default for configuration")
}
else {
var jsonString = JSON.stringify(result);
conf = JSON.parse(jsonString)['m2m:conf'];
useparenthostname = conf.tas.parenthostname;
useparentport = conf.tas.parentport;
if (conf.upload != null) {
if (conf.upload['ctname'] != null) {
upload_arr[0] = conf.upload;
}
else {
upload_arr = conf.upload;
}
}
if (conf.download != null) {
if (conf.download['ctname'] != null) {
download_arr[0] = conf.download;
}
else {
download_arr = conf.download;
}
}
}
});
}
});
var tas_state = 'init';
var upload_client = null;
var t_count = 0;
var tas_download_count = 0;
function on_receive(data) {
if (tas_state == 'connect' || tas_state == 'reconnect' || tas_state == 'upload') {
var data_arr = data.toString().split('<EOF>');
if (data_arr.length >= 2) {
for (var i = 0; i < data_arr.length - 1; i++) {
var line = data_arr[i];
var sink_str = util.format('%s', line.toString());
var sink_obj = JSON.parse(sink_str);
if (sink_obj.ctname == null || sink_obj.con == null) {
console.log('Received: data format mismatch');
}
else {
if (sink_obj.con == 'hello') {
console.log('Received: ' + line);
if (++tas_download_count >= download_arr.length) {
tas_state = 'upload';
}
}
else {
for (var j = 0; j < upload_arr.length; j++) {
if (upload_arr[j].ctname == sink_obj.ctname) {
console.log('ACK : ' + line + ' <----');
break;
}
}
for (j = 0; j < download_arr.length; j++) {
if (download_arr[j].ctname == sink_obj.ctname) {
g_down_buf = JSON.stringify({id: download_arr[i].id, con: sink_obj.con});
console.log(g_down_buf + ' <----');
break;
}
}
}
}
}
}
}
}
function tas_watchdog() {
if (tas_state == 'init') {
upload_client = new net.Socket();
upload_client.on('data', on_receive);
upload_client.on('error', function(err) {
console.log(err);
tas_state = 'reconnect';
});
upload_client.on('close', function() {
console.log('Connection closed');
upload_client.destroy();
tas_state = 'reconnect';
});
if (upload_client) {
console.log('tas init ok');
tas_state = 'init_thing';
}
}
else if (tas_state == 'init_thing') {
// init things
tas_state = 'connect';
}
else if (tas_state == 'connect' || tas_state == 'reconnect') {
upload_client.connect(useparentport, useparenthostname, function() {
console.log('upload Connected');
tas_download_count = 0;
for (var i = 0; i < download_arr.length; i++) {
console.log('download Connected - ' + download_arr[i].ctname + ' hello');
var cin = {ctname: download_arr[i].ctname, con: 'hello'};
upload_client.write(JSON.stringify(cin) + '<EOF>');
}
if (tas_download_count >= download_arr.length) {
tas_state = 'upload';
}
});
}
}
// Every 3 seconds, check if the TAS is not working
wdt.set_wdt(require('shortid').generate(), 3, tas_watchdog);
const Gpio = require('pigpio').Gpio;
// The number of microseconds it takes sound to travel 1cm at 20 degrees celcius
const MICROSECDONDS_PER_CM = 1e6/34321;
const trigger = new Gpio(20, {mode: Gpio.OUTPUT}); // GPIO23: trigger pin
const echo = new Gpio(21, {mode: Gpio.INPUT, alert: true}); // GPIO24: echo pin
const range_max = 600; // maximum range for detection
const range_min = 0; // minimum range for detection
var dist_0 = 0;
var dist_1 = 0;
var ultrasonic_update = true;
trigger.digitalWrite(0);
const watchHCSR04 = () => {
let startTick;
echo.on('alert', (level, tick) => {
if (level == 1) {
startTick = tick;
} else {
const endTick = tick;
const diff = (endTick >> 0) - (startTick >> 0); // Unsigned 32 bit arithmetic
// console.log(diff / 2 / MICROSECDONDS_PER_CM);
dist_1 = (diff / 2 / MICROSECDONDS_PER_CM).toFixed(2);
if (dist_1 >= range_max || dist_1 <= range_min)
dist_1 = -1;
}
});
};
watchHCSR04();
setInterval(() => {
trigger.trigger(10, 1);
// comment out the below if-else statement to update at every interval
if (dist_1 > 23){
con_data = 1;
}
else {
con_data = 0;
}
if (ultrasonic_update) {
if (tas_state=='upload') {
for(var i = 0; i < upload_arr.length; i++) {
if(upload_arr[i].id != "ultrasound") {
var cin = {ctname: upload_arr[i].ctname, con: con_data};
console.log("SEND : " + JSON.stringify(cin) + ' ---->')
upload_client.write(JSON.stringify(cin) + '<EOF>');
break;
}
}
}
dist_0 = dist_1;
}
}, 1000);
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<m2m:conf xmlns:m2m="http://www.onem2m.org/xml/protocols" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tas>
<parenthostname>localhost</parenthostname>
<parentport>3105</parentport>
</tas>
<upload>
<ctname>remains</ctname>
<id>remains#1</id>
</upload>
</m2m:conf>
eat or not nCube conf.js code
JavaScript/**
* Created by Il Yeup, Ahn in KETI on 2017-02-23.
*/
/**
* Copyright (c) 2018, OCEAN
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var ip = require("ip");
var conf = {};
var cse = {};
var ae = {};
var cnt_arr = [];
var sub_arr = [];
var acp = {};
conf.useprotocol = 'http'; // select one for 'http' or 'mqtt' or 'coap' or 'ws'
// build cse
cse.host = '203.253.128.177';
cse.port = '7579';
cse.name = 'Mobius';
cse.id = '/Mobius2';
cse.mqttport = '1883';
cse.wsport = '7577';
// build ae
ae.name = 'walwal';
ae.id = 'SgkP2YGD89v';
ae.parent = '/' + cse.name;
ae.appid = 'measure_co2';
ae.port = '9727';
ae.bodytype = 'json'; // select 'json' or 'xml' or 'cbor'
ae.tasport = '3105';
// build cnt
var count = 0;
cnt_arr[count] = {};
cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
cnt_arr[count++].name = 'eat';
// build sub
count = 0;
// --------
sub_arr[count] = {};
sub_arr[count].parent = '/' + cse.name + '/' + ae.name + '/' + cnt_arr[0].name;
sub_arr[count].name = 'sub';
sub_arr[count++].nu = 'mqtt://' + cse.host + '/' + ae.id + '?ct=' + ae.bodytype; // mqtt
// build acp: not complete
acp.parent = '/' + cse.name + '/' + ae.name;
acp.name = 'acp-' + ae.name;
acp.id = ae.id;
conf.usesecure = 'disable';
if(conf.usesecure === 'enable') {
cse.mqttport = '8883';
}
conf.cse = cse;
conf.ae = ae;
conf.cnt = cnt_arr;
conf.sub = sub_arr;
conf.acp = acp;
module.exports = conf;
Whether dogs eat food or not. nCube conf.js code of ultrasonic sensor.
JavaScriptvar net = require('net');
var util = require('util');
var fs = require('fs');
var xml2js = require('xml2js');
var wdt = require('./wdt');
var useparentport = '';
var useparenthostname = '';
var upload_arr = [];
var download_arr = [];
var conf = {};
// This is an async file read
fs.readFile('conf.xml', 'utf-8', function (err, data) {
if (err) {
console.log("FATAL An error occurred trying to read in the file: " + err);
console.log("error : set to default for configuration")
}
else {
var parser = new xml2js.Parser({explicitArray: false});
parser.parseString(data, function (err, result) {
if (err) {
console.log("Parsing An error occurred trying to read in the file: " + err);
console.log("error : set to default for configuration")
}
else {
var jsonString = JSON.stringify(result);
conf = JSON.parse(jsonString)['m2m:conf'];
useparenthostname = conf.tas.parenthostname;
useparentport = conf.tas.parentport;
if (conf.upload != null) {
if (conf.upload['ctname'] != null) {
upload_arr[0] = conf.upload;
}
else {
upload_arr = conf.upload;
}
}
if (conf.download != null) {
if (conf.download['ctname'] != null) {
download_arr[0] = conf.download;
}
else {
download_arr = conf.download;
}
}
}
});
}
});
var tas_state = 'init';
var upload_client = null;
var t_count = 0;
var tas_download_count = 0;
function on_receive(data) {
if (tas_state == 'connect' || tas_state == 'reconnect' || tas_state == 'upload') {
var data_arr = data.toString().split('<EOF>');
if (data_arr.length >= 2) {
for (var i = 0; i < data_arr.length - 1; i++) {
var line = data_arr[i];
var sink_str = util.format('%s', line.toString());
var sink_obj = JSON.parse(sink_str);
if (sink_obj.ctname == null || sink_obj.con == null) {
console.log('Received: data format mismatch');
}
else {
if (sink_obj.con == 'hello') {
console.log('Received: ' + line);
if (++tas_download_count >= download_arr.length) {
tas_state = 'upload';
}
}
else {
for (var j = 0; j < upload_arr.length; j++) {
if (upload_arr[j].ctname == sink_obj.ctname) {
console.log('ACK : ' + line + ' <----');
break;
}
}
for (j = 0; j < download_arr.length; j++) {
if (download_arr[j].ctname == sink_obj.ctname) {
g_down_buf = JSON.stringify({id: download_arr[i].id, con: sink_obj.con});
console.log(g_down_buf + ' <----');
break;
}
}
}
}
}
}
}
}
function tas_watchdog() {
if (tas_state == 'init') {
upload_client = new net.Socket();
upload_client.on('data', on_receive);
upload_client.on('error', function(err) {
console.log(err);
tas_state = 'reconnect';
});
upload_client.on('close', function() {
console.log('Connection closed');
upload_client.destroy();
tas_state = 'reconnect';
});
if (upload_client) {
console.log('tas init ok');
tas_state = 'init_thing';
}
}
else if (tas_state == 'init_thing') {
// init things
tas_state = 'connect';
}
else if (tas_state == 'connect' || tas_state == 'reconnect') {
upload_client.connect(useparentport, useparenthostname, function() {
console.log('upload Connected');
tas_download_count = 0;
for (var i = 0; i < download_arr.length; i++) {
console.log('download Connected - ' + download_arr[i].ctname + ' hello');
var cin = {ctname: download_arr[i].ctname, con: 'hello'};
upload_client.write(JSON.stringify(cin) + '<EOF>');
}
if (tas_download_count >= download_arr.length) {
tas_state = 'upload';
}
});
}
}
// Every 3 seconds, check if the TAS is not working
wdt.set_wdt(require('shortid').generate(), 3, tas_watchdog);
const Gpio = require('pigpio').Gpio;
// The number of microseconds it takes sound to travel 1cm at 20 degrees celcius
const MICROSECDONDS_PER_CM = 1e6/34321;
const trigger = new Gpio(20, {mode: Gpio.OUTPUT}); // GPIO20: trigger pin
const echo = new Gpio(21, {mode: Gpio.INPUT, alert: true}); // GPIO21: echo pin
const range_max = 600; // maximum range for detection
const range_min = 0; // minimum range for detection
var dist_0 = 0;
var dist_1 = 0;
var ultrasonic_update = true;
trigger.digitalWrite(0);
const watchHCSR04 = () => {
let startTick;
echo.on('alert', (level, tick) => {
if (level == 1) {
startTick = tick;
} else {
const endTick = tick;
const diff = (endTick >> 0) - (startTick >> 0); // Unsigned 32 bit arithmetic
// console.log(diff / 2 / MICROSECDONDS_PER_CM);
dist_1 = (diff / 2 / MICROSECDONDS_PER_CM).toFixed(2);
if (dist_1 >= range_max || dist_1 <= range_min)
dist_1 = -1;
}
});
};
watchHCSR04();
setInterval(() => {
trigger.trigger(10, 1);
// comment out the below if-else statement to update at every interval
if (dist_1 > 23){
con_data = 1;
}
else {
con_data = 0;
}
if (ultrasonic_update) {
if (tas_state=='upload') {
for(var i = 0; i < upload_arr.length; i++) {
if(upload_arr[i].id != "ultrasound") {
var cin = {ctname: upload_arr[i].ctname, con: con_data};
console.log("SEND : " + JSON.stringify(cin) + ' ---->')
upload_client.write(JSON.stringify(cin) + '<EOF>');
break;
}
}
}
dist_0 = dist_1;
}
}, 1000);
GPS alarm
PythonIf it escape send alarm message to mobius.
import time
import board
import busio
import requests
from parse import *
import adafruit_gps
import serial
uart = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=10)
gps = adafruit_gps.GPS(uart) # Use UART/pyserial
#Turn on only GPRMC
gps.send_command(b'PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
gps.send_command(b'PMTK220,2000')
timestamp = time.monotonic()
out_alarm = False
while True:
data = gps.read(64)
data_string = "".join([chr(b) for b in data])
list = data_string.split(',')
print(list)
if "V" in list:
print("Can't read base_GPS")
elif "A" in list:
position = list.index("A")
if (len(list[position:]) > 3):
latitude_temp = list[position+1]
longitude_temp = list[position+3]
print(latitude_temp)
base_latitude = int(latitude_temp[:2]) + (float(latitude_temp[2:]) / 60)
base_longitude = int(longitude_temp[:2]) + (float(longitude_temp[2:]) / 60)
print(base_latitude, " ", base_longitude)
break
while True:
data = gps.read(64)
if data is not None:
data_string = "".join([chr(b) for b in data])
list = data_string.split(',')
time.sleep(0.5)
if "V" in list:
position = list.index("V")
print("Can't read GPS")
elif "A" in list:
position = list.index("A")
if (len(list[position:]) > 3):
latitude_temp = list[position+1]
longitude_temp = list[position+3]
latitude = int(latitude_temp[:2]) + (float(latitude_temp[2:]) / 60)
print(longitude_temp[2:])
longitude = int(longitude_temp[:2]) + (float(longitude_temp[2:]) / 60)
distance = (abs(base_latitude - latitude) + abs(base_longitude - longitude))
#print(distance)
if distance > 0.0004 and distance < 1:
out_alarm = True
break
if time.monotonic() - timestamp > 5:
gps.send_command(b"PMTK605")
timestamp = time.monotonic()
if out_alarm == True:
mobius_data = "Out!"
url = 'http://203.253.128.177:7579/Mobius/walwal/alert'
headers = {
'Accept':'application/json',
'X-M2M-RI':'12345',
'X-M2M-Origin':'XXXXXXXXXXX', # change to your aei
'Content-Type':'application/vnd.onem2m-res+json; ty=4'
}
data = {
"m2m:cin": {
"con": "1"
}
}
r = requests.post(url, headers=headers, json=data)
try:
r.raise_for_status()
print(r)
except Exception as exc:
print('There was a problem: %s' % (exc))
nCube 'conf.js' for Training Machine
JavaScript/**
* Created by Il Yeup, Ahn in KETI on 2017-02-23.
*/
/**
* Copyright (c) 2018, OCEAN
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Modified by 'Giyeong Hong'
*/
var ip = require("ip");
var conf = {};
var cse = {};
var ae = {};
var cnt_arr = [];
var sub_arr = [];
var acp = {};
conf.useprotocol = 'http'; // select one for 'http' or 'mqtt' or 'coap' or 'ws'
// build cse
cse.host = '203.253.128.177';
cse.port = '7579';
cse.name = 'Mobius';
cse.id = '/Mobius2';
cse.mqttport = '1883';
cse.wsport = '7577';
// build ae
ae.name = 'walwal';
ae.id = 'SgkP2YGD89v';
ae.parent = '/' + cse.name;
ae.appid = 'measure_co2';
ae.port = '9727';
ae.bodytype = 'json'; // select 'json' or 'xml' or 'cbor'
ae.tasport = '3105';
// build cnt
var count = 0;
cnt_arr[count] = {};
cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
cnt_arr[count++].name = 'training';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'touch';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'sound';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'pir';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'ultrasonic';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'temp';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'accel';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'light';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'dust';
// cnt_arr[count] = {};
// cnt_arr[count].parent = '/' + cse.name + '/' + ae.name;
// cnt_arr[count++].name = 'ledm';
// build sub
count = 0;
//sub_arr[count] = {};
//sub_arr[count].parent = '/' + cse.name + '/' + ae.name + '/' + cnt_arr[1].name;
//sub_arr[count].name = 'sub-ctrl';
//sub_arr[count++].nu = 'mqtt://' + cse.host + '/' + ae.id;
// --------
sub_arr[count] = {};
sub_arr[count].parent = '/' + cse.name + '/' + ae.name + '/' + cnt_arr[0].name;
sub_arr[count].name = 'sub';
sub_arr[count++].nu = 'mqtt://' + cse.host + '/' + ae.id + '?ct=' + ae.bodytype; // mqtt
//sub_arr[count++].nu = 'http://' + ip.address() + ':' + ae.port + '/noti?ct=json'; // http
//sub_arr[count++].nu = 'Mobius/'+ae.name; // mqtt
// --------
/*// --------
sub_arr[count] = {};
sub_arr[count].parent = '/' + cse.name + '/' + ae.name + '/' + cnt_arr[1].name;
sub_arr[count].name = 'sub2';
//sub_arr[count++].nu = 'http://' + ip.address() + ':' + ae.port + '/noti?ct=json'; // http
//sub_arr[count++].nu = 'mqtt://' + cse.host + '/' + ae.id + '?rcn=9&ct=' + ae.bodytype; // mqtt
sub_arr[count++].nu = 'mqtt://' + cse.host + '/' + ae.id + '?ct=json'; // mqtt
// -------- */
// build acp: not complete
acp.parent = '/' + cse.name + '/' + ae.name;
acp.name = 'acp-' + ae.name;
acp.id = ae.id;
conf.usesecure = 'disable';
if(conf.usesecure === 'enable') {
cse.mqttport = '8883';
}
conf.cse = cse;
conf.ae = ae;
conf.cnt = cnt_arr;
conf.sub = sub_arr;
conf.acp = acp;
module.exports = conf;
"http_app.js" file for training machines.
JavaScriptIf it meets the conditions, the training is conducted.
/**
* Copyright (c) 2018, OCEAN
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Created by ryeubi on 2015-08-31.
*/
const spawn = require('child_process').spawn;
var http = require('http');
var express = require('express');
var fs = require('fs');
var bodyParser = require('body-parser');
var mqtt = require('mqtt');
var util = require('util');
var xml2js = require('xml2js');
var url = require('url');
var ip = require('ip');
var shortid = require('shortid');
var cbor = require('cbor');
global.sh_adn = require('./http_adn');
var noti = require('./noti');
var tas = require('./thyme_tas');
var HTTP_SUBSCRIPTION_ENABLE = 0;
var MQTT_SUBSCRIPTION_ENABLE = 0;
var app = express();
//app.use(bodyParser.urlencoded({ extended: true }));
//app.use(bodyParser.json());
//app.use(bodyParser.json({ type: 'application/*+json' }));
//app.use(bodyParser.text({ type: 'application/*+xml' }));
// ?????? ????????.
var server = null;
var noti_topic = '';
// ready for mqtt
for(var i = 0; i < conf.sub.length; i++) {
if(conf.sub[i].name != null) {
if(url.parse(conf.sub[i].nu).protocol === 'http:') {
HTTP_SUBSCRIPTION_ENABLE = 1;
if(url.parse(conf.sub[i]['nu']).hostname === 'autoset') {
conf.sub[i]['nu'] = 'http://' + ip.address() + ':' + conf.ae.port + url.parse(conf.sub[i]['nu']).pathname;
}
}
else if(url.parse(conf.sub[i].nu).protocol === 'mqtt:') {
MQTT_SUBSCRIPTION_ENABLE = 1;
}
else {
//console.log('notification uri of subscription is not supported');
//process.exit();
}
}
}
var return_count = 0;
var request_count = 0;
function ready_for_notification() {
if(HTTP_SUBSCRIPTION_ENABLE == 1) {
server = http.createServer(app);
server.listen(conf.ae.port, function () {
console.log('http_server running at ' + conf.ae.port + ' port');
});
}
if(MQTT_SUBSCRIPTION_ENABLE == 1) {
for(var i = 0; i < conf.sub.length; i++) {
if (conf.sub[i].name != null) {
if (url.parse(conf.sub[i].nu).protocol === 'mqtt:') {
if (url.parse(conf.sub[i]['nu']).hostname === 'autoset') {
conf.sub[i]['nu'] = 'mqtt://' + conf.cse.host + '/' + conf.ae.id;
noti_topic = util.format('/oneM2M/req/+/%s/#', conf.ae.id);
}
else if (url.parse(conf.sub[i]['nu']).hostname === conf.cse.host) {
noti_topic = util.format('/oneM2M/req/+/%s/#', conf.ae.id);
}
else {
noti_topic = util.format('%s', url.parse(conf.sub[i].nu).pathname);
}
}
}
}
mqtt_connect(conf.cse.host, noti_topic);
}
}
function ae_response_action(status, res_body, callback) {
var aeid = res_body['m2m:ae']['aei'];
conf.ae.id = aeid;
callback(status, aeid);
}
function create_cnt_all(count, callback) {
if(conf.cnt.length == 0) {
callback(2001, count);
}
else {
var parent = conf.cnt[count].parent;
var rn = conf.cnt[count].name;
sh_adn.crtct(parent, rn, count, function (rsc, res_body, count) {
if(rsc == 5106 || rsc == 2001 || rsc == 4105) {
callback(rsc, count);
}
else {
callback('9999', count);
}
});
}
}
function delete_sub_all(count, callback) {
if(conf.sub.length == 0) {
callback(2001, count);
}
else {
var target = conf.sub[count].parent + '/' + conf.sub[count].name;
sh_adn.delsub(target, count, function (rsc, res_body, count) {
if(rsc == 5106 || rsc == 2002 || rsc == 2000 || rsc == 4105 || rsc == 4004) {
callback(rsc, count);
}
else {
callback('9999', count);
}
});
}
}
function create_sub_all(count, callback) {
if(conf.sub.length == 0) {
callback(2001, count);
}
else {
var parent = conf.sub[count].parent;
var rn = conf.sub[count].name;
var nu = conf.sub[count].nu;
sh_adn.crtsub(parent, rn, nu, count, function (rsc, res_body, count) {
if(rsc == 5106 || rsc == 2001 || rsc == 4105) {
callback(rsc, count);
}
else {
callback('9999', count);
}
});
}
}
function http_watchdog() {
if (sh_state === 'crtae') {
console.log('[sh_state] : ' + sh_state);
sh_adn.crtae(conf.ae.parent, conf.ae.name, conf.ae.appid, function (status, res_body) {
console.log(res_body);
if (status == 2001) {
ae_response_action(status, res_body, function (status, aeid) {
console.log('x-m2m-rsc : ' + status + ' - ' + aeid + ' <----');
sh_state = 'crtct';
request_count = 0;
return_count = 0;
});
}
else if (status == 5106 || status == 4105) {
console.log('x-m2m-rsc : ' + status + ' <----');
sh_state = 'rtvae'
}
});
}
else if (sh_state === 'rtvae') {
if (conf.ae.id === 'S') {
conf.ae.id = 'S' + shortid.generate();
}
console.log('[sh_state] : ' + sh_state);
sh_adn.rtvae(conf.ae.parent + '/' + conf.ae.name, function (status, res_body) {
if (status == 2000) {
var aeid = res_body['m2m:ae']['aei'];
console.log('x-m2m-rsc : ' + status + ' - ' + aeid + ' <----');
if(conf.ae.id != aeid && conf.ae.id != ('/'+aeid)) {
console.log('AE-ID created is ' + aeid + ' not equal to device AE-ID is ' + conf.ae.id);
}
else {
sh_state = 'crtct';
request_count = 0;
return_count = 0;
}
}
else {
console.log('x-m2m-rsc : ' + status + ' <----');
}
});
}
else if (sh_state === 'crtct') {
console.log('[sh_state] : ' + sh_state);
if(return_count == 0) {
create_cnt_all(request_count, function (status, count) {
request_count = ++count;
return_count = 0;
if (conf.cnt.length <= count) {
sh_state = 'delsub';
request_count = 0;
return_count = 0;
}
});
}
return_count++;
if(return_count >= 3) {
return_count = 0;
}
}
else if (sh_state === 'delsub') {
console.log('[sh_state] : ' + sh_state);
if(return_count == 0) {
delete_sub_all(request_count, function (status, count) {
request_count = ++count;
return_count = 0;
if (conf.sub.length <= count) {
sh_state = 'crtsub';
request_count = 0;
return_count = 0;
}
});
}
return_count++;
if(return_count >= 3) {
return_count = 0;
}
}
else if (sh_state === 'crtsub') {
console.log('[sh_state] : ' + sh_state);
if(return_count == 0) {
create_sub_all(request_count, function (status, count) {
request_count = ++count;
return_count = 0;
if (conf.sub.length <= count) {
sh_state = 'crtci';
ready_for_notification();
tas.ready();
// var _ae = {};
// _ae.id = conf.ae.id;
// fs.writeFileSync('aei.json', JSON.stringify(_ae, null, 4), 'utf8');
}
});
}
return_count++;
if(return_count >= 3) {
return_count = 0;
}
}
else if (sh_state === 'crtci') {
}
}
wdt.set_wdt(require('shortid').generate(), 2, http_watchdog);
// for notification
//var xmlParser = bodyParser.text({ type: '*/*' });
function mqtt_connect(serverip, noti_topic) {
if(mqtt_client == null) {
if (conf.usesecure === 'disable') {
var connectOptions = {
host: serverip,
port: conf.cse.mqttport,
// username: 'keti',
// password: 'keti123',
protocol: "mqtt",
keepalive: 10,
// clientId: serverUID,
protocolId: "MQTT",
protocolVersion: 4,
clean: true,
reconnectPeriod: 2000,
connectTimeout: 2000,
rejectUnauthorized: false
};
}
else {
connectOptions = {
host: serverip,
port: conf.cse.mqttport,
protocol: "mqtts",
keepalive: 10,
// clientId: serverUID,
protocolId: "MQTT",
protocolVersion: 4,
clean: true,
reconnectPeriod: 2000,
connectTimeout: 2000,
key: fs.readFileSync("./server-key.pem"),
cert: fs.readFileSync("./server-crt.pem"),
rejectUnauthorized: false
};
}
mqtt_client = mqtt.connect(connectOptions);
}
mqtt_client.on('connect', function () {
mqtt_client.subscribe(noti_topic);
console.log('[mqtt_connect] noti_topic : ' + noti_topic);
});
mqtt_client.on('message', function (topic, message) {
var topic_arr = topic.split("/");
var bodytype = conf.ae.bodytype;
if(topic_arr[5] != null) {
bodytype = (topic_arr[5] === 'xml') ? topic_arr[5] : ((topic_arr[5] === 'json') ? topic_arr[5] : ((topic_arr[5] === 'cbor') ? topic_arr[5] : 'json'));
}
if(topic_arr[1] === 'oneM2M' && topic_arr[2] === 'req' && topic_arr[4] === conf.ae.id) {
var temp_string = message.toString();
console.log(temp_string);
/////////////////////////////////////////////////////////////////////////////////////////////////////////
var con_value = Number(temp_string[temp_string.indexOf('con":"') + 6]) //number type
console.log("Received data : " + con_value);
switch(con_value) {
case 1:
console.log("Sit");
var spawn = require('child_process').spawn;
var result = spawn('python3.7', ['./instruct.py', String(con_value)]);
result.stdout.on('data', function(data) { console.log(data.toString()); });
result.stderr.on('data', function(data) { console.log(data.toString()); });
break;
case 2:
console.log("Wait");
var spawn = require('child_process').spawn;
var result = spawn('python3.7', ['./instruct.py', String(con_value)]);
result.stdout.on('data', function(data) { console.log(data.toString()); });
result.stderr.on('data', function(data) { console.log(data.toString()); });
break;
default:
console.log("Not working");
break;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
if(bodytype === 'xml') {
var parser = new xml2js.Parser({explicitArray: false});
parser.parseString(message.toString(), function (err, jsonObj) {
if (err) {
console.log('[mqtt noti xml2js parser error]');
}
else {
noti.mqtt_noti_action(topic_arr, jsonObj);
}
});
}
else if(bodytype === 'cbor') {
var encoded = message.toString();
cbor.decodeFirst(encoded, function(err, jsonObj) {
if (err) {
console.log('[mqtt noti cbor parser error]');
}
else {
noti.mqtt_noti_action(topic_arr, jsonObj);
}
});
}
else { // json
var jsonObj = JSON.parse(message.toString());
if (jsonObj['m2m:rqp'] == null) {
jsonObj['m2m:rqp'] = jsonObj;
}
noti.mqtt_noti_action(topic_arr, jsonObj);
}
}
else {
console.log('topic is not supported');
}
});
mqtt_client.on('error', function (err) {
console.log(err.message);
});
}
var onem2mParser = bodyParser.text(
{
limit: '1mb',
type: 'application/onem2m-resource+xml;application/xml;application/json;application/vnd.onem2m-res+xml;application/vnd.onem2m-res+json'
}
);
var noti_count = 0;
app.post('/:resourcename0', onem2mParser, function(request, response) {
var fullBody = '';
request.on('data', function (chunk) {
fullBody += chunk.toString();
});
request.on('end', function () {
request.body = fullBody;
console.log(fullBody);
for (var i = 0; i < conf.sub.length; i++) {
if (conf.sub[i]['nu'] != null) {
if(url.parse(conf.sub[i].nu).protocol === 'http:') {
var nu_path = url.parse(conf.sub[i]['nu']).pathname.toString().split('/')[1];
if (nu_path === request.params.resourcename0) {
var content_type = request.headers['content-type'];
if(content_type.includes('xml')) {
var bodytype = 'xml';
}
else if(content_type.includes('cbor')) {
bodytype = 'cbor';
}
else {
bodytype = 'json';
}
if (bodytype === 'json') {
try {
var pc = JSON.parse(request.body);
var rqi = request.headers['x-m2m-ri'];
noti.http_noti_action(rqi, pc, 'json', response);
}
catch (e) {
console.log(e);
}
}
else if(bodytype === 'cbor') {
var encoded = request.body;
cbor.decodeFirst(encoded, function(err, pc) {
if (err) {
console.log('[http noti cbor parser error]');
}
else {
var rqi = request.headers['x-m2m-ri'];
noti.http_noti_action(rqi, pc, 'cbor', response);
}
});
}
else {
var parser = new xml2js.Parser({explicitArray: false});
parser.parseString(request.body, function (err, pc) {
if (err) {
console.log('[http noti xml2js parser error]');
}
else {
var rqi = request.headers['x-m2m-ri'];
noti.http_noti_action(rqi, pc, 'xml', response);
}
});
}
break;
}
}
}
}
});
});
app.get('/conf', onem2mParser, function(request, response, next) {
});
/* for testing
app.use(function(request, response, next) {
var fullBody = '';
request.on('data', function (chunk) {
fullBody += chunk.toString();
});
request.on('end', function () {
request.body = fullBody;
console.log(fullBody);
response.status(200).send('');
});
});
*/
'instruct.py' file for training machine
PythonThereafter, a command is delivered to Arduino through UART communication for device startup.
import sys
import time
import serial
import os
def instruct_send(code):
while True:
code = str(code).encode('utf-8')
temp = arduino.write(code)
if temp > 2000:
break
if __name__ == '__main__':
arduino = serial.Serial('/dev/ttyACM0', 9600)
arduino.flush()
instruct_send(1) # send to arduino value of 1 or 2
print("Sit1 OK")
os.system('omxplayer sit.m4a &')
import sit
file_sit = 'sit.py'
sit_return = sit.return_value
sit_return = bool(sit_return)
# sit_return = True ############################################# temp value of return sit test
# training result and arduino excute
if sys.argv[1] == '1': #if argv is sit?
if sit_return == True: #<<sit mode>> return value true?
instruct_send(5) #arduino 'give snack'
print("GIVE SNACK OK(SIT)")
instruct_send(3) #arduino return sit
print("Sit2 OK(SUCCEED)")
arduino.flush()
elif sit_return == False: #<<sit mode>> return value false?
instruct_send(6)
print("Dummy for control Error")
instruct_send(3) #arduino 'sit2'
print("Sit2 OK(FAILED)")
arduino.flush()
elif sys.argv[1] == '2':
if sit_return == True: #<<sit mode>> return value true??
instruct_send(2) #arduino 'wait1'
print("WAIT1 OK(SUCCEED)")
os.system('omxplayer wait.m4a &')
import wait
file_wait = 'wait.py'
wait_return = wait.return_value
wait_return = bool(wait_return)
# wait_return = False ######################################################## temp value of return wait test
if wait_return == True: #<<wait mode>> return value true??
instruct_send(5) #arduino 'give snack'
print("GIVE SNACK OK(WAIT)")
instruct_send(4)
print("WAIT2 OK(SUCCEED)")
arduino.flush()
elif wait_return == False: #<<wait mode>> return value false?
instruct_send(6)
print("Dummy for control Error")
instruct_send(4)
print("WAIT2 OK(FAILED)")
arduino.flush()
elif sit_return == False:
instruct_send(6)
print("Dummy for control Error")
instruct_send(3) #arduino 'sit2'
print("SIT2 OK(FAILED IN WAIT)")
arduino.flush()
'TotalTraining.ino' code for actual device startup.
Arduino#include <Servo.h>
const int servoPin1 = 2;
const int servoPin2 = 3;
const int servoPin3 = 4;
const int servoPin4 = 5;
const int servoPin5 = 6;
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
int angle1 = 0;
int angle2 = 180;
int angle3 = 180;
int angle4 = 0;
int angle5 = 0;
void setup() {
Serial.begin(9600);
servo1.attach(servoPin1);
servo2.attach(servoPin2);
servo3.attach(servoPin3);
servo4.attach(servoPin4);
servo5.attach(servoPin5);
servo1.write(0);
servo2.write(180);
servo3.write(180);
servo4.write(0);
servo5.write(0);
}
int i;
int j;
int k;
//angle1 = 0~90
//angle2 = 90~180
//angle3 = 90~180
//angle4 = 0~90
void training_sit_1() {
for(i = 0; i < 45; i++) {
servo1.write(i);
servo2.write(180 - i);
delay(20);
}
for(j = 0; j < 135; j++) {
servo3.write(180 - j);
servo4.write(j);
delay(20);
}
}
void training_sit_2() {
for(j = 135; j > 0; j--) {
servo3.write(180 - j);
servo4.write(j);
delay(20);
}
for(i = 45; i > 0; i--) {
servo1.write(i);
servo2.write(180 - i);
delay(20);
}
}
void training_wait_1() {
for(j = 135; j > 60; j--) {
servo3.write(180 - j);
servo4.write(j);
delay(20);
}
for(i = 45; i < 60; i++) {
servo1.write(i);
servo2.write(180 - i);
delay(20);
}
}
void training_wait_2() {
for(i = 60; i > 0; i--) {
servo1.write(i);
servo2.write(180 - i);
delay(20);
}
for(j = 70; j > 0; j--) {
servo3.write(180 - j);
servo4.write(j);
delay(20);
}
}
void give_snack() {
for(k = 0; k < 180; k++) {
servo5.write(k);
delay(20);
}
for(k = 180; k > 0; k--) {
servo5.write(k);
delay(20);
}
}
void dummy() {
for(k = 0; k < 180; k++) {
servo5.write(0);
delay(20);
}
for(k = 180; k > 0; k--) {
servo5.write(0);
delay(20);
}
}
void loop() {
while (Serial.available() > 0) {
char c = Serial.read();
Serial.print(c);
switch(c) {
case '1':
training_sit_1(); // ( )
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
case '2':
training_wait_1();// ( , )
dummy();
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
case '3':
training_sit_2(); //
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
case '4':
training_wait_2(); //
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
case '5': //
give_snack();
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
case '6': //
dummy();
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
default:
while(Serial.available() > 0){
Serial.read();
c = 0;
Serial.flush();
}
break;
}
}
}
Android MainActivity.java for Mobius App
JavaThis is the app's vital code.
MQTT API is to receive real-time information.
- Subscribe to Topic to receive real-time information and listen to automatic reception (subscribe)
- After receiving the real-time information, I received the data well, but it's a response request (publish)
package sch.iot.onem2mapp;
import android.app.NotificationChannel; // added by S. Lee, SCH Univ.
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.ToggleButton;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import fr.arnaudguyon.xmltojsonlib. XmlToJson;
import static sch.iot.onem2mapp.R.layout.activity_main;
public class MainActivity extends AppCompatActivity implements Button.OnClickListener, CompoundButton.OnCheckedChangeListener {
public Button btnRetrieve;
public Switch Switch_MQTT;
public TextView textViewData;
// added by by S. Lee, SCH Univ.
public TextView textTrain;
public TextView textRemains;
public TextView textEat;
public TextView textAlert;
public TextView textSuccess;
public ToggleButton btn_train;
public ToggleButton btnSitdown;
public ToggleButton btnWait;
public Handler handler;
public ToggleButton btnAddr_Set;
private static CSEBase csebase = new CSEBase();
private static AE ae = new AE();
private static String TAG = "MainActivity";
private String MQTTPort = "1883";
// Modify this variable associated with your AE name in Mobius, by J. Yun, SCH Univ.
private String ServiceAEName = "walwal";
private String MQTT_Req_Topic = "";
private String MQTT_Resp_Topic = "";
private MqttAndroidClient mqttClient = null;
private EditText EditText_Address =null;
private String Mobius_Address ="";
// added b
private static final String PRIMARY_CHANNEL_ID_1 = "primary_notification_channel_1";
private static final String PRIMARY_CHANNEL_ID_2 = "primary_notification_channel_2";
private static final String PRIMARY_CHANNEL_ID_3 = "primary_notification_channel_3";
private static final String PRIMARY_CHANNEL_ID_4 = "primary_notification_channel_4";
private static final String PRIMARY_CHANNEL_ID_5 = "primary_notification_channel_5";
private static final String PRIMARY_CHANNEL_ID_6 = "primary_notification_channel_6";
private NotificationManager mNotificationManager;
private static final int NOTIFICATION_ID_1 = 0;
private static final int NOTIFICATION_ID_2 = 0;
private static final int NOTIFICATION_ID_3 = 0;
private static final int NOTIFICATION_ID_4 = 0;
private static final int NOTIFICATION_ID_5 = 0;
private static final int NOTIFICATION_ID_6 = 0;
public Button button_notify_1;
public Button button_notify_2;
public Button button_notify_3;
public Button button_notify_4;
public Button button_notify_5;
public Button button_notify_6;
// Main
public MainActivity() {
handler = new Handler();
}
/* onCreate */
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_main);
btnRetrieve = findViewById(R.id.btnRetrieve);
Switch_MQTT = findViewById(R.id.switch_mqtt);
textViewData = findViewById(R.id.textViewData);
EditText_Address = findViewById(R.id.editText);
btnAddr_Set = findViewById(R.id.toggleButton_Addr);
btn_train = findViewById(R.id.btn_train);
btnSitdown = findViewById(R.id.btnSitdown);
btnWait = findViewById(R.id.btnWait);
textRemains = findViewById(R.id.textRemains);
textEat = findViewById(R.id.textEat);
textAlert = findViewById(R.id.textAlert);
textSuccess = findViewById(R.id.textSuccess);
btnRetrieve.setOnClickListener(this);
Switch_MQTT.setOnCheckedChangeListener(this);
btn_train.setOnClickListener(this);
btnWait.setOnClickListener(this);
btnSitdown.setOnClickListener(this);
btnAddr_Set.setOnClickListener(this);
// added by by S. Lee, SCH Univ.
button_notify_1 = findViewById(R.id.notify_1);
button_notify_2 = findViewById(R.id.notify_2);
button_notify_3 = findViewById(R.id.notify_3);
button_notify_4 = findViewById(R.id.notify_4);
button_notify_5 = findViewById(R.id.notify_5);
button_notify_6 = findViewById(R.id.notify_6);
btnAddr_Set.setFocusable(true);
btnSitdown.setVisibility(View.INVISIBLE);
btnWait.setVisibility(View.INVISIBLE);
// Create AE and Get AEID
button_notify_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification_1();
}
});
button_notify_2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification_2();
}
});
button_notify_3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification_3();
}
});
button_notify_4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification_4();
}
});
button_notify_5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification_5();
}
});
button_notify_6.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendNotification_6();
}
});
createNotificationChannel();
btnAddr_Set.performClick();
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
btnRetrieve.performClick();
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
Switch_MQTT.performClick();
}
}, 600);
}
}, 600);
}
/* AE Create for Androdi AE */
public void GetAEInfo() {
// You can put the IP address directly in code,
// but also get it from EditText window
Mobius_Address = EditText_Address.getText().toString();
// csebase.setInfo(Mobius_Address,"7579","Mobius","1883");
csebase.setInfo("203.253.128.177","7579","Mobius","1883");
// AE Create for Android AE
ae.setAppName("ncubeapp");
aeCreateRequest aeCreate = new aeCreateRequest();
aeCreate.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
Log.d(TAG, "** AE Create ResponseCode[" + msg +"]");
if( Integer.parseInt(msg) == 201 ){
MQTT_Req_Topic = "/oneM2M/req/Mobius2/"+ae.getAEid()+"_sub"+"/#";
MQTT_Resp_Topic = "/oneM2M/resp/Mobius2/"+ae.getAEid()+"_sub"+"/json";
Log.d(TAG, "ReqTopic["+ MQTT_Req_Topic+"]");
Log.d(TAG, "ResTopic["+ MQTT_Resp_Topic+"]");
}
else { // If AE is Exist , GET AEID
aeRetrieveRequest aeRetrive = new aeRetrieveRequest();
aeRetrive.setReceiver(new IReceived() {
public void getResponseBody(final String resmsg) {
handler.post(new Runnable() {
public void run() {
Log.d(TAG, "** AE Retrive ResponseCode[" + resmsg +"]");
MQTT_Req_Topic = "/oneM2M/req/Mobius2/"+ae.getAEid()+"_sub"+"/#";
MQTT_Resp_Topic = "/oneM2M/resp/Mobius2/"+ae.getAEid()+"_sub"+"/json";
Log.d(TAG, "ReqTopic["+ MQTT_Req_Topic+"]");
Log.d(TAG, "ResTopic["+ MQTT_Resp_Topic+"]");
}
});
}
});
aeRetrive.start();
}
}
});
}
});
aeCreate.start();
}
// Switch - Get MQTT, by J. Yun, SCH Univ.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.d(TAG, "MQTT Create");
MQTT_Create(true);
} else {
Log.d(TAG, "MQTT Close");
MQTT_Create(false);
}
}
/* MQTT Subscription */
public void MQTT_Create(boolean mtqqStart) {
if (mtqqStart && mqttClient == null) {
/* Subscription Resource Create to Yellow Turtle */
// added by S. Lee, SCH Univ.
SubscribeResource
subcribeResource = new SubscribeResource("remains");
subcribeResource.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText("**** Subscription Resource Creation Response ****\r\n\r\n" + msg);
}
});
}
});
subcribeResource.start();
subcribeResource = new SubscribeResource("eat");
subcribeResource.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText("**** Subscription Resource Creation Response ****\r\n\r\n" + msg);
}
});
}
});
subcribeResource.start();
subcribeResource = new SubscribeResource("alert");
subcribeResource.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText("**** Subscription Resource Creation Response ****\r\n\r\n" + msg);
}
});
}
});
subcribeResource.start();
subcribeResource = new SubscribeResource("success");
subcribeResource.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText("**** Subscription Resource Creation Response ****\r\n\r\n" + msg);
}
});
}
});
subcribeResource.start();
/* MQTT Subscribe */
mqttClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://" + csebase.getHost() + ":" + csebase.getMQTTPort(), MqttClient.generateClientId());
mqttClient.setCallback(mainMqttCallback);
try {
// added by J. Yun, SCH Univ.
// Modified by S. Lee, SCH Univ.
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setKeepAliveInterval(600);
mqttConnectOptions.setCleanSession(false);
IMqttToken token = mqttClient.connect(mqttConnectOptions);
token.setActionCallback(mainIMqttActionListener);
} catch (MqttException e) {
e.printStackTrace();
}
} else {
/* MQTT unSubscribe or Client Close */
mqttClient.setCallback(null);
mqttClient.close();
mqttClient = null;
}
}
/* MQTT Listener */
private IMqttActionListener mainIMqttActionListener = new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d(TAG, "onSuccess");
String payload = "";
int mqttQos = 1; /* 0: NO QoS, 1: No Check , 2: Each Check */
MqttMessage message = new MqttMessage(payload.getBytes());
try {
mqttClient.subscribe(MQTT_Req_Topic, mqttQos);
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.d(TAG, "onFailure");
}
};
/* MQTT Broker Message Received */
private MqttCallback mainMqttCallback = new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
Log.d(TAG, "connectionLost");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.d(TAG, "messageArrived");
textViewData.setText("");
textViewData.setText("MQTT data received\r\n\r\n" + message.toString().replaceAll(",", "\n"));
Log.d(TAG, "Notify ResMessage:" + message.toString());
// Added by J. Yun, SCH Univ.
// Modified by S. Lee, SCH Univ.
String cnt = getContainerName(message.toString());
Log.d(TAG, "Received container name is " + cnt);
//textViewData.setText(cnt);
if (cnt.indexOf("eat") != -1)
{
if(Integer.parseInt(getContainerContentJSON(message.toString())) == 1)
{
textEat.setText("Ate");
sendNotification_3();
}
else
{
textEat.setText("Not");
}
}
if (cnt.indexOf("success") != -1)
{
if(Integer.parseInt(getContainerContentJSON(message.toString())) == 1)
{
textSuccess.setText("ASDFASDF");
sendNotification_4();
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
btn_train.performClick();
btnSitdown.setChecked(false);
btnWait.setChecked(false);
}
}, 600);
}
else
{
sendNotification_6();
btn_train.performClick();
btnSitdown.setChecked(false);
btnWait.setChecked(false);
}
}
if (cnt.indexOf("alert") != -1)
{
if(Integer.parseInt(getContainerContentJSON(message.toString())) == 1)
{
textAlert.setText("Alert!");
sendNotification_5();
}
else
{
textAlert.setText("Nope Alert :)");
}
}
else
;
/* Json Type Response Parsing */
String retrqi = MqttClientRequestParser.notificationJsonParse(message.toString());
Log.d(TAG, "RQI["+ retrqi +"]");
String responseMessage = MqttClientRequest.notificationResponse(retrqi);
Log.d(TAG, "Recv OK ResMessage ["+responseMessage+"]");
/* Make json for MQTT Response Message */
MqttMessage res_message = new MqttMessage(responseMessage.getBytes());
try {
mqttClient.publish(MQTT_Resp_Topic, res_message);
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.d(TAG, "deliveryComplete");
}
};
// Added by J. Yun, SCH Univ.
// Modified by S. Lee, SCH Univ.
private String getContainerName(String msg) {
String cnt = "";
try {
JSONObject jsonObject = new JSONObject(msg);
cnt = jsonObject.getJSONObject("pc").
getJSONObject("m2m:sgn").getString("sur");
// Log.d(TAG, "Content is " + cnt);
} catch (JSONException e) {
Log.e(TAG, "JSONObject error!");
}
return cnt;
}
// Added by J. Yun, SCH Univ.
private String getContainerContentJSON(String msg) {
String con = "";
try {
JSONObject jsonObject = new JSONObject(msg);
con = jsonObject.getJSONObject("pc").
getJSONObject("m2m:sgn").
getJSONObject("nev").
getJSONObject("rep").
getJSONObject("m2m:cin").
getString("con");
// Log.d(TAG, "Content is " + con);
} catch (JSONException e) {
Log.e(TAG, "JSONObject error!");
}
return con;
}
// Added by J. Yun, SCH Univ.
private String getContainerContentXML(String msg) {
String con = "";
try {
XmlToJson xmlToJson = new XmlToJson.Builder(msg).build();
JSONObject jsonObject = xmlToJson.toJson();
con = jsonObject.getJSONObject("m2m:cin").getString("con");
// Log.d(TAG, "Content is " + con);
} catch (JSONException e) {
Log.e(TAG, "JSONObject error!");
}
return con;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSitdown: {
if (((ToggleButton) v).isChecked()) {
btnSitdown.setVisibility(View.VISIBLE);
btnWait.setVisibility(View.INVISIBLE);
ControlRequest req = new ControlRequest("1");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText(msg);
}
});
}
});
req.start();
}
else
{
btnSitdown.setVisibility(View.VISIBLE);
btnWait.setVisibility(View.VISIBLE);
}
break;
}
case R.id.btnWait: {
if (((ToggleButton) v).isChecked()) {
btnSitdown.setVisibility(View.INVISIBLE);
btnWait.setVisibility(View.VISIBLE);
ControlRequest req = new ControlRequest("2");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText(msg);
}
});
}
});
req.start();
}
else
{
btnSitdown.setVisibility(View.VISIBLE);
btnWait.setVisibility(View.VISIBLE);
}
break;
}
case R.id.btnVideo:
// for URL
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://wnsgml4.ddns.net:8081"));
// Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://google.com"));
startActivity(intent);
break;
case R.id.btnRetrieve: {
RetrieveRequest
//MQTT
req = new RetrieveRequest("success");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
if(Integer.parseInt(getContainerContentXML(msg)) == 1)
{
textSuccess.setText("YES");
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
btn_train.performClick();
btnSitdown.setChecked(false);
btnWait.setChecked(false);
}
}, 600);
}
else
textSuccess.setText("NO");
}
});
}
});
req.start();
req = new RetrieveRequest("eat");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
if(Integer.parseInt(getContainerContentXML(msg)) == 1)
{
textEat.setText("Ate");
sendNotification_3();
}
else
textEat.setText("Not");
}
});
}
});
req.start();
req = new RetrieveRequest("alert");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
if(Integer.parseInt(getContainerContentXML(msg)) == 1)
{
textAlert.setText("Alert!");
sendNotification_5();
}
else
textAlert.setText("Nope Alert :)");
}
});
}
});
req.start();
req = new RetrieveRequest("remains");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textRemains.setText(getContainerContentXML(msg)+"%");
switch (getContainerContentXML(msg)) {
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
case "10":
case "11":
case "12":
case "13":
case "14":
case "15":
case "16":
case "17":
case "18":
case "19":
case "20":
case "21":
case "22":
case "23":
case "24":
case "25":
case "26":
case "27":
case "28":
case "29":
case "30":
case "31":
case "32":
case "33":
sendNotification_2();
break;
case "34":
case "35":
case "36":
case "37":
case "38":
case "39":
case "40":
case "41":
case "42":
case "43":
case "44":
case "45":
case "46":
case "47":
case "48":
case "49":
case "50":
case "51":
case "52":
case "53":
case "54":
case "55":
case "56":
case "57":
case "58":
case "59":
case "60":
case "61":
case "62":
case "63":
case "64":
case "65":
case "66":
sendNotification_1();
break;
default:
break;
}
}
});
}
});
req.start();
break;
}
case R.id.btn_train: {
if (((ToggleButton) v).isChecked()) {
btnSitdown.setVisibility(View.VISIBLE);
btnWait.setVisibility(View.VISIBLE);
ControlRequest req = new ControlRequest("0");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText(msg);
}
});
}
});
req.start();
}
else
{
btnSitdown.setVisibility(View.VISIBLE);
btnWait.setVisibility(View.VISIBLE);
ControlRequest req = new ControlRequest("0");
req.setReceiver(new IReceived() {
public void getResponseBody(final String msg) {
handler.post(new Runnable() {
public void run() {
textViewData.setText(msg);
}
});
}
});
req.start();
}
break;
}
case R.id.toggleButton_Addr: {
btnRetrieve.setVisibility(View.VISIBLE);
Switch_MQTT.setVisibility(View.VISIBLE);
EditText_Address.setHintTextColor(Color.BLUE);
EditText_Address.setBackgroundColor(Color.LTGRAY);
EditText_Address.setFocusable(false);
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(EditText_Address.getWindowToken(), 0);//hide keyboard
GetAEInfo();
break;
}
}
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onStop() {
super.onStop();
}
/* Response callback Interface */
public interface IReceived {
void getResponseBody(String msg);
}
// Retrieve , added by J. Yun, SCH Univ, Modified by S. Lee, SCH Univ.
class RetrieveRequest extends Thread {
private final Logger LOG = Logger.getLogger(RetrieveRequest.class.getName());
private IReceived receiver;
// private String ContainerName = "cnt-co2";
private String ContainerName = "";
public RetrieveRequest(String containerName) {
this.ContainerName = containerName;
}
public RetrieveRequest() {}
public void setReceiver(IReceived hanlder) { this.receiver = hanlder; }
@Override
public void run() {
try {
String sb = csebase.getServiceUrl() + "/" + ServiceAEName + "/" + ContainerName + "/" + "latest";
URL mUrl = new URL(sb);
HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setRequestProperty("Accept", "application/xml");
conn.setRequestProperty("X-M2M-RI", "12345");
conn.setRequestProperty("X-M2M-Origin", ae.getAEid() );
conn.setRequestProperty("nmtype", "long");
conn.connect();
String strResp = "";
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String strLine= "";
while ((strLine = in.readLine()) != null) {
strResp += strLine;
}
if ( strResp != "" ) {
receiver.getResponseBody(strResp);
}
conn.disconnect();
} catch (Exception exp) {
LOG.log(Level.WARNING, exp.getMessage());
}
}
}
/* Request Control train */
class ControlRequest extends Thread {
private final Logger LOG = Logger.getLogger(ControlRequest.class.getName());
private IReceived receiver;
private String container_name = "training";
public ContentInstanceObject contentinstance;
public ControlRequest(String comm) {
contentinstance = new ContentInstanceObject();
contentinstance.setContent(comm);
}
public void setReceiver(IReceived hanlder) { this.receiver = hanlder; }
@Override
public void run() {
try {
String sb = csebase.getServiceUrl() +"/" + ServiceAEName + "/" + container_name;
URL mUrl = new URL(sb);
HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(false);
conn.setRequestProperty("Accept", "application/xml");
conn.setRequestProperty("Content-Type", "application/vnd.onem2m-res+xml;ty=4");
conn.setRequestProperty("locale", "ko");
conn.setRequestProperty("X-M2M-RI", "12345");
conn.setRequestProperty("X-M2M-Origin", ae.getAEid() );
String reqContent = contentinstance.makeXML();
conn.setRequestProperty("Content-Length", String.valueOf(reqContent.length()));
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.write(reqContent.getBytes());
dos.flush();
dos.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String resp = "";
String strLine="";
while ((strLine = in.readLine()) != null) {
resp += strLine;
}
if (resp != "") {
receiver.getResponseBody(resp);
}
conn.disconnect();
} catch (Exception exp) {
LOG.log(Level.SEVERE, exp.getMessage());
}
}
}
/* Request AE Creation */
class aeCreateRequest extends Thread {
private final Logger LOG = Logger.getLogger(aeCreateRequest.class.getName());
String TAG = aeCreateRequest.class.getName();
private IReceived receiver;
int responseCode=0;
public ApplicationEntityObject applicationEntity;
public void setReceiver(IReceived hanlder) { this.receiver = hanlder; }
public aeCreateRequest(){
applicationEntity = new ApplicationEntityObject();
applicationEntity.setResourceName(ae.getappName());
Log.d(TAG, ae.getappName() + "JJjj");
}
@Override
public void run() {
try {
String sb = csebase.getServiceUrl();
URL mUrl = new URL(sb);
HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(false);
conn.setRequestProperty("Content-Type", "application/vnd.onem2m-res+xml;ty=2");
conn.setRequestProperty("Accept", "application/xml");
conn.setRequestProperty("locale", "ko");
conn.setRequestProperty("X-M2M-Origin", "S"+ae.getappName());
conn.setRequestProperty("X-M2M-RI", "12345");
conn.setRequestProperty("X-M2M-NM", ae.getappName() );
String reqXml = applicationEntity.makeXML();
conn.setRequestProperty("Content-Length", String.valueOf(reqXml.length()));
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.write(reqXml.getBytes());
dos.flush();
dos.close();
responseCode = conn.getResponseCode();
BufferedReader in = null;
String aei = "";
if (responseCode == 201) {
// Get AEID from Response Data
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String resp = "";
String strLine;
while ((strLine = in.readLine()) != null) {
resp += strLine;
}
ParseElementXml pxml = new ParseElementXml();
...
This file has been truncated, please download it to see its full contents.
Android strings.xml for Mobius App
XMLThis file contains text information necessary to run the app.
<resources>
<string name="app_name">WALWAL: Pet care for everyone</string>
<string name="textview_about">WALWAL: Pet care for everyone</string>
<string name="btn_retrieve">Reload</string>
<string name="title">WALWAL</string>
<string name="btn_switch">Automatic\nreceiving</string>
<string name="mobius_address">203.253.128.177</string>
<string name="addr_unset">Disconnected</string>
<string name="addr_set">Connecting</string>
<!-- Added by LSC -->
<string name="textview_train_label">Training</string>
<string name="textview_train_value">Training</string>
<string name="textview_remains_label">Remains</string>
<string name="textview_remains_value">"?%</string>
<string name="textview_eat_label">Food</string>
<string name="textview_eat_value">...</string>
<string name="textview_alert_label">alert</string>
<string name="textview_alert_value">alert</string>
<string name="textview_success_label">SUCCESS</string>
<string name="textview_success_value">SUCCESS</string>
<string name="btn_train"></string>
<string name="btn_Sitdown"></string>
<string name="btn_Wait"></string>
</resources>
Android activity_main.xml for Mobius App
XMLactivity_main.xml is a file dedicated to the layout of the app, that is, the layout of the screen.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textViewTitle"
android:layout_width="match_parent"
android:layout_height="1sp"
android:textSize="20sp" ></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:autofillHints="" tools:targetApi="o"
android:focusable="false"
tools:ignore="Suspicious0dp" ></EditText>
<ToggleButton
android:id="@+id/toggleButton_Addr"
android:layout_marginTop="1115sp"
android:layout_marginLeft="110dp"
android:layout_width="0sp"
android:layout_height="0dp"
android:layout_weight="1"
android:textSize="0sp" ></ToggleButton>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnVideo"
android:layout_width="260sp"
android:layout_height="260sp"
android:onClick="onClick"
android:layout_marginLeft="440sp"
android:layout_marginTop="310sp"
android:background="#00ff0011"
android:text="" ></Button>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp">
<Switch
android:id="@+id/switch_mqtt"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="1114sp"
android:layout_marginLeft="20sp"
android:textSize="24sp"
android:textColor="#000000" ></Switch>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ToggleButton
android:id="@+id/btn_train"
android:layout_marginTop="700sp"
android:layout_marginLeft="100dp"
android:layout_width="250sp"
android:layout_height="60dp"
android:layout_weight="1"
android:textSize="16sp"
android:textOff="Waiting for training"
android:textOn="Training" ></ToggleButton>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnRetrieve"
android:layout_width="match_parent"
android:layout_height="60sp"
android:layout_weight="10"
android:layout_marginTop="1115sp"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:text="Reload"
android:textSize="30sp" ></Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ToggleButton
android:id="@+id/btnSitdown"
android:layout_width="match_parent"
android:layout_height="50sp"
android:layout_weight="0"
android:layout_marginTop="760sp"
android:layout_marginLeft="100sp"
android:layout_marginRight="450sp"
android:textSize="16sp"
android:textOff="Sit down - Waiting"
android:textOn="Sit down - Ongoing"
android:text="Sitdown"></ToggleButton>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ToggleButton
android:id="@+id/btnWait"
android:layout_width="match_parent"
android:layout_height="50sp"
android:layout_weight="0"
android:layout_marginTop="810sp"
android:layout_marginLeft="100sp"
android:layout_marginRight="450sp"
android:textSize="16sp"
android:textOff="Wait - Waiting"
android:textOn="Wait - Ongoing"
android:text="Wait"></ToggleButton>
</LinearLayout>
<!-- DATA -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="150sp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="0sp" ></TextView>
<TextView
android:id="@+id/textRemains"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25sp"
android:layout_marginTop="420sp"
android:textSize="70sp" ></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:textColor="@android:color/black"
android:textSize="0sp" ></TextView>
<TextView
android:id="@+id/textSuccess"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="25sp"
android:layout_marginTop="20sp"
android:textSize="70sp" ></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="100sp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="0sp" ></TextView>
<TextView
android:id="@+id/textAlert"
android:layout_width="0sp"
android:layout_height="0sp"
android:textSize="70sp" ></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="50sp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="0sp" ></TextView>
<TextView
android:id="@+id/textEat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="440sp"
android:layout_marginTop="720sp"
android:textSize="100sp" ></TextView>
</LinearLayout>
<ScrollView
android:id="@+id/scrollViewText"
android:layout_width="match_parent"
android:layout_height="0sp"
android:layout_marginLeft="10sp"
android:layout_marginTop="5sp"
android:layout_marginRight="10sp"
android:layout_weight="0.50"
android:background="#575c72">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:id="@+id/textViewData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#fdfcfc"
android:textSize="12sp" ></TextView>
</LinearLayout>
</ScrollView>
<!--FOR PUSH-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/notify_1"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="1">
</Button>
<Button
android:id="@+id/notify_2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="2">
</Button>
<Button
android:id="@+id/notify_3"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="3">
</Button>
<Button
android:id="@+id/notify_4"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="4">
</Button>
<Button
android:id="@+id/notify_5"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="5">
</Button>
<Button
android:id="@+id/notify_6"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="1">
</Button>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
Android AndroidManifest.xml for Mobius App
XMLEvery app project must have an AndroidManifest.xml file (with precisely that name) at the root of the project source set. The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play.
I referred to the site.
https://developer.android.com/guide/topics/manifest/manifest-intro
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="sch.iot.onem2mapp">
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK" ></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" ></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" ></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
tools:ignore="Instantiatable">
<intent-filter>
<action android:name="android.intent.action.MAIN" ></action>
<category android:name="android.intent.category.LAUNCHER" ></category>
</intent-filter>
</activity>
<service android:name="org.eclipse.paho.android.service.MqttService" ></service>
</application>
</manifest>
Comments