IOT SYSTEM FULL SYSTEM UBUNTU C++ C PYTHON Qt BUID ALL SYSTEM + MOBILE APP
G?THUB:
https://github.com/tarnetintern/ciftlikOtomasyon
https://github.com/flavves/BTU-SMRT-HOME
This project has a 3 part
- WEB API
- MOBILE APP
- NODEMCU ESP-32S V1.1 & ARDUINO
WEB API
Let’s build together
required libraries
- Flask
- json
- os
Environment
- Ubuntu 22 server
We need to add 2 method POST & GET
Build POST method
from flask import Flask, request, jsonify
from flask_httpauth import HTTPBasicAuth
import json
import os
app = Flask(__name__)
auth = HTTPBasicAuth()
users = {
"user1": "pass",
"user2":"pass"
}
@auth.verify_password
def verify_password(username, password):
if username in users and users[username] == password:
return username
@app.route('/webhook', methods=['POST'])
@auth.login_required
def webhook():
# ?stek içeri?ini JSON olarak al
data = request.json
# Gelen veriyi i?le (Örne?in, basitçe yazd?r)
#print("Al?nan Veri:", data)
# JSON dosyas?n? oku veya yoksa yeni bir sözlük olu?tur
if os.path.exists('data.json'):
with open('data.json', 'r') as file:
file_data = json.load(file)
else:
file_data = {}
# Veriyi güncelle veya ekle
for key, value in data.items():
file_data[key] = value
# Güncellenmi? veriyi dosyaya yaz
with open('data.json', 'w') as file:
json.dump(file_data, file, indent=4)
# Ba?ar?l? bir yan?t döndür
return jsonify({"message": "Veri basar?yla alindi",
"data":data}), 200
Build GET method
@app.route('/todo', methods=['GET'])
@auth.login_required
def todo():
if os.path.exists('data.json'):
with open('data.json', 'r') as file:
data = json.load(file)
else:
data = {"error": "Veri bulunamad?."}
return jsonify(data), 200
#
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=7171)
Then we need to start our server this code
open terminal and write this command
nano startWebhook.sh
#then write
cd path/yur/pyfile
python3 pythoncode.py
# press ctrl+x and y
#I recommend VS Code for ssh server.
sudo chmod +x start.sh
screen -S my_session
nohup ./start.sh &
#then control
ps aux | grep python
#if you want to kill your script
kill <your scripts code>
Server is okay now we need to build an application.
MOBILE APP
If you know C++ and Qt you can continue this part and build your mobile app. If you don’t know, you can use the telegram api. I wrote example code for this but it needs to be upgraded.
Telegram code ! This code is not finished and integrated ! Please wait my update or update this code!
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
import threading
import time
import requests
import time
import requests
from datetime import datetime
global app
try:
with open ("evIsiklar1.txt","r") as dosya:
deneme=dosya.readline()
dosya.close()
except:
with open ("evIsiklar1.txt","w") as dosya:
dosya.write("")
dosya.close()
try:
with open ("evAdminleri.txt","r") as dosya:
deneme=dosya.readline()
dosya.close()
except:
with open ("evAdminleri.txt","w") as dosya:
dosya.write("")
dosya.close()
try:
with open ("evGorevleri.txt","r") as dosya:
deneme=dosya.readline()
dosya.close()
except:
with open ("evGorevleri.txt","w") as dosya:
dosya.write("")
dosya.close()
async def chatidal(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
chat_id = update.effective_user.id
await update.message.reply_text(chat_id)
async def adminkaydiyap(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
msg=update.message.text.replace("/a ","")
try:
userId=msg.split(" ")[1]
sifre=msg.split(" ")[0]
if sifre=="pass":
#buras? sadece belirli bir kullanici oldu?unda ççal??acak
with open ("evAdminleri.txt","r") as dosya:
idler=dosya.readline()
dosya.close()
idler=idler.split(";")
if str(userId) in idler:
await update.message.reply_text(f'Bu kullan?c? zaten kaydedildi!')
else:
with open ("evAdminleri.txt","a") as dosya:
dosya.write(str(userId)+";")
dosya.close()
try:
await update.message.reply_text(f'Kaydedilen kullan?c? ID: {userId}')
except:
await update.message.reply_text(f'Kay?t Ba?ar?s?z kullan?c? ID: {userId}')
else:
await update.message.reply_text("sifre yanl??")
except:
await update.message.reply_text("ornek format /a ?ifre userId")
async def gorevOlustur(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
gelenUserId=str(update.effective_user.id)
gelenMesaj=update.message.text
if gelenMesaj=="/go":
await update.message.reply_text("ornek format /go ???klar? kapat")
else:
gelenMesaj=gelenMesaj.replace("/go ","")
with open ("evAdminleri.txt","r") as dosya:
idler=dosya.readline()
dosya.close()
idler=idler.split(";")
donecekListe=""
if gelenUserId in idler:
print("kullanici kayitli gorev ekleyebilir")
with open ("evGorevleri.txt","a") as dosya:
dosya.write(gelenMesaj+"\n")
dosya.close()
await update.message.reply_text("Gorev ba?ar?yla eklendi")
async def isiklar(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
gelenUserId=str(update.effective_user.id)
gelenMesaj=update.message.text
if gelenMesaj=="/isiklar1":
await update.message.reply_text("ornek format /isiklar1 1 <???klar? 1 açar 0 kapat?r>")
else:
gelenMesaj=gelenMesaj.replace("/isiklar1 ","")
with open ("evAdminleri.txt","r") as dosya:
idler=dosya.readline()
dosya.close()
idler=idler.split(";")
donecekListe=""
if gelenUserId in idler:
print("???klar görevi geldi")
with open ("evIsiklar1.txt","w") as dosya:
dosya.write(gelenMesaj)
dosya.close()
await update.message.reply_text("???klar?n durumu: %s"%str(gelenMesaj))
pass
app = ApplicationBuilder().token("token").build()
#app.add_handler(CommandHandler("hello", hello))
app.add_handler(CommandHandler("chatidal", chatidal))
app.add_handler(CommandHandler("a", adminkaydiyap))
app.add_handler(CommandHandler("go", gorevOlustur))
app.add_handler(CommandHandler("isiklar1", isiklar))
app.run_polling()
Let’s build together
required
Environment
- Windows & MAC & Linux & Android
evkontrolpaneli.h
#ifndef EVKONTROLPANELI_H
#define EVKONTROLPANELI_H
#include <QApplication>
#include <QTimer>
#include <QElapsedTimer>
#include <QMap>
#include <QSet>
#include <QMetaMethod>
#include <QMetaObject>
#include <QGuiApplication>
#include <QQuickItem>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QFile>
#include <QUrl>
#include <QJsonDocument>
#include <QJsonObject>
class EvKontrolPaneli :public QObject
{
Q_OBJECT
public:
EvKontrolPaneli(QObject* parent = nullptr);
~EvKontrolPaneli();
Q_INVOKABLE bool baglanAuth(QString url,QString port,QString kullaniciAdi,QString sifre);
Q_INVOKABLE bool baglan(QString url,QString port);
Q_INVOKABLE bool baglantiyiKes();
Q_INVOKABLE bool baglantiyiKesAuth();
Q_INVOKABLE bool baglantiyiKontrolEt();
Q_INVOKABLE bool baglantiyiKontrolEtAuth();
Q_INVOKABLE bool postData(QString url,QString jsonData);
Q_INVOKABLE bool postDataAuth(QString url,QString jsonData,QString kullaniciAdi,QString sifre);
bool getData(QString url);
void handleApiResponse(QNetworkReply *reply);
void handleApiResponseAuth(QNetworkReply *reply);
private slots:
void performGetRequest(); // Yeni slot
private:
QNetworkAccessManager *manager;
QNetworkAccessManager *managerAuth;
QTimer *timer; // QTimer nesnesi
QString requestUrl="http://<apiurl>/todo"; // GET iste?i yap?lacak URL
signals:
void apiResponseReceived(QString response,int statusCode);
};
#endif // EVKONTROLPANELI_H
evkontrolpaneli.cpp
#include "evkontrolpaneli.h"
EvKontrolPaneli::EvKontrolPaneli(QObject *parent) : QObject(parent)
,manager (new QNetworkAccessManager(this))
,managerAuth (new QNetworkAccessManager(this))
,timer(new QTimer(this))
{
connect(manager, &QNetworkAccessManager::finished, this, &EvKontrolPaneli::handleApiResponse);
// Timer'? ayarlay?n ve performGetRequest slot'una ba?lay?n
//timer->setInterval(10000); // 10 saniye
//connect(timer, &QTimer::timeout, this, &EvKontrolPaneli::performGetRequest);
//timer->start();
}
EvKontrolPaneli::~EvKontrolPaneli()
{
delete manager;
delete managerAuth;
delete timer;
}
void EvKontrolPaneli::performGetRequest()
{
getData(requestUrl); // Burada URL'nizi belirtin
}
bool EvKontrolPaneli::getData(QString url)
{
QUrl serviceUrl(url);
QNetworkRequest request(serviceUrl);
// GET iste?ini ba?lat
manager->get(request);
return true;
}
bool EvKontrolPaneli::baglanAuth(QString url, QString port, QString kullaniciAdi, QString sifre)
{
return true;
}
bool EvKontrolPaneli::baglan(QString url, QString port)
{
return true;
}
bool EvKontrolPaneli::baglantiyiKes()
{
return true;
}
bool EvKontrolPaneli::baglantiyiKesAuth()
{
return true;
}
bool EvKontrolPaneli::baglantiyiKontrolEt()
{
return true;
}
bool EvKontrolPaneli::baglantiyiKontrolEtAuth()
{
return true;
}
bool EvKontrolPaneli::postData(QString url, QString jsonData)
{
QUrl serviceUrl = QUrl(url);
QNetworkRequest request(serviceUrl);
// HTTP Header ayarlar?
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// JSON verisini QJsonDocument nesnesine dönü?türme
QJsonDocument doc = QJsonDocument::fromJson(jsonData.toUtf8());
// POST iste?ini gönderme
manager->post(request, doc.toJson());
return true;
}
bool EvKontrolPaneli::postDataAuth(QString url, QString jsonData, QString kullaniciAdi, QString sifre)
{
QUrl serviceUrl = QUrl(url);
QNetworkRequest request(serviceUrl);
// HTTP Header ayarlar?
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// Basic Auth için kullan?c? ad? ve ?ifreyi Base64 ile kodlama
QByteArray auth = kullaniciAdi.toUtf8() + ":" + sifre.toUtf8();
auth = "Basic " + auth.toBase64();
request.setRawHeader("Authorization", auth);
// JSON verisini QJsonDocument nesnesine dönü?türme
QJsonDocument doc = QJsonDocument::fromJson(jsonData.toUtf8());
// POST iste?ini gönderme
manager->post(request, doc.toJson());
return true;
}
void EvKontrolPaneli::handleApiResponse(QNetworkReply *reply)
{
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (reply->error() == QNetworkReply::NoError) {
// ?stek ba?ar?l?, yan?t? oku
QByteArray responseData = reply->readAll();
QString responseString(responseData);
// Yan?t? konsola yazd?r veya gerekti?i ?ekilde i?le
qDebug() << "Sunucu Yan?t?:" << responseString;
emit apiResponseReceived(responseString, statusCode.toInt());
} else {
// Bir hata olu?tu, hata mesaj?n? yazd?r
qDebug() << "Hata:" << reply->errorString();
emit apiResponseReceived("responseString", statusCode.toInt());
}
reply->deleteLater();
}
void EvKontrolPaneli::handleApiResponseAuth(QNetworkReply *reply)
{
}
evKontrolPaneli.qml
import QtQuick 2.15
import COtomasyon.evControl 1.0
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.11
import QtQuick.Window 2.15
import COtomasyon.ScreenToolsController 1.0
import COtomasyon.Ayarlar 1.0
Item {
property double defaultSpacing: screen.desktopAvailableWidth/40
property double defaultWidth: mainWindow.width
property double defaultHeight: mainWindow.height
property bool tinyScreen : Screen.desktopAvailableWidth < 700
property var verilerListesi:Ayarlar.ayarlarSayfasiVerileriGetir()
property bool verilerListesiHazir:verilerListesi.length>0
property string apiUrl: verilerListesiHazir ? verilerListesi[0]:""
property string username: verilerListesiHazir ? verilerListesi[1]:""
property string password: verilerListesiHazir ? verilerListesi[2]:""
property int defaultFontPixelWidth: tinyScreen ? 10:20
property int defaultFontPixelHeight: tinyScreen ? 5:10
property int largeFontPointSize: 30
ListModel {
id: lightsModel
ListElement { name: "Isiklar 1" }
ListElement { name: "Isiklar 2" }
ListElement { name: "Isiklar 3" }
ListElement { name: "Isiklar 4" }
ListElement { name: "Alarm 1" }
ListElement { name: "Alarm 2" }
ListElement { name: "Role 1" }
ListElement { name: "Role 2" }
ListElement { name: "Role 3" }
// Daha fazla ???k eklemek isterseniz ListElement ekleyebilirsiniz
}
ScrollView {
anchors.fill: parent
anchors.centerIn: parent
clip: true
GridLayout {
id: gridLayout
columns: 1
columnSpacing: defaultFontPixelWidth
rowSpacing: defaultSpacing
Repeater {
model: lightsModel
Item {
width: gridLayout.width
height: childrenRect.height
GridLayout {
columns: 4
columnSpacing: defaultFontPixelWidth
rowSpacing: defaultSpacing
Text {
color: "#3cd731"
text: model.name
font.bold: true
font.pointSize: 12
}
Button {
text: "aç"
onClicked: {
var url = apiUrl+"webhook";
var json = JSON.stringify({ [model.name]: "1" });
//EvControl.postData(url, json)
EvControl.postDataAuth(url,json,username,password)
}
}
Button {
text: "kapat"
onClicked: {
var url = apiUrl+"webhook";
var json = JSON.stringify({ [model.name]: "0" });
//EvControl.postData(url, json)
EvControl.postDataAuth(url,json,username,password)
}
}
Text {
id: sonucYazisi
color: "#3cd731"
text: qsTr("Sonuç Yaz?s?")
font.bold: true
font.pointSize: 12
}
}
Connections {
target: EvControl
onApiResponseReceived: {
if (statusCode===200) {
//console.log(JSON.parse(response)["data"][model.name])
if (JSON.parse(response)["data"][model.name] === "1")
sonucYazisi.text = "Aç?k"
else if (JSON.parse(response)["data"][model.name] === "0")
sonucYazisi.text = "Kapal?"
}
}
}
}
}
}
}
Component.onCompleted: {
//EvControl.baglan("","")
}
focus: true // Oda?? etkinle?tirir
Keys.onBackPressed: {
console.log("Geri tu?una bas?ld?");
// Geri tu?una bas?ld???nda yap?lacak i?lemler
}
}
-
Those are a just code you need to be build this project or you can my base app project on github
Project photos

NODEMCU ESP-32S V1.1 & ARDUINO
Arduino Code <updated 25.12.2023>
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'*', '0', '#', 'D'},
{'7', '8', '9', 'C'},
{'4', '5', '6', 'B'},
{'1', '2', '3', 'A'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
const int role1Pin = 11; // Role 1 için pin numaras?
const int role2Pin = 12; // Role 2 için pin numaras?
const int role3Pin = 13; // Role 1 için pin numaras?
const int sifrePin = 10; // Role 1 için pin numaras?
// Di?er röleler için benzer ?ekilde pin tan?mlamalar? yapabilirsiniz
String inputBuffer = "";
String gelenSifre="";
String defaultSifre="1220";
char customKey;
bool SifreYoneticisi(char customKey){
gelenSifre+=customKey;
int uzunluk = gelenSifre.length(); //
if(uzunluk>3){
if(gelenSifre==defaultSifre){
Serial.println("Sifre Dogru");
digitalWrite(sifrePin,HIGH);
gelenSifre="";
return true;
}
else{
Serial.println("Sifre Yanlis");
gelenSifre="";
digitalWrite(sifrePin,LOW);
return false;
}
gelenSifre="";
}
else{
digitalWrite(sifrePin,LOW);
return false;
}
}
void setup() {
Serial.begin(115200);
pinMode(role1Pin, OUTPUT);
pinMode(role2Pin, OUTPUT);
pinMode(role3Pin, OUTPUT);
pinMode(sifrePin, OUTPUT);
// Di?er pinler için de pinMode ayarlar?
}
void loop() {
customKey = customKeypad.getKey();
if (customKey){
digitalWrite(sifrePin,HIGH);
delay(100);
digitalWrite(sifrePin,LOW);
SifreYoneticisi(customKey);
// USE HERE 74hc04
}
while (Serial.available() > 0) {
char incomingByte = Serial.read();
if (incomingByte == '<') {
inputBuffer = ""; // Yeni komut ba?lad?, tamponu temizle
} else if (incomingByte == '>') {
processCommand(inputBuffer); // Komut tamamland?, i?le
} else {
inputBuffer += incomingByte; // Gelen veriyi tampona ekle
}
}
}
void processCommand(String command) {
if (command.startsWith("Role 1")) {
digitalWrite(role1Pin, command.endsWith("HIGH") ? HIGH : LOW);
}
else if (command.startsWith("Role 2")) {
digitalWrite(role2Pin, command.endsWith("HIGH") ? HIGH : LOW);
}
else if (command.startsWith("Role 3")) {
digitalWrite(role3Pin, command.endsWith("HIGH") ? HIGH : LOW);
}
// Burada gelen komutu ayr??t?r?p ilgili aksiyonlar? yap?n
// Örne?in, komut "Role1:1" ise, Role1 pinini HIGH yap
}
Nodemcu Code <updated 25.12.2023>
#include <Base64.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "<ssid>";//""; // WiFi SSID'nizi girin
const char* password = "<pass>>";//""; // WiFi ?ifrenizi girin
//
void setup() {
Serial.begin(115200); // Seri ileti?im ba?lat?l?yor
Serial.flush();
Serial.println("Merhaba"); // Mesaj? gönder
WiFi.begin(ssid, password); // WiFi a??na ba?lan
pinMode(18, OUTPUT); // Pin'i ç?k?? olarak ayarla
pinMode(19, OUTPUT);
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
pinMode(16, OUTPUT);
pinMode(5, OUTPUT);
pinMode(17, OUTPUT);
pinMode(4, OUTPUT);
pinMode(0, OUTPUT);
Serial.println("Merhaba"); // Mesaj? gönder
while (WiFi.status() != WL_CONNECTED) { // WiFi'a ba?lanana kadar döngü
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void sendCommand(const char* command, int pin, const char* value) {
if (pin != -1) {
Serial.print("<"); // Ba?lang?ç biti
Serial.print(command); // Komut
Serial.print(value); // De?er
Serial.println(">"); // Biti? biti
digitalWrite(pin, strcmp(value, "1") == 0 ? HIGH : LOW);
}
}
bool sistemleriKontrolEt(DynamicJsonDocument& doc) {
for (JsonPair p : doc.as<JsonObject>()) {
const char* key = p.key().c_str(); // JSON anahtar?n? al
const char* value = p.value(); // JSON de?erini al
// Anahtar de?erlerine göre GPIO pin numaralar?n? belirle
int pin = -1;
if (strcmp(key, "Isiklar 1") == 0) {
pin = 18;
} else if (strcmp(key, "Isiklar 2") == 0) {
pin = 19;
}else if (strcmp(key, "Isiklar 3") == 0) {
pin = 21;
}else if (strcmp(key, "Isiklar 4") == 0) {
pin = 4;
}else if (strcmp(key, "Alarm 1") == 0) {
pin = 0;
}else if (strcmp(key, "Alarm 2") == 0) {
pin = 22;
}else if (strcmp(key, "Role 1") == 0) {
pin = 5;
}else if (strcmp(key, "Role 2") == 0) {
pin = 17;
}else if (strcmp(key, "Role 3") == 0) {
pin = 16;
}
// Di?er anahtarlar için benzer ifadeler eklenebilir
if (pin != -1) {
// "1" ise pin'i HIGH yap, "0" ise LOW yap
if (strcmp(value, "1") == 0) {
//Serial.print(key); Serial.println(" -> HIGH");
sendCommand(key,pin,"HIGH");
//digitalWrite(pin, HIGH);
} else if (strcmp(value, "0") == 0) {
//Serial.print(key); Serial.println(" -> LOW");
sendCommand(key,pin,"LOW");
//digitalWrite(pin, LOW);
}
}
}
return true;
}
void loop() {
if(WiFi.status() == WL_CONNECTED) { // WiFi'a ba?l?ysa
HTTPClient http; // HTTPClient nesnesi olu?tur
String auth = "<username:pass>"; // Kullan?c? ad?n?z ve ?ifrenizi girin
auth = base64::encode(auth);
http.begin("<api>"); // Webhook URL'nizi girin
http.addHeader("Authorization", "Basic " + auth);
int httpCode = http.GET(); // HTTP GET iste?i yap
if (httpCode > 0) { // HTTP iste?i ba?ar?l? m? kontrol et
String response = http.getString(); // Sunucudan gelen yan?t? al
//Serial.println(response);
DynamicJsonDocument doc(1024);
deserializeJson(doc, response);
sistemleriKontrolEt(doc);
} else {
Serial.println("Error on HTTP request");
}
http.end(); // HTTPClient nesnesini kapat
} else {
Serial.println("WiFi not connected");
}
delay(1000); // Her 10 saniyede bir bu i?lemi tekrarla
}
—-
NodeMCU & ARDUINO communicate with serial comminacition. MCU send bytes with start