Created
August 9, 2023 12:00
-
-
Save Gamer08YT/369364481727008ee18c31b69aea45c7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <Arduino.h> | |
| #include "Ethernet.h" | |
| #include <ArduinoHA.h> | |
| #define ARDUINOHA_DEBUG; | |
| //#include "ArduinoOTA.h" | |
| //#include "InternalStorage.h" | |
| // Store MAC Address of Device. | |
| byte macIO[] = { | |
| 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED | |
| }; | |
| // Store EthernetServer Instance. | |
| EthernetServer serverIO(80); | |
| EthernetClient client; | |
| // Define Home Assistant Credentials. | |
| HADevice device; | |
| // Define Home Assistant MQTT Instance. | |
| HAMqtt mqtt(client, device); | |
| // Store Refill Trigger. | |
| HANumber trigger("switch_refill"); | |
| void setupLAN(); | |
| void setupOTA(); | |
| void handleOTA(); | |
| void handleWeb(); | |
| void setupHA(); | |
| void setupMQTT(); | |
| /** | |
| * @brief Initializes the variables and resources required for the setup. | |
| * | |
| * This function should be called once at the beginning of the program execution | |
| * to initialize the necessary variables and resources. | |
| * | |
| * @details | |
| * This function sets up any global variables and resources that are needed | |
| * before the main code execution starts. | |
| * | |
| * Example usage: | |
| * @code | |
| * setup(); | |
| * @endcode | |
| * | |
| * @note | |
| * It is recommended to call this function from the main() function. | |
| */ | |
| void setup() { | |
| // Begin Serial Console. | |
| Serial.begin(9600); | |
| // Print Debug Message. | |
| Serial.println("Starting Hauswasserwerk..."); | |
| // Setup LAN Connection. | |
| setupLAN(); | |
| // Wait for a short Period. | |
| delay(250); | |
| // Setup HomeAssistant. | |
| setupHA(); | |
| // Wait for a short Period. | |
| delay(500); | |
| // Setup MQTT. | |
| setupMQTT(); | |
| // Setup OTA Server. | |
| setupOTA(); | |
| } | |
| /** | |
| * @brief This function is called when a successful connection is established. | |
| * | |
| * This function is invoked when a connection to a remote device is successfully established. | |
| * It can be used to perform any necessary actions or setup required after a successful connection. | |
| * | |
| * @note This function should be implemented by the user. | |
| * | |
| * @param void No parameters are required for this function. | |
| * | |
| * @return void This function does not return any value. | |
| * | |
| * @see onDisconnected() | |
| */ | |
| void onConnected() { | |
| Serial.println("Connected to MQTT Server."); | |
| } | |
| /** | |
| * @brief Handles the received message from the specified topic. | |
| * | |
| * This function is called whenever a message is received on the specified topic. | |
| * It takes the received topic, payload, and payload length as input parameters. | |
| * | |
| * @param topic The topic on which the message was received. | |
| * @param payload The payload of the received message. | |
| * @param length The length of the payload in bytes. | |
| */ | |
| void onMessage(const char *topic, const uint8_t *payload, uint16_t length) { | |
| Serial.println("Received "); | |
| Serial.print(topic); | |
| Serial.println(" - "); | |
| //(payload); | |
| } | |
| /** | |
| * @brief Sets up the MQTT connection with the MQTT broker. | |
| * | |
| * This function initializes the necessary resources and establishes a | |
| * connection with the MQTT broker. It performs the configuration settings | |
| * required for a successful MQTT connection. | |
| * | |
| * @note The function assumes that the necessary parameters like broker URL, | |
| * credentials, client ID, etc. are already set before calling this function. | |
| * Ensure that the required parameters are correctly set prior to calling | |
| * this function. | |
| * | |
| * @see setBrokerURL() | |
| * @see setCredentials() | |
| * @see setClientID() | |
| * @see setKeepAlive() | |
| * | |
| * @return void | |
| */ | |
| void setupMQTT() { | |
| // Add MQTT Listener. | |
| mqtt.onMessage(onMessage); | |
| mqtt.onConnected(onConnected); | |
| // Connect to HomeAssistant. | |
| mqtt.begin("homeassistant.local", "wasserwerk", "wasserwerk"); | |
| // Print Debug Message. | |
| Serial.println("Connecting to HomeAssistant MQTT Server."); | |
| } | |
| /** | |
| * @brief Initial setup for Home Automation | |
| * | |
| * This function sets up the necessary variables and configurations for Home Automation. | |
| * It initializes the required devices, sensors, and controllers. | |
| * After calling this function, the home automation system is ready to be used. | |
| * | |
| * @details | |
| * The setupHA() function performs the following tasks: | |
| * 1. Initializes the communication protocols and configurations for controlling devices. | |
| * 2. Configures and connects to sensors for collecting data. | |
| * 3. Initializes and configures the Home Automation Controller. | |
| * 4. Sets up the necessary event handlers for monitoring and responding to events. | |
| * | |
| * @note | |
| * This function should be called once at the beginning of the Home Automation system. | |
| * After calling this function, the main loop of the Home Automation system should be implemented. | |
| * Make sure to configure and handle events as required for the specific Home Automation use case. | |
| * | |
| * @see loopHA() for the main loop of the Home Automation system. | |
| * @see handleEvent() for handling specific events in the Home Automation system. | |
| */ | |
| void setupHA() { | |
| // Set ID of Device. | |
| device.setUniqueId(macIO, sizeof(macIO)); | |
| // Prepare for Home Assistant. | |
| device.setName("Wasserwerk"); | |
| device.setSoftwareVersion("1.0.0"); | |
| device.setModel("ATmega2560"); | |
| device.setManufacturer("Jan Heil (www.byte-store.de)"); | |
| device.enableSharedAvailability(); | |
| device.enableLastWill(); | |
| // Prepare Power Trigger. | |
| trigger.setMax(100); | |
| trigger.setMin(10); | |
| trigger.setName("Refill Trigger"); | |
| trigger.setUnitOfMeasurement("%"); | |
| trigger.setDeviceClass("moisture"); | |
| trigger.setMode(HANumber::ModeBox); | |
| //trigger.setCurrentState(Device::getTrigger()); | |
| //trigger.onCommand(MQTT::onTrigger); | |
| // Print Debug Message. | |
| Serial.println("Finished registration in HomeAssistant."); | |
| } | |
| /** | |
| * @brief Sets up OTA (Over-The-Air) update functionality | |
| * | |
| * This function initializes the OTA update functionality, which allows the firmware | |
| * of the device to be updated remotely over a network connection. It sets up | |
| * the required OTA callbacks, configures the OTA parameters, and starts the OTA | |
| * update service. | |
| * | |
| * Usage: Call this function in the setup() function of your Arduino sketch to | |
| * enable OTA updates for your device. | |
| * | |
| * OTA provides a convenient way to remotely update firmware, ensuring the latest | |
| * version of the code is running on the device. It eliminates the need for manual | |
| * firmware updates via USB or other means, simplifying the process for both | |
| * developers and end users. | |
| * | |
| * @note This function should only be called once in the setup() function. | |
| * | |
| * @return void | |
| */ | |
| void setupOTA() { | |
| // Begin OTA Server with Internal Storage. | |
| //ArduinoOTA.begin(Ethernet.localIP(), "ByteWasserwerk", "@ByteWasserwerk2023", InternalStorage); | |
| } | |
| /** | |
| * \brief Sets up the local area network (LAN) configuration. | |
| * | |
| * This function initializes the necessary variables and settings for | |
| * configuring and establishing a local area network (LAN). | |
| * | |
| * \note This function assumes that the necessary hardware and software | |
| * requirements for LAN setup are already in place. | |
| * | |
| * \note The specific implementation of this function may vary depending | |
| * on the platform and network architecture being used. | |
| * | |
| * \return No return value. | |
| */ | |
| void setupLAN() { | |
| // Select Ethernet Board. | |
| //Ethernet.init(10); | |
| // Start Ethernet Connection and Server via DHCP. | |
| if (Ethernet.begin(macIO) == 0) { | |
| // Print Debug Message. | |
| Serial.println("Failed to configure Ethernet using DHCP."); | |
| // Check if Hardware exits. | |
| if (Ethernet.hardwareStatus() == EthernetNoHardware) { | |
| // Print Hardware Missing. | |
| Serial.println("Ethernet Hardware was not found."); | |
| } else if (Ethernet.linkStatus() == LinkOFF) { | |
| // Print Unplugged. | |
| Serial.println("Ethernet cable is not connected."); | |
| } | |
| // Wait until DHCP resolved. | |
| while (true) { | |
| delay(1); | |
| } | |
| } | |
| // Print Success Message. | |
| Serial.print("Successfully connected with Network IP-Address "); | |
| Serial.println(Ethernet.localIP()); | |
| } | |
| /** | |
| * @brief Executes a loop continuously until exit condition is met. | |
| * | |
| * The loop() function is a placeholder to demonstrate the structure of a loop execution. | |
| * It continues to execute until an exit condition is met. You can define various conditions | |
| * and actions inside the loop to perform repetitive tasks. | |
| * | |
| * @details | |
| * This is a generic loop function that can be used as a starting point in your code. | |
| * It does not provide any specific functionality, but it can be customized to suit your | |
| * program requirements. Please refer to the examples and documentation to learn how | |
| * to use this function effectively in your program. | |
| * | |
| * @warning | |
| * Be cautious while implementing infinite loops and ensure there is a mechanism to break | |
| * the loop when necessary. Otherwise, it may result in an infinite execution and may lead | |
| * to system locks or freezes. | |
| * | |
| * @param none | |
| * @retval none | |
| * | |
| * @see exitCondition() | |
| * @see performAction() | |
| * | |
| */ | |
| void loop() { | |
| // Keep Ethernet Maintained. | |
| Ethernet.maintain(); | |
| // Handle OTA Poll. | |
| //handleOTA(); | |
| // Handle MQTT Stream. | |
| mqtt.loop(); | |
| // Handle WebServer Connections. | |
| //handleWeb(); | |
| } | |
| /** | |
| * @brief A method to handle Over-the-Air (OTA) firmware updates. | |
| * | |
| * This method is responsible for managing and processing OTA firmware updates | |
| * for the target device. It performs the necessary tasks to initiate and complete | |
| * the firmware update process using the OTA mechanism. | |
| * | |
| * @remarks This method should be called to handle OTA updates periodically or | |
| * based on certain triggers/events. | |
| * | |
| * @return void | |
| */ | |
| void handleOTA() { | |
| // Check for OTA Updates. | |
| //ArduinoOTA.poll(); | |
| } | |
| /** | |
| * @brief Handles the web request and performs necessary actions. | |
| * | |
| * This function is responsible for handling the web request and performing all the necessary actions | |
| * based on the request and its parameters. The function follows a certain algorithm to process the | |
| * request and produces the desired output. | |
| * | |
| * @details | |
| * This function can be called to handle any web request and it will perform the following steps: | |
| * - Parse the request parameters and validate them. | |
| * - Determine the type of request and perform specific action based on the request type. | |
| * - Process the data and generate the response accordingly. | |
| * - Send the response back to the client. | |
| * | |
| * It is important to note that this function assumes a working and established connection with the client. | |
| * The function expects that the necessary resources and network infrastructure are properly set up. | |
| * | |
| * @pre | |
| * - A valid web request is received from the client. | |
| * | |
| * @post | |
| * - The web request is handled and the appropriate response is sent back to the client. | |
| * | |
| * @note | |
| * - This function handles a wide range of request types and can perform different actions depending on the request. | |
| * - Customization and extension of this function is possible by modifying the specific action blocks. | |
| * | |
| * @throw | |
| * - This function may throw errors or exceptions in case of invalid or malformed requests. | |
| * | |
| * @return | |
| * - This function does not return any value. | |
| */ | |
| void handleWeb() { | |
| // Listen for new Client Connections. | |
| EthernetClient clientIO = serverIO.available(); | |
| // Check if Client is not null/undefined. | |
| if (clientIO) { | |
| // Print Debug Message. | |
| Serial.println("Client connected to Web Server"); | |
| // an HTTP request ends with a blank line | |
| bool currentLineIsBlank = true; | |
| while (clientIO.connected()) { | |
| if (clientIO.available()) { | |
| char c = clientIO.read(); | |
| Serial.write(c); | |
| // if you've gotten to the end of the line (received a newline | |
| // character) and the line is blank, the HTTP request has ended, | |
| // so you can send a reply | |
| if (c == '\n' && currentLineIsBlank) { | |
| // send a standard HTTP response header | |
| clientIO.println("HTTP/1.1 200 OK"); | |
| clientIO.println("Content-Type: text/html"); | |
| clientIO.println( | |
| "Connection: close"); // the connection will be closed after completion of the response | |
| //clientIO.println("Refresh: 5"); // refresh the page automatically every 5 sec | |
| clientIO.println(); | |
| clientIO.println("<!DOCTYPE HTML>"); | |
| clientIO.println( | |
| R"(<html data-bs-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>ByteWasserwerk</title><link rel="stylesheet" href="http://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"></head><body>)"); | |
| clientIO.println( | |
| "<div class=\"container my-5\"><div class=\"bg-body border border-dashed p-5 position-relative rounded-5 text-center text-muted\"><h1 class=\"text-body-emphasis\">Wasser<b>werk</b></h1><p class=\"col-lg-6 mb-4 mx-auto\">Das Wasserwerk ist betriebsbereit und die Einstellungen können über den Button unten eingesehen werden. Das System wurde von Jan Heil (www.byte-store.de) entwickelt und programmiert.</p><a href=\"./config\" class=\"btn btn-primary mb-5 px-5\"type=\"button\">Konfiguration</a></div></div>"); | |
| /*clientIO.println( | |
| R"(<div class="container"><footer class="align-items-center d-flex border-top flex-wrap justify-content-between my-4 py-3"><div class="align-items-center d-flex col-md-4"><a class="mb-3 mb-md-0 text-body-secondary lh-1 me-2 text-decoration-none"href="/"></a><span class="mb-3 mb-md-0 text-body-secondary">Copyright by 2023 Jan Heil (www.byte-store.de)</span></div></footer></div>)"); | |
| */ | |
| clientIO.println("</body></html>"); | |
| clientIO.flush(); | |
| break; | |
| } | |
| if (c == '\n') { | |
| // you're starting a new line | |
| currentLineIsBlank = true; | |
| } else if (c != '\r') { | |
| // you've gotten a character on the current line | |
| currentLineIsBlank = false; | |
| } | |
| } | |
| } | |
| // Wait a while for the Web Browser. | |
| delay(1); | |
| // Close the Connection. | |
| clientIO.stop(); | |
| // Print Debug Message. | |
| Serial.println("Client disconnected from Web Server"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment