You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
10 KiB

#ifndef __WIFI_H
#define __WIFI_H
#include "Settings.h"
#include "Debug.h"
#include <ESP8266WiFi.h>
#include <Pinger.h> // von url=https://www.technologytourist.com
String SSID = ""; // bestes WLan
// Prototypes
time_t getNow ();
boolean setupWifi ();
boolean checkWifi();
String findWifi () {
//----------------
String ssid;
int32_t rssi;
uint8_t encryptionType;
uint8_t* bssid;
int32_t channel;
bool hidden;
int scanResult;
String best_ssid = "";
int32_t best_rssi = -100;
DEBUG_OUT.println(F("Starting WiFi scan..."));
scanResult = WiFi.scanNetworks(/*async=*/false, /*hidden=*/true);
if (scanResult == 0) {
DEBUG_OUT.println(F("keine WLans"));
} else if (scanResult > 0) {
DEBUG_OUT.printf(PSTR("%d WLans gefunden:\n"), scanResult);
// Print unsorted scan results
for (int8_t i = 0; i < scanResult; i++) {
WiFi.getNetworkInfo(i, ssid, encryptionType, rssi, bssid, channel, hidden);
DEBUG_OUT.printf(PSTR(" %02d: [CH %02d] [%02X:%02X:%02X:%02X:%02X:%02X] %ddBm %c %c %s\n"),
i,
channel,
bssid[0], bssid[1], bssid[2],
bssid[3], bssid[4], bssid[5],
rssi,
(encryptionType == ENC_TYPE_NONE) ? ' ' : '*',
hidden ? 'H' : 'V',
ssid.c_str());
delay(1);
boolean check;
#ifdef SSID_PREFIX1
check = ssid.substring(0,strlen(SSID_PREFIX1)).equals(SSID_PREFIX1);
#else
check = true;
#endif
#ifdef SSID_PREFIX2
check = check || ssid.substring(0,strlen(SSID_PREFIX2)).equals(SSID_PREFIX2);
#endif
if (check) {
if (rssi > best_rssi) {
best_rssi = rssi;
best_ssid = ssid;
}
}
}
} else {
DEBUG_OUT.printf(PSTR("WiFi scan error %d"), scanResult);
}
if (! best_ssid.equals("")) {
SSID = best_ssid;
DEBUG_OUT.printf ("Bestes Wifi unter: %s\n", SSID.c_str());
return SSID;
}
else
return "";
}
void IP2string (IPAddress IP, char * buf) {
sprintf (buf, "%d.%d.%d.%d", IP[0], IP[1], IP[2], IP[3]);
}
void connectWifi() {
//------------------
// if (SSID.equals(""))
String s = findWifi();
if (!SSID.equals("")) {
DEBUG_OUT.print("versuche zu verbinden mit "); DEBUG_OUT.println(SSID);
//while (WiFi.status() != WL_CONNECTED) {
WiFi.begin (SSID, SSID_PASSWORD);
int versuche = 20;
while (WiFi.status() != WL_CONNECTED && versuche > 0) {
delay(1000);
versuche--;
DEBUG_OUT.print(versuche); DEBUG_OUT.print(' ');
}
//}
if (WiFi.status() == WL_CONNECTED) {
char buffer[30];
IP2string (WiFi.localIP(), buffer);
String out = "\n[WiFi]Verbunden; meine IP:" + String (buffer);
DEBUG_OUT.println (out);
}
else
DEBUG_OUT.print("\nkeine Verbindung mit SSID "); DEBUG_OUT.println(SSID);
}
}
boolean setupWifi () {
//------------------
int count=5;
while (count-- && WiFi.status() != WL_CONNECTED)
connectWifi();
return (WiFi.status() == WL_CONNECTED);
}
Pinger pinger;
IPAddress ROUTER = IPAddress(192,168,1,1);
boolean checkWifi() {
//---------------
boolean NotConnected = (WiFi.status() != WL_CONNECTED) || !pinger.Ping(ROUTER);
if (NotConnected) {
setupWifi();
if (WiFi.status() == WL_CONNECTED)
getNow();
}
return (WiFi.status() == WL_CONNECTED);
}
// ################ Clock #################
#include <WiFiUdp.h>
#include <TimeLib.h>
IPAddress timeServer;
unsigned int localPort = 8888;
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuf[NTP_PACKET_SIZE]; // Buffer to hold incoming and outgoing packets
const int timeZone = 1; // Central European Time = +1
long SYNCINTERVALL = 0;
WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP
// prototypes
time_t getNtpTime ();
void sendNTPpacket (IPAddress &address);
time_t getNow ();
char* getDateTimeStr (time_t no = getNow());
time_t offsetDayLightSaving (uint32_t local_t);
bool isDayofDaylightChange (time_t local_t);
void _setSyncInterval (long intervall) {
//----------------------------------------
SYNCINTERVALL = intervall;
setSyncInterval (intervall);
}
void setupClock() {
//-----------------
WiFi.hostByName (TIMESERVER_NAME,timeServer); // at this point the function works
Udp.begin(localPort);
getNtpTime();
setSyncProvider (getNtpTime);
while(timeStatus()== timeNotSet)
delay(1); //
_setSyncInterval (SECS_PER_DAY / 2); // Set seconds between re-sync
//lastClock = now();
//Serial.print("[NTP] get time from NTP server ");
getNow();
//char buf[20];
DEBUG_OUT.print ("[NTP] get time from NTP server ");
DEBUG_OUT.print (timeServer);
//sprintf (buf, ": %02d:%02d:%02d", hour(no), minute(no), second(no));
DEBUG_OUT.print (": got ");
DEBUG_OUT.println (getDateTimeStr());
}
//*-------- NTP code ----------*/
time_t getNtpTime() {
//-------------------
sendNTPpacket(timeServer); // send an NTP packet to a time server
//uint32_t beginWait = millis();
//while (millis() - beginWait < 1500) {
int versuch = 0;
while (versuch < 5) {
int wait = 150; // results in max 1500 ms waitTime
while (wait--) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
//Serial.println("Receive NTP Response");
Udp.read(packetBuf, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuf[40] << 24;
secsSince1900 |= (unsigned long)packetBuf[41] << 16;
secsSince1900 |= (unsigned long)packetBuf[42] << 8;
secsSince1900 |= (unsigned long)packetBuf[43];
// time_t now = secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
time_t utc = secsSince1900 - 2208988800UL;
time_t now = utc + (timeZone +offsetDayLightSaving(utc)) * SECS_PER_HOUR;
if (isDayofDaylightChange (utc) && hour(utc) <= 4)
_setSyncInterval (SECS_PER_HOUR);
else
_setSyncInterval (SECS_PER_DAY / 2);
return now;
}
else
delay(10);
}
versuch++;
}
return 0;
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress& address) {
//------------------------------------
memset(packetBuf, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
// Initialize values needed to form NTP request
packetBuf[0] = B11100011; // LI, Version, Mode
packetBuf[1] = 0; // Stratum
packetBuf[2] = 6; // Max Interval between messages in seconds
packetBuf[3] = 0xEC; // Clock Precision
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
packetBuf[12] = 49; // four-byte reference ID identifying
packetBuf[13] = 0x4E;
packetBuf[14] = 49;
packetBuf[15] = 52;
// send the packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuf,NTP_PACKET_SIZE);
Udp.endPacket();
}
int getTimeTrials = 0;
bool isValidDateTime (time_t no) {
return (year(no) > 2020 && year(no) < 2038);
}
bool isDayofDaylightChange (time_t local_t) {
//-----------------------------------------
int jahr = year (local_t);
int monat = month (local_t);
int tag = day (local_t);
bool ret = ( (monat ==3 && tag == (31 - (5 * jahr /4 + 4) % 7)) ||
(monat==10 && tag == (31 - (5 * jahr /4 + 1) % 7)));
DEBUG_OUT.print ("isDayofDaylightChange="); DEBUG_OUT.println (ret);
return ret;
}
// calculates the daylight saving time for middle Europe. Input: Unixtime in UTC (!)
// übernommen von Jurs, see : https://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536
time_t offsetDayLightSaving (uint32_t local_t) {
//--------------------------------------------
int monat = month (local_t);
if (monat < 3 || monat > 10) return 0; // no DSL in Jan, Feb, Nov, Dez
if (monat > 3 && monat < 10) return 1; // DSL in Apr, May, Jun, Jul, Aug, Sep
int jahr = year (local_t);
int std = hour (local_t);
//int tag = day (local_t);
int stundenBisHeute = (std + 24 * day(local_t));
if ( (monat == 3 && stundenBisHeute >= (1 + timeZone + 24 * (31 - (5 * jahr /4 + 4) % 7))) ||
(monat == 10 && stundenBisHeute < (1 + timeZone + 24 * (31 - (5 * jahr /4 + 1) % 7))) )
return 1;
else
return 0;
/*
int stundenBisWechsel = (1 + 24 * (31 - (5 * year(local_t) / 4 + 4) % 7));
if (monat == 3 && stundenBisHeute >= stundenBisWechsel || monat == 10 && stundenBisHeute < stundenBisWechsel)
return 1;
else
return 0;
*/
}
time_t getNow () {
//---------------
time_t jetzt = now();
while (!isValidDateTime(jetzt) && getTimeTrials < 10) { // ungültig, max 10x probieren
if (getTimeTrials) {
//Serial.print (getTimeTrials);
//Serial.println(". Versuch für getNtpTime");
}
jetzt = getNtpTime ();
if (isValidDateTime(jetzt)) {
setTime (jetzt);
getTimeTrials = 0;
}
else
getTimeTrials++;
}
//return jetzt + offsetDayLightSaving(jetzt)*SECS_PER_HOUR;
return jetzt;
}
char _timestr[24];
char* getNowStr (time_t no = getNow()) {
//------------------------------------
sprintf (_timestr, "%02d:%02d:%02d", hour(no), minute(no), second(no));
return _timestr;
}
char* getTimeStr (time_t no = getNow()) {
//------------------------------------
return getNowStr (no);
}
char* getDateTimeStr (time_t no) {
//------------------------------
sprintf (_timestr, "%04d-%02d-%02d+%02d:%02d:%02d", year(no), month(no), day(no), hour(no), minute(no), second(no));
return _timestr;
}
char* getDateStr (time_t no) {
//------------------------------
sprintf (_timestr, "%04d-%02d-%02d", year(no), month(no), day(no));
return _timestr;
}
#endif