Analisis Kinerja Model Rancangan Sistem Home_Automation Berbasis Internet Protocol Terhadap Penggunaan Http Persistent dan Non-Persistent
LAMPIRAN 1
KODE PROGRAM KONTROLER
Fugue.ino
/ **
* Fugue – Sebuah pr ogr am Ar dui no unt uk Home Aut omat i on.
*
* @package Nugr aha
* @Aut hor Wahyu Nugr aha
*/
#i nc l ude " Fugue. h"
names pac e Mai n {
us i ng Nugr aha: : Foundat i on: : Bas eCont r ol l er ;
c l as s Cont r ol l er : publ i c v i r t ual Bas eCont r ol l
{
publ i c :
v oi d s et up( )
{
Debug: : i s DebugMode = t r ue;
i f ( ! env : : wi f i : : obt ai nI pAddr es s Aut omat i
Wi Fi . c onf i g( env : : wi f i : : i p, env : : wi
env : : wi f i : : dns 1, env : : wi f i : :
}
boar d- >i ni t i al i z e( ) ;
boar d- >aut omat e( ) ;
}
er
c al l y ) {
f i : : gat eway , env : : wi f i : : s ubnet ,
dns 2) ;
v oi d l oop( )
{
Sc hedul er : : handl eEv ent s ( ) ;
}
};
}
#i nc l ude " boot s t r ap/ boot s t r ap. hpp"
App/Boards/WemosD1.hpp
namespace App { namespace Boards {
usingnamespace App::Devices;
using Nugraha::Foundation::Board;
using App::Gateways::WebServer::Server;
usingnamespace App::Gateways::HttpClients;
79
Universitas Sumatera Utara
classWemosD1 : publicvirtual Board {
protected:
void gateways()
{
// this->attachGateway(new Server());
this->attachGateway(new PersistentHttp(std::map({
, env::httpClient::host },
{ "host"
{ "mode"
, env::httpClient::mode },
{ "publishKey"
, env::httpClient::publishKey },
{ "subscribeKey" , env::httpClient::subscribeKey },
, env::httpClient::signature },
{ "signature"
{ "channelName" , env::httpClient::channelName },
{ "callback"
, env::httpClient::callback }
})));
}
void devices()
{
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
}
Lampu(D2, NULL));
Lampu(D3, NULL));
Lampu(D4, NULL));
Lampu(D5, NULL));
AirConditioner(D6, NULL));
LED(BUILTIN_LED, NULL));
void sensors()
{
}
};
}}
app/Devices/AirConditioner.hpp
namespace App { namespace Devices {
using Nugraha::Sensors::Sensor;
using Nugraha::Devices::Device;
using Nugraha::Devices::Drivers::AirConditionerDriver;
classAirConditioner : publicvirtual Device
{
public:
AirConditioner(int pin, Sensor* sensor=NULL) : Device(pin, sensor) {}
void initialize()
{
pinMode(this->pin, OUTPUT);
setDriver(new AirConditionerDriver());
}
void behavior()
80
Universitas Sumatera Utara
{
}
};
}}
app/Devices/Lampu.hpp
namespace App { namespace Devices {
using Nugraha::Sensors::Sensor;
using Nugraha::Devices::Device;
classLampu : publicvirtual Device
{
public:
Lampu(int pin, Sensor* sensor=NULL) : Device(pin, sensor) {}
void initialize()
{
pinMode(this->pin, OUTPUT);
}
void behavior()
{
}
};
}}
app/Gateways/HttpClients/NonPersistentHttp.hpp
namespace App { namespace Gateways { namespace HttpClients {
using Nugraha::Gateways::Esp8266::WifiHttpClient;
classNonPersistentHttp : publicvirtual WifiHttpClient
{
public:
NonPersistentHttp(std::map setting):WifiHttpClient(setting) {}
void service()
{
Debug::println("Memulai service koneksi HTTP Non-persistent...");
interval = 0;
http.setReuse(false);
Scheduler::every(interval, [=]() {
updateMessage();
httpGet(generateUri(), [=]() {
board->executeUserCommand(response);
});
});
}
};
81
Universitas Sumatera Utara
}}}
app/Gateways/HttpClients/PersistentHttp.hpp
namespace App { namespace Gateways { namespace HttpClients {
using Nugraha::Gateways::Esp8266::WifiHttpClient;
classPersistentHttp : publicvirtual WifiHttpClient
{
public:
PersistentHttp(std::map setting) : WifiHttpClient(setting) {}
void service()
{
Debug::println("Memulai service koneksi HTTP Persistent...");
interval = 0;
http.setReuse(true);
Scheduler::every(interval, [=]() {
updateMessage();
httpGet(generateUri(), [=]() {
board->executeUserCommand(response);
});
});
}
};
}}}
config/env.hpp
namespace env {
namespace wifi {
String ssid = "Fugue2";
String password = "fugue123";
bool obtainIpAddressAutomatically = false;
IPAddress ip(192, 168, 137, 69);
IPAddress subnet(255, 255, 255, 0);
IPAddress gateway(192, 168, 137, 1);
IPAddress dns1(8, 8, 8, 8);
IPAddress dns2(8, 8, 4, 4);
}
namespace httpClient {
String host = "www.wahyunugraha.com";
String mode = "publish";
String publishKey = "pub-w-3e5de365-5d57-48c7-a317-366ef2846eb4";
String subscribeKey = "sub-n-cca59b64-d972-11e5-bdd5-02ee2ddab7fe";
String signature = "0";
String channelName = "rumah1";
String callback = "0";
}
82
Universitas Sumatera Utara
namespace server {
ESP8266WebServer* server =
}
new ESP8266WebServer(80);
}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Devices/Drivers/AirConditionerDriver.hpp
namespace Nugraha { namespace Devices { namespace Drivers {
using Nugraha::Support::Facades::Scheduler::Scheduler;
classAirConditionerDriver: publicvirtual Driver
{
protected:
public:
bool turnOn(int pin)
{
digitalWrite(pin, HIGH);
Scheduler::after(50, [=]() {
digitalWrite(pin, LOW);
});
returntrue;
}
bool turnOff(int pin)
{
digitalWrite(pin, HIGH);
Scheduler::after(50, [=]() {
digitalWrite(pin, LOW);
});
returntrue;
}
};
}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Devices/Drivers/SinkModeDriver.hpp
namespace Nugraha { namespace Devices { namespace Drivers {
classSinkModeDriver : publicvirtual Driver
{
protected:
public:
bool turnOn(int pin)
{
digitalWrite(pin, LOW);
returntrue;
}
bool turnOff(int pin)
{
digitalWrite(pin, HIGH);
returntrue;
}
};
83
Universitas Sumatera Utara
}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Devices/Device.hpp
namespace Nugraha { namespace Devices {
using Nugraha::Traits::HasId;
using Nugraha::Traits::HasLogger;
using Nugraha::Support::Facades::Debug;
using Nugraha::Contracts::Sensors::SensorContract;
using Nugraha::Contracts::Devices::DriverContract;
using Nugraha::Contracts::Devices::DeviceContract;
using Nugraha::Contracts::Foundation::LoggerContract;
classDevice : publicvirtual DeviceContract, public HasLogger, public HasId
{
protected:
int pin = -1;
bool isOn = false;
SensorContract* sensor;
DriverContract* driver;
unsignedlong previousMillis = 0;
static DriverContract* defaultDriver;
public:
Device(int pin, SensorContract* sensor)
{
this->pin = pin;
this->sensor = sensor;
this->driver = Device::defaultDriver;
}
virtual ~Device() {}
void toggle()
{
if (this->isOn==false) {
this->turnOn();
}
else {
this->turnOff();
}
}
void turnOn()
{
if(this->pin != -1) {
if(driver->turnOn(this->pin)) {
this->isOn = true;
logger->addNotification(1, String(this->pin));
}
}
}
void turnOff()
{
if(this->pin != -1) {
if(driver->turnOff(this->pin)) {
this->isOn = false;
logger->addNotification(0, String(this->pin));
}
}
84
Universitas Sumatera Utara
}
int getPin()
{
returnthis->pin;
}
void setSensor(SensorContract* sensor)
{
this->sensor = sensor;
}
void setDriver(DriverContract* driver)
{
this->driver = driver;
}
int getId() override {HasId::getId();}
void setLogger(LoggerContract* logger) override {HasLogger::setLogger(logger);}
LoggerContract* getLogger() override {HasLogger::getLogger();}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/Application.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Contracts::Foundation::BoardContract;
classApplication
{
public:
BaseController* controller;
int serialBaudRate;
bool beginSerial;
Application(BaseController* controller, BoardContract* board, int
serialBaudRate, bool beginSerial)
{
this->controller = controller;
this->controller->board = board;
this->serialBaudRate = serialBaudRate;
this->beginSerial = beginSerial;
}
virtual ~Application() {}
virtualvoid setup()
{
this->controller->setup();
}
virtualvoid loop()
{
this->controller->loop();
}
85
Universitas Sumatera Utara
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/BaseController.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Contracts::Foundation::BoardContract;
classBaseController
{
public:
BoardContract* board;
virtual ~BaseController() {}
virtualvoid setup()=0;
virtualvoid loop()=0;
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/Board.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Traits::HasLogger;
using Nugraha::Collections::Vector;
using Nugraha::Contracts::Devices::DeviceContract;
using Nugraha::Contracts::Sensors::SensorContract;
using Nugraha::Contracts::Gateways::GatewayContract;
using Nugraha::Contracts::Foundation::BoardContract;
using Nugraha::Contracts::Foundation::LoggerContract;
using Nugraha::Contracts::Collections::CollectionContract;
classBoard : publicvirtual BoardContract, public HasLogger
{
protected:
CollectionContract* devicesCollection;
CollectionContract* sensorsCollection;
CollectionContract* gatewaysCollection;
DeviceContract* Default = NULL;
voidinitializeAll()
{
/** Inisialisasi setiap Gateway. */
for(int i=0; icount(); i++) {
if(gatewaysCollection->getMemberAt(i) != NULL) {
gatewaysCollection->getMemberAt(i)->initialize();
}
}
/** Inisialisasi setiap Device. */
for(int i=0; icount(); i++) {
if(devicesCollection->getMemberAt(i) != NULL) {
devicesCollection->getMemberAt(i)->initialize();
}
86
Universitas Sumatera Utara
}
}
public:
Board()
{
devicesCollection = new Vector();
sensorsCollection = new Vector();
gatewaysCollection = new Vector();
setLogger(new Logger());
}
void initialize()
{
sensors();
devices();
gateways();
initializeAll();
}
void automate()
{
/** Jalankan behavior setiap Device. */
for(int i=0; icount(); i++) {
if(devicesCollection->getMemberAt(i) != NULL) {
devicesCollection->getMemberAt(i)->behavior();
devicesCollection->getMemberAt(i)->setLogger(logger);
}
}
/** Jalankan service setiap Gateway. */
for(int i=0; icount(); i++) {
if(gatewaysCollection->getMemberAt(i) != NULL) {
gatewaysCollection->getMemberAt(i)->service();
gatewaysCollection->getMemberAt(i)->setLogger(logger);
gatewaysCollection->getMemberAt(i)->setBoard(this);
}
}
}
void attachDevice(DeviceContract* device)
{
devicesCollection->add(device);
}
void attachSensor(SensorContract* sensor)
{
sensorsCollection->add(sensor);
}
void attachGateway(GatewayContract* gateway)
{
gatewaysCollection->add(gateway);
}
void executeUserCommand(String userCommands)
{
DeviceContract* device;
DynamicJsonBuffer jsonBuffer;
87
Universitas Sumatera Utara
JsonObject& root = jsonBuffer.parseObject(userCommands);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
for(int i=0; iturnOn();
}
} elseif(action=="turnOff") {
if((device=getDeviceByPin(pin)) != NULL) {
device->turnOff();
}
} elseif(action=="toggle") {
if((device=getDeviceByPin(pin)) != NULL) {
device->toggle();
}
}
}
}
DeviceContract* getDeviceByPin(int pin)
{
DeviceContract* device;
for(int i=0; icount(); i++) {
device = devicesCollection->getMemberAt(i);
if(device != NULL) {
if(device->getPin() == pin) {
return device;
}
}
}
returnNULL;
}
~Board()
{
delete gatewaysCollection;
delete devicesCollection;
delete sensorsCollection;
delete logger;
}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/Logger.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Contracts::Foundation::LoggerContract;
88
Universitas Sumatera Utara
classLogger : public LoggerContract {
protected:
DynamicJsonBuffer* jsonBuffer = new DynamicJsonBuffer();
JsonObject* root = &jsonBuffer->createObject();
JsonArray* notifications = &root->createNestedArray("notifications");
JsonArray* measurements = &root->createNestedArray("measurements");
JsonArray* connectionInfos = &root>createNestedArray("connectionInfos");
bool sendBoardInfo = true;
voidclean()
{
delete jsonBuffer;
jsonBuffer = NULL;
}
voidreInitializeJsonBuffer()
{
jsonBuffer = new DynamicJsonBuffer();
root = &jsonBuffer->createObject();
notifications = &root->createNestedArray("notifications");
measurements = &root->createNestedArray("measurements");
connectionInfos = &root->createNestedArray("connectionInfos");
}
voidaddBoardInfoToRecord()
{
JsonObject& boardInfo = root->createNestedObject("boardInfo");
boardInfo["chipId"] = ESP.getChipId();
boardInfo["cpuFreqMHz"] = ESP.getCpuFreqMHz();
boardInfo["sdkVersion"] = ESP.getSdkVersion();
boardInfo["bootVersion"] = ESP.getBootVersion();
boardInfo["bootMode"] = ESP.getBootMode();
boardInfo["cycleCount"] = ESP.getCycleCount();
boardInfo["freeHeap"] = ESP.getFreeHeap();
boardInfo["sketchSize"] = ESP.getSketchSize();
boardInfo["freeSketchSpace"] = ESP.getFreeSketchSpace();
}
public:
void addNotification(int code, String message)
{
if(jsonBuffer == NULL)
reInitializeJsonBuffer();
String state;
switch(code) {
case0 :
state = "off";
break;
case1 :
state = "on";
break;
default :
break;
}
JsonObject& notification = notifications->createNestedObject();
notification["pin"] = message;
89
Universitas Sumatera Utara
notification["state"] = state;
}
void addConnectionInfo(String parameter, String value)
{
if(jsonBuffer == NULL)
reInitializeJsonBuffer();
JsonObject& connectionInfo = connectionInfos->createNestedObject();
connectionInfo["parameter"] = parameter;
connectionInfo["value"] = value;
}
void addSensorMeasurement(String sensorName, String measurementValue)
{
if(jsonBuffer == NULL)
reInitializeJsonBuffer();
JsonObject& measurement = measurements->createNestedObject();
measurement["sensor"] = sensorName;
measurement["value"] = measurementValue;
}
String getLogMessage()
{
if(jsonBuffer != NULL) {
if(sendBoardInfo) {
addBoardInfoToRecord();
}
String logMessages;
root->printTo(logMessages);
clean();
reInitializeJsonBuffer();
return logMessages;
} else {
return"{\"records\":[]}";
}
}
void printToSerial()
{
if(jsonBuffer != NULL) {
if(sendBoardInfo) {
addBoardInfoToRecord();
}
root->prettyPrintTo(Serial);
}
else
Serial.println("NULL");
}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Gateways/Esp8266/WifiHttpClient.hpp
90
Universitas Sumatera Utara
namespace Nugraha { namespace Gateways { namespace Esp8266 {
using Nugraha::Traits::HasId;
using Nugraha::Traits::HasLogger;
using Nugraha::Contracts::Gateways::GatewayContract;
using Nugraha::Contracts::Foundation::BoardContract;
using Nugraha::Contracts::Foundation::LoggerContract;
classWifiHttpClient : publicvirtual GatewayContract, public HasLogger,
public HasId
{
protected:
ESP8266WiFiMulti WiFiMulti;
HTTPClient http;
BoardContract* board;
String ssid
= env::wifi::ssid;
String password
= env::wifi::password;
unsignedlong interval = 1000;
String
String
String
String
String
String
String
String
String
host;
mode;
publishKey;
subscribeKey;
signature;
channelName;
callback;
message = "{\"text\":\"hello\"}";
response;
public:
WifiHttpClient(std::map setting)
{
this->host = setting["host"];
this->mode = setting["mode"];
this->publishKey = setting["publishKey"];
this->subscribeKey = setting["subscribeKey"];
this->signature = setting["signature"];
this->channelName = setting["channelName"];
this->callback = setting["callback"];
}
virtual ~WifiHttpClient() {}
void initialize()
{
Serial.println();
Serial.println();
Serial.println();
for(uint8_t t = 4; t >0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP("Fugue2", "fugue123");
}
String generateUri()
91
Universitas Sumatera Utara
{
if(message != "") {
String uri = "http://" + host + "/" + mode + "/" + publishKey
+ "/" + subscribeKey + "/" + signature + "/" + channelName +
"/" + callback + "/" + message;
Serial.println(uri);
return uri;
}
}
template
void httpGet(String uri, Callback callback)
{
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
unsignedlong tempMillis = millis();
http.begin(uri);
int httpCode = http.GET();
if(httpCode >0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
// Hitung delay.
addDelayToRecord(String(millis() - tempMillis));
// Ekstrak pesan dan panggil fungsi callback.
response = http.getString();
callback();
} else {
addDelayToRecord(String(-1));
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n",
http.errorToString(httpCode).c_str());
}
http.end();
}
}
int getId() override {HasId::getId();}
void updateMessage()
{
this->message = getLogger()->getLogMessage();
}
void setLogger(LoggerContract* logger) override
{
HasLogger::setLogger(logger);
addDelayToRecord(String(0));
}
LoggerContract* getLogger()
{
return logger;
}
92
Universitas Sumatera Utara
void setBoard(BoardContract* board)
{
this->board = board;
}
void addDelayToRecord(String value)
{
getLogger()->addConnectionInfo("delay", value);
}
};
}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Sensors/Sensor.hpp
namespace Nugraha { namespace Sensors {
using Nugraha::Traits::HasId;
using Nugraha::Traits::HasLogger;
using Nugraha::Sensors::Drivers::Driver;
using Nugraha::Sensors::Drivers::GenericDriver;
using Nugraha::Contracts::Sensors::SensorContract;
using Nugraha::Contracts::Foundation::LoggerContract;
classSensor : publicvirtual SensorContract, public HasLogger, public HasId
{
protected:
Driver* driver;
public:
int id;
int pin;
constchar* name;
virtual ~Sensor() {}
Sensor(int pin, constchar* name)
this->pin = pin;
this->name = name;
this->driver = new GenericDriver();
}
{
int getId() override {HasId::getId();}
void setLogger(LoggerContract* logger) override
{HasLogger::setLogger(logger);}
LoggerContract* getLogger() override {HasLogger::getLogger();}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Support/Facades/Scheduler/BaseEvent.hpp
93
Universitas Sumatera Utara
namespace Nugraha { namespace Support { namespace Facades { namespace
Scheduler {
using Nugraha::Contracts::Support::Facades::Scheduler::EventContract;
using Nugraha::Traits::HasId;
classBaseEvent : publicvirtual EventContract, publicvirtual HasId
{
protected:
unsignedlong interval;
unsignedlong previousMillis;
int repeatCount = -1;
public:
BaseEvent(unsignedlong interval, int repeatCount)
{
this->previousMillis = millis();
this->interval = interval;
this->repeatCount = repeatCount;
}
virtual ~BaseEvent()
{
}
int executionCount = 0;
voidupdate(unsignedlong now)
{
if(now - previousMillis >= interval && (repeatCount == -1 ||
repeatCount >0)) {
previousMillis = now;
Serial.printf("[%d] ", this->id);
executeCallback();
if(repeatCount != -1) {
repeatCount--;
}
}
}
intgetRepeatCount()
{
return repeatCount;
}
intgetId() override
{
HasId::getId();
}
};
}}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Support/Facades/Scheduler/Scheduler.hpp
namespace Nugraha { namespace Support { namespace Facades { namespace
Scheduler {
using Nugraha::Collections::Collection;
using Nugraha::Contracts::Collections::CollectionContract;
94
Universitas Sumatera Utara
classScheduler
{
protected:
static CollectionContract* eventCollection;
staticbool init;
public:
staticvoid handleEvents()
{
if(init) {
after(1, [=](){Serial.println();});
init = false;
}
for(auto event = eventCollection->getMembers().begin(); event !=
eventCollection->getMembers().end();) {
(*event)->update(millis());
if((*event)->getRepeatCount() == 0) {
delete *event;
*event = NULL;
event = eventCollection->getMembers().erase(event);
} else {
++event;
}
}
}
template
staticvoid every(unsignedlong interval, Callback callback, int
repeatCount = -1)
{
eventCollection->add(new StaticEvent(interval, callback,
repeatCount));
}
template
staticvoid every(unsignedlong interval, ObjectType object, Callback
callback, int repeatCount = -1)
{
eventCollection->add(new Event(interval,
callback, object, repeatCount));
}
template
staticvoid after(unsignedlong afterMillis, Callback callback)
{
every(afterMillis, callback, 1);
}
static BaseEvent* getEventAt(int index)
{
return eventCollection->getMemberAt(index);
}
};
CollectionContract* Scheduler::eventCollection = new
Collection();
bool Scheduler::init = true;
95
Universitas Sumatera Utara
}}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Support/Facades/Scheduler/StaticEvent.hp
p
names pac e Nugr aha { names pac e Suppor t { names pac e Fac ades { names pac e Sc hedul er {
t empl at e
c l as s St at i c Ev ent : publ i c v i r t ual Bas eEv ent
{
pr ot ec t ed:
Cal l bac k c al l bac k ;
publ i c :
St at i c Ev ent ( uns i gned l ong i nt er v al , Cal l bac k c al l bac k , i nt r epeat Count ) :
Bas eEv ent ( i nt er v al , r epeat Count ) , c al l bac k ( c al l bac k )
{
}
v oi d ex ec ut eCal l bac k ( )
{
t hi s - >c al l bac k ( ) ;
}
};
}}}}
96
Universitas Sumatera Utara
LAMPIRAN 2
KODE PROGRAM APLIKASI WEB
App/Http/routes.php
KODE PROGRAM KONTROLER
Fugue.ino
/ **
* Fugue – Sebuah pr ogr am Ar dui no unt uk Home Aut omat i on.
*
* @package Nugr aha
* @Aut hor Wahyu Nugr aha
*/
#i nc l ude " Fugue. h"
names pac e Mai n {
us i ng Nugr aha: : Foundat i on: : Bas eCont r ol l er ;
c l as s Cont r ol l er : publ i c v i r t ual Bas eCont r ol l
{
publ i c :
v oi d s et up( )
{
Debug: : i s DebugMode = t r ue;
i f ( ! env : : wi f i : : obt ai nI pAddr es s Aut omat i
Wi Fi . c onf i g( env : : wi f i : : i p, env : : wi
env : : wi f i : : dns 1, env : : wi f i : :
}
boar d- >i ni t i al i z e( ) ;
boar d- >aut omat e( ) ;
}
er
c al l y ) {
f i : : gat eway , env : : wi f i : : s ubnet ,
dns 2) ;
v oi d l oop( )
{
Sc hedul er : : handl eEv ent s ( ) ;
}
};
}
#i nc l ude " boot s t r ap/ boot s t r ap. hpp"
App/Boards/WemosD1.hpp
namespace App { namespace Boards {
usingnamespace App::Devices;
using Nugraha::Foundation::Board;
using App::Gateways::WebServer::Server;
usingnamespace App::Gateways::HttpClients;
79
Universitas Sumatera Utara
classWemosD1 : publicvirtual Board {
protected:
void gateways()
{
// this->attachGateway(new Server());
this->attachGateway(new PersistentHttp(std::map({
, env::httpClient::host },
{ "host"
{ "mode"
, env::httpClient::mode },
{ "publishKey"
, env::httpClient::publishKey },
{ "subscribeKey" , env::httpClient::subscribeKey },
, env::httpClient::signature },
{ "signature"
{ "channelName" , env::httpClient::channelName },
{ "callback"
, env::httpClient::callback }
})));
}
void devices()
{
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
this->attachDevice(new
}
Lampu(D2, NULL));
Lampu(D3, NULL));
Lampu(D4, NULL));
Lampu(D5, NULL));
AirConditioner(D6, NULL));
LED(BUILTIN_LED, NULL));
void sensors()
{
}
};
}}
app/Devices/AirConditioner.hpp
namespace App { namespace Devices {
using Nugraha::Sensors::Sensor;
using Nugraha::Devices::Device;
using Nugraha::Devices::Drivers::AirConditionerDriver;
classAirConditioner : publicvirtual Device
{
public:
AirConditioner(int pin, Sensor* sensor=NULL) : Device(pin, sensor) {}
void initialize()
{
pinMode(this->pin, OUTPUT);
setDriver(new AirConditionerDriver());
}
void behavior()
80
Universitas Sumatera Utara
{
}
};
}}
app/Devices/Lampu.hpp
namespace App { namespace Devices {
using Nugraha::Sensors::Sensor;
using Nugraha::Devices::Device;
classLampu : publicvirtual Device
{
public:
Lampu(int pin, Sensor* sensor=NULL) : Device(pin, sensor) {}
void initialize()
{
pinMode(this->pin, OUTPUT);
}
void behavior()
{
}
};
}}
app/Gateways/HttpClients/NonPersistentHttp.hpp
namespace App { namespace Gateways { namespace HttpClients {
using Nugraha::Gateways::Esp8266::WifiHttpClient;
classNonPersistentHttp : publicvirtual WifiHttpClient
{
public:
NonPersistentHttp(std::map setting):WifiHttpClient(setting) {}
void service()
{
Debug::println("Memulai service koneksi HTTP Non-persistent...");
interval = 0;
http.setReuse(false);
Scheduler::every(interval, [=]() {
updateMessage();
httpGet(generateUri(), [=]() {
board->executeUserCommand(response);
});
});
}
};
81
Universitas Sumatera Utara
}}}
app/Gateways/HttpClients/PersistentHttp.hpp
namespace App { namespace Gateways { namespace HttpClients {
using Nugraha::Gateways::Esp8266::WifiHttpClient;
classPersistentHttp : publicvirtual WifiHttpClient
{
public:
PersistentHttp(std::map setting) : WifiHttpClient(setting) {}
void service()
{
Debug::println("Memulai service koneksi HTTP Persistent...");
interval = 0;
http.setReuse(true);
Scheduler::every(interval, [=]() {
updateMessage();
httpGet(generateUri(), [=]() {
board->executeUserCommand(response);
});
});
}
};
}}}
config/env.hpp
namespace env {
namespace wifi {
String ssid = "Fugue2";
String password = "fugue123";
bool obtainIpAddressAutomatically = false;
IPAddress ip(192, 168, 137, 69);
IPAddress subnet(255, 255, 255, 0);
IPAddress gateway(192, 168, 137, 1);
IPAddress dns1(8, 8, 8, 8);
IPAddress dns2(8, 8, 4, 4);
}
namespace httpClient {
String host = "www.wahyunugraha.com";
String mode = "publish";
String publishKey = "pub-w-3e5de365-5d57-48c7-a317-366ef2846eb4";
String subscribeKey = "sub-n-cca59b64-d972-11e5-bdd5-02ee2ddab7fe";
String signature = "0";
String channelName = "rumah1";
String callback = "0";
}
82
Universitas Sumatera Utara
namespace server {
ESP8266WebServer* server =
}
new ESP8266WebServer(80);
}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Devices/Drivers/AirConditionerDriver.hpp
namespace Nugraha { namespace Devices { namespace Drivers {
using Nugraha::Support::Facades::Scheduler::Scheduler;
classAirConditionerDriver: publicvirtual Driver
{
protected:
public:
bool turnOn(int pin)
{
digitalWrite(pin, HIGH);
Scheduler::after(50, [=]() {
digitalWrite(pin, LOW);
});
returntrue;
}
bool turnOff(int pin)
{
digitalWrite(pin, HIGH);
Scheduler::after(50, [=]() {
digitalWrite(pin, LOW);
});
returntrue;
}
};
}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Devices/Drivers/SinkModeDriver.hpp
namespace Nugraha { namespace Devices { namespace Drivers {
classSinkModeDriver : publicvirtual Driver
{
protected:
public:
bool turnOn(int pin)
{
digitalWrite(pin, LOW);
returntrue;
}
bool turnOff(int pin)
{
digitalWrite(pin, HIGH);
returntrue;
}
};
83
Universitas Sumatera Utara
}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Devices/Device.hpp
namespace Nugraha { namespace Devices {
using Nugraha::Traits::HasId;
using Nugraha::Traits::HasLogger;
using Nugraha::Support::Facades::Debug;
using Nugraha::Contracts::Sensors::SensorContract;
using Nugraha::Contracts::Devices::DriverContract;
using Nugraha::Contracts::Devices::DeviceContract;
using Nugraha::Contracts::Foundation::LoggerContract;
classDevice : publicvirtual DeviceContract, public HasLogger, public HasId
{
protected:
int pin = -1;
bool isOn = false;
SensorContract* sensor;
DriverContract* driver;
unsignedlong previousMillis = 0;
static DriverContract* defaultDriver;
public:
Device(int pin, SensorContract* sensor)
{
this->pin = pin;
this->sensor = sensor;
this->driver = Device::defaultDriver;
}
virtual ~Device() {}
void toggle()
{
if (this->isOn==false) {
this->turnOn();
}
else {
this->turnOff();
}
}
void turnOn()
{
if(this->pin != -1) {
if(driver->turnOn(this->pin)) {
this->isOn = true;
logger->addNotification(1, String(this->pin));
}
}
}
void turnOff()
{
if(this->pin != -1) {
if(driver->turnOff(this->pin)) {
this->isOn = false;
logger->addNotification(0, String(this->pin));
}
}
84
Universitas Sumatera Utara
}
int getPin()
{
returnthis->pin;
}
void setSensor(SensorContract* sensor)
{
this->sensor = sensor;
}
void setDriver(DriverContract* driver)
{
this->driver = driver;
}
int getId() override {HasId::getId();}
void setLogger(LoggerContract* logger) override {HasLogger::setLogger(logger);}
LoggerContract* getLogger() override {HasLogger::getLogger();}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/Application.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Contracts::Foundation::BoardContract;
classApplication
{
public:
BaseController* controller;
int serialBaudRate;
bool beginSerial;
Application(BaseController* controller, BoardContract* board, int
serialBaudRate, bool beginSerial)
{
this->controller = controller;
this->controller->board = board;
this->serialBaudRate = serialBaudRate;
this->beginSerial = beginSerial;
}
virtual ~Application() {}
virtualvoid setup()
{
this->controller->setup();
}
virtualvoid loop()
{
this->controller->loop();
}
85
Universitas Sumatera Utara
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/BaseController.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Contracts::Foundation::BoardContract;
classBaseController
{
public:
BoardContract* board;
virtual ~BaseController() {}
virtualvoid setup()=0;
virtualvoid loop()=0;
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/Board.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Traits::HasLogger;
using Nugraha::Collections::Vector;
using Nugraha::Contracts::Devices::DeviceContract;
using Nugraha::Contracts::Sensors::SensorContract;
using Nugraha::Contracts::Gateways::GatewayContract;
using Nugraha::Contracts::Foundation::BoardContract;
using Nugraha::Contracts::Foundation::LoggerContract;
using Nugraha::Contracts::Collections::CollectionContract;
classBoard : publicvirtual BoardContract, public HasLogger
{
protected:
CollectionContract* devicesCollection;
CollectionContract* sensorsCollection;
CollectionContract* gatewaysCollection;
DeviceContract* Default = NULL;
voidinitializeAll()
{
/** Inisialisasi setiap Gateway. */
for(int i=0; icount(); i++) {
if(gatewaysCollection->getMemberAt(i) != NULL) {
gatewaysCollection->getMemberAt(i)->initialize();
}
}
/** Inisialisasi setiap Device. */
for(int i=0; icount(); i++) {
if(devicesCollection->getMemberAt(i) != NULL) {
devicesCollection->getMemberAt(i)->initialize();
}
86
Universitas Sumatera Utara
}
}
public:
Board()
{
devicesCollection = new Vector();
sensorsCollection = new Vector();
gatewaysCollection = new Vector();
setLogger(new Logger());
}
void initialize()
{
sensors();
devices();
gateways();
initializeAll();
}
void automate()
{
/** Jalankan behavior setiap Device. */
for(int i=0; icount(); i++) {
if(devicesCollection->getMemberAt(i) != NULL) {
devicesCollection->getMemberAt(i)->behavior();
devicesCollection->getMemberAt(i)->setLogger(logger);
}
}
/** Jalankan service setiap Gateway. */
for(int i=0; icount(); i++) {
if(gatewaysCollection->getMemberAt(i) != NULL) {
gatewaysCollection->getMemberAt(i)->service();
gatewaysCollection->getMemberAt(i)->setLogger(logger);
gatewaysCollection->getMemberAt(i)->setBoard(this);
}
}
}
void attachDevice(DeviceContract* device)
{
devicesCollection->add(device);
}
void attachSensor(SensorContract* sensor)
{
sensorsCollection->add(sensor);
}
void attachGateway(GatewayContract* gateway)
{
gatewaysCollection->add(gateway);
}
void executeUserCommand(String userCommands)
{
DeviceContract* device;
DynamicJsonBuffer jsonBuffer;
87
Universitas Sumatera Utara
JsonObject& root = jsonBuffer.parseObject(userCommands);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
for(int i=0; iturnOn();
}
} elseif(action=="turnOff") {
if((device=getDeviceByPin(pin)) != NULL) {
device->turnOff();
}
} elseif(action=="toggle") {
if((device=getDeviceByPin(pin)) != NULL) {
device->toggle();
}
}
}
}
DeviceContract* getDeviceByPin(int pin)
{
DeviceContract* device;
for(int i=0; icount(); i++) {
device = devicesCollection->getMemberAt(i);
if(device != NULL) {
if(device->getPin() == pin) {
return device;
}
}
}
returnNULL;
}
~Board()
{
delete gatewaysCollection;
delete devicesCollection;
delete sensorsCollection;
delete logger;
}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Foundation/Logger.hpp
namespace Nugraha { namespace Foundation {
using Nugraha::Contracts::Foundation::LoggerContract;
88
Universitas Sumatera Utara
classLogger : public LoggerContract {
protected:
DynamicJsonBuffer* jsonBuffer = new DynamicJsonBuffer();
JsonObject* root = &jsonBuffer->createObject();
JsonArray* notifications = &root->createNestedArray("notifications");
JsonArray* measurements = &root->createNestedArray("measurements");
JsonArray* connectionInfos = &root>createNestedArray("connectionInfos");
bool sendBoardInfo = true;
voidclean()
{
delete jsonBuffer;
jsonBuffer = NULL;
}
voidreInitializeJsonBuffer()
{
jsonBuffer = new DynamicJsonBuffer();
root = &jsonBuffer->createObject();
notifications = &root->createNestedArray("notifications");
measurements = &root->createNestedArray("measurements");
connectionInfos = &root->createNestedArray("connectionInfos");
}
voidaddBoardInfoToRecord()
{
JsonObject& boardInfo = root->createNestedObject("boardInfo");
boardInfo["chipId"] = ESP.getChipId();
boardInfo["cpuFreqMHz"] = ESP.getCpuFreqMHz();
boardInfo["sdkVersion"] = ESP.getSdkVersion();
boardInfo["bootVersion"] = ESP.getBootVersion();
boardInfo["bootMode"] = ESP.getBootMode();
boardInfo["cycleCount"] = ESP.getCycleCount();
boardInfo["freeHeap"] = ESP.getFreeHeap();
boardInfo["sketchSize"] = ESP.getSketchSize();
boardInfo["freeSketchSpace"] = ESP.getFreeSketchSpace();
}
public:
void addNotification(int code, String message)
{
if(jsonBuffer == NULL)
reInitializeJsonBuffer();
String state;
switch(code) {
case0 :
state = "off";
break;
case1 :
state = "on";
break;
default :
break;
}
JsonObject& notification = notifications->createNestedObject();
notification["pin"] = message;
89
Universitas Sumatera Utara
notification["state"] = state;
}
void addConnectionInfo(String parameter, String value)
{
if(jsonBuffer == NULL)
reInitializeJsonBuffer();
JsonObject& connectionInfo = connectionInfos->createNestedObject();
connectionInfo["parameter"] = parameter;
connectionInfo["value"] = value;
}
void addSensorMeasurement(String sensorName, String measurementValue)
{
if(jsonBuffer == NULL)
reInitializeJsonBuffer();
JsonObject& measurement = measurements->createNestedObject();
measurement["sensor"] = sensorName;
measurement["value"] = measurementValue;
}
String getLogMessage()
{
if(jsonBuffer != NULL) {
if(sendBoardInfo) {
addBoardInfoToRecord();
}
String logMessages;
root->printTo(logMessages);
clean();
reInitializeJsonBuffer();
return logMessages;
} else {
return"{\"records\":[]}";
}
}
void printToSerial()
{
if(jsonBuffer != NULL) {
if(sendBoardInfo) {
addBoardInfoToRecord();
}
root->prettyPrintTo(Serial);
}
else
Serial.println("NULL");
}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Gateways/Esp8266/WifiHttpClient.hpp
90
Universitas Sumatera Utara
namespace Nugraha { namespace Gateways { namespace Esp8266 {
using Nugraha::Traits::HasId;
using Nugraha::Traits::HasLogger;
using Nugraha::Contracts::Gateways::GatewayContract;
using Nugraha::Contracts::Foundation::BoardContract;
using Nugraha::Contracts::Foundation::LoggerContract;
classWifiHttpClient : publicvirtual GatewayContract, public HasLogger,
public HasId
{
protected:
ESP8266WiFiMulti WiFiMulti;
HTTPClient http;
BoardContract* board;
String ssid
= env::wifi::ssid;
String password
= env::wifi::password;
unsignedlong interval = 1000;
String
String
String
String
String
String
String
String
String
host;
mode;
publishKey;
subscribeKey;
signature;
channelName;
callback;
message = "{\"text\":\"hello\"}";
response;
public:
WifiHttpClient(std::map setting)
{
this->host = setting["host"];
this->mode = setting["mode"];
this->publishKey = setting["publishKey"];
this->subscribeKey = setting["subscribeKey"];
this->signature = setting["signature"];
this->channelName = setting["channelName"];
this->callback = setting["callback"];
}
virtual ~WifiHttpClient() {}
void initialize()
{
Serial.println();
Serial.println();
Serial.println();
for(uint8_t t = 4; t >0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP("Fugue2", "fugue123");
}
String generateUri()
91
Universitas Sumatera Utara
{
if(message != "") {
String uri = "http://" + host + "/" + mode + "/" + publishKey
+ "/" + subscribeKey + "/" + signature + "/" + channelName +
"/" + callback + "/" + message;
Serial.println(uri);
return uri;
}
}
template
void httpGet(String uri, Callback callback)
{
// wait for WiFi connection
if((WiFiMulti.run() == WL_CONNECTED)) {
unsignedlong tempMillis = millis();
http.begin(uri);
int httpCode = http.GET();
if(httpCode >0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
// Hitung delay.
addDelayToRecord(String(millis() - tempMillis));
// Ekstrak pesan dan panggil fungsi callback.
response = http.getString();
callback();
} else {
addDelayToRecord(String(-1));
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n",
http.errorToString(httpCode).c_str());
}
http.end();
}
}
int getId() override {HasId::getId();}
void updateMessage()
{
this->message = getLogger()->getLogMessage();
}
void setLogger(LoggerContract* logger) override
{
HasLogger::setLogger(logger);
addDelayToRecord(String(0));
}
LoggerContract* getLogger()
{
return logger;
}
92
Universitas Sumatera Utara
void setBoard(BoardContract* board)
{
this->board = board;
}
void addDelayToRecord(String value)
{
getLogger()->addConnectionInfo("delay", value);
}
};
}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Sensors/Sensor.hpp
namespace Nugraha { namespace Sensors {
using Nugraha::Traits::HasId;
using Nugraha::Traits::HasLogger;
using Nugraha::Sensors::Drivers::Driver;
using Nugraha::Sensors::Drivers::GenericDriver;
using Nugraha::Contracts::Sensors::SensorContract;
using Nugraha::Contracts::Foundation::LoggerContract;
classSensor : publicvirtual SensorContract, public HasLogger, public HasId
{
protected:
Driver* driver;
public:
int id;
int pin;
constchar* name;
virtual ~Sensor() {}
Sensor(int pin, constchar* name)
this->pin = pin;
this->name = name;
this->driver = new GenericDriver();
}
{
int getId() override {HasId::getId();}
void setLogger(LoggerContract* logger) override
{HasLogger::setLogger(logger);}
LoggerContract* getLogger() override {HasLogger::getLogger();}
};
}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Support/Facades/Scheduler/BaseEvent.hpp
93
Universitas Sumatera Utara
namespace Nugraha { namespace Support { namespace Facades { namespace
Scheduler {
using Nugraha::Contracts::Support::Facades::Scheduler::EventContract;
using Nugraha::Traits::HasId;
classBaseEvent : publicvirtual EventContract, publicvirtual HasId
{
protected:
unsignedlong interval;
unsignedlong previousMillis;
int repeatCount = -1;
public:
BaseEvent(unsignedlong interval, int repeatCount)
{
this->previousMillis = millis();
this->interval = interval;
this->repeatCount = repeatCount;
}
virtual ~BaseEvent()
{
}
int executionCount = 0;
voidupdate(unsignedlong now)
{
if(now - previousMillis >= interval && (repeatCount == -1 ||
repeatCount >0)) {
previousMillis = now;
Serial.printf("[%d] ", this->id);
executeCallback();
if(repeatCount != -1) {
repeatCount--;
}
}
}
intgetRepeatCount()
{
return repeatCount;
}
intgetId() override
{
HasId::getId();
}
};
}}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Support/Facades/Scheduler/Scheduler.hpp
namespace Nugraha { namespace Support { namespace Facades { namespace
Scheduler {
using Nugraha::Collections::Collection;
using Nugraha::Contracts::Collections::CollectionContract;
94
Universitas Sumatera Utara
classScheduler
{
protected:
static CollectionContract* eventCollection;
staticbool init;
public:
staticvoid handleEvents()
{
if(init) {
after(1, [=](){Serial.println();});
init = false;
}
for(auto event = eventCollection->getMembers().begin(); event !=
eventCollection->getMembers().end();) {
(*event)->update(millis());
if((*event)->getRepeatCount() == 0) {
delete *event;
*event = NULL;
event = eventCollection->getMembers().erase(event);
} else {
++event;
}
}
}
template
staticvoid every(unsignedlong interval, Callback callback, int
repeatCount = -1)
{
eventCollection->add(new StaticEvent(interval, callback,
repeatCount));
}
template
staticvoid every(unsignedlong interval, ObjectType object, Callback
callback, int repeatCount = -1)
{
eventCollection->add(new Event(interval,
callback, object, repeatCount));
}
template
staticvoid after(unsignedlong afterMillis, Callback callback)
{
every(afterMillis, callback, 1);
}
static BaseEvent* getEventAt(int index)
{
return eventCollection->getMemberAt(index);
}
};
CollectionContract* Scheduler::eventCollection = new
Collection();
bool Scheduler::init = true;
95
Universitas Sumatera Utara
}}}}
vendor/nugraha/tugasAkhirWahyu/src/Nugraha/Support/Facades/Scheduler/StaticEvent.hp
p
names pac e Nugr aha { names pac e Suppor t { names pac e Fac ades { names pac e Sc hedul er {
t empl at e
c l as s St at i c Ev ent : publ i c v i r t ual Bas eEv ent
{
pr ot ec t ed:
Cal l bac k c al l bac k ;
publ i c :
St at i c Ev ent ( uns i gned l ong i nt er v al , Cal l bac k c al l bac k , i nt r epeat Count ) :
Bas eEv ent ( i nt er v al , r epeat Count ) , c al l bac k ( c al l bac k )
{
}
v oi d ex ec ut eCal l bac k ( )
{
t hi s - >c al l bac k ( ) ;
}
};
}}}}
96
Universitas Sumatera Utara
LAMPIRAN 2
KODE PROGRAM APLIKASI WEB
App/Http/routes.php