Work on Github update #171

This commit is contained in:
Robert Strouse 2023-10-27 11:34:45 -07:00
parent 844a163e5d
commit 13aff49479
12 changed files with 146 additions and 24 deletions

View file

@ -3,7 +3,7 @@
#ifndef configsettings_h
#define configsettings_h
#define FW_VERSION "v2.1.10"
#define FW_VERSION "v2.2.0"
enum DeviceStatus {
DS_OK = 0,
DS_ERROR = 1,

View file

@ -46,7 +46,7 @@ bool GitRelease::toJSON(JsonObject &obj) {
}
#define ERR_CLIENT_OFFSET -50
int8_t GitRepo::getReleases(uint8_t num) {
int16_t GitRepo::getReleases(uint8_t num) {
WiFiClientSecure *client = new WiFiClientSecure;
if(client) {
client->setInsecure();
@ -63,8 +63,8 @@ int8_t GitRepo::getReleases(uint8_t num) {
strcpy(main->version.name, "main");
strcpy(main->name, "Main");
if(https.begin(*client, url)) {
Serial.print("[HTTPS] GET...\n");
int httpCode = https.GET();
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
if(httpCode > 0) {
int len = https.getSize();
Serial.printf("[HTTPS] GET... code: %d - %d\n", httpCode, len);
@ -154,6 +154,7 @@ int8_t GitRepo::getReleases(uint8_t num) {
}
https.end();
}
delete client;
}
return 0;
}
@ -201,9 +202,13 @@ void GitUpdater::checkForUpdate() {
GitRepo repo;
this->lastCheck = millis();
this->updateAvailable = false;
if(repo.getReleases(2) == 0) { // Get 2 releases so we can filter our pre-releases
this->error = repo.getReleases(2);
if(this->error == 0) { // Get 2 releases so we can filter our pre-releases
this->setCurrentRelease(repo);
}
else {
this->emitUpdateCheck();
}
this->status = GIT_STATUS_READY;
}
void GitUpdater::setCurrentRelease(GitRepo &repo) {

View file

@ -28,7 +28,7 @@ class GitRelease {
class GitRepo {
public:
int8_t getReleases(uint8_t num = GIT_MAX_RELEASES);
int16_t getReleases(uint8_t num = GIT_MAX_RELEASES);
GitRelease releases[GIT_MAX_RELEASES + 1];
bool toJSON(JsonObject &obj);
};
@ -39,7 +39,7 @@ class GitUpdater {
bool updateAvailable = false;
appver_t latest;
bool cancelled = false;
int8_t error = 0;
int16_t error = 0;
char targetRelease[32];
char currentFile[64] = "";
char baseUrl[128] = "";

View file

@ -326,7 +326,7 @@ bool Network::connectWiFi() {
case WL_NO_SSID_AVAIL:
Serial.print(" Connection failed the SSID ");
Serial.print(settings.WIFI.ssid);
Serial.print(" could not be found");
Serial.println(" could not be found");
return false;
default:
break;
@ -497,10 +497,7 @@ void Network::networkEvent(WiFiEvent_t event) {
Serial.println("WiFi AP Started");
break;
case ARDUINO_EVENT_WIFI_STA_START:
Serial.println("WiFi STA Started");
if(settings.hostname[0] != '\0') WiFi.setHostname(settings.hostname);
Serial.print("Set hostname event to:");
Serial.println(WiFi.getHostname());
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
break;

View file

@ -785,6 +785,7 @@ bool SomfyRemote::hasLight() { return (this->flags & static_cast<uint8_t>(somfy_
void SomfyRemote::setSunSensor(bool bHasSensor ) { bHasSensor ? this->flags |= static_cast<uint8_t>(somfy_flags_t::SunSensor) : this->flags &= ~(static_cast<uint8_t>(somfy_flags_t::SunSensor)); }
void SomfyRemote::setLight(bool bHasLight ) { bHasLight ? this->flags |= static_cast<uint8_t>(somfy_flags_t::Light) : this->flags &= ~(static_cast<uint8_t>(somfy_flags_t::Light)); }
void SomfyGroup::updateFlags() {
uint8_t oldFlags = this->flags;
this->flags = 0;
for(uint8_t i = 0; i < SOMFY_MAX_GROUPED_SHADES; i++) {
if(this->linkedShades[i] != 0) {
@ -793,6 +794,7 @@ void SomfyGroup::updateFlags() {
}
else break;
}
if(oldFlags != this->flags) this->emitState();
}
bool SomfyShade::isInGroup() {
if(this->getShadeId() == 255) return false;
@ -2107,14 +2109,14 @@ void SomfyShade::processInternalCommand(somfy_commands cmd, uint8_t repeat) {
}
break;
case somfy_commands::Flag:
if(this->hasSunSensor()) {
this->p_sunFlag(false);
//this->flags &= ~(static_cast<uint8_t>(somfy_flags_t::SunFlag));
if(this->hasSunSensor()) {
somfy.isDirty = true;
this->emitState();
}
else
else {
Serial.printf("Shade does not have sensor %d\n", this->flags);
}
break;
case somfy_commands::SunFlag:
if(this->hasSunSensor()) {

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
2.1.10
2.2.0

View file

@ -3,11 +3,11 @@
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="main.css?v=2.1.10" type="text/css" />
<link rel="stylesheet" href="widgets.css?v=2.1.10" type="text/css" />
<link rel="stylesheet" href="icons.css?v=2.1.10" type="text/css" />
<link rel="stylesheet" href="main.css?v=2.2.0" type="text/css" />
<link rel="stylesheet" href="widgets.css?v=2.2.0" type="text/css" />
<link rel="stylesheet" href="icons.css?v=2.2.0" type="text/css" />
<link rel="icon" type="image/png" href="favicon.png" />
<script type="text/javascript" src="index.js?v=2.1.10"></script>
<script type="text/javascript" src="index.js?v=2.2.0"></script>
</head>
<body>
<div id="divContainer" class="container main" data-auth="false">

View file

@ -977,6 +977,23 @@ class UIBinder {
div.querySelector('#btnYes').addEventListener('click', onYes);
return div;
}
infoMessage(el, msg, onOk) {
if (arguments.length === 1) {
onOk = msg;
msg = el;
el = document.getElementById('divContainer');
}
let div = document.createElement('div');
div.innerHTML = '<div class="info-text">' + msg + '</div><div class="sub-message"></div><div class="button-container" style="text-align:center;"><button id="btnOk" type="button" style="width:40%;display:inline-block;">Ok</button></div></div>';
div.classList.add('info-message');
div.classList.add('message-overlay');
el.appendChild(div);
if (typeof onOk === 'function') div.querySelector('#btnOk').addEventListener('click', onOk);
else div.querySelector('#btnOk').addEventListener('click', (e) => { div.remove() });
//div.querySelector('#btnYes').addEventListener('click', onYes);
return div;
}
clearErrors() {
let errors = document.querySelectorAll('div.message-overlay');
if (errors && errors.length > 0) errors.forEach((el) => { el.remove(); });
@ -1235,7 +1252,7 @@ var security = new Security();
class General {
initialized = false;
appVersion = 'v2.1.10';
appVersion = 'v2.2.0';
reloadApp = false;
init() {
if (this.initialized) return;
@ -2444,7 +2461,7 @@ class Somfy {
}
divCtl += '</div></div>';
divCtl += `<div class="groupctl-buttons">`;
divCtl += `<div class="button-sunflag cmd-button" data-cmd="sunflag" data-groupid="${group.groupId}" data-on="${group.flags & 0x01 ? 'true' : 'false'}" style="${!group.sunSensor ? 'display:none' : ''}"><i class="icss-sun-c"></i><i class="icss-sun-o"></i></div>`;
divCtl += `<div class="button-sunflag cmd-button" data-cmd="sunflag" data-groupid="${group.groupId}" data-on="${group.flags & 0x20 ? 'true' : 'false'}" style="${!group.sunSensor ? 'display:none' : ''}"><i class="icss-sun-c"></i><i class="icss-sun-o"></i></div>`;
divCtl += `<div class="button-outline cmd-button" data-cmd="up" data-groupid="${group.groupId}"><i class="icss-somfy-up"></i></div>`;
divCtl += `<div class="button-outline cmd-button my-button" data-cmd="my" data-groupid="${group.groupId}" style="font-size:2em;padding:10px;"><span>my</span></div>`;
divCtl += `<div class="button-outline cmd-button" data-cmd="down" data-groupid="${group.groupId}"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>`;
@ -2648,7 +2665,7 @@ class Somfy {
let flags = document.querySelectorAll(`.button-sunflag[data-groupid="${state.groupId}"]`);
for (let i = 0; i < flags.length; i++) {
flags[i].style.display = state.sunSensor ? '' : 'none';
flags[i].setAttribute('data-on', state.flags & 0x01 === 0x01 ? 'true' : 'false');
flags[i].setAttribute('data-on', state.flags & 0x20 === 0x20 ? 'true' : 'false');
}
}
procShadeState(state) {
@ -4180,12 +4197,12 @@ class Firmware {
div.style.alignContent = 'center';
let html = `<div>Select a version from the repository to install using the dropdown below. Then press the update button to install that version.</div><div style="font-size:.7em;margin-top:4px;">Select Main to install the most recent alpha version from the repository.</div>`;
html += `<div class="field-group" style = "text-align:center;">`;
html += `<select id="selVersion" data-bind="version" style="width:50%;font-size:2em;color:white;">`
html += `<select id="selVersion" data-bind="version" style="width:50%;font-size:2em;color:white;" onchange="firmware.gitReleaseSelected(document.getElementById('divGitInstall'));">`
for (let i = 0; i < rel.releases.length; i++) {
html += `<option style="text-align:left;font-size:.5em;color:black;" value="${rel.releases[i].version.name}">${rel.releases[i].name}</option>`
}
html += `<label for="selVersion">Select a version</label>`;
html += '</select></div>';
html += `</select><label for="selVersion">Select a version</label></div>`;
html += `<div class="button-container" id="divReleaseNotes" style="text-align:center;margin-top:-20px;display:none;"><button type="button" onclick="firmware.showReleaseNotes(document.getElementById('selVersion').value);" style="display:inline-block;width:auto;padding-left:20px;padding-right:20px;">Release Notes</button></div>`;
if (this.isMobile()) {
html += `<div style="width:100%;color:red;text-align:center;font-weight:bold;"><span style="margin-top:7px;width:100%;background:yellow;padding:3px;display:inline-block;border-radius:5px;background:white;">WARNING<span></div>`;
html += '<hr/><div style="font-size:14px;margin-bottom:10px;">This browser does not support automatic backups. It is highly recommended that you back up your configuration using the backup button before proceeding.</div>';
@ -4204,10 +4221,104 @@ class Firmware {
div.innerHTML = html;
document.getElementById('divContainer').appendChild(div);
this.gitReleaseSelected(div);
}
});
}
gitReleaseSelected(div) {
let obj = ui.fromElement(div);
let divNotes = div.querySelector('#divReleaseNotes');
if (divNotes) {
if (!obj.version || obj.version === 'main' || obj.version === '') divNotes.style.display = 'none';
else divNotes.style.display = '';
}
}
async getReleaseInfo(tag) {
let overlay = ui.waitMessage(document.getElementById('divContainer'));
try {
let ret = {};
ret.resp = await fetch(`https://api.github.com/repos/rstrouse/espsomfy-rts/releases/tags/${tag}`);
if (ret.resp.ok)
ret.info = await ret.resp.json();
return ret;
}
catch (err) {
return { err: err };
}
finally { overlay.remove(); }
}
async showReleaseNotes(tagName) {
console.log(tagName);
let r = await this.getReleaseInfo(tagName);
console.log(r);
let fnToItem = (txt, tag) => { }
if (r.resp.ok) {
// Convert this to html.
let lines = r.info.body.split('\r\n');
let ctx = { html: '', llvl: 0, lines: r.info.body.split('\r\n'), ndx: 0 };
ctx.toHead = function (txt) {
let num = txt.indexOf(' ');
return `<h${num}>${txt.substring(num).trim()}</h${num}>`;
};
ctx.toUL = function () {
let txt = this.lines[this.ndx++];
let tok = this.token(txt);
this.html += `<ul>${this.toLI(tok.txt)}`;
while (this.ndx < this.lines.length) {
txt = this.lines[this.ndx];
let t = this.token(txt);
if (t.ch === '*') {
if (t.indent !== tok.indent) this.toUL();
else {
this.html += this.toLI(t.txt);
this.ndx++;
}
}
else break;
}
this.html += '</ul>';
};
ctx.toLI = function (txt) { return `<li>${txt.trim()}</li>`; }
ctx.token = function (txt) {
let tok = { ch: '', indent: 0, txt:'' }
for (let i = 0; i < txt.length; i++) {
if (txt[i] === ' ') tok.indent++;
else {
tok.ch = txt[i];
let tmp = txt.substring(tok.indent);
tok.txt = tmp.substring(tmp.indexOf(' '));
break;
}
}
return tok;
};
ctx.next = function () {
if (this.ndx >= this.lines.length) return false;
let tok = this.token(this.lines[this.ndx]);
switch (tok.ch) {
case '#':
this.html += this.toHead(this.lines[this.ndx]);
this.ndx++;
break;
case '*':
this.toUL();
break;
case '':
this.ndx++;
this.html += `<br/><div>${tok.txt}</div>`;
break;
default:
this.ndx++;
break;
}
return true;
};
while (ctx.next());
console.log(ctx);
ui.infoMessage(ctx.html);
}
}
updateFirmware() {
let div = this.createFileUploader('/updateFirmware');
let inst = div.querySelector('div[id=divInstText]');

View file

@ -218,6 +218,7 @@ a {
bottom: 7px;
border-bottom: 1px solid #00bcd4;
}
div.info-message,
div.prompt-message,
div.error-message {
position:absolute;

View file

@ -54,6 +54,12 @@
padding-bottom: 2px;
min-height: 147px;
}
.info-message .info-text {
text-align:left;
font-size:14px;
max-height:calc(100% - 77px);
overflow:auto;
}
.prompt-message .sub-message {
font-size: 17px;
padding-left: 10px;