/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/ttgo-lora32-sx1276-arduino-ide/
ttgoOLED_TX.ino LOCAL with Pi send single letter commands to get a one off response WIFI from Pi
/Users/graham/Dropbox/SystemsinUse/46_office_lora/lora_esp32/ttgoOLED_TX_command_from_office_WIFI/ttgoOLED_TX_command_from_office_WIFI.ino
NB! corrected by GPT 21/9/25 update 26/11/25 - OK - 27/11/25 OK
*********/
#include <WiFi.h>
#include <WebServer.h>
#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Wi-Fi credentials
const char* ssid = "deco";
const char* password = "uu8diode";

String reply = "";


WebServer server(80);
String receivedData = "";

// LoRa configuration
#define SCK 18
#define MISO 19
#define MOSI 23
#define SS 5
#define RST 14
#define DIO0 2

#define BAND 868E6

#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

void setup() {
Serial.begin(115200);

// OLED reset
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);

Wire.begin(OLED_SDA, OLED_SCL);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Wi-Fi + LoRa Node");
display.display();

IPAddress staticIP(192, 168, 1, 123); // ESP32 static IP
IPAddress gateway(192, 168, 1, 1); // Router IP
IPAddress subnet(255, 255, 255, 0); // Subnet mask
IPAddress primaryDNS(192, 168, 1, 1); // DNS (often same as router)
IPAddress secondaryDNS(8, 8, 8, 8); // Optional (Google DNS)
WiFi.mode(WIFI_STA); // Make sure we are in Station mode only
// Configure static IP – check for failure
if (!WiFi.config(staticIP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}

WiFi.begin(ssid, password);

display.setCursor(0, 10);
display.print("Connecting Wi-Fi...");
display.display();

String reply = "";

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Connected. IP: ");
Serial.println(WiFi.localIP());

display.setCursor(0, 20);
display.println("Connected!");
display.display();



SPI.begin(SCK, MISO, MOSI, SS);
LoRa.setPins(SS, RST, DIO0);

if (!LoRa.begin(BAND)) {
Serial.println("LoRa init failed!");
while (true) { delay(1000); }
}

// --- NOW set parameters, after begin() ---
LoRa.setSpreadingFactor(9); // match Heltec
LoRa.setSignalBandwidth(125E3);
LoRa.setCodingRate4(5);
LoRa.setTxPower(17);
LoRa.setPreambleLength(8);
LoRa.setSyncWord(0x34);

// Keep CRC off, to match your Heltec's radio.setCRC(0)
LoRa.disableCrc(); // explicit, just to be sure
LoRa.disableInvertIQ(); // explicit, normal mode




// HTTP handler
server.on("/command", HTTP_POST, []() {
if (!server.hasArg("plain")) {
server.send(400, "text/plain", "Missing body");
return;
}

String command = server.arg("plain");
Serial.print("ESP32 IP Address: ");
Serial.println(WiFi.localIP()); // Print the ESP32 IP address to Serial Monitor
Serial.println("Received command: " + command); //WiFi command

display.clearDisplay();
display.setCursor(0, 0);
display.print("Wi-Fi cmd: ");
display.println(command);
display.display();

// Send command via LoRa
LoRa.beginPacket();
LoRa.print(command);
LoRa.endPacket();


// --- Wait for reply from slave ---
String reply = "";
int rssi = 0;
float snr = 0;
unsigned long start = millis();

while (millis() - start < 5000) { // wait up to 5 seconds
int packetSize = LoRa.parsePacket();
if (packetSize) {
reply = LoRa.readString();

// Get LoRa signal stats for this packet
rssi = LoRa.packetRssi(); // signal strength in dBm
snr = LoRa.packetSnr(); // signal-to-noise in dB

break;
}
delay(10); // small yield to avoid watchdog reset
}

if (reply == "") {
reply = "NoData";
}

// --- Serial output ---
Serial.println("Reply: " + reply);
Serial.print("LoRa RSSI: ");
Serial.print(rssi);
Serial.println(" dBm");
Serial.print("LoRa SNR: ");
Serial.print(snr);
Serial.println(" dB");

// --- HTTP reply to Pi ---
server.send(200, "text/plain", reply);

// --- OLED output ---
display.setCursor(0, 10);
display.println(WiFi.localIP());

display.setCursor(0, 20);
display.println(reply);

display.setCursor(0, 40);
display.print("RSSI: ");
display.print(rssi);
display.print(" dBm");

display.setCursor(0, 50);
display.print("SNR: ");
display.print(snr, 1);
display.print(" dB");
display.display();

});

server.begin();
Serial.println("HTTP server started");
}

void loop() {
server.handleClient();
}