mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 19:12:10 +01:00
Fix setting My position for some motors #15
This commit is contained in:
parent
53ac717cf3
commit
ac6d6ee34d
9 changed files with 99 additions and 20 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
#ifndef configsettings_h
|
#ifndef configsettings_h
|
||||||
#define configsettings_h
|
#define configsettings_h
|
||||||
|
|
||||||
#define FW_VERSION "v1.5.3"
|
#define FW_VERSION "v1.5.4"
|
||||||
enum DeviceStatus {
|
enum DeviceStatus {
|
||||||
DS_OK = 0,
|
DS_OK = 0,
|
||||||
DS_ERROR = 1,
|
DS_ERROR = 1,
|
||||||
|
|
|
||||||
81
Somfy.cpp
81
Somfy.cpp
|
|
@ -24,7 +24,7 @@ uint8_t rxmode = 0; // Indicates whether the radio is in receive mode. Just to
|
||||||
#define RECEIVE_ATTR
|
#define RECEIVE_ATTR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SETMY_REPEATS 15
|
#define SETMY_REPEATS 35
|
||||||
#define TILT_REPEATS 15
|
#define TILT_REPEATS 15
|
||||||
|
|
||||||
int sort_asc(const void *cmp1, const void *cmp2) {
|
int sort_asc(const void *cmp1, const void *cmp2) {
|
||||||
|
|
@ -1123,7 +1123,7 @@ void SomfyShade::setMovement(int8_t dir) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
|
void SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
|
||||||
if(this->direction != 0) return; // Don't do this if it is moving.
|
if(!this->isIdle()) return; // Don't do this if it is moving.
|
||||||
if(this->tiltType != tilt_types::none) {
|
if(this->tiltType != tilt_types::none) {
|
||||||
if(tilt < 0) tilt = 0;
|
if(tilt < 0) tilt = 0;
|
||||||
if(pos != floor(this->currentPos) || tilt != floor(currentTiltPos)) {
|
if(pos != floor(this->currentPos) || tilt != floor(currentTiltPos)) {
|
||||||
|
|
@ -1134,12 +1134,21 @@ void SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
|
||||||
this->moveToTarget(pos, tilt);
|
this->moveToTarget(pos, tilt);
|
||||||
}
|
}
|
||||||
else if(pos == floor(this->myPos) && tilt == floor(this->myTiltPos)) {
|
else if(pos == floor(this->myPos) && tilt == floor(this->myTiltPos)) {
|
||||||
SomfyRemote::sendCommand(somfy_commands::My, SETMY_REPEATS);
|
// Of so we need to clear the my position. These motors are finicky so send
|
||||||
this->myPos = this->myTiltPos = -1;
|
// a my command to ensure we are actually at the my position then send the clear
|
||||||
this->commitMyPosition();
|
// command. There really is no other way to do this.
|
||||||
this->emitState();
|
if(this->currentPos != this->myPos || this->currentTiltPos != this->myTiltPos) {
|
||||||
|
this->settingMyPos = true;
|
||||||
|
this->moveToMyPosition();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
SomfyRemote::sendCommand(somfy_commands::My, 1);
|
||||||
|
this->settingPos = false;
|
||||||
|
this->settingMyPos = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SomfyRemote::sendCommand(somfy_commands::My, SETMY_REPEATS);
|
||||||
this->myPos = this->currentPos;
|
this->myPos = this->currentPos;
|
||||||
this->myTiltPos = this->currentTiltPos;
|
this->myTiltPos = this->currentTiltPos;
|
||||||
}
|
}
|
||||||
|
|
@ -1155,12 +1164,21 @@ void SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
|
||||||
this->moveToTarget(pos);
|
this->moveToTarget(pos);
|
||||||
}
|
}
|
||||||
else if(pos == floor(this->myPos)) {
|
else if(pos == floor(this->myPos)) {
|
||||||
SomfyRemote::sendCommand(somfy_commands::My, SETMY_REPEATS);
|
// Of so we need to clear the my position. These motors are finicky so send
|
||||||
this->myPos = this->myTiltPos = -1;
|
// a my command to ensure we are actually at the my position then send the clear
|
||||||
this->commitMyPosition();
|
// command. There really is no other way to do this.
|
||||||
this->emitState();
|
if(this->myPos != this->currentPos) {
|
||||||
|
this->settingMyPos = true;
|
||||||
|
this->moveToMyPosition();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
SomfyRemote::sendCommand(somfy_commands::My, 1);
|
||||||
|
this->settingPos = false;
|
||||||
|
this->settingMyPos = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SomfyRemote::sendCommand(somfy_commands::My, SETMY_REPEATS);
|
||||||
this->myPos = currentPos;
|
this->myPos = currentPos;
|
||||||
this->myTiltPos = -1;
|
this->myTiltPos = -1;
|
||||||
this->commitMyPosition();
|
this->commitMyPosition();
|
||||||
|
|
@ -1190,6 +1208,7 @@ void SomfyShade::moveToMyPosition() {
|
||||||
Serial.println(this->direction);
|
Serial.println(this->direction);
|
||||||
if(this->myPos >= 0.0f && this->myPos <= 100.0f) this->target = this->myPos;
|
if(this->myPos >= 0.0f && this->myPos <= 100.0f) this->target = this->myPos;
|
||||||
if(this->myTiltPos >= 0.0f && this->myTiltPos <= 100.0f) this->tiltTarget = this->myTiltPos;
|
if(this->myTiltPos >= 0.0f && this->myTiltPos <= 100.0f) this->tiltTarget = this->myTiltPos;
|
||||||
|
this->settingPos = false;
|
||||||
SomfyRemote::sendCommand(somfy_commands::My);
|
SomfyRemote::sendCommand(somfy_commands::My);
|
||||||
}
|
}
|
||||||
void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
||||||
|
|
@ -1719,13 +1738,53 @@ static uint16_t timing_index = 0;
|
||||||
static somfy_rx_t somfy_rx;
|
static somfy_rx_t somfy_rx;
|
||||||
static somfy_rx_queue_t rx_queue;
|
static somfy_rx_queue_t rx_queue;
|
||||||
|
|
||||||
|
bool somfy_tx_queue_t::pop(somfy_tx_t *tx) {
|
||||||
|
// Read the oldest index.
|
||||||
|
for(uint8_t i = MAX_TX_BUFFER - 1; i >= 0; i--) {
|
||||||
|
if(this->index[i] < MAX_TX_BUFFER) {
|
||||||
|
uint8_t ndx = this->index[i];
|
||||||
|
memcpy(tx, &this->items[ndx], sizeof(somfy_tx_t));
|
||||||
|
memset(&this->items[ndx], 0x00, sizeof(somfy_tx_t));
|
||||||
|
this->length--;
|
||||||
|
this->index[i] = 255;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool somfy_tx_queue_t::push(uint32_t await, somfy_commands cmd, uint8_t repeats) {
|
||||||
|
if(this->length >= MAX_TX_BUFFER) {
|
||||||
|
uint8_t ndx = this->index[MAX_TX_BUFFER - 1];
|
||||||
|
this->index[MAX_TX_BUFFER - 1] = 255;
|
||||||
|
this->length = MAX_TX_BUFFER - 1;
|
||||||
|
if(ndx < MAX_TX_BUFFER) memset(&this->items[ndx], 0x00, sizeof(somfy_tx_t));
|
||||||
|
}
|
||||||
|
// Place the command in the first empty slot. Empty slots are those
|
||||||
|
// with a millis of 0. We will shift the indexes right so that this
|
||||||
|
// is indexed int slot 0.
|
||||||
|
for(uint8_t i = 0; i < MAX_TX_BUFFER; i++) {
|
||||||
|
if(this->items[i].await == 0) {
|
||||||
|
this->items[i].await = await;
|
||||||
|
this->items[i].cmd = cmd;
|
||||||
|
this->items[i].repeats = repeats;
|
||||||
|
// Move the index so that it is the at position 0. The oldest item will fall off.
|
||||||
|
for(uint8_t j = MAX_TX_BUFFER - 1; j > 0; j--) {
|
||||||
|
this->index[j] = this->index[j - 1];
|
||||||
|
}
|
||||||
|
this->length++;
|
||||||
|
this->index[0] = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void somfy_rx_queue_t::init() {
|
void somfy_rx_queue_t::init() {
|
||||||
Serial.println("Initializing RX Queue");
|
Serial.println("Initializing RX Queue");
|
||||||
memset(&this->items[0], 0x00, sizeof(somfy_rx_t) * MAX_RX_BUFFER);
|
memset(&this->items[0], 0x00, sizeof(somfy_rx_t) * MAX_RX_BUFFER);
|
||||||
memset(&this->index[0], 0xFF, MAX_RX_BUFFER);
|
memset(&this->index[0], 0xFF, MAX_RX_BUFFER);
|
||||||
this->length = 0;
|
this->length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool somfy_rx_queue_t::pop(somfy_rx_t *rx) {
|
bool somfy_rx_queue_t::pop(somfy_rx_t *rx) {
|
||||||
// Read off the data from the oldest index.
|
// Read off the data from the oldest index.
|
||||||
//Serial.println("Popping RX Queue");
|
//Serial.println("Popping RX Queue");
|
||||||
|
|
|
||||||
17
Somfy.h
17
Somfy.h
|
|
@ -46,12 +46,14 @@ somfy_commands translateSomfyCommand(const String& string);
|
||||||
|
|
||||||
#define MAX_TIMINGS 300
|
#define MAX_TIMINGS 300
|
||||||
#define MAX_RX_BUFFER 3
|
#define MAX_RX_BUFFER 3
|
||||||
|
#define MAX_TX_BUFFER 3
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
waiting_synchro = 0,
|
waiting_synchro = 0,
|
||||||
receiving_data = 1,
|
receiving_data = 1,
|
||||||
complete = 2
|
complete = 2
|
||||||
} t_status;
|
} t_status;
|
||||||
|
|
||||||
typedef struct somfy_rx_t {
|
typedef struct somfy_rx_t {
|
||||||
t_status status;
|
t_status status;
|
||||||
uint8_t bit_length = 56;
|
uint8_t bit_length = 56;
|
||||||
|
|
@ -74,6 +76,20 @@ typedef struct somfy_rx_queue_t {
|
||||||
//void push(somfy_rx_t *rx);
|
//void push(somfy_rx_t *rx);
|
||||||
bool pop(somfy_rx_t *rx);
|
bool pop(somfy_rx_t *rx);
|
||||||
};
|
};
|
||||||
|
typedef struct somfy_tx_t {
|
||||||
|
uint32_t await = 0;
|
||||||
|
somfy_commands cmd;
|
||||||
|
uint8_t repeats;
|
||||||
|
};
|
||||||
|
typedef struct somfy_tx_queue_t {
|
||||||
|
somfy_tx_queue_t() { memset(this->index, 255, MAX_TX_BUFFER); memset(&this->items[0], 0x00, sizeof(somfy_tx_queue_t) * MAX_TX_BUFFER); }
|
||||||
|
void clear() { memset(&this->index[0], 255, MAX_TX_BUFFER); memset(&this->items[0], 0x00, sizeof(somfy_tx_queue_t) * MAX_TX_BUFFER); }
|
||||||
|
uint8_t length = 0;
|
||||||
|
uint8_t index[MAX_TX_BUFFER];
|
||||||
|
somfy_tx_t items[MAX_TX_BUFFER];
|
||||||
|
bool pop(somfy_tx_t *tx);
|
||||||
|
bool push(uint32_t await, somfy_commands cmd, uint8_t repeats);
|
||||||
|
};
|
||||||
typedef struct somfy_frame_t {
|
typedef struct somfy_frame_t {
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
|
|
@ -134,6 +150,7 @@ class SomfyShade : public SomfyRemote {
|
||||||
shade_types shadeType = shade_types::roller;
|
shade_types shadeType = shade_types::roller;
|
||||||
tilt_types tiltType = tilt_types::none;
|
tilt_types tiltType = tilt_types::none;
|
||||||
void load();
|
void load();
|
||||||
|
somfy_tx_queue_t txQueue;
|
||||||
somfy_frame_t lastFrame;
|
somfy_frame_t lastFrame;
|
||||||
float currentPos = 0.0f;
|
float currentPos = 0.0f;
|
||||||
float currentTiltPos = 0.0f;
|
float currentTiltPos = 0.0f;
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
1
Web.cpp
1
Web.cpp
|
|
@ -810,6 +810,7 @@ void Web::begin() {
|
||||||
if (shade) {
|
if (shade) {
|
||||||
// Send the command to the shade.
|
// Send the command to the shade.
|
||||||
if(tilt < 0) tilt = shade->myPos;
|
if(tilt < 0) tilt = shade->myPos;
|
||||||
|
if(shade->tiltType == tilt_types::none) tilt = -1;
|
||||||
if(pos >= 0 && pos <= 100)
|
if(pos >= 0 && pos <= 100)
|
||||||
shade->setMyPosition(pos, tilt);
|
shade->setMyPosition(pos, tilt);
|
||||||
DynamicJsonDocument sdoc(512);
|
DynamicJsonDocument sdoc(512);
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
1.5.2
|
1.5.4
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="main.css?v=1.5.3" type="text/css" />
|
<link rel="stylesheet" href="main.css?v=1.5.4" type="text/css" />
|
||||||
<link rel="stylesheet" href="icons.css?v=1.5.3" type="text/css" />
|
<link rel="stylesheet" href="icons.css?v=1.5.4" type="text/css" />
|
||||||
<link rel="icon" type="image/png" href="favicon.png" />
|
<link rel="icon" type="image/png" href="favicon.png" />
|
||||||
<script type="text/javascript" src="index.js?v=1.5.3"></script>
|
<script type="text/javascript" src="index.js?v=1.5.4"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="divContainer" class="container" style="user-select:none;position:relative;border-radius:27px;">
|
<div id="divContainer" class="container" style="user-select:none;position:relative;border-radius:27px;">
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ async function reopenSocket() {
|
||||||
await initSockets();
|
await initSockets();
|
||||||
}
|
}
|
||||||
class General {
|
class General {
|
||||||
appVersion = 'v1.5.3';
|
appVersion = 'v1.5.4';
|
||||||
reloadApp = false;
|
reloadApp = false;
|
||||||
async init() {
|
async init() {
|
||||||
this.setAppVersion();
|
this.setAppVersion();
|
||||||
|
|
@ -1182,10 +1182,10 @@ class Somfy {
|
||||||
if (myTiltPos >= 0 && tiltType > 0)
|
if (myTiltPos >= 0 && tiltType > 0)
|
||||||
html += `<div onclick="document.getElementById('slidShadeTiltTarget').value = ${myTiltPos}; document.getElementById('slidShadeTarget').dispatchEvent(new Event('change'));"><span style="display:inline-block;width:47px;">Tilt:</span><span>${myTiltPos}</span><span>%</span></div>`;
|
html += `<div onclick="document.getElementById('slidShadeTiltTarget').value = ${myTiltPos}; document.getElementById('slidShadeTarget').dispatchEvent(new Event('change'));"><span style="display:inline-block;width:47px;">Tilt:</span><span>${myTiltPos}</span><span>%</span></div>`;
|
||||||
html += `</div></div >`;
|
html += `</div></div >`;
|
||||||
html += `<input id="slidShadeTarget" name="shadeTarget" type="range" min="0" max="100" step="1" value="${currPos}" oninput="document.getElementById('spanShadeTarget').innerHTML = this.value;" />`;
|
html += `<input id="slidShadeTarget" name="shadeTarget" type="range" min="0" max="100" step="1" oninput="document.getElementById('spanShadeTarget').innerHTML = this.value;" />`;
|
||||||
html += `<label for="slidShadeTarget"><span>Target Position </span><span><span id="spanShadeTarget" class="shade-target">${currPos}</span><span>%</span></span></label>`;
|
html += `<label for="slidShadeTarget"><span>Target Position </span><span><span id="spanShadeTarget" class="shade-target">${currPos}</span><span>%</span></span></label>`;
|
||||||
html += '<div id="divTiltTarget" style="display:none;">';
|
html += '<div id="divTiltTarget" style="display:none;">';
|
||||||
html += `<input id="slidShadeTiltTarget" name="shadeTiltTarget" type="range" min="0" max="100" step="1" value="${currTiltPos}" oninput="document.getElementById('spanShadeTiltTarget').innerHTML = this.value;" />`;
|
html += `<input id="slidShadeTiltTarget" name="shadeTiltTarget" type="range" min="0" max="100" step="1" oninput="document.getElementById('spanShadeTiltTarget').innerHTML = this.value;" />`;
|
||||||
html += `<label for="slidShadeTiltTarget"><span>Target Tilt </span><span><span id="spanShadeTiltTarget" class="shade-target">${currTiltPos}</span><span>%</span></span></label>`;
|
html += `<label for="slidShadeTiltTarget"><span>Target Tilt </span><span><span id="spanShadeTiltTarget" class="shade-target">${currTiltPos}</span><span>%</span></span></label>`;
|
||||||
html += '</div>'
|
html += '</div>'
|
||||||
html += `<hr></hr>`;
|
html += `<hr></hr>`;
|
||||||
|
|
@ -1201,12 +1201,14 @@ class Somfy {
|
||||||
shade.appendChild(div);
|
shade.appendChild(div);
|
||||||
let elTarget = div.querySelector('input#slidShadeTarget');
|
let elTarget = div.querySelector('input#slidShadeTarget');
|
||||||
let elTiltTarget = div.querySelector('input#slidShadeTiltTarget');
|
let elTiltTarget = div.querySelector('input#slidShadeTiltTarget');
|
||||||
|
elTarget.value = currPos;
|
||||||
|
elTiltTarget.value = currTiltPos;
|
||||||
let elBtn = div.querySelector('button#btnSetMyPosition');
|
let elBtn = div.querySelector('button#btnSetMyPosition');
|
||||||
if (tiltType > 0) div.querySelector('div#divTiltTarget').style.display = '';
|
if (tiltType > 0) div.querySelector('div#divTiltTarget').style.display = '';
|
||||||
let fnProcessChange = () => {
|
let fnProcessChange = () => {
|
||||||
let pos = parseInt(elTarget.value, 10);
|
let pos = parseInt(elTarget.value, 10);
|
||||||
let tilt = parseInt(elTiltTarget.value, 10);
|
let tilt = parseInt(elTiltTarget.value, 10);
|
||||||
if (pos === myPos && tilt === myTiltPos) {
|
if (pos === myPos && (tiltType === 0 || tilt === myTiltPos)) {
|
||||||
elBtn.innerHTML = 'Clear My Position';
|
elBtn.innerHTML = 'Clear My Position';
|
||||||
elBtn.style.background = 'orangered';
|
elBtn.style.background = 'orangered';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue