Merge pull request #7493 from to-scho/feature/shutterlock

New command ShutterLock
This commit is contained in:
Theo Arends 2020-01-12 15:02:05 +01:00 committed by GitHub
commit 8ffae03ff7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 115 additions and 92 deletions

View File

@ -516,6 +516,7 @@
#define D_CMND_SHUTTER_MOTORDELAY "MotorDelay" #define D_CMND_SHUTTER_MOTORDELAY "MotorDelay"
#define D_CMND_SHUTTER_FREQUENCY "Frequency" #define D_CMND_SHUTTER_FREQUENCY "Frequency"
#define D_CMND_SHUTTER_BUTTON "Button" #define D_CMND_SHUTTER_BUTTON "Button"
#define D_CMND_SHUTTER_LOCK "Lock"
// Commands xdrv_32_hotplug.ino // Commands xdrv_32_hotplug.ino
#define D_CMND_HOTPLUG "HotPlug" #define D_CMND_HOTPLUG "HotPlug"

View File

@ -432,7 +432,7 @@ struct SYSCFG {
uint16_t shutter_opentime[MAX_SHUTTERS]; // E40 uint16_t shutter_opentime[MAX_SHUTTERS]; // E40
uint16_t shutter_closetime[MAX_SHUTTERS]; // E48 uint16_t shutter_closetime[MAX_SHUTTERS]; // E48
int16_t shuttercoeff[5][MAX_SHUTTERS]; // E50 int16_t shuttercoeff[5][MAX_SHUTTERS]; // E50
uint8_t shutter_invert[MAX_SHUTTERS]; // E78 uint8_t shutter_options[MAX_SHUTTERS]; // E78
uint8_t shutter_set50percent[MAX_SHUTTERS]; // E7C uint8_t shutter_set50percent[MAX_SHUTTERS]; // E7C
uint8_t shutter_position[MAX_SHUTTERS]; // E80 uint8_t shutter_position[MAX_SHUTTERS]; // E80
uint8_t shutter_startrelay[MAX_SHUTTERS]; // E84 uint8_t shutter_startrelay[MAX_SHUTTERS]; // E84

View File

@ -1212,7 +1212,6 @@ bool HandleRootStatusRefresh(void)
int32_t ShutterWebButton; int32_t ShutterWebButton;
if (ShutterWebButton = IsShutterWebButton(device)) { if (ShutterWebButton = IsShutterWebButton(device)) {
snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), abs(ShutterWebButton), (ShutterWebButton>0) ? PSTR(D_CMND_SHUTTER_TOGGLEUP) : PSTR(D_CMND_SHUTTER_TOGGLEDOWN)); snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), abs(ShutterWebButton), (ShutterWebButton>0) ? PSTR(D_CMND_SHUTTER_TOGGLEUP) : PSTR(D_CMND_SHUTTER_TOGGLEDOWN));
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: WebButton %d, %s"), ShutterWebButton, svalue);
ExecuteWebCommand(svalue, SRC_WEBGUI); ExecuteWebCommand(svalue, SRC_WEBGUI);
} else { } else {
#endif // USE_SHUTTER #endif // USE_SHUTTER

View File

@ -279,7 +279,7 @@ void HueLightStatus1(uint8_t device, String *response)
#ifdef USE_SHUTTER #ifdef USE_SHUTTER
if (ShutterState(device)) { if (ShutterState(device)) {
bri = (float)(Settings.shutter_invert[device-1] ? 100 - Settings.shutter_position[device-1] : Settings.shutter_position[device-1]) / 100; bri = (float)((Settings.shutter_options[device-1] & 1) ? 100 - Settings.shutter_position[device-1] : Settings.shutter_position[device-1]) / 100;
} }
#endif #endif
@ -681,7 +681,7 @@ void HueLights(String *path)
if (change) { if (change) {
#ifdef USE_SHUTTER #ifdef USE_SHUTTER
if (ShutterState(device)) { if (ShutterState(device)) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Settings.shutter_invert: %d"), Settings.shutter_invert[device-1]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Settings.shutter_invert: %d"), Settings.shutter_options[device-1] & 1);
ShutterSetPosition(device, bri * 100.0f ); ShutterSetPosition(device, bri * 100.0f );
} else } else
#endif #endif

View File

@ -40,13 +40,13 @@ const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|"
D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|" D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|"
D_CMND_SHUTTER_OPENTIME "|" D_CMND_SHUTTER_CLOSETIME "|" D_CMND_SHUTTER_RELAY "|" D_CMND_SHUTTER_OPENTIME "|" D_CMND_SHUTTER_CLOSETIME "|" D_CMND_SHUTTER_RELAY "|"
D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|"
D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON; D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK;
void (* const ShutterCommand[])(void) PROGMEM = { void (* const ShutterCommand[])(void) PROGMEM = {
&CmndShutterOpen, &CmndShutterClose, &CmndShutterStop, &CmndShutterPosition, &CmndShutterOpen, &CmndShutterClose, &CmndShutterStop, &CmndShutterPosition,
&CmndShutterOpenTime, &CmndShutterCloseTime, &CmndShutterRelay, &CmndShutterOpenTime, &CmndShutterCloseTime, &CmndShutterRelay,
&CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay,
&CmndShutterFrequency, &CmndShutterButton}; &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock};
const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d}"; const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d}";
@ -233,10 +233,10 @@ void ShutterInit(void)
dtostrfd((float)Shutter.open_time[i] / 10 , 1, shutter_open_chr); dtostrfd((float)Shutter.open_time[i] / 10 , 1, shutter_open_chr);
char shutter_close_chr[10]; char shutter_close_chr[10];
dtostrfd((float)Shutter.close_time[i] / 10, 1, shutter_close_chr); dtostrfd((float)Shutter.close_time[i] / 10, 1, shutter_close_chr);
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100 Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, shuttermode %d,motordelay %d"), AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100, Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, is locked %d, shuttermode %d, motordelay %d"),
i+1, Settings.shutter_startrelay[i], Shutter.real_position[i], Settings.shutter_position[i], Shutter.close_velocity[i], Shutter.open_max[i], shutter_open_chr, shutter_close_chr, i+1, Settings.shutter_startrelay[i], Shutter.real_position[i], Settings.shutter_position[i], Shutter.close_velocity[i], Shutter.open_max[i], shutter_open_chr, shutter_close_chr,
Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i], Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i],
Shutter.mask, Settings.shutter_invert[i], Shutter.mode, Shutter.motordelay[i]); Shutter.mask, (Settings.shutter_options[i]&1) ? 1 : 0, (Settings.shutter_options[i]&2) ? 1 : 0, Shutter.mode, Shutter.motordelay[i]);
} else { } else {
// terminate loop at first INVALID shutter. // terminate loop at first INVALID shutter.
@ -259,7 +259,7 @@ void ShutterReportPosition(bool always)
ShutterLogPos(i); ShutterLogPos(i);
} }
if (i) { ResponseAppend_P(PSTR(",")); } if (i) { ResponseAppend_P(PSTR(",")); }
ResponseAppend_P(JSON_SHUTTER_POS, i+1, Settings.shutter_invert[i] ? 100-position : position, Shutter.direction[i]); ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings.shutter_options[i] & 1) ? 100-position : position, Shutter.direction[i]);
} }
ResponseJsonEnd(); ResponseJsonEnd();
if (always || (1 == shutter_moving)) { if (always || (1 == shutter_moving)) {
@ -371,7 +371,7 @@ void ShutterUpdatePosition(void)
// sending MQTT result to broker // sending MQTT result to broker
snprintf_P(scommand, sizeof(scommand),PSTR(D_SHUTTER "%d"), i+1); snprintf_P(scommand, sizeof(scommand),PSTR(D_SHUTTER "%d"), i+1);
GetTopic_P(stopic, STAT, mqtt_topic, scommand); GetTopic_P(stopic, STAT, mqtt_topic, scommand);
Response_P("%d", Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]); Response_P("%d", (Settings.shutter_options[i] & 1) ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]);
MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
Shutter.direction[i] = 0; Shutter.direction[i] = 0;
@ -690,22 +690,27 @@ void CmndShutterClose(void)
void CmndShutterStop(void) void CmndShutterStop(void)
{ {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { if (!(Settings.shutter_options[XdrvMailbox.index-1] & 2)) {
XdrvMailbox.index = XdrvMailbox.payload; if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) {
} XdrvMailbox.index = XdrvMailbox.payload;
uint32_t i = XdrvMailbox.index -1; }
if (Shutter.direction[i] != 0) { uint32_t i = XdrvMailbox.index -1;
if (Shutter.direction[i] != 0) {
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]); AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]);
// set stop position 10 steps ahead (0.5sec to allow normal stop) // set stop position 10 steps ahead (0.5sec to allow normal stop)
int32_t temp_realpos = Shutter.start_position[i] + ( (Shutter.time[i]+10) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i])); int32_t temp_realpos = Shutter.start_position[i] + ( (Shutter.time[i]+10) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i]));
XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, i); XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, i);
//XdrvMailbox.payload = Settings.shuttercoeff[2][i] * 5 > temp_realpos ? temp_realpos / Settings.shuttercoeff[2][i] : (temp_realpos-Settings.shuttercoeff[0,i]) / Settings.shuttercoeff[1][i]; //XdrvMailbox.payload = Settings.shuttercoeff[2][i] * 5 > temp_realpos ? temp_realpos / Settings.shuttercoeff[2][i] : (temp_realpos-Settings.shuttercoeff[0,i]) / Settings.shuttercoeff[1][i];
last_source = SRC_WEBGUI; last_source = SRC_WEBGUI;
CmndShutterPosition(); CmndShutterPosition();
} else {
if (XdrvMailbox.command)
ResponseCmndDone();
}
} else { } else {
if (XdrvMailbox.command) if (XdrvMailbox.command)
ResponseCmndDone(); ResponseCmndIdxChar("Locked");
} }
} }
} }
@ -713,78 +718,83 @@ void CmndShutterStop(void)
void CmndShutterPosition(void) void CmndShutterPosition(void)
{ {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
uint32_t index = XdrvMailbox.index-1; if (!(Settings.shutter_options[XdrvMailbox.index-1] & 2)) {
//limit the payload uint32_t index = XdrvMailbox.index-1;
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source ); //limit the payload
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source );
// value 0 with data_len > 0 can mean Open // value 0 with data_len > 0 can mean Open
if ((XdrvMailbox.data_len > 1) && (XdrvMailbox.payload <= 0)) { if ((XdrvMailbox.data_len > 1) && (XdrvMailbox.payload <= 0)) {
//UpperCase(XdrvMailbox.data, XdrvMailbox.data); //UpperCase(XdrvMailbox.data, XdrvMailbox.data);
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_UP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP))) { if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_UP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP))) {
CmndShutterOpen(); CmndShutterOpen();
return; return;
}
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_DOWN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN))) {
CmndShutterClose();
return;
}
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN)))) {
XdrvMailbox.payload = -99;
CmndShutterStop();
return;
}
} }
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_DOWN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN))) {
CmndShutterClose();
return;
}
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN)))) {
XdrvMailbox.payload = -99;
CmndShutterStop();
return;
}
}
int8_t target_pos_percent = (XdrvMailbox.payload < 0) ? 0 : ((XdrvMailbox.payload > 100) ? 100 : XdrvMailbox.payload); int8_t target_pos_percent = (XdrvMailbox.payload < 0) ? 0 : ((XdrvMailbox.payload > 100) ? 100 : XdrvMailbox.payload);
// webgui still send also on inverted shutter the native position. // webgui still send also on inverted shutter the native position.
target_pos_percent = (Settings.shutter_invert[index] && (SRC_WEBGUI != last_source)) ? 100 - target_pos_percent : target_pos_percent; target_pos_percent = ((Settings.shutter_options[index] & 1) && (SRC_WEBGUI != last_source)) ? 100 - target_pos_percent : target_pos_percent;
if (XdrvMailbox.payload != -99) { if (XdrvMailbox.payload != -99) {
//target_pos_percent = Settings.shutter_invert[index] ? 100 - target_pos_percent : target_pos_percent; //target_pos_percent = (Settings.shutter_options[index] & 1) ? 100 - target_pos_percent : target_pos_percent;
Shutter.target_position[index] = ShutterPercentToRealPosition(target_pos_percent, index); Shutter.target_position[index] = ShutterPercentToRealPosition(target_pos_percent, index);
Shutter.accelerator[index] = Shutter.max_pwm_frequency / ((Shutter.motordelay[index] > 0) ? Shutter.motordelay[index] : 1); Shutter.accelerator[index] = Shutter.max_pwm_frequency / ((Shutter.motordelay[index] > 0) ? Shutter.motordelay[index] : 1);
//Shutter.target_position[index] = XdrvMailbox.payload < 5 ? Settings.shuttercoeff[2][index] * XdrvMailbox.payload : Settings.shuttercoeff[1][index] * XdrvMailbox.payload + Settings.shuttercoeff[0,index]; //Shutter.target_position[index] = XdrvMailbox.payload < 5 ? Settings.shuttercoeff[2][index] * XdrvMailbox.payload : Settings.shuttercoeff[1][index] * XdrvMailbox.payload + Settings.shuttercoeff[0,index];
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent);
} }
if ( (target_pos_percent >= 0) && (target_pos_percent <= 100) && abs(Shutter.target_position[index] - Shutter.real_position[index] ) / Shutter.close_velocity[index] > 2) { if ( (target_pos_percent >= 0) && (target_pos_percent <= 100) && abs(Shutter.target_position[index] - Shutter.real_position[index] ) / Shutter.close_velocity[index] > 2) {
int8_t new_shutterdirection = Shutter.real_position[index] < Shutter.target_position[index] ? 1 : -1; int8_t new_shutterdirection = Shutter.real_position[index] < Shutter.target_position[index] ? 1 : -1;
if (Shutter.direction[index] == -new_shutterdirection) { if (Shutter.direction[index] == -new_shutterdirection) {
// direction need to be changed. on momentary switches first stop the Shutter // direction need to be changed. on momentary switches first stop the Shutter
if (SHT_PULSE_OPEN__PULSE_CLOSE == Shutter.mode) { if (SHT_PULSE_OPEN__PULSE_CLOSE == Shutter.mode) {
// code for momentary shutters only small switch on to stop Shutter // code for momentary shutters only small switch on to stop Shutter
ExecuteCommandPower(Settings.shutter_startrelay[index] + ((new_shutterdirection == 1) ? 0 : 1), 1, SRC_SHUTTER); ExecuteCommandPower(Settings.shutter_startrelay[index] + ((new_shutterdirection == 1) ? 0 : 1), 1, SRC_SHUTTER);
delay(100); delay(100);
} else { } else {
if (SHT_OFF_OPEN__OFF_CLOSE == Shutter.mode) { if (SHT_OFF_OPEN__OFF_CLOSE == Shutter.mode) {
ExecuteCommandPower(Settings.shutter_startrelay[index] + ((new_shutterdirection == 1) ? 1 : 0), 0, SRC_SHUTTER); ExecuteCommandPower(Settings.shutter_startrelay[index] + ((new_shutterdirection == 1) ? 1 : 0), 0, SRC_SHUTTER);
ShutterWaitForMotorStop(index); ShutterWaitForMotorStop(index);
}
} }
} }
} if (Shutter.direction[index] != new_shutterdirection) {
if (Shutter.direction[index] != new_shutterdirection) { if ((SHT_OFF_ON__OPEN_CLOSE == Shutter.mode) || (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode)) {
if ((SHT_OFF_ON__OPEN_CLOSE == Shutter.mode) || (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode)) { //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload);
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload); ShutterWaitForMotorStop(index);
ShutterWaitForMotorStop(index); ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER);
ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER); ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]);
ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]); // Code for shutters with circuit safe configuration, switch the direction Relay
// Code for shutters with circuit safe configuration, switch the direction Relay ExecuteCommandPower(Settings.shutter_startrelay[index] +1, new_shutterdirection == 1 ? 0 : 1, SRC_SHUTTER);
ExecuteCommandPower(Settings.shutter_startrelay[index] +1, new_shutterdirection == 1 ? 0 : 1, SRC_SHUTTER); // power on
// power on ExecuteCommandPower(Settings.shutter_startrelay[index], 1, SRC_SHUTTER);
ExecuteCommandPower(Settings.shutter_startrelay[index], 1, SRC_SHUTTER); } else {
} else { // now start the motor for the right direction, work for momentary and normal shutters.
// now start the motor for the right direction, work for momentary and normal shutters. AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start in dir %d"), Shutter.direction[index]);
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start in dir %d"), Shutter.direction[index]); ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]);
ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]); ExecuteCommandPower(Settings.shutter_startrelay[index] + (new_shutterdirection == 1 ? 0 : 1), 1, SRC_SHUTTER);
ExecuteCommandPower(Settings.shutter_startrelay[index] + (new_shutterdirection == 1 ? 0 : 1), 1, SRC_SHUTTER); //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay6 5s, xdrv %d"), XdrvMailbox.payload);
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay6 5s, xdrv %d"), XdrvMailbox.payload); }
Shutter.switched_relay = 0;
} }
Shutter.switched_relay = 0; } else {
target_pos_percent = ShutterRealToPercentPosition(Shutter.real_position[index], index);
} }
XdrvMailbox.index = index +1; // Fix random index for ShutterClose
if (XdrvMailbox.command)
ResponseCmndIdxNumber((Settings.shutter_options[index] & 1) ? 100 - target_pos_percent : target_pos_percent);
} else { } else {
target_pos_percent = ShutterRealToPercentPosition(Shutter.real_position[index], index); if (XdrvMailbox.command)
ResponseCmndIdxChar("Locked");
} }
XdrvMailbox.index = index +1; // Fix random index for ShutterClose
if (XdrvMailbox.command)
ResponseCmndIdxNumber(Settings.shutter_invert[index] ? 100 - target_pos_percent : target_pos_percent);
} }
} }
@ -972,10 +982,10 @@ void CmndShutterSetHalfway(void)
{ {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
Settings.shutter_set50percent[XdrvMailbox.index -1] = Settings.shutter_invert[XdrvMailbox.index -1] ? 100 - XdrvMailbox.payload : XdrvMailbox.payload; Settings.shutter_set50percent[XdrvMailbox.index -1] = (Settings.shutter_options[XdrvMailbox.index -1] & 1) ? 100 - XdrvMailbox.payload : XdrvMailbox.payload;
ShutterInit(); ShutterInit();
} }
ResponseCmndIdxNumber(Settings.shutter_invert[XdrvMailbox.index -1] ? 100 - Settings.shutter_set50percent[XdrvMailbox.index -1] : Settings.shutter_set50percent[XdrvMailbox.index -1]); ResponseCmndIdxNumber((Settings.shutter_options[XdrvMailbox.index -1] & 1) ? 100 - Settings.shutter_set50percent[XdrvMailbox.index -1] : Settings.shutter_set50percent[XdrvMailbox.index -1]);
} }
} }
@ -1006,10 +1016,12 @@ void CmndShutterSetClose(void)
void CmndShutterInvert(void) void CmndShutterInvert(void)
{ {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { if (XdrvMailbox.payload == 0) {
Settings.shutter_invert[XdrvMailbox.index -1] = XdrvMailbox.payload; Settings.shutter_options[XdrvMailbox.index -1] &= ~(1);
} else if (XdrvMailbox.payload == 1) {
Settings.shutter_options[XdrvMailbox.index -1] |= (1);
} }
ResponseCmndIdxNumber(Settings.shutter_invert[XdrvMailbox.index -1]); ResponseCmndIdxNumber((Settings.shutter_options[XdrvMailbox.index -1] & 1) ? 1 : 0);
} }
} }
@ -1046,6 +1058,17 @@ void CmndShutterCalibration(void)
} }
} }
void CmndShutterLock(void) {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
if (XdrvMailbox.payload == 0) {
Settings.shutter_options[XdrvMailbox.index -1] &= ~(2);
} else if (XdrvMailbox.payload == 1) {
Settings.shutter_options[XdrvMailbox.index -1] |= (2);
}
ResponseCmndIdxNumber((Settings.shutter_options[XdrvMailbox.index -1] & 2) ? 1 : 0);
}
}
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
@ -1072,7 +1095,7 @@ bool Xdrv27(uint8_t function)
break; break;
case FUNC_JSON_APPEND: case FUNC_JSON_APPEND:
for (uint8_t i = 0; i < shutters_present; i++) { for (uint8_t i = 0; i < shutters_present; i++) {
uint8_t position = Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]; uint8_t position = (Settings.shutter_options[i] & 1) ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i];
ResponseAppend_P(","); ResponseAppend_P(",");
ResponseAppend_P(JSON_SHUTTER_POS, i+1, position, Shutter.direction[i]); ResponseAppend_P(JSON_SHUTTER_POS, i+1, position, Shutter.direction[i]);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ