mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 02:52:11 +01:00
Fix toggle button for 1-button controllers.
This commit is contained in:
parent
5598790310
commit
ea37fa0002
6 changed files with 219 additions and 15 deletions
109
Somfy.cpp
109
Somfy.cpp
|
|
@ -347,6 +347,7 @@ void somfy_frame_t::encodeFrame(byte *frame) {
|
|||
frame[9] = 25;
|
||||
break;
|
||||
case somfy_commands::Prog:
|
||||
//frame[0] = 0xA6;
|
||||
frame[7] = 196;
|
||||
frame[8] = 0;
|
||||
frame[9] = 25;
|
||||
|
|
@ -1637,13 +1638,23 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
|||
}
|
||||
break;
|
||||
case somfy_commands::My:
|
||||
if(this->shadeType == shade_types::drycontact) {
|
||||
if(this->shadeType == shade_types::garage1) {
|
||||
if(this->lastFrame.processed) return;
|
||||
this->lastFrame.processed = true;
|
||||
if(!this->isIdle()) this->target = this->currentPos;
|
||||
else if(this->currentPos == 100.0f) this->target = 0;
|
||||
else if(this->currentPos == 0.0f) this->target = 100;
|
||||
else this->target = this->lastMovement == -1 ? 100 : 0;
|
||||
return;
|
||||
}
|
||||
else if(this->shadeType == shade_types::drycontact) {
|
||||
// In this case we need to toggle the contact but we only should do this if
|
||||
// this is not a repeat.
|
||||
if(this->lastFrame.processed) return;
|
||||
this->lastFrame.processed = true;
|
||||
this->target = this->currentPos = this->currentPos > 0 ? 0 : 100;
|
||||
this->emitState();
|
||||
if(this->currentPos == 100.0f) this->target = 0;
|
||||
else if(this->currentPos == 0.0f) this->target = 100;
|
||||
else this->target = this->lastMovement == -1 ? 100 : 0;
|
||||
return;
|
||||
}
|
||||
if(this->isIdle()) {
|
||||
|
|
@ -2030,7 +2041,9 @@ void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
|||
if(this->tiltType == tilt_types::integrated) this->tiltTarget = 100.0f;
|
||||
}
|
||||
else if(cmd == somfy_commands::My) {
|
||||
if(this->isIdle()) {
|
||||
if(this->shadeType == shade_types::garage1 || this->shadeType == shade_types::drycontact)
|
||||
SomfyRemote::sendCommand(cmd, repeat);
|
||||
else if(this->isIdle()) {
|
||||
this->moveToMyPosition();
|
||||
return;
|
||||
}
|
||||
|
|
@ -2040,6 +2053,10 @@ void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
|||
this->tiltTarget = this->currentTiltPos;
|
||||
}
|
||||
}
|
||||
else if(cmd == somfy_commands::Toggle) {
|
||||
if(this->bitLength != 80) SomfyRemote::sendCommand(somfy_commands::My, repeat);
|
||||
else SomfyRemote::sendCommand(somfy_commands::Toggle, repeat);
|
||||
}
|
||||
else if(this->shadeType == shade_types::garage1 && cmd == somfy_commands::Prog) {
|
||||
SomfyRemote::sendCommand(somfy_commands::Toggle, repeat);
|
||||
}
|
||||
|
|
@ -3114,6 +3131,69 @@ void RECEIVE_ATTR Transceiver::handleReceive() {
|
|||
somfy_rx.status = waiting_synchro;
|
||||
}
|
||||
}
|
||||
float currFreq = 433.0f;
|
||||
int currRSSI = -100;
|
||||
float markFreq = 433.0f;
|
||||
int markRSSI = -100;
|
||||
uint32_t lastScan = 0;
|
||||
void Transceiver::beginFrequencyScan() {
|
||||
if(this->config.enabled) {
|
||||
this->disableReceive();
|
||||
rxmode = 3;
|
||||
pinMode(this->config.RXPin, INPUT);
|
||||
interruptPin = digitalPinToInterrupt(this->config.RXPin);
|
||||
ELECHOUSE_cc1101.setRxBW(this->config.rxBandwidth); // Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz.
|
||||
ELECHOUSE_cc1101.SetRx();
|
||||
markFreq = currFreq = 433.0f;
|
||||
markRSSI = -100;
|
||||
ELECHOUSE_cc1101.setMHZ(currFreq);
|
||||
Serial.printf("Begin frequency scan on Pin #%d\n", this->config.RXPin);
|
||||
attachInterrupt(interruptPin, handleReceive, CHANGE);
|
||||
this->emitFrequencyScan();
|
||||
}
|
||||
}
|
||||
void Transceiver::processFrequencyScan(bool received) {
|
||||
if(this->config.enabled && rxmode == 3) {
|
||||
if(received) {
|
||||
currRSSI = ELECHOUSE_cc1101.getRssi();
|
||||
if((long)(markFreq * 100) == (long)(currFreq * 100)) {
|
||||
markRSSI = currRSSI;
|
||||
}
|
||||
else if(currRSSI >-75) {
|
||||
if(currRSSI > markRSSI) {
|
||||
markRSSI = currRSSI;
|
||||
markFreq = currFreq;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
currRSSI = -100;
|
||||
}
|
||||
|
||||
if(millis() - lastScan > 100 && somfy_rx.status == waiting_synchro) {
|
||||
lastScan = millis();
|
||||
this->emitFrequencyScan();
|
||||
currFreq += 0.01f;
|
||||
if(currFreq > 434.0f) currFreq = 433.0f;
|
||||
ELECHOUSE_cc1101.setMHZ(currFreq);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Transceiver::endFrequencyScan() {
|
||||
if(rxmode == 3) {
|
||||
rxmode = 0;
|
||||
if(interruptPin > 0) detachInterrupt(interruptPin);
|
||||
interruptPin = 0;
|
||||
this->config.apply();
|
||||
this->emitFrequencyScan();
|
||||
}
|
||||
}
|
||||
void Transceiver::emitFrequencyScan(uint8_t num) {
|
||||
char buf[420];
|
||||
snprintf(buf, sizeof(buf), "{\"scanning\":%s,\"testFreq\":%f,\"testRSSI\":%d,\"frequency\":%f,\"RSSI\":%d}", rxmode == 3 ? "true" : "false", currFreq, currRSSI, markFreq, markRSSI);
|
||||
if(num >= 255) sockEmit.sendToClients("frequencyScan", buf);
|
||||
else sockEmit.sendToClient(num, "frequencyScan", buf);
|
||||
}
|
||||
bool Transceiver::receive() {
|
||||
// Check to see if there is anything in the buffer
|
||||
if(rx_queue.length > 0) {
|
||||
|
|
@ -3123,7 +3203,6 @@ bool Transceiver::receive() {
|
|||
this->frame.decodeFrame(&rx);
|
||||
this->emitFrame(&this->frame, &rx);
|
||||
return this->frame.valid;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3494,13 +3573,21 @@ bool Transceiver::begin() {
|
|||
return true;
|
||||
}
|
||||
void Transceiver::loop() {
|
||||
if (this->receive()) {
|
||||
//this->clearReceived();
|
||||
somfy.processFrame(this->frame, false);
|
||||
}
|
||||
else {
|
||||
somfy.processWaitingFrame();
|
||||
if(rxmode == 3) {
|
||||
if(rx_queue.length > 0) {
|
||||
//Serial.printf("Processing receive %d\n", rx_queue.length);
|
||||
somfy_rx_t rx;
|
||||
rx_queue.pop(&rx);
|
||||
this->frame.decodeFrame(&rx);
|
||||
this->processFrequencyScan(this->frame.valid);
|
||||
}
|
||||
else
|
||||
this->processFrequencyScan(false);
|
||||
}
|
||||
else if (this->receive())
|
||||
somfy.processFrame(this->frame, false);
|
||||
else
|
||||
somfy.processWaitingFrame();
|
||||
}
|
||||
somfy_frame_t& Transceiver::lastFrame() { return this->frame; }
|
||||
void Transceiver::beginTransmit() {
|
||||
|
|
|
|||
4
Somfy.h
4
Somfy.h
|
|
@ -413,6 +413,10 @@ class Transceiver {
|
|||
void beginTransmit();
|
||||
void endTransmit();
|
||||
void emitFrame(somfy_frame_t *frame, somfy_rx_t *rx = nullptr);
|
||||
void beginFrequencyScan();
|
||||
void endFrequencyScan();
|
||||
void processFrequencyScan(bool received = false);
|
||||
void emitFrequencyScan(uint8_t num = 255);
|
||||
};
|
||||
class SomfyShadeController {
|
||||
protected:
|
||||
|
|
|
|||
Binary file not shown.
19
Web.cpp
19
Web.cpp
|
|
@ -2180,6 +2180,25 @@ void Web::begin() {
|
|||
}
|
||||
}
|
||||
});
|
||||
server.on("/beginFrequencyScan", []() {
|
||||
webServer.sendCORSHeaders(server);
|
||||
somfy.transceiver.beginFrequencyScan();
|
||||
DynamicJsonDocument doc(1024);
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
somfy.transceiver.toJSON(obj);
|
||||
serializeJson(doc, g_content);
|
||||
server.send(200, _encoding_json, g_content);
|
||||
});
|
||||
server.on("/endFrequencyScan", []() {
|
||||
webServer.sendCORSHeaders(server);
|
||||
somfy.transceiver.endFrequencyScan();
|
||||
DynamicJsonDocument doc(1024);
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
somfy.transceiver.toJSON(obj);
|
||||
serializeJson(doc, g_content);
|
||||
server.send(200, _encoding_json, g_content);
|
||||
});
|
||||
|
||||
server.begin();
|
||||
apiServer.begin();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,13 +388,13 @@
|
|||
<label for="cbHasLight" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Has Light</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:-10px;">
|
||||
<div style="margin-top:-10px;" id="divFlipCommands">
|
||||
<div class="field-group" style="display:inline-block">
|
||||
<input id="cbFlipCommands" name="flipCommands" data-bind="flipCommands" type="checkbox" style="" />
|
||||
<label for="cbFlipCommands" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Invert Commands</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:-10px;">
|
||||
<div style="margin-top:-10px;" id="divFlipPosition">
|
||||
<div class="field-group">
|
||||
<input id="cbFlipPosition" name="flipPos" data-bind="flipPosition" type="checkbox" style="" />
|
||||
<label for="cbFlipPosition" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Invert Position (expressed in % of open)</label>
|
||||
|
|
@ -666,7 +666,7 @@
|
|||
</div>
|
||||
<div class="field-group" style="display:inline-block;width:auto;min-width:247px;margin-top:-20px;vertical-align:top;">
|
||||
<div class="field-group">
|
||||
<input id="slidFrequency" name="frequency" type="range" min="433330" max="434399" step="1" style="width:100%;" data-bind="transceiver.config.frequency" data-datatype="float" data-mult="1000" oninput="somfy.frequencyChanged(this);" />
|
||||
<input id="slidFrequency" name="frequency" type="range" min="433000" max="434399" step="1" style="width:100%;" data-bind="transceiver.config.frequency" data-datatype="float" data-mult="1000" oninput="somfy.frequencyChanged(this);" />
|
||||
<label for="slidFrequency" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;">
|
||||
<span>Base Frequency </span>
|
||||
<span style="float:right;display:inline-block;margin-right:7px;">
|
||||
|
|
@ -703,6 +703,10 @@
|
|||
<button id="btnSaveRadio" type="button" onclick="somfy.saveRadio();">
|
||||
Save Radio
|
||||
</button>
|
||||
<button id="btnScanFrequency" type="button" onclick="somfy.scanFrequency(true);">
|
||||
Scan Frequency
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="divFrameLog" class="subtab-content frame-log" style="display:none;margin:0px;padding:0px;">
|
||||
|
|
|
|||
|
|
@ -489,6 +489,9 @@ async function initSockets() {
|
|||
case 'packetPulses':
|
||||
console.log(msg);
|
||||
break;
|
||||
case 'frequencyScan':
|
||||
somfy.procFrequencyScan(msg);
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (err) {
|
||||
|
|
@ -1929,6 +1932,86 @@ class Somfy {
|
|||
}
|
||||
}
|
||||
}
|
||||
procFrequencyScan(scan) {
|
||||
//console.log(scan);
|
||||
let div = this.scanFrequency();
|
||||
let spanTestFreq = document.getElementById('spanTestFreq');
|
||||
let spanTestRSSI = document.getElementById('spanTestRSSI');
|
||||
let spanBestFreq = document.getElementById('spanBestFreq');
|
||||
let spanBestRSSI = document.getElementById('spanBestRSSI');
|
||||
if (spanBestFreq) {
|
||||
spanBestFreq.innerHTML = scan.RSSI !== -100 ? scan.frequency.fmt('###.00') : '----';
|
||||
}
|
||||
if (spanBestRSSI) {
|
||||
spanBestRSSI.innerHTML = scan.RSSI !== -100 ? scan.RSSI : '----';
|
||||
}
|
||||
if (spanTestFreq) {
|
||||
spanTestFreq.innerHTML = scan.testFreq.fmt('###.00');
|
||||
}
|
||||
if (spanTestRSSI) {
|
||||
spanTestRSSI.innerHTML = scan.testRSSI !== -100 ? scan.testRSSI : '----';
|
||||
}
|
||||
if (scan.RSSI !== -100)
|
||||
div.setAttribute('data-frequency', scan.frequency);
|
||||
}
|
||||
scanFrequency(initScan) {
|
||||
let div = document.getElementById('divScanFrequency');
|
||||
if (!div || typeof div === 'undefined') {
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('id', 'divScanFrequency');
|
||||
div.classList.add('prompt-message');
|
||||
let html = '<div class="sub-message">Frequency Scanning has started. Press and hold any button on your remote and ESPSomfy RTS will find the closest frequency to the remote.</div>';
|
||||
html += '<hr style="width:100%;margin:0px;"></hr>';
|
||||
html += '<div class="" style="font-size:20px;"><label style="padding-right:7px;display:inline-block;width:87px;">Scanning</label><span id="spanTestFreq" style="display:inline-block;width:4em;text-align:right;">433.00</span><span>MHz</span><label style="padding-left:12px;padding-right:7px;">RSSI</label><span id="spanTestRSSI">----</span><span>dBm</span></div>';
|
||||
html += '<div class="" style="font-size:20px;"><label style="padding-right:7px;display:inline-block;width:87px;">Frequency</label><span id="spanBestFreq" style="display:inline-block;width:4em;text-align:right;">---.--</span><span>MHz</span><label style="padding-left:12px;padding-right:7px;">RSSI</label><span id="spanBestRSSI">----</span><span>dBm</span></div>';
|
||||
html += `<div class="button-container">`;
|
||||
html += `<button id="btnStopScanning" type="button" style="padding-left:20px;padding-right:20px;" onclick="somfy.stopScanningFrequency(true);">Stop Scanning</button>`;
|
||||
html += `<button id="btnRestartScanning" type="button" style="padding-left:20px;padding-right:20px;display:none;" onclick="somfy.scanFrequency(true);">Start Scanning</button>`;
|
||||
html += `<button id="btnCopyFrequency" type="button" style="padding-left:20px;padding-right:20px;display:none;" onclick="somfy.setScannedFrequency();">Set Frequency</button>`;
|
||||
html += `<button id="btnCloseScanning" type="button" style="padding-left:20px;padding-right:20px;width:100%;display:none;" onclick="document.getElementById('divScanFrequency').remove();">Close</button>`;
|
||||
html += `</div>`;
|
||||
div.innerHTML = html;
|
||||
document.getElementById('divRadioSettings').appendChild(div);
|
||||
}
|
||||
if (initScan) {
|
||||
div.setAttribute('data-initscan', true);
|
||||
putJSONSync('/beginFrequencyScan', {}, (err, trans) => {
|
||||
if (!err) {
|
||||
document.getElementById('btnStopScanning').style.display = '';
|
||||
document.getElementById('btnRestartScanning').style.display = 'none';
|
||||
document.getElementById('btnCopyFrequency').style.display = 'none';
|
||||
document.getElementById('btnCloseScanning').style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
return div;
|
||||
}
|
||||
setScannedFrequency() {
|
||||
let div = document.getElementById('divScanFrequency');
|
||||
let freq = parseFloat(div.getAttribute('data-frequency'));
|
||||
let slid = document.getElementById('slidFrequency');
|
||||
slid.value = Math.round(freq * 1000);
|
||||
somfy.frequencyChanged(slid);
|
||||
div.remove();
|
||||
}
|
||||
stopScanningFrequency(killScan) {
|
||||
let div = document.getElementById('divScanFrequency');
|
||||
if (div && killScan !== true) {
|
||||
div.remove();
|
||||
}
|
||||
else {
|
||||
putJSONSync('/endFrequencyScan', {}, (err, trans) => {
|
||||
if (err) ui.serviceError(err);
|
||||
else {
|
||||
let freq = parseFloat(div.getAttribute('data-frequency'));
|
||||
document.getElementById('btnStopScanning').style.display = 'none';
|
||||
document.getElementById('btnRestartScanning').style.display = '';
|
||||
if(typeof freq === 'number') document.getElementById('btnCopyFrequency').style.display = '';
|
||||
document.getElementById('btnCloseScanning').style.display = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
btnDown = null;
|
||||
btnTimer = null;
|
||||
// Sort the array first to allow the user to drag and drop where they want the shade.
|
||||
|
|
@ -2585,6 +2668,8 @@ class Somfy {
|
|||
let sun = true;
|
||||
let light = false;
|
||||
let lift = true;
|
||||
let flipCommands = true;
|
||||
let flipPosition = true;
|
||||
let ico = document.getElementById('icoShade');
|
||||
let type = parseInt(sel.value, 10);
|
||||
document.getElementById('somfyShade').setAttribute('data-shadetype', type);
|
||||
|
|
@ -2641,8 +2726,9 @@ class Somfy {
|
|||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
||||
tilt = false;
|
||||
break;
|
||||
case 6:
|
||||
case 5:
|
||||
flipCommands = false;
|
||||
case 6:
|
||||
document.getElementById('divTiltSettings').style.display = 'none';
|
||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
||||
|
|
@ -2698,6 +2784,8 @@ class Somfy {
|
|||
tilt = false;
|
||||
light = false;
|
||||
sun = false;
|
||||
flipPosition = false;
|
||||
flipCommands = false;
|
||||
break;
|
||||
|
||||
|
||||
|
|
@ -2720,6 +2808,8 @@ class Somfy {
|
|||
document.querySelector('#divSomfyButtons i.icss-window-tilt').style.display = tilt ? '' : 'none';
|
||||
document.getElementById('divSunSensor').style.display = sun ? '' : 'none';
|
||||
document.getElementById('divLightSwitch').style.display = light ? '' : 'none';
|
||||
document.getElementById('divFlipPosition').style.display = flipPosition ? '' : 'none';
|
||||
document.getElementById('divFlipCommands').style.display = flipCommands ? '' : 'none';
|
||||
if (!light) document.getElementById('cbHasLight').checked = false;
|
||||
if (!sun) document.getElementById('cbHasSunsensor').checked = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue