diff --git a/CSS.h b/CSS.h new file mode 100644 index 0000000..caa43e3 --- /dev/null +++ b/CSS.h @@ -0,0 +1,84 @@ +void append_page_header() { + webpage = F("<!DOCTYPE html><html>"); + webpage += F("<head>"); + webpage += F("<title>File MK-BlindControl</title>"); // NOTE: 1em = 16px + + webpage += F("<meta name='viewport' content='user-scalable=yes,initial-scale=1.0,width=device-width'>"); + webpage += F("<style>"); + //webpage += F("body{max-width:65%;margin:0 auto;font-family:arial;font-size:105%;text-align:center;color:blue;background-color:#FFFFFF;}"); + webpage += F("body{max-width:65%;margin:0 auto;font-family:arial;font-size:105%;text-align:center;color:blue;background-color:#F7F2Fd;}"); + + webpage += F("ul{list-style-type:none;margin:0.1em;padding:0;border-radius:0.375em;overflow:hidden;background-color:#dcade6;font-size:1em;}"); + webpage += F("li{float:left;border-radius:0.375em;border-right:0.06em solid #bbb;}last-child {border-right:none;font-size:85%}"); + webpage += F("li a{display: block;border-radius:0.375em;padding:0.44em 0.44em;text-decoration:none;font-size:85%}"); + webpage += F("li a:hover{background-color:#EAE3EA;border-radius:0.375em;font-size:85%}"); + webpage += F("section {font-size:0.88em;}"); + webpage += F("h1{color:white;border-radius:0.5em;font-size:1em;padding:0.2em 0.2em;background:#558ED5;}"); + webpage += F("h2{color:orange;font-size:1.0em;}"); + webpage += F("h3{font-size:0.8em;}"); + webpage += F("table{font-family:arial,sans-serif;font-size:0.9em;border-collapse:collapse;width:85%;}"); + webpage += F("th,td {border:0.06em solid #dddddd;text-align:left;padding:0.3em;border-bottom:0.06em solid #dddddd;}"); + webpage += F("tr:nth-child(odd) {background-color:#eeeeee;}"); + webpage += F(".rcorners_n {border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:20%;color:white;font-size:75%;}"); + webpage += F(".rcorners_m {border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:50%;color:white;font-size:75%;}"); + webpage += F(".rcorners_w {border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:70%;color:white;font-size:75%;}"); + webpage += F(".column{float:left;width:50%;height:45%;}"); + webpage += F(".row:after{content:'';display:table;clear:both;}"); + //webpage += F("*{box-sizing:border-box;}"); + /////eedfff + webpage += F("footer{background-color:#eedfff; text-align:center;padding:0.3em 0.3em;border-radius:0.375em;font-size:60%;}"); + webpage += F("button{border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:20%;color:white;font-size:130%;}"); + webpage += F(".buttons {border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:15%;color:white;font-size:80%;}"); + webpage += F(".buttonsm{border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:9%; color:white;font-size:70%;}"); + webpage += F(".buttonm {border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:15%;color:white;font-size:70%;}"); + webpage += F(".buttonw {border-radius:0.5em;background:#558ED5;padding:0.3em 0.3em;width:40%;color:white;font-size:70%;}"); + ////// + webpage += F("a{font-size:75%;}"); + webpage += F("p{font-size:75%;}"); + ///+String(file.name())+ + + + + webpage += F("</style></head><body><h1>MK-BlindControl "); webpage += String(ServerVersion) + "</h1>"; +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +void append_page_footer(){ // Saves repeating many lines of code for HTML page footers + ////for coding footer see web sites + //////https://bit-calculator.com/bit-shift-calculator + //////https://lwp.interglacial.com/appf_01.htm + webpage += F("<ul>"); + webpage += F("<li><a href='/'>Home</a></li>"); // Lower Menu bar command entries + + webpage += F("<li><a href='/firmwareupdate'>Firmware</a></li>"); + webpage += F("<li><a href='/reboot'>Reboot</a></li>"); + webpage += F("<li><a href='/reset'>Reset</a></li>"); + webpage += F("<li><a href='/set-servo'>Align</a></li>"); + webpage += F("<li><a href='/set-limits'>Limit Set</a></li>"); + webpage += F("<li><a href='/setup'>Setup</a></li>"); + webpage += F("<li><a href='/saveconfig'>Save</a></li>"); + webpage += F("<li><a href='/filemanager'>File Manager</a></li>"); + //webpage += F("<li><a href='/help'>About</a></li>"); + webpage += F("<li><a href='https://mountaineagle-technologies.com.au/tasmota/mkblindcontrol.html'>About</a></li>"); + webpage += F("</ul>"); + ///2020 + + ////// trade mark space + //webpage += "<footer>™"+String(char(byte(0x40>>1)))+String(char(byte(0x9a>>1)))+String(char(byte(0x8a>>1)))+String(char(byte(0x5a>>1)))+String(char(byte(0xa6>>1))); + //webpage += String(char((0xda>>1)))+String(char(byte(0xc2>>1)))+String(char(0xe4>>1))+String(char(0xe8>>1))+String(char(byte(0xd0>>1))); + //webpage += String(char(byte(0xde>>1)))+String(char(byte(0xea>>1)))+String(char(byte(0xe6>>1)))+String(char(0xca>>1)); +///////// TM space M o u n +webpage += "<footer>™"+String(char(byte(0x40>>1)))+String(char(byte(0x9a>>1)))+String(char(byte(0xde>>1)))+String(char(byte(0xea>>1)))+String(char(byte(0xdc>>1))); +////// t a i n e +webpage += String(char((0xe8>>1)))+String(char(byte(0xc2>>1)))+String(char(0xd2>>1))+String(char(0xdc>>1))+String(char(byte(0x8a>>1))); +/////// a g l e - +webpage += String(char((0xc2>>1)))+String(char(byte(0xce>>1)))+String(char(0xd8>>1))+String(char(0xca>>1))+String(char(byte(0x5a>>1))); +///////// T e c h n +webpage += String(char((0xa8>>1)))+String(char(byte(0xca>>1)))+String(char(0xc6>>1))+String(char(0xd0>>1))+String(char(byte(0xdc>>1))); +////////// o l o g i +webpage += String(char((0xde>>1)))+String(char(byte(0xd8>>1)))+String(char(0xde>>1))+String(char(0xce>>1))+String(char(byte(0xd2>>1))); +////////// e s +webpage += String(char((0xca>>1)))+String(char(byte(0xe6>>1))); +//// //// space 2 0 2 2 + webpage += String(char(byte(0x40>>1)))+String(char(byte(0x64>>1)))+String(char(byte(0x60>>1)))+String(char(byte(0x64>>1)))+String(char(0x64>>1))+"</footer>"; + webpage += F("</body></html>"); +} diff --git a/HAMqttDevice.h b/HAMqttDevice.h new file mode 100644 index 0000000..370494a --- /dev/null +++ b/HAMqttDevice.h @@ -0,0 +1,77 @@ +#ifndef HA_MQTT_DEVICE_H +#define HA_MQTT_DEVICE_H + +#include "Arduino.h" + +class HAMqttDevice +{ +public: + enum DeviceType + { + ALARM_CONTROL_PANEL, + BINARY_SENSOR, + CAMERA, + COVER, + FAN, + LIGHT, + LOCK, + SENSOR, + SWITCH, + CLIMATE, + VACUUM + }; + +private: + // Device proprieties + const String _name; + const DeviceType _type; + + String _identifier; + String _topic; + + // Config variables handling + struct ConfigVar + { + String key; + String value; + }; + std::vector<ConfigVar> _configVars; + + // Device attributes handling + struct Attribute + { + String key; + String value; + }; + std::vector<Attribute> _attributes; + +public: + HAMqttDevice( + const String &name, + const DeviceType type, + const String &haMQTTPrefix = "homeassistant"); + + ~HAMqttDevice(); + + HAMqttDevice &enableCommandTopic(); + HAMqttDevice &enableStateTopic(); + HAMqttDevice &enableAttributesTopic(); + + HAMqttDevice &addConfigVar(const String &key, const String &value); + HAMqttDevice &addAttribute(const String &key, const String &value); + HAMqttDevice &clearAttributes(); + + const String getConfigPayload() const; + const String getAttributesPayload() const; + + inline const String getTopic() const { return _topic; } + inline const String getStateTopic() const { return _topic + "/state"; } + inline const String getConfigTopic() const { return _topic + "/config"; } + inline const String getAttributesTopic() const { return _topic + "/attr"; } + inline const String getCommandTopic() const { return _topic + "/cmd"; } + +private: + static String deviceTypeToStr(DeviceType type); +}; + +#endif \ No newline at end of file diff --git a/PageIndex.h b/PageIndex.h new file mode 100644 index 0000000..554a848 --- /dev/null +++ b/PageIndex.h @@ -0,0 +1,164 @@ +const char MAIN_page[] PROGMEM = R"=====( + +<!DOCTYPE html> + +<html> + + <head> + + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <style> + + html { + + font-family: Arial; + + display: inline-block; + + margin: 0px auto; + + text-align: center; + + } + + + + .slidecontainer { + + width: 100%; + + } + + .slider { + + -webkit-appearance: none; + + width: 50%; + + height: 15px; + + border-radius: 5px; + + background: orange; + + outline: none; + + opacity: 0.5; + + -webkit-transition: .2s; + + transition: opacity .2s; + + } + + .slider:hover { + + opacity: 2; + + } + + .slider::-webkit-slider-thumb { + + -webkit-appearance: none; + + appearance: none; + + width: 25px; + + height: 25px; + + border-radius: 50%; + + background: brown; + + cursor: pointer; + + } + + .slider::-moz-range-thumb { + + width: 25px; + + height: 25px; + + border-radius: 50%; + + background: #4CAF50; + + cursor: pointer; + + } + + </style> + + </head> + + <body> + + <h1> Use Mouse or Left/Right Arrow Keys to Position Blind</h1> + <h1> For fine tunning use Left/Right Arrow Keys + <h1> Take note of default values above as these are system generated and can change + <h1> Click Required Set Position OPEN or CLOSED</h1> + <h1> Click Save when done</h1> + <h1> Click HOME to de-energise servo's when done</h1> + + + + + + <br><br> + + <div class="slidecontainer"> + + + <input type="range" min="0" value="90" max="180" class="slider" id="myRange"> + + <p>Servo position: <span id="demo"></span></p> + + </div> + + <script> + + function sendData(pos) { + + var xhttp = new XMLHttpRequest(); + + xhttp.onreadystatechange = function() { + + if (this.readyState == 4 && this.status == 200) { + + console.log(this.responseText); + + } + + }; + + xhttp.open("GET", "setPOS?servoPOS="+pos, true); + + xhttp.send(); + + } + + var slider = document.getElementById("myRange"); + + var output = document.getElementById("demo"); + + output.innerHTML = slider.value; + + slider.oninput = function() { + + output.innerHTML = this.value; + + sendData(output.innerHTML); + + } + + </script> + + </body> + +</html> + +)====="; +