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