mirror of
https://github.com/HASwitchPlate/HASPone.git
synced 2025-07-25 12:16:41 +00:00
commit
08130252d2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
3D_Printable_Models/HASwitchPlate_front_4in_box.stl
Normal file
BIN
3D_Printable_Models/HASwitchPlate_front_4in_box.stl
Normal file
Binary file not shown.
Binary file not shown.
5
Arduino_Sketch/.gitignore
vendored
Normal file
5
Arduino_Sketch/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
Binary file not shown.
@ -6,7 +6,7 @@
|
|||||||
// Home Automation Switch Plate
|
// Home Automation Switch Plate
|
||||||
// https://github.com/aderusha/HASwitchPlate
|
// https://github.com/aderusha/HASwitchPlate
|
||||||
//
|
//
|
||||||
// Copyright (c) 2021 Allen Derusha allen@derusha.org
|
// Copyright (c) 2024 Allen Derusha allen@derusha.org
|
||||||
//
|
//
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
@ -26,6 +26,7 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE PRODUCT OR THE USE OR OTHER DEALINGS IN THE PRODUCT.
|
// OUT OF OR IN CONNECTION WITH THE PRODUCT OR THE USE OR OTHER DEALINGS IN THE PRODUCT.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
#include <EspSaveCrash.h>
|
#include <EspSaveCrash.h>
|
||||||
@ -43,6 +44,7 @@
|
|||||||
#include <MQTT.h>
|
#include <MQTT.h>
|
||||||
#include <SoftwareSerial.h>
|
#include <SoftwareSerial.h>
|
||||||
#include <ESP8266Ping.h>
|
#include <ESP8266Ping.h>
|
||||||
|
#include <LittleFS.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// These defaults may be overwritten with values saved by the web interface
|
// These defaults may be overwritten with values saved by the web interface
|
||||||
@ -62,8 +64,7 @@ char motionPinConfig[3] = "0";
|
|||||||
char nextionBaud[7] = "115200";
|
char nextionBaud[7] = "115200";
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const float haspVersion = 1.06; // Current HASPone software release version
|
||||||
const float haspVersion = 1.05; // Current HASPone software release version
|
|
||||||
const uint16_t mqttMaxPacketSize = 2048; // Size of buffer for incoming MQTT message
|
const uint16_t mqttMaxPacketSize = 2048; // Size of buffer for incoming MQTT message
|
||||||
byte nextionReturnBuffer[128]; // Byte array to pass around data coming from the panel
|
byte nextionReturnBuffer[128]; // Byte array to pass around data coming from the panel
|
||||||
uint8_t nextionReturnIndex = 0; // Index for nextionReturnBuffer
|
uint8_t nextionReturnIndex = 0; // Index for nextionReturnBuffer
|
||||||
@ -75,7 +76,7 @@ bool shouldSaveConfig = false; // Flag to save json confi
|
|||||||
bool nextionReportPage0 = false; // If false, don't report page 0 sendme
|
bool nextionReportPage0 = false; // If false, don't report page 0 sendme
|
||||||
const unsigned long updateCheckInterval = 43200000; // Time in msec between update checks (12 hours)
|
const unsigned long updateCheckInterval = 43200000; // Time in msec between update checks (12 hours)
|
||||||
unsigned long updateCheckTimer = updateCheckInterval; // Timer for update check
|
unsigned long updateCheckTimer = updateCheckInterval; // Timer for update check
|
||||||
unsigned long updateCheckFirstRun = 60000; // First-run check offset
|
unsigned long updateCheckFirstRun = 30000; // First-run check offset
|
||||||
bool updateEspAvailable = false; // Flag for update check to report new ESP FW version
|
bool updateEspAvailable = false; // Flag for update check to report new ESP FW version
|
||||||
float updateEspAvailableVersion; // Float to hold the new ESP FW version number
|
float updateEspAvailableVersion; // Float to hold the new ESP FW version number
|
||||||
bool updateLcdAvailable = false; // Flag for update check to report new LCD FW version
|
bool updateLcdAvailable = false; // Flag for update check to report new LCD FW version
|
||||||
@ -87,6 +88,9 @@ bool nextionBufferOverrun = false; // Set to true if an overr
|
|||||||
bool nextionAckEnable = false; // Wait for each Nextion command to be acked before continuing
|
bool nextionAckEnable = false; // Wait for each Nextion command to be acked before continuing
|
||||||
bool nextionAckReceived = false; // Ack was received
|
bool nextionAckReceived = false; // Ack was received
|
||||||
bool rebootOnp0b1 = false; // When true, reboot device on button press of p[0].b[1]
|
bool rebootOnp0b1 = false; // When true, reboot device on button press of p[0].b[1]
|
||||||
|
bool rebootOnLongPress = true; // When true, reboot device on long press of any button
|
||||||
|
unsigned long rebootOnLongPressTimer = 0; // Clock for long press reboot timer
|
||||||
|
unsigned long rebootOnLongPressTimeout = 10000; // Timeout value for long press reboot timer
|
||||||
const unsigned long nextionAckTimeout = 1000; // Timeout to wait for an ack before throwing error
|
const unsigned long nextionAckTimeout = 1000; // Timeout to wait for an ack before throwing error
|
||||||
unsigned long nextionAckTimer = 0; // Timer to track Nextion ack
|
unsigned long nextionAckTimer = 0; // Timer to track Nextion ack
|
||||||
const unsigned long telnetInputMax = 128; // Size of user input buffer for user telnet session
|
const unsigned long telnetInputMax = 128; // Size of user input buffer for user telnet session
|
||||||
@ -162,13 +166,67 @@ MDNSResponder::hMDNSService hMDNSService; // mDNS
|
|||||||
EspSaveCrash SaveCrash; // Save crash details to flash
|
EspSaveCrash SaveCrash; // Save crash details to flash
|
||||||
|
|
||||||
// URL for auto-update check of "version.json"
|
// URL for auto-update check of "version.json"
|
||||||
const char UPDATE_URL[] PROGMEM = "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/update/version.json";
|
const char UPDATE_URL[] PROGMEM = "https://haswitchplate.com/update/version.json";
|
||||||
// Additional CSS style to match Hass theme
|
// Additional CSS style to match Hass theme
|
||||||
const char HASP_STYLE[] PROGMEM = "<style>button{background-color:#03A9F4;}body{width:60%;margin:auto;}input:invalid{border:1px solid red;}input[type=checkbox]{width:20px;}.wrap{text-align:left;display:inline-block;min-width:260px;max-width:1000px}</style>";
|
const char HASP_STYLE[] PROGMEM = "<style>button{background-color:#03A9F4;}body{width:60%;margin:auto;}input:invalid{border:1px solid red;}input[type=checkbox]{width:20px;}.wrap{text-align:left;display:inline-block;min-width:260px;max-width:1000px}</style>";
|
||||||
// Default link to compiled Arduino firmware image
|
// Default link to compiled Arduino firmware image
|
||||||
String espFirmwareUrl = "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Arduino_Sketch/HASwitchPlate.ino.d1_mini.bin";
|
String espFirmwareUrl = "https://haswitchplate.com/update/HASwitchPlate.ino.d1_mini.bin";
|
||||||
// Default link to compiled Nextion firmware images
|
// Default link to compiled Nextion firmware images
|
||||||
String lcdFirmwareUrl = "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate.tft";
|
String lcdFirmwareUrl = "https://haswitchplate.com/update/HASwitchPlate.tft";
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
void loop();
|
||||||
|
void mqttConnect();
|
||||||
|
void mqttProcessInput(String &strTopic, String &strPayload);
|
||||||
|
void mqttStatusUpdate();
|
||||||
|
void mqttDiscovery();
|
||||||
|
void nextionHandleInput();
|
||||||
|
void nextionProcessInput();
|
||||||
|
void nextionSendCmd(const String &nextionCmd);
|
||||||
|
void nextionSetAttr(const String &hmiAttribute, const String &hmiValue);
|
||||||
|
void nextionGetAttr(const String &hmiAttribute);
|
||||||
|
void nextionParseJson(const String &strPayload);
|
||||||
|
void nextionOtaStartDownload(const String &lcdOtaUrl);
|
||||||
|
bool nextionOtaResponse();
|
||||||
|
bool nextionConnect();
|
||||||
|
void nextionSetSpeed();
|
||||||
|
void nextionReset();
|
||||||
|
void nextionUpdateProgress(const unsigned int &progress, const unsigned int &total);
|
||||||
|
void espWifiConnect();
|
||||||
|
void espWifiReconnect();
|
||||||
|
void espSetupOta();
|
||||||
|
void espStartOta(const String &espOtaUrl);
|
||||||
|
void espReset();
|
||||||
|
void configRead();
|
||||||
|
void configSaveCallback();
|
||||||
|
void configSave();
|
||||||
|
void configClearSaved();
|
||||||
|
void webHandleNotFound();
|
||||||
|
void webHandleRoot();
|
||||||
|
void webHandleSaveConfig();
|
||||||
|
void webHandleResetConfig();
|
||||||
|
void webHandleShowConfig();
|
||||||
|
void webHandleResetBacklight();
|
||||||
|
void webHandleFirmware();
|
||||||
|
void webHandleEspFirmware();
|
||||||
|
void webHandleLcdUpload();
|
||||||
|
void webHandleLcdUpdateSuccess();
|
||||||
|
void webHandleLcdUpdateFailure();
|
||||||
|
void webHandleLcdDownload();
|
||||||
|
void webHandleTftFileSize();
|
||||||
|
void webHandleReboot();
|
||||||
|
void espWifiConfigCallback(WiFiManager *myWiFiManager);
|
||||||
|
bool updateCheck();
|
||||||
|
void motionSetup();
|
||||||
|
void motionHandle();
|
||||||
|
void beepHandle();
|
||||||
|
void telnetHandleClient();
|
||||||
|
void debugPrintln(const String &debugText);
|
||||||
|
void debugPrint(const String &debugText);
|
||||||
|
void debugPrintCrash();
|
||||||
|
void debugPrintFile(const String &fileName);
|
||||||
|
String getSubtringField(String data, char separator, int index);
|
||||||
|
String printHex8(byte *data, uint8_t length);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void setup()
|
void setup()
|
||||||
@ -652,65 +710,65 @@ void mqttProcessInput(String &strTopic, String &strPayload)
|
|||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
else if (strTopic == (mqttCommandTopic + "/debugserialenabled") || strTopic == (mqttGroupCommandTopic + "/debugserialenabled"))
|
else if (strTopic == (mqttCommandTopic + "/debugserialenabled") || strTopic == (mqttGroupCommandTopic + "/debugserialenabled"))
|
||||||
{ // '[...]/device/command/debugserialenabled' -m 'true' == enable serial debug output
|
{ // '[...]/device/command/debugserialenabled' -m 'true' == enable serial debug output
|
||||||
if (strPayload.equalsIgnoreCase("true"))
|
if (strPayload.equalsIgnoreCase("true"))
|
||||||
{
|
{
|
||||||
debugSerialEnabled = true;
|
debugSerialEnabled = true;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
else if(strPayload.equalsIgnoreCase("false"))
|
else if (strPayload.equalsIgnoreCase("false"))
|
||||||
{
|
{
|
||||||
debugSerialEnabled = false;
|
debugSerialEnabled = false;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strTopic == (mqttCommandTopic + "/debugtelnetenabled") || strTopic == (mqttGroupCommandTopic + "/debugtelnetenabled"))
|
else if (strTopic == (mqttCommandTopic + "/debugtelnetenabled") || strTopic == (mqttGroupCommandTopic + "/debugtelnetenabled"))
|
||||||
{ // '[...]/device/command/debugtelnetenabled' -m 'true' == enable telnet debug output
|
{ // '[...]/device/command/debugtelnetenabled' -m 'true' == enable telnet debug output
|
||||||
if (strPayload.equalsIgnoreCase("true"))
|
if (strPayload.equalsIgnoreCase("true"))
|
||||||
{
|
{
|
||||||
debugTelnetEnabled = true;
|
debugTelnetEnabled = true;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
else if(strPayload.equalsIgnoreCase("false"))
|
else if (strPayload.equalsIgnoreCase("false"))
|
||||||
{
|
{
|
||||||
debugTelnetEnabled = false;
|
debugTelnetEnabled = false;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strTopic == (mqttCommandTopic + "/mdnsenabled") || strTopic == (mqttGroupCommandTopic + "/mdnsenabled"))
|
else if (strTopic == (mqttCommandTopic + "/mdnsenabled") || strTopic == (mqttGroupCommandTopic + "/mdnsenabled"))
|
||||||
{ // '[...]/device/command/mdnsenabled' -m 'true' == enable mDNS responder
|
{ // '[...]/device/command/mdnsenabled' -m 'true' == enable mDNS responder
|
||||||
if (strPayload.equalsIgnoreCase("true"))
|
if (strPayload.equalsIgnoreCase("true"))
|
||||||
{
|
{
|
||||||
mdnsEnabled = true;
|
mdnsEnabled = true;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
else if(strPayload.equalsIgnoreCase("false"))
|
else if (strPayload.equalsIgnoreCase("false"))
|
||||||
{
|
{
|
||||||
mdnsEnabled = false;
|
mdnsEnabled = false;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strTopic == (mqttCommandTopic + "/beepenabled") || strTopic == (mqttGroupCommandTopic + "/beepenabled"))
|
else if (strTopic == (mqttCommandTopic + "/beepenabled") || strTopic == (mqttGroupCommandTopic + "/beepenabled"))
|
||||||
{ // '[...]/device/command/beepenabled' -m 'true' == enable beep output on keypress
|
{ // '[...]/device/command/beepenabled' -m 'true' == enable beep output on keypress
|
||||||
if (strPayload.equalsIgnoreCase("true"))
|
if (strPayload.equalsIgnoreCase("true"))
|
||||||
{
|
{
|
||||||
beepEnabled = true;
|
beepEnabled = true;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
else if(strPayload.equalsIgnoreCase("false"))
|
else if (strPayload.equalsIgnoreCase("false"))
|
||||||
{
|
{
|
||||||
beepEnabled = false;
|
beepEnabled = false;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strTopic == (mqttCommandTopic + "/ignoretouchwhenoff") || strTopic == (mqttGroupCommandTopic + "/ignoretouchwhenoff"))
|
else if (strTopic == (mqttCommandTopic + "/ignoretouchwhenoff") || strTopic == (mqttGroupCommandTopic + "/ignoretouchwhenoff"))
|
||||||
{ // '[...]/device/command/ignoretouchwhenoff' -m 'true' == disable actions on keypress
|
{ // '[...]/device/command/ignoretouchwhenoff' -m 'true' == disable actions on keypress
|
||||||
if (strPayload.equalsIgnoreCase("true"))
|
if (strPayload.equalsIgnoreCase("true"))
|
||||||
{
|
{
|
||||||
ignoreTouchWhenOff = true;
|
ignoreTouchWhenOff = true;
|
||||||
configSave();
|
configSave();
|
||||||
}
|
}
|
||||||
else if(strPayload.equalsIgnoreCase("false"))
|
else if (strPayload.equalsIgnoreCase("false"))
|
||||||
{
|
{
|
||||||
ignoreTouchWhenOff = false;
|
ignoreTouchWhenOff = false;
|
||||||
configSave();
|
configSave();
|
||||||
@ -844,8 +902,8 @@ void mqttProcessInput(String &strTopic, String &strPayload)
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void mqttStatusUpdate()
|
void mqttStatusUpdate()
|
||||||
{ // Periodically publish system status
|
{ // Periodically publish system status
|
||||||
String mqttSensorPayload = "{";
|
String mqttSensorPayload = String(F("{\"espVersion\":"));
|
||||||
mqttSensorPayload += String(F("\"espVersion\":")) + String(haspVersion) + String(F(","));
|
mqttSensorPayload += String(haspVersion) + String(F(","));
|
||||||
if (updateEspAvailable)
|
if (updateEspAvailable)
|
||||||
{
|
{
|
||||||
mqttSensorPayload += String(F("\"updateEspAvailable\":true,"));
|
mqttSensorPayload += String(F("\"updateEspAvailable\":true,"));
|
||||||
@ -892,24 +950,23 @@ void mqttStatusUpdate()
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void mqttDiscovery()
|
void mqttDiscovery()
|
||||||
{ // Publish Home Assistant discovery messages
|
{ // Publish Home Assistant discovery messages
|
||||||
|
const String mqttDiscoveryDevice = String(F("\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"configuration_url\":\"http://")) + WiFi.localIP().toString() + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("},\"origin\":{\"name\":\"HASPone\",\"support_url\":\"https://haswitchplate.com\",\"sw\":")) + String(haspVersion) + String(F("}}"));
|
||||||
String macAddress = String(espMac[0], HEX) + String(F(":")) + String(espMac[1], HEX) + String(F(":")) + String(espMac[2], HEX) + String(F(":")) + String(espMac[3], HEX) + String(F(":")) + String(espMac[4], HEX) + String(F(":")) + String(espMac[5], HEX);
|
|
||||||
|
|
||||||
// light discovery for backlight
|
// light discovery for backlight
|
||||||
String mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/config"));
|
String mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/config"));
|
||||||
String mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" backlight\",\"command_topic\":\"")) + mqttLightCommandTopic + String(F("\",\"state_topic\":\"")) + mqttLightStateTopic + String(F("\",\"brightness_state_topic\":\"")) + mqttLightBrightStateTopic + String(F("\",\"brightness_command_topic\":\"")) + mqttLightBrightCommandTopic + String(F("\",\"availability_topic\":\"")) + mqttStatusTopic + String(F("\",\"brightness_scale\":100,\"unique_id\":\"")) + mqttClientId + String(F("-backlight\",\"payload_on\":\"ON\",\"payload_off\":\"OFF\",\"payload_available\":\"ON\",\"payload_not_available\":\"OFF\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
String mqttDiscoveryPayload = String(F("{\"name\":\"backlight\",\"object_id\":\"")) + String(haspNode) + String(F("_backlight\",\"command_topic\":\"")) + mqttLightCommandTopic + String(F("\",\"state_topic\":\"")) + mqttLightStateTopic + String(F("\",\"brightness_state_topic\":\"")) + mqttLightBrightStateTopic + String(F("\",\"brightness_command_topic\":\"")) + mqttLightBrightCommandTopic + String(F("\",\"availability_topic\":\"")) + mqttStatusTopic + String(F("\",\"brightness_scale\":100,\"unique_id\":\"")) + mqttClientId + String(F("-backlight\",\"payload_on\":\"ON\",\"payload_off\":\"OFF\",\"payload_available\":\"ON\",\"payload_not_available\":\"OFF\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
// sensor discovery for device telemetry
|
// sensor discovery for device telemetry
|
||||||
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/sensor/")) + String(haspNode) + String(F("/config"));
|
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/sensor/")) + String(haspNode) + String(F("/config"));
|
||||||
mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" sensor\",\"json_attributes_topic\":\"")) + mqttSensorTopic + String(F("\",\"state_topic\":\"")) + mqttStatusTopic + String(F("\",\"unique_id\":\"")) + mqttClientId + String(F("-sensor\",\"icon\":\"mdi:cellphone-text\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
mqttDiscoveryPayload = String(F("{\"name\":\"sensor\",\"object_id\":\"")) + String(haspNode) + String(F("_sensor\",\"json_attributes_topic\":\"")) + mqttSensorTopic + String(F("\",\"state_topic\":\"")) + mqttStatusTopic + String(F("\",\"unique_id\":\"")) + mqttClientId + String(F("-sensor\",\"icon\":\"mdi:cellphone-text\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
// number discovery for active page
|
// number discovery for active page
|
||||||
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/number/")) + String(haspNode) + String(F("/config"));
|
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/number/")) + String(haspNode) + String(F("/config"));
|
||||||
mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" active page\",\"command_topic\":\"")) + mqttCommandTopic + String(F("/page\",\"state_topic\":\"")) + mqttStateTopic + String(F("/page\",\"step\":1,\"min\":0,\"max\":")) + String(nextionMaxPages) + String(F(",\"retain\":true,\"optimistic\":true,\"icon\":\"mdi:page-next-outline\",\"unique_id\":\"")) + mqttClientId + String(F("-page\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
mqttDiscoveryPayload = String(F("{\"name\":\"active page\",\"object_id\":\"")) + String(haspNode) + String(F("_active_page\",\"command_topic\":\"")) + mqttCommandTopic + String(F("/page\",\"state_topic\":\"")) + mqttStateTopic + String(F("/page\",\"step\":1,\"min\":0,\"max\":")) + String(nextionMaxPages) + String(F(",\"retain\":true,\"optimistic\":true,\"icon\":\"mdi:page-next-outline\",\"unique_id\":\"")) + mqttClientId + String(F("-page\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
@ -919,33 +976,32 @@ void mqttDiscovery()
|
|||||||
|
|
||||||
// rgb light discovery for selectedforegroundcolor
|
// rgb light discovery for selectedforegroundcolor
|
||||||
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/selectedforegroundcolor/config"));
|
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/selectedforegroundcolor/config"));
|
||||||
mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" selected foreground color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedforegroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedforegroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-selectedforegroundcolor\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
mqttDiscoveryPayload = String(F("{\"name\":\"selected foreground color\",\"object_id\":\"")) + String(haspNode) + String(F("_selected_foreground_color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedforegroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedforegroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-selectedforegroundcolor\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
// rgb light discovery for selectedbackgroundcolor
|
// rgb light discovery for selectedbackgroundcolor
|
||||||
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/selectedbackgroundcolor/config"));
|
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/selectedbackgroundcolor/config"));
|
||||||
mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" selected background color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedbackgroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedbackgroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-selectedbackgroundcolor\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
mqttDiscoveryPayload = String(F("{\"name\":\"selected background color\",\"object_id\":\"")) + String(haspNode) + String(F("_selected_background_color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedbackgroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/selectedbackgroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-selectedbackgroundcolor\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
// rgb light discovery for unselectedforegroundcolor
|
// rgb light discovery for unselectedforegroundcolor
|
||||||
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/unselectedforegroundcolor/config"));
|
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/unselectedforegroundcolor/config"));
|
||||||
mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" unselected foreground color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedforegroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedforegroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-unselectedforegroundcolor\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
mqttDiscoveryPayload = String(F("{\"name\":\"unselected foreground color\",\"object_id\":\"")) + String(haspNode) + String(F("_unselected_foreground_color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedforegroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedforegroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-unselectedforegroundcolor\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
// rgb light discovery for unselectedbackgroundcolor
|
// rgb light discovery for unselectedbackgroundcolor
|
||||||
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/unselectedbackgroundcolor/config"));
|
mqttDiscoveryTopic = String(hassDiscovery) + String(F("/light/")) + String(haspNode) + String(F("/unselectedbackgroundcolor/config"));
|
||||||
mqttDiscoveryPayload = String(F("{\"name\":\"")) + String(haspNode) + String(F(" unselected background color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedbackgroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedbackgroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-unselectedbackgroundcolor\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
mqttDiscoveryPayload = String(F("{\"name\":\"unselected background color\",\"object_id\":\"")) + String(haspNode) + String(F("_unselected_background_color\",\"command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedbackgroundcolor/switch\",\"state_topic\":\"hasp/")) + String(haspNode) + String(F("/alwayson\",\"rgb_command_topic\":\"hasp/")) + String(haspNode) + String(F("/light/unselectedbackgroundcolor/rgb\",\"rgb_command_template\":\"{{(red|bitwise_and(248)*256)+(green|bitwise_and(252)*8)+(blue|bitwise_and(248)/8)|int }}\",\"retain\":true,\"unique_id\":\"")) + mqttClientId + String(F("-unselectedbackgroundcolor\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
|
|
||||||
if (motionEnabled)
|
if (motionEnabled)
|
||||||
{ // binary_sensor for motion
|
{ // binary_sensor for motion
|
||||||
String macAddress = String(espMac[0], HEX) + String(F(":")) + String(espMac[1], HEX) + String(F(":")) + String(espMac[2], HEX) + String(F(":")) + String(espMac[3], HEX) + String(F(":")) + String(espMac[4], HEX) + String(F(":")) + String(espMac[5], HEX);
|
|
||||||
String mqttDiscoveryTopic = String(hassDiscovery) + String(F("/binary_sensor/")) + String(haspNode) + String(F("-motion/config"));
|
String mqttDiscoveryTopic = String(hassDiscovery) + String(F("/binary_sensor/")) + String(haspNode) + String(F("-motion/config"));
|
||||||
String mqttDiscoveryPayload = String(F("{\"device_class\":\"motion\",\"name\":\"")) + String(haspNode) + String(F(" motion\",\"state_topic\":\"")) + mqttMotionStateTopic + String(F("\",\"unique_id\":\"")) + mqttClientId + String(F("-motion\",\"payload_on\":\"ON\",\"payload_off\":\"OFF\",\"device\":{\"identifiers\":[\"")) + mqttClientId + String(F("\"],\"name\":\"")) + String(haspNode) + String(F("\",\"manufacturer\":\"HASwitchPlate\",\"model\":\"HASPone v1.0.0\",\"sw_version\":")) + String(haspVersion) + String(F("}}"));
|
String mqttDiscoveryPayload = String(F("{\"device_class\":\"motion\",\"name\":\"motion\",\"object_id\":\"")) + String(haspNode) + String(F("_motion\",\"state_topic\":\"")) + mqttMotionStateTopic + String(F("\",\"unique_id\":\"")) + mqttClientId + String(F("-motion\",\"payload_on\":\"ON\",\"payload_off\":\"OFF\",")) + mqttDiscoveryDevice;
|
||||||
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
mqttClient.publish(mqttDiscoveryTopic, mqttDiscoveryPayload, true, 1);
|
||||||
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
debugPrintln(String(F("MQTT OUT: '")) + mqttDiscoveryTopic + String(F("' : '")) + String(mqttDiscoveryPayload) + String(F("'")));
|
||||||
}
|
}
|
||||||
@ -1250,6 +1306,10 @@ void nextionProcessInput()
|
|||||||
debugPrintln(String(F("HMI IN: p[0].b[1] pressed during HASPone configuration, rebooting.")));
|
debugPrintln(String(F("HMI IN: p[0].b[1] pressed during HASPone configuration, rebooting.")));
|
||||||
espReset();
|
espReset();
|
||||||
}
|
}
|
||||||
|
if (rebootOnLongPress)
|
||||||
|
{
|
||||||
|
rebootOnLongPressTimer = millis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (nextionButtonAction == 0x00)
|
else if (nextionButtonAction == 0x00)
|
||||||
{
|
{
|
||||||
@ -1280,6 +1340,12 @@ void nextionProcessInput()
|
|||||||
nextionGetAttr("p[" + nextionPage + "].b[" + nextionButtonID + "].val");
|
nextionGetAttr("p[" + nextionPage + "].b[" + nextionButtonID + "].val");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rebootOnLongPress && (millis() - rebootOnLongPressTimer > rebootOnLongPressTimeout))
|
||||||
|
{
|
||||||
|
debugPrintln(String(F("HMI IN: Button long press, rebooting.")));
|
||||||
|
espReset();
|
||||||
|
}
|
||||||
|
rebootOnLongPressTimer = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nextionReturnBuffer[0] == 0x66)
|
else if (nextionReturnBuffer[0] == 0x66)
|
||||||
@ -1624,8 +1690,6 @@ void nextionParseJson(const String &strPayload)
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
void nextionOtaStartDownload(const String &lcdOtaUrl)
|
void nextionOtaStartDownload(const String &lcdOtaUrl)
|
||||||
{ // Upload firmware to the Nextion LCD via HTTP download
|
{ // Upload firmware to the Nextion LCD via HTTP download
|
||||||
// based in large part on code posted by indev2 here:
|
|
||||||
// http://support.iteadstudio.com/support/discussions/topics/11000007686/page/2
|
|
||||||
|
|
||||||
uint32_t lcdOtaFileSize = 0;
|
uint32_t lcdOtaFileSize = 0;
|
||||||
String lcdOtaNextionCmd;
|
String lcdOtaNextionCmd;
|
||||||
@ -1967,6 +2031,8 @@ void espWifiConnect()
|
|||||||
nextionSendCmd("page 0");
|
nextionSendCmd("page 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WiFi.persistent(false);
|
||||||
|
enableWiFiAtBootTime();
|
||||||
WiFi.macAddress(espMac); // Read our MAC address and save it to espMac
|
WiFi.macAddress(espMac); // Read our MAC address and save it to espMac
|
||||||
WiFi.hostname(haspNode); // Assign our hostname before connecting to WiFi
|
WiFi.hostname(haspNode); // Assign our hostname before connecting to WiFi
|
||||||
WiFi.setAutoReconnect(true); // Tell WiFi to autoreconnect if connection has dropped
|
WiFi.setAutoReconnect(true); // Tell WiFi to autoreconnect if connection has dropped
|
||||||
@ -1981,7 +2047,9 @@ void espWifiConnect()
|
|||||||
{
|
{
|
||||||
nextionSetAttr("p[0].b[1].txt", "\"WiFi Connecting...\\r " + String(WiFi.SSID()) + "\"");
|
nextionSetAttr("p[0].b[1].txt", "\"WiFi Connecting...\\r " + String(WiFi.SSID()) + "\"");
|
||||||
unsigned long connectTimer = millis() + 10000;
|
unsigned long connectTimer = millis() + 10000;
|
||||||
|
|
||||||
debugPrintln(String(F("WIFI: Connecting to previously-saved SSID: ")) + String(WiFi.SSID()));
|
debugPrintln(String(F("WIFI: Connecting to previously-saved SSID: ")) + String(WiFi.SSID()));
|
||||||
|
|
||||||
WiFi.begin();
|
WiFi.begin();
|
||||||
while ((WiFi.status() != WL_CONNECTED) && (millis() < connectTimer))
|
while ((WiFi.status() != WL_CONNECTED) && (millis() < connectTimer))
|
||||||
{
|
{
|
||||||
@ -2004,13 +2072,19 @@ void espWifiConnect()
|
|||||||
{
|
{
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WiFi.localIP().toString() == "(IP unset)")
|
||||||
|
{ // Check if we have our IP yet
|
||||||
|
debugPrintln(F("WIFI: Failed to lease address from DHCP, disconnecting and trying again"));
|
||||||
|
WiFi.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WiFi.status() != WL_CONNECTED)
|
if (WiFi.status() != WL_CONNECTED)
|
||||||
{ // We gave it a shot, still couldn't connect, so let WiFiManager run to make one last
|
{ // We gave it a shot, still couldn't connect, so let WiFiManager run to make one last
|
||||||
// connection attempt and then flip to AP mode to collect credentials from the user.
|
// connection attempt and then flip to AP mode to collect credentials from the user.
|
||||||
|
WiFi.persistent(true);
|
||||||
WiFiManagerParameter custom_haspNodeHeader("<br/><b>HASPone Node</b>");
|
WiFiManagerParameter custom_haspNodeHeader("<br/><b>HASPone Node</b>");
|
||||||
WiFiManagerParameter custom_haspNode("haspNode", "<br/>Node Name <small>(required: lowercase letters, numbers, and _ only)</small>", haspNode, 15, " maxlength=15 required pattern='[a-z0-9_]*'");
|
WiFiManagerParameter custom_haspNode("haspNode", "<br/>Node Name <small>(required: lowercase letters, numbers, and _ only)</small>", haspNode, 15, " maxlength=15 required pattern='[a-z0-9_]*'");
|
||||||
WiFiManagerParameter custom_groupName("groupName", "Group Name <small>(required)</small>", groupName, 15, " maxlength=15 required");
|
WiFiManagerParameter custom_groupName("groupName", "Group Name <small>(required)</small>", groupName, 15, " maxlength=15 required");
|
||||||
@ -2170,16 +2244,14 @@ void espSetupOta()
|
|||||||
debugPrintln(F("ESP OTA: update start"));
|
debugPrintln(F("ESP OTA: update start"));
|
||||||
nextionSetAttr("p[0].b[1].txt", "\"\\rHASPone update:\\r\\r\\r \"");
|
nextionSetAttr("p[0].b[1].txt", "\"\\rHASPone update:\\r\\r\\r \"");
|
||||||
nextionSendCmd("page 0");
|
nextionSendCmd("page 0");
|
||||||
nextionSendCmd("vis 4,1");
|
nextionSendCmd("vis 4,1"); });
|
||||||
});
|
|
||||||
ArduinoOTA.onEnd([]()
|
ArduinoOTA.onEnd([]()
|
||||||
{
|
{
|
||||||
debugPrintln(F("ESP OTA: update complete"));
|
debugPrintln(F("ESP OTA: update complete"));
|
||||||
nextionSetAttr("p[0].b[1].txt", "\"\\rHASPone update:\\r\\r Complete!\\rRestarting.\"");
|
nextionSetAttr("p[0].b[1].txt", "\"\\rHASPone update:\\r\\r Complete!\\rRestarting.\"");
|
||||||
nextionSendCmd("vis 4,1");
|
nextionSendCmd("vis 4,1");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
espReset();
|
espReset(); });
|
||||||
});
|
|
||||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
|
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
|
||||||
{ nextionUpdateProgress(progress, total); });
|
{ nextionUpdateProgress(progress, total); });
|
||||||
ArduinoOTA.onError([](ota_error_t error)
|
ArduinoOTA.onError([](ota_error_t error)
|
||||||
@ -2198,8 +2270,7 @@ void espSetupOta()
|
|||||||
nextionSendCmd("vis 4,0");
|
nextionSendCmd("vis 4,0");
|
||||||
nextionSetAttr("p[0].b[1].txt", "\"HASPone update:\\r FAILED\\rerror: " + String(error) + "\"");
|
nextionSetAttr("p[0].b[1].txt", "\"HASPone update:\\r FAILED\\rerror: " + String(error) + "\"");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
nextionSendCmd("page " + String(nextionActivePage));
|
nextionSendCmd("page " + String(nextionActivePage)); });
|
||||||
});
|
|
||||||
ArduinoOTA.begin();
|
ArduinoOTA.begin();
|
||||||
debugPrintln(F("ESP OTA: Over the Air firmware update ready"));
|
debugPrintln(F("ESP OTA: Over the Air firmware update ready"));
|
||||||
}
|
}
|
||||||
@ -2214,8 +2285,14 @@ void espStartOta(const String &espOtaUrl)
|
|||||||
|
|
||||||
WiFiUDP::stopAll(); // Keep mDNS responder from breaking things
|
WiFiUDP::stopAll(); // Keep mDNS responder from breaking things
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
|
int startHost = espOtaUrl.indexOf("://") + 3; // Find the end of 'https://'
|
||||||
|
int endHost = espOtaUrl.indexOf('/', startHost); // Find the next '/' after 'https://'
|
||||||
|
String espOtaHost = espOtaUrl.substring(startHost, endHost); // Extract host
|
||||||
|
String espOtaUri = espOtaUrl.substring(endHost); // Extract URI
|
||||||
ESPhttpUpdate.rebootOnUpdate(false);
|
ESPhttpUpdate.rebootOnUpdate(false);
|
||||||
ESPhttpUpdate.onProgress(nextionUpdateProgress);
|
ESPhttpUpdate.onProgress(nextionUpdateProgress);
|
||||||
|
ESPhttpUpdate.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
|
||||||
t_httpUpdate_return espOtaUrlReturnCode;
|
t_httpUpdate_return espOtaUrlReturnCode;
|
||||||
if (espOtaUrl.startsWith(F("https")))
|
if (espOtaUrl.startsWith(F("https")))
|
||||||
{
|
{
|
||||||
@ -2224,6 +2301,7 @@ void espStartOta(const String &espOtaUrl)
|
|||||||
wifiEspOtaClientSecure.setInsecure();
|
wifiEspOtaClientSecure.setInsecure();
|
||||||
wifiEspOtaClientSecure.setBufferSizes(512, 512);
|
wifiEspOtaClientSecure.setBufferSizes(512, 512);
|
||||||
espOtaUrlReturnCode = ESPhttpUpdate.update(wifiEspOtaClientSecure, espOtaUrl);
|
espOtaUrlReturnCode = ESPhttpUpdate.update(wifiEspOtaClientSecure, espOtaUrl);
|
||||||
|
wifiEspOtaClientSecure.stop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2579,7 +2657,7 @@ void webHandleNotFound()
|
|||||||
void webHandleRoot()
|
void webHandleRoot()
|
||||||
{ // http://plate01/
|
{ // http://plate01/
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -2832,7 +2910,7 @@ void webHandleRoot()
|
|||||||
void webHandleSaveConfig()
|
void webHandleSaveConfig()
|
||||||
{ // http://plate01/saveConfig
|
{ // http://plate01/saveConfig
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3028,7 +3106,7 @@ void webHandleSaveConfig()
|
|||||||
void webHandleResetConfig()
|
void webHandleResetConfig()
|
||||||
{ // http://plate01/resetConfig
|
{ // http://plate01/resetConfig
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3070,7 +3148,7 @@ void webHandleResetConfig()
|
|||||||
void webHandleResetBacklight()
|
void webHandleResetBacklight()
|
||||||
{ // http://plate01/resetBacklight
|
{ // http://plate01/resetBacklight
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3101,7 +3179,7 @@ void webHandleResetBacklight()
|
|||||||
void webHandleFirmware()
|
void webHandleFirmware()
|
||||||
{ // http://plate01/firmware
|
{ // http://plate01/firmware
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3145,7 +3223,7 @@ void webHandleFirmware()
|
|||||||
{
|
{
|
||||||
webServer.sendContent(F("<font color='green'><b>HASPone LCD update available!</b></font>"));
|
webServer.sendContent(F("<font color='green'><b>HASPone LCD update available!</b></font>"));
|
||||||
}
|
}
|
||||||
webServer.sendContent(F("<br/><b>Update Nextion LCD from URL</b><small><i> http only</i></small>"));
|
webServer.sendContent(F("<br/><b>Update Nextion LCD from URL</b>"));
|
||||||
webServer.sendContent(F("<br/><input id='lcdFirmware' name='lcdFirmware' value='"));
|
webServer.sendContent(F("<br/><input id='lcdFirmware' name='lcdFirmware' value='"));
|
||||||
webServer.sendContent(lcdFirmwareUrl);
|
webServer.sendContent(lcdFirmwareUrl);
|
||||||
webServer.sendContent(F("'><br/><br/><button type='submit'>Update LCD from URL</button></form>"));
|
webServer.sendContent(F("'><br/><br/><button type='submit'>Update LCD from URL</button></form>"));
|
||||||
@ -3174,7 +3252,7 @@ void webHandleFirmware()
|
|||||||
void webHandleEspFirmware()
|
void webHandleEspFirmware()
|
||||||
{ // http://plate01/espfirmware
|
{ // http://plate01/espfirmware
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3209,7 +3287,7 @@ void webHandleLcdUpload()
|
|||||||
// Upload firmware to the Nextion LCD via HTTP upload
|
// Upload firmware to the Nextion LCD via HTTP upload
|
||||||
|
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3443,7 +3521,7 @@ void webHandleLcdUpload()
|
|||||||
void webHandleLcdUpdateSuccess()
|
void webHandleLcdUpdateSuccess()
|
||||||
{ // http://plate01/lcdOtaSuccess
|
{ // http://plate01/lcdOtaSuccess
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3471,7 +3549,7 @@ void webHandleLcdUpdateSuccess()
|
|||||||
void webHandleLcdUpdateFailure()
|
void webHandleLcdUpdateFailure()
|
||||||
{ // http://plate01/lcdOtaFailure
|
{ // http://plate01/lcdOtaFailure
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3499,7 +3577,7 @@ void webHandleLcdUpdateFailure()
|
|||||||
void webHandleLcdDownload()
|
void webHandleLcdDownload()
|
||||||
{ // http://plate01/lcddownload
|
{ // http://plate01/lcddownload
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3528,7 +3606,7 @@ void webHandleLcdDownload()
|
|||||||
void webHandleTftFileSize()
|
void webHandleTftFileSize()
|
||||||
{ // http://plate01/tftFileSize
|
{ // http://plate01/tftFileSize
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3548,7 +3626,7 @@ void webHandleTftFileSize()
|
|||||||
void webHandleReboot()
|
void webHandleReboot()
|
||||||
{ // http://plate01/reboot
|
{ // http://plate01/reboot
|
||||||
if (configPassword[0] != '\0')
|
if (configPassword[0] != '\0')
|
||||||
{ //Request HTTP auth if configPassword is set
|
{ // Request HTTP auth if configPassword is set
|
||||||
if (!webServer.authenticate(configUser, configPassword))
|
if (!webServer.authenticate(configUser, configPassword))
|
||||||
{
|
{
|
||||||
return webServer.requestAuthentication();
|
return webServer.requestAuthentication();
|
||||||
@ -3726,12 +3804,12 @@ void telnetHandleClient()
|
|||||||
{
|
{
|
||||||
telnetClient.stop(); // client disconnected
|
telnetClient.stop(); // client disconnected
|
||||||
}
|
}
|
||||||
telnetClient = telnetServer.available(); // ready for new client
|
telnetClient = telnetServer.accept(); // ready for new client
|
||||||
telnetInputIndex = 0; // reset input buffer index
|
telnetInputIndex = 0; // reset input buffer index
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
telnetServer.available().stop(); // have client, block new connections
|
telnetServer.accept().stop(); // have client, block new connections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle client input from telnet connection.
|
// Handle client input from telnet connection.
|
Binary file not shown.
@ -9,17 +9,17 @@
|
|||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[env:d1_mini]
|
[env:d1_mini]
|
||||||
platform = https://github.com/platformio/platform-espressif8266.git @ ^3.2.0
|
platform = https://github.com/platformio/platform-espressif8266.git @ ^4.2.1
|
||||||
board = d1_mini
|
board = d1_mini
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.f_cpu = 160000000L
|
board_build.f_cpu = 160000000L
|
||||||
board_build.ldscript = eagle.flash.4m1m.ld
|
board_build.ldscript = eagle.flash.4m1m.ld
|
||||||
build_flags =
|
build_flags =
|
||||||
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122
|
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
|
||||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson @ ^6.18.5
|
256dpi/MQTT @ ^2.5.2
|
||||||
256dpi/MQTT @ ^2.5.0
|
dancol90/ESP8266Ping @ ^1.1.0
|
||||||
dancol90/ESP8266Ping @ ^1.0
|
bblanchon/ArduinoJson @ ^7.0.4
|
||||||
krzychb/EspSaveCrash @ ^1.2.0
|
krzychb/EspSaveCrash @ ^1.3.0
|
||||||
https://github.com/tzapu/WiFiManager.git#8452df79bbc55265d6a999d7384204220f4d22c6
|
https://github.com/tzapu/WiFiManager.git#e978bc059c522404c01e06cd136fcf23234eb784
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] activates a page"
|
name: "HASPone p[x].b[y] activates a page"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone activates a selected page after a specified period of inactivity"
|
name: "HASPone activates a selected page after a specified period of inactivity"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ condition:
|
|||||||
|
|
||||||
action:
|
action:
|
||||||
- delay:
|
- delay:
|
||||||
seconds: "{{idletime|int}}"
|
seconds: "{{idletime|int(default=30)}}"
|
||||||
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] has theme colors applied"
|
name: "HASPone p[x].b[y] has theme colors applied"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
|
326
Home_Assistant/blueprints/hasp_Apply_Theme_Multiple_Buttons.yaml
Normal file
326
Home_Assistant/blueprints/hasp_Apply_Theme_Multiple_Buttons.yaml
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "HASPone buttons have theme colors applied"
|
||||||
|
description: |
|
||||||
|
|
||||||
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Several buttons on the HASPone will have the current device theme or custom colors applied.
|
||||||
|
|
||||||
|
## HASPone Page and Button Reference
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
The images below show each available HASPone page along with the layout of available button objects.
|
||||||
|
|
||||||
|
| Page 0 | Pages 1-3 | Pages 4-5 |
|
||||||
|
|--------|-----------|-----------|
|
||||||
|
|  |  |  |
|
||||||
|
|
||||||
|
| Page 6 | Page 7 | Page 8 |
|
||||||
|
|--------|--------|--------|
|
||||||
|
|  |  |  |
|
||||||
|
|
||||||
|
| Page 9 | Page 10 | Page 11 |
|
||||||
|
|--------|---------|---------|
|
||||||
|
|  |  | 
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Nextion color codes
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
The Nextion environment utilizes RGB 565 encoding. [Use this handy convertor](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to select your colors and convert to the RGB 565 format.
|
||||||
|
|
||||||
|
Here are some example colors:
|
||||||
|
|
||||||
|
| Color | Code |
|
||||||
|
|--------|-------|
|
||||||
|
| White | 65535 |
|
||||||
|
| Black | 0 |
|
||||||
|
| Grey | 25388 |
|
||||||
|
| Red | 63488 |
|
||||||
|
| Green | 2016 |
|
||||||
|
| Blue | 31 |
|
||||||
|
| Yellow | 65504 |
|
||||||
|
| Orange | 64512 |
|
||||||
|
| Brown | 48192 |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
haspdevice:
|
||||||
|
name: "HASPone Device"
|
||||||
|
description: "Select the HASPone device"
|
||||||
|
selector:
|
||||||
|
device:
|
||||||
|
integration: mqtt
|
||||||
|
manufacturer: "HASwitchPlate"
|
||||||
|
model: "HASPone v1.0.0"
|
||||||
|
objects:
|
||||||
|
name: "HASPone buttons"
|
||||||
|
description: "Apply the current theme or colors defined below to all of the objects in this list"
|
||||||
|
default:
|
||||||
|
- p[1].b[4]
|
||||||
|
- p[1].b[5]
|
||||||
|
- p[1].b[6]
|
||||||
|
- p[1].b[7]
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
selected_fgcolor:
|
||||||
|
name: "Selected foreground color"
|
||||||
|
description: 'Selected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected foreground color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
selected_bgcolor:
|
||||||
|
name: "Selected background color"
|
||||||
|
description: 'Selected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected background color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
unselected_fgcolor:
|
||||||
|
name: "Unselected foreground color"
|
||||||
|
description: 'Unselected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected foreground color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
unselected_bgcolor:
|
||||||
|
name: "Unselected background color"
|
||||||
|
description: 'Unselected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected background color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
mode: parallel
|
||||||
|
max_exceeded: silent
|
||||||
|
|
||||||
|
variables:
|
||||||
|
haspdevice: !input haspdevice
|
||||||
|
haspname: >-
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
|
||||||
|
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
objects: !input objects
|
||||||
|
selected_fgcolor: !input selected_fgcolor
|
||||||
|
selected_bgcolor: !input selected_bgcolor
|
||||||
|
unselected_fgcolor: !input unselected_fgcolor
|
||||||
|
unselected_bgcolor: !input unselected_bgcolor
|
||||||
|
# haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
|
||||||
|
# commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
|
||||||
|
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
|
||||||
|
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
|
||||||
|
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
|
||||||
|
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
|
||||||
|
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
|
||||||
|
selectedfg: >-
|
||||||
|
{%- if (selected_fgcolor|int) >= 0 -%}
|
||||||
|
{{ selected_fgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
selectedbg: >-
|
||||||
|
{%- if (selected_bgcolor|int) >= 0 -%}
|
||||||
|
{{ selected_bgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
unselectedfg: >-
|
||||||
|
{%- if (unselected_fgcolor|int) >= 0 -%}
|
||||||
|
{{ unselected_fgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
unselectedbg: >-
|
||||||
|
{%- if (unselected_bgcolor|int) >= 0 -%}
|
||||||
|
{{ unselected_bgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
trigger_variables:
|
||||||
|
haspdevice: !input haspdevice
|
||||||
|
haspname: >-
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
|
||||||
|
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
haspsensor: >-
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
|
||||||
|
{{ entity }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
|
||||||
|
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
|
||||||
|
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
|
||||||
|
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
|
||||||
|
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: homeassistant
|
||||||
|
event: start
|
||||||
|
- platform: template
|
||||||
|
value_template: "{{ is_state(haspsensor, 'ON') }}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{selectedfgtopic}}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{selectedbgtopic}}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{unselectedfgtopic}}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{unselectedbgtopic}}"
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_state(haspsensor, 'ON') }}"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- choose:
|
||||||
|
#########################################################################
|
||||||
|
# RUN ACTIONS or Home Assistant Startup or HASPone Connect
|
||||||
|
# Apply text style
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{{-
|
||||||
|
(trigger is not defined)
|
||||||
|
or
|
||||||
|
(trigger.platform is none)
|
||||||
|
or
|
||||||
|
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
|
||||||
|
or
|
||||||
|
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
|
||||||
|
-}}
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{objects|length}}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{jsoncommandtopic}}"
|
||||||
|
payload: >-
|
||||||
|
[
|
||||||
|
"{{objects[repeat.index-1]}}.pco={{selectedfg}}",
|
||||||
|
"{{objects[repeat.index-1]}}.bco={{selectedbg}}",
|
||||||
|
"{{objects[repeat.index-1]}}.pco2={{unselectedfg}}",
|
||||||
|
"{{objects[repeat.index-1]}}.bco2={{unselectedbg}}"
|
||||||
|
]
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
# Catch triggers fired by incoming MQTT messages
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: '{{ trigger.platform == "mqtt" }}'
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply selected foreground color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == selectedfgtopic) and ((selected_fgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{objects|length}}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".pco" }}'
|
||||||
|
payload: "{{trigger.payload}}"
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply selected background color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == selectedbgtopic) and ((selected_bgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{objects|length}}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".bco" }}'
|
||||||
|
payload: "{{trigger.payload}}"
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply unselected foreground color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == unselectedfgtopic) and ((unselected_fgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{objects|length}}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".pco2" }}'
|
||||||
|
payload: "{{trigger.payload}}"
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply unselected background color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == unselectedbgtopic) and ((unselected_bgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{objects|length}}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".bco2" }}'
|
||||||
|
payload: "{{trigger.payload}}"
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone Core functionality"
|
name: "HASPone Core functionality"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
@ -234,15 +234,15 @@ variables:
|
|||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
page1text: !input page1text
|
page1text: !input page1text
|
||||||
page1font_select: !input page1font_select
|
page1font_select: !input page1font_select
|
||||||
page1font: "{{ page1font_select.split(' - ')[0] | int }}"
|
page1font: "{{ page1font_select.split(' - ')[0] | int(default=6) }}"
|
||||||
page1page: !input page1page
|
page1page: !input page1page
|
||||||
page2text: !input page2text
|
page2text: !input page2text
|
||||||
page2font_select: !input page2font_select
|
page2font_select: !input page2font_select
|
||||||
page2font: "{{ page2font_select.split(' - ')[0] | int }}"
|
page2font: "{{ page2font_select.split(' - ')[0] | int(default=6) }}"
|
||||||
page2page: !input page2page
|
page2page: !input page2page
|
||||||
page3text: !input page3text
|
page3text: !input page3text
|
||||||
page3font_select: !input page3font_select
|
page3font_select: !input page3font_select
|
||||||
page3font: "{{ page3font_select.split(' - ')[0] | int }}"
|
page3font: "{{ page3font_select.split(' - ')[0] | int(default=6) }}"
|
||||||
page3page: !input page3page
|
page3page: !input page3page
|
||||||
page_scroll: !input page_scroll
|
page_scroll: !input page_scroll
|
||||||
page_scroll_list: !input page_scroll_list
|
page_scroll_list: !input page_scroll_list
|
||||||
@ -289,29 +289,29 @@ variables:
|
|||||||
page_list: '{{page_scroll_list.split(",")}}'
|
page_list: '{{page_scroll_list.split(",")}}'
|
||||||
page_previous: >
|
page_previous: >
|
||||||
{%- set page = namespace() -%}
|
{%- set page = namespace() -%}
|
||||||
{%- set page.previous = page_list[(page_list|length)-1]|int -%}
|
{%- set page.previous = page_list[(page_list|length)-1]|int(default=10) -%}
|
||||||
{%- set page.next = page_list[0]|int -%}
|
{%- set page.next = page_list[0]|int(default=1) -%}
|
||||||
{%- for item in page_list -%}
|
{%- for item in page_list -%}
|
||||||
{%- if item|int == activepage -%}
|
{%- if item|int(default=1) == activepage -%}
|
||||||
{%- if not loop.first -%}
|
{%- if not loop.first -%}
|
||||||
{%- set page.previous = loop.previtem|int -%}
|
{%- set page.previous = loop.previtem|int(default=1) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if not loop.last -%}
|
{%- if not loop.last -%}
|
||||||
{%- set page.next = loop.nextitem|int -%}
|
{%- set page.next = loop.nextitem|int(default=1) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endfor -%}{{page.previous}}
|
{%- endfor -%}{{page.previous}}
|
||||||
page_next: >
|
page_next: >
|
||||||
{%- set page = namespace() -%}
|
{%- set page = namespace() -%}
|
||||||
{%- set page.previous = page_list[(page_list|length)-1]|int -%}
|
{%- set page.previous = page_list[(page_list|length)-1]|int(default=10) -%}
|
||||||
{%- set page.next = page_list[0]|int -%}
|
{%- set page.next = page_list[0]|int(default=1) -%}
|
||||||
{%- for item in page_list -%}
|
{%- for item in page_list -%}
|
||||||
{%- if item|int == activepage -%}
|
{%- if item|int(default=1) == activepage -%}
|
||||||
{%- if not loop.first -%}
|
{%- if not loop.first -%}
|
||||||
{%- set page.previous = loop.previtem|int -%}
|
{%- set page.previous = loop.previtem|int(default=1) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if not loop.last -%}
|
{%- if not loop.last -%}
|
||||||
{%- set page.next = loop.nextitem|int -%}
|
{%- set page.next = loop.nextitem|int(default=1) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endfor -%}{{page.next}}
|
{%- endfor -%}{{page.next}}
|
||||||
@ -608,11 +608,11 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=0) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # apply selected background color to page select buttons
|
- service: mqtt.publish # apply selected background color to page select buttons
|
||||||
data:
|
data:
|
||||||
@ -628,11 +628,11 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=65535) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # apply unselected foreground color to page select buttons
|
- service: mqtt.publish # apply unselected foreground color to page select buttons
|
||||||
data:
|
data:
|
||||||
@ -648,11 +648,11 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=59164) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # apply unselected background color to page select buttons
|
- service: mqtt.publish # apply unselected background color to page select buttons
|
||||||
data:
|
data:
|
||||||
@ -668,11 +668,11 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=16904) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
@ -707,11 +707,12 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=0) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[2].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # apply selected background color to page select buttons
|
- service: mqtt.publish # apply selected background color to page select buttons
|
||||||
data:
|
data:
|
||||||
@ -727,11 +728,12 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=65535) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[2].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # apply unselected foreground color to page select buttons
|
- service: mqtt.publish # apply unselected foreground color to page select buttons
|
||||||
data:
|
data:
|
||||||
@ -747,11 +749,12 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=59164) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[2].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # apply unselected background color to page select buttons
|
- service: mqtt.publish # apply unselected background color to page select buttons
|
||||||
data:
|
data:
|
||||||
@ -767,11 +770,12 @@ action:
|
|||||||
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
|
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=16904) -%}
|
||||||
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[2].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
|
||||||
|
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||||
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
|
||||||
- service: mqtt.publish # request sensor update
|
- service: mqtt.publish # request sensor update
|
||||||
data:
|
data:
|
||||||
@ -847,9 +851,9 @@ action:
|
|||||||
data:
|
data:
|
||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == selectedfgtopic) and page_scroll }}"
|
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == selectedfgtopic) and page_scroll }}"
|
||||||
@ -859,7 +863,7 @@ action:
|
|||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{trigger.payload}}",{%- endfor -%}
|
[{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}"p[{{p}}].b[2].pco={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@ -869,9 +873,9 @@ action:
|
|||||||
data:
|
data:
|
||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == selectedbgtopic) and page_scroll }}"
|
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == selectedbgtopic) and page_scroll }}"
|
||||||
@ -881,7 +885,7 @@ action:
|
|||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{trigger.payload}}",{%- endfor -%}
|
[{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}"p[{{p}}].b[2].bco={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@ -891,9 +895,9 @@ action:
|
|||||||
data:
|
data:
|
||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == unselectedfgtopic) and page_scroll }}"
|
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == unselectedfgtopic) and page_scroll }}"
|
||||||
@ -903,7 +907,7 @@ action:
|
|||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{trigger.payload}}",{%- endfor -%}
|
[{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}"p[{{p}}].b[2].pco2={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@ -913,9 +917,9 @@ action:
|
|||||||
data:
|
data:
|
||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == unselectedbgtopic) and page_scroll }}"
|
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == unselectedbgtopic) and page_scroll }}"
|
||||||
@ -925,5 +929,5 @@ action:
|
|||||||
topic: "{{jsoncommandtopic}}"
|
topic: "{{jsoncommandtopic}}"
|
||||||
payload: >-
|
payload: >-
|
||||||
[{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{trigger.payload}}",{%- endfor -%}
|
[{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
|
{%- for p in range(1,12) %}"p[{{p}}].b[2].bco2={{trigger.payload}}",{%- endfor -%}
|
||||||
{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone create device triggers"
|
name: "HASPone create device triggers"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] cycles through multiple automations"
|
name: "HASPone p[x].b[y] cycles through multiple automations"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone dim the display screen after a specified period of inactivity"
|
name: "HASPone dim the display screen after a specified period of inactivity"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone dims the backlight with the sun"
|
name: "HASPone dims the backlight with the sun"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[7].b[all] displays an alarm control panel"
|
name: "HASPone p[7].b[all] displays an alarm control panel"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the month + date with a calendar icon"
|
name: "HASPone p[x].b[y] displays the month + date with a calendar icon"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays a clock"
|
name: "HASPone p[x].b[y] displays a clock"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -165,11 +165,11 @@ variables:
|
|||||||
hasppage: !input hasppage
|
hasppage: !input hasppage
|
||||||
haspbutton: !input haspbutton
|
haspbutton: !input haspbutton
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
hour24: !input hour24
|
hour24: !input hour24
|
||||||
ampm: !input ampm
|
ampm: !input ampm
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays a clock with a clock icon"
|
name: "HASPone p[x].b[y] displays a clock with a clock icon"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
1216
Home_Assistant/blueprints/hasp_Display_Color_Swatches.yaml
Normal file
1216
Home_Assistant/blueprints/hasp_Display_Color_Swatches.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays a dimmer with a toggle on/off icon"
|
name: "HASPone p[x].b[y] displays a dimmer with a toggle on/off icon"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -144,11 +144,11 @@ variables:
|
|||||||
text_on: !input text_on
|
text_on: !input text_on
|
||||||
text_off: !input text_off
|
text_off: !input text_off
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=6) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
icon_on: !input icon_on
|
icon_on: !input icon_on
|
||||||
icon_off: !input icon_off
|
icon_off: !input icon_off
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the state or attribute value of an entity"
|
name: "HASPone p[x].b[y] displays the state or attribute value of an entity"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -239,11 +239,11 @@ variables:
|
|||||||
prefix: !input prefix
|
prefix: !input prefix
|
||||||
suffix: !input suffix
|
suffix: !input suffix
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
title_case: !input title_case
|
title_case: !input title_case
|
||||||
selected_fgcolor: !input selected_fgcolor
|
selected_fgcolor: !input selected_fgcolor
|
||||||
@ -474,4 +474,3 @@ action:
|
|||||||
data:
|
data:
|
||||||
topic: "{{commandtopic}}.bco2"
|
topic: "{{commandtopic}}.bco2"
|
||||||
payload: "{{trigger.payload}}"
|
payload: "{{trigger.payload}}"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[6].b[all] Page 6 displays Heatpump controls"
|
name: "HASPone p[6].b[all] Page 6 displays Heatpump controls"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[9].b[all] Page 9 displays Heatpump controls"
|
name: "HASPone p[9].b[all] Page 9 displays Heatpump controls"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[8].b[all] Page 8 displays media controls"
|
name: "HASPone p[8].b[all] Page 8 displays media controls"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the output of a template"
|
name: "HASPone p[x].b[y] displays the output of a template"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ blueprint:
|
|||||||
description: "Enter a well-formed [Home Assistant template](https://www.home-assistant.io/docs/configuration/templating/) string. The variable `trigger_entity` will contain the entity name selected above."
|
description: "Enter a well-formed [Home Assistant template](https://www.home-assistant.io/docs/configuration/templating/) string. The variable `trigger_entity` will contain the entity name selected above."
|
||||||
default: 'Forecast: {{state_attr("weather.home", "forecast")[0].condition|title}}'
|
default: 'Forecast: {{state_attr("weather.home", "forecast")[0].condition|title}}'
|
||||||
selector:
|
selector:
|
||||||
text:
|
template:
|
||||||
font_select:
|
font_select:
|
||||||
name: "Font"
|
name: "Font"
|
||||||
description: "Select the font for the displayed text. Refer to the HASPone Font Reference above."
|
description: "Select the font for the displayed text. Refer to the HASPone Font Reference above."
|
||||||
@ -232,11 +232,11 @@ variables:
|
|||||||
trigger_entity: !input trigger_entity
|
trigger_entity: !input trigger_entity
|
||||||
text: !input template
|
text: !input template
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
selected_fgcolor: !input selected_fgcolor
|
selected_fgcolor: !input selected_fgcolor
|
||||||
selected_bgcolor: !input selected_bgcolor
|
selected_bgcolor: !input selected_bgcolor
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays text"
|
name: "HASPone p[x].b[y] displays text"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
@ -215,11 +215,11 @@ variables:
|
|||||||
haspbutton: !input haspbutton
|
haspbutton: !input haspbutton
|
||||||
text: !input text
|
text: !input text
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
selected_fgcolor: !input selected_fgcolor
|
selected_fgcolor: !input selected_fgcolor
|
||||||
selected_bgcolor: !input selected_bgcolor
|
selected_bgcolor: !input selected_bgcolor
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays a toggle button"
|
name: "HASPone p[x].b[y] displays a toggle button"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -268,6 +268,12 @@ blueprint:
|
|||||||
default: false
|
default: false
|
||||||
selector:
|
selector:
|
||||||
boolean:
|
boolean:
|
||||||
|
text_enable:
|
||||||
|
name: "Text enabled"
|
||||||
|
description: "Enable text, font, and colors. If disabled, no output will be sent to the button but the toggle actions will still be activated on press. Useful to combine with other blueprints that might place output on this button."
|
||||||
|
default: true
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
|
||||||
mode: parallel
|
mode: parallel
|
||||||
max_exceeded: silent
|
max_exceeded: silent
|
||||||
@ -294,12 +300,13 @@ variables:
|
|||||||
off_fgcolor: !input off_fgcolor
|
off_fgcolor: !input off_fgcolor
|
||||||
off_bgcolor: !input off_bgcolor
|
off_bgcolor: !input off_bgcolor
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
|
text_enable: !input text_enable
|
||||||
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
|
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
|
||||||
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
|
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
|
||||||
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
|
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
|
||||||
@ -429,6 +436,8 @@ action:
|
|||||||
or
|
or
|
||||||
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
|
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
|
||||||
-}}
|
-}}
|
||||||
|
|
||||||
|
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
@ -450,7 +459,7 @@ action:
|
|||||||
# Update display if our entity has changed state
|
# Update display if our entity has changed state
|
||||||
- conditions: # Update display if our entity has changed state
|
- conditions: # Update display if our entity has changed state
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == entity) }}'
|
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == entity) and (text_enable == true) }}'
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
@ -493,7 +502,7 @@ action:
|
|||||||
# Theme: Apply selected foreground color when it changes
|
# Theme: Apply selected foreground color when it changes
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.topic == selectedfgtopic }}"
|
value_template: "{{ (trigger.topic == selectedfgtopic) and (text_enable == true) }}"
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
@ -503,7 +512,7 @@ action:
|
|||||||
# Theme: Apply selected background color on change
|
# Theme: Apply selected background color on change
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.topic == selectedbgtopic }}"
|
value_template: "{{ (trigger.topic == selectedbgtopic) and (text_enable == true) }}"
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
@ -513,7 +522,7 @@ action:
|
|||||||
# Theme: Apply unselected foreground color on change
|
# Theme: Apply unselected foreground color on change
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.topic == unselectedfgtopic }}"
|
value_template: "{{ (trigger.topic == unselectedfgtopic) and (text_enable == true) }}"
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
@ -523,7 +532,7 @@ action:
|
|||||||
# Theme: Apply unselected background color on change
|
# Theme: Apply unselected background color on change
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.topic == unselectedbgtopic }}"
|
value_template: "{{ (trigger.topic == unselectedbgtopic) and (text_enable == true) }}"
|
||||||
sequence:
|
sequence:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the value of a given entity with icons and colors"
|
name: "HASPone p[x].b[y] displays the value of a given entity with icons and colors"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[8].b[9] The slider button on page 8 displays a volume control"
|
name: "HASPone p[8].b[9] The slider button on page 8 displays a volume control"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the current weather condition"
|
name: "HASPone p[x].b[y] displays the current weather condition"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -214,11 +214,11 @@ variables:
|
|||||||
haspbutton: !input haspbutton
|
haspbutton: !input haspbutton
|
||||||
weather_provider: !input weather_provider
|
weather_provider: !input weather_provider
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
wrap: !input wrap
|
wrap: !input wrap
|
||||||
selected_fgcolor: !input selected_fgcolor
|
selected_fgcolor: !input selected_fgcolor
|
||||||
selected_bgcolor: !input selected_bgcolor
|
selected_bgcolor: !input selected_bgcolor
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the current weather condition icon only"
|
name: "HASPone p[x].b[y] displays the current weather condition icon only"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -183,11 +183,11 @@ variables:
|
|||||||
haspbutton: !input haspbutton
|
haspbutton: !input haspbutton
|
||||||
weather_provider: !input weather_provider
|
weather_provider: !input weather_provider
|
||||||
font_select: !input font_select
|
font_select: !input font_select
|
||||||
font: '{{ font_select.split(" - ")[0] | int }}'
|
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
|
||||||
xcen_select: !input xcen_select
|
xcen_select: !input xcen_select
|
||||||
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
ycen_select: !input ycen_select
|
ycen_select: !input ycen_select
|
||||||
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
|
||||||
selected_fgcolor: !input selected_fgcolor
|
selected_fgcolor: !input selected_fgcolor
|
||||||
selected_bgcolor: !input selected_bgcolor
|
selected_bgcolor: !input selected_bgcolor
|
||||||
unselected_fgcolor: !input unselected_fgcolor
|
unselected_fgcolor: !input unselected_fgcolor
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the current weather condition with icons"
|
name: "HASPone p[x].b[y] displays the current weather condition with icons"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the weather forecast"
|
name: "HASPone p[x].b[y] displays the weather forecast"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
@ -120,19 +120,29 @@ blueprint:
|
|||||||
selector:
|
selector:
|
||||||
entity:
|
entity:
|
||||||
domain: weather
|
domain: weather
|
||||||
|
forecast_interval:
|
||||||
|
name: "Forecast interval"
|
||||||
|
description: 'Forecast interval, one of "hourly", "twice daily", or "daily". Not all weather providers will offer all options.'
|
||||||
|
default: "daily"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "hourly"
|
||||||
|
- "twice_daily"
|
||||||
|
- "daily"
|
||||||
forecast_index:
|
forecast_index:
|
||||||
name: "Forecast index"
|
name: "Forecast index"
|
||||||
description: 'Weather forecasts are provided at intervals determined by your weather source. The next time interval will be index "0". Increment this number for future forecasts'
|
description: 'Select a specific forecast, the next time interval will be index "0". Increment this number for future forecasts'
|
||||||
default: 0
|
default: 0
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
min: 0
|
min: 0
|
||||||
max: 10
|
max: 48
|
||||||
mode: slider
|
mode: slider
|
||||||
unit_of_measurement: index
|
unit_of_measurement: index
|
||||||
forecast_attribute:
|
forecast_attribute:
|
||||||
name: "Enter the desired forecast attribute"
|
name: "Enter the desired forecast attribute"
|
||||||
description: 'Type in the name of the desired forecast attribute for your provider. "condition" is a common attribute for many providers.'
|
description: 'Type in the name of the desired forecast attribute for your provider. "condition" is a common attribute for many providers.'
|
||||||
default: "condition"
|
default: "condition"
|
||||||
selector:
|
selector:
|
||||||
text:
|
text:
|
||||||
@ -243,6 +253,7 @@ variables:
|
|||||||
hasppage: !input hasppage
|
hasppage: !input hasppage
|
||||||
haspbutton: !input haspbutton
|
haspbutton: !input haspbutton
|
||||||
weather_provider: !input weather_provider
|
weather_provider: !input weather_provider
|
||||||
|
forecast_interval: !input forecast_interval
|
||||||
forecast_index: !input forecast_index
|
forecast_index: !input forecast_index
|
||||||
forecast_attribute: !input forecast_attribute
|
forecast_attribute: !input forecast_attribute
|
||||||
prefix: !input prefix
|
prefix: !input prefix
|
||||||
@ -261,15 +272,6 @@ variables:
|
|||||||
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
|
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
|
||||||
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
|
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
|
||||||
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
|
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
|
||||||
text: >-
|
|
||||||
{%- if prefix|lower != "none" -%}
|
|
||||||
{{ prefix }}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- if title_case -%}
|
|
||||||
{{ state_attr(weather_provider, "forecast")[forecast_index|int(default=0)].get(forecast_attribute)|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") | title }}
|
|
||||||
{%- else -%}
|
|
||||||
{{ state_attr(weather_provider, "forecast")[forecast_index|int(default=0)].get(forecast_attribute)|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") }}
|
|
||||||
{%- endif -%}
|
|
||||||
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
|
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
|
||||||
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
|
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
|
||||||
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
|
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
|
||||||
@ -380,6 +382,23 @@ condition:
|
|||||||
value_template: "{{ is_state(haspsensor, 'ON') }}"
|
value_template: "{{ is_state(haspsensor, 'ON') }}"
|
||||||
|
|
||||||
action:
|
action:
|
||||||
|
- service: weather.get_forecasts
|
||||||
|
target:
|
||||||
|
entity_id: !input weather_provider
|
||||||
|
data:
|
||||||
|
type: "{{forecast_interval}}"
|
||||||
|
response_variable: weather_forecast
|
||||||
|
- variables:
|
||||||
|
text: >-
|
||||||
|
{%- if prefix|lower != "none" -%}
|
||||||
|
{{ prefix }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if title_case -%}
|
||||||
|
{{ weather_forecast[weather_provider]['forecast'][forecast_index][forecast_attribute]|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") | title }}
|
||||||
|
{%- else -%}
|
||||||
|
{{ weather_forecast[weather_provider]['forecast'][forecast_index][forecast_attribute]|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
- choose:
|
- choose:
|
||||||
#########################################################################
|
#########################################################################
|
||||||
# Display attribute and apply text style when "RUN ACTIONS" is pressed by the user
|
# Display attribute and apply text style when "RUN ACTIONS" is pressed by the user
|
||||||
|
@ -0,0 +1,459 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "HASPone p[x].b[y] displays the weather forecast High and Low temperature"
|
||||||
|
description: |
|
||||||
|
|
||||||
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
A HASPone button displays the high and low temperatures from a selected weather forecast.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## HASPone Page and Button Reference
|
||||||
|
|
||||||
|
The images below show each available HASPone page along with the layout of available button objects.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| Page 0 | Pages 1-3 | Pages 4-5 |
|
||||||
|
|--------|-----------|-----------|
|
||||||
|
|  |  |  |
|
||||||
|
|
||||||
|
| Page 6 | Page 7 | Page 8 |
|
||||||
|
|--------|--------|--------|
|
||||||
|
|  |  |  |
|
||||||
|
|
||||||
|
| Page 9 | Page 10 | Page 11 |
|
||||||
|
|--------|---------|---------|
|
||||||
|
|  |  | 
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## HASPone Font Reference
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASPone project includes [Consolas](https://docs.microsoft.com/en-us/typography/font-list/consolas) monospace in 4 sizes, [Webdings](https://en.wikipedia.org/wiki/Webdings#Character_set) in 1 size, and [Google's "Noto Sans"](https://github.com/googlefonts/noto-fonts) proportional in 5 sizes
|
||||||
|
|
||||||
|
| Font | Name | Characters per line | Lines per button |
|
||||||
|
| :--- | :---------------- | :-------------------| :--------------- |
|
||||||
|
| 0 | Consolas 24 | 20 characters | 2 lines |
|
||||||
|
| 1 | Consolas 32 | 15 characters | 2 lines |
|
||||||
|
| 2 | Consolas 48 | 10 characters | 1 line |
|
||||||
|
| 3 | Consolas 80 | 6 characters | 1 line |
|
||||||
|
| 4 | Webdings 56 | 8 characters | 1 line |
|
||||||
|
| 5 | Noto Sans 24 | Proportional | 2 lines |
|
||||||
|
| 6 | Noto Sans 32 | Proportional | 2 lines |
|
||||||
|
| 7 | Noto Sans 48 | Proportional | 1 line |
|
||||||
|
| 8 | Noto Sans 64 | Proportional | 1 line |
|
||||||
|
| 9 | Noto Sans 80 | Proportional | 1 line |
|
||||||
|
| 10 | Noto Sans Bold 80 | Proportional | 1 line |
|
||||||
|
|
||||||
|
### Icons
|
||||||
|
|
||||||
|
Fonts 5-10 also include [1400+ icons which you can copy and paste from here](https://htmlpreview.github.io/?https://github.com/HASwitchPlate/HASPone/blob/main/images/hasp-fontawesome5.html)
|
||||||
|
|
||||||
|
### Font examples
|
||||||
|
|
||||||
|
  
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Nextion color codes
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
The Nextion environment utilizes RGB 565 encoding. [Use this handy convertor](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to select your colors and convert to the RGB 565 format.
|
||||||
|
|
||||||
|
Here are some example colors:
|
||||||
|
|
||||||
|
| Color | Code |
|
||||||
|
|--------|-------|
|
||||||
|
| White | 65535 |
|
||||||
|
| Black | 0 |
|
||||||
|
| Grey | 25388 |
|
||||||
|
| Red | 63488 |
|
||||||
|
| Green | 2016 |
|
||||||
|
| Blue | 31 |
|
||||||
|
| Yellow | 65504 |
|
||||||
|
| Orange | 64512 |
|
||||||
|
| Brown | 48192 |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
haspdevice:
|
||||||
|
name: "HASPone Device"
|
||||||
|
description: "Select the HASPone device"
|
||||||
|
selector:
|
||||||
|
device:
|
||||||
|
integration: mqtt
|
||||||
|
manufacturer: "HASwitchPlate"
|
||||||
|
model: "HASPone v1.0.0"
|
||||||
|
hasppage:
|
||||||
|
name: "HASPone Page"
|
||||||
|
description: "Select the HASPone page (1-11) for the forecast. Refer to the HASPone Page and Button reference above."
|
||||||
|
default: 1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 11
|
||||||
|
mode: slider
|
||||||
|
unit_of_measurement: page
|
||||||
|
haspbutton:
|
||||||
|
name: "HASPone Button"
|
||||||
|
description: "Select the HASPone button (4-15) for the forecast. Refer to the HASPone Page and Button reference above."
|
||||||
|
default: 4
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 4
|
||||||
|
max: 15
|
||||||
|
mode: slider
|
||||||
|
unit_of_measurement: button
|
||||||
|
weather_provider:
|
||||||
|
name: "Weather provider"
|
||||||
|
description: "Select the weather provider to obtain the forecast"
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: weather
|
||||||
|
forecast_interval:
|
||||||
|
name: "Forecast interval"
|
||||||
|
description: 'Forecast interval, one of "hourly", "twice daily", or "daily". Not all weather providers will offer all options.'
|
||||||
|
default: "daily"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "hourly"
|
||||||
|
- "twice_daily"
|
||||||
|
- "daily"
|
||||||
|
forecast_index:
|
||||||
|
name: "Forecast index"
|
||||||
|
description: 'Select a specific forecast, the next time interval will be index "0". Increment this number for future forecasts'
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 48
|
||||||
|
mode: slider
|
||||||
|
unit_of_measurement: index
|
||||||
|
font_select:
|
||||||
|
name: "Font"
|
||||||
|
description: "Select the font for the displayed text. You probably want to leave this as 10, refer to the HASPone Font Reference above."
|
||||||
|
default: "10 - Noto Sans Bold 80"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "0 - Consolas 24"
|
||||||
|
- "1 - Consolas 32"
|
||||||
|
- "2 - Consolas 48"
|
||||||
|
- "3 - Consolas 80"
|
||||||
|
- "4 - Webdings 56"
|
||||||
|
- "5 - Noto Sans 24"
|
||||||
|
- "6 - Noto Sans 32"
|
||||||
|
- "7 - Noto Sans 48"
|
||||||
|
- "8 - Noto Sans 64"
|
||||||
|
- "9 - Noto Sans 80"
|
||||||
|
- "10 - Noto Sans Bold 80"
|
||||||
|
xcen_select:
|
||||||
|
name: "Text horizontal alignment"
|
||||||
|
description: "Horizontal text alignment: 0=Left 1=Center 2=Right"
|
||||||
|
default: "1 - Centered"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "0 - Left aligned"
|
||||||
|
- "1 - Centered"
|
||||||
|
- "2 - Right aligned"
|
||||||
|
ycen_select:
|
||||||
|
name: "Text vertical alignment"
|
||||||
|
description: "Vertical text alignment: 0=Top 1=Center 2=Bottom"
|
||||||
|
default: "1 - Centered"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "0 - Top aligned"
|
||||||
|
- "1 - Centered"
|
||||||
|
- "2 - Bottom aligned"
|
||||||
|
wrap:
|
||||||
|
name: "Text wrap"
|
||||||
|
default: false
|
||||||
|
description: "Enable line-wrapping text if too long to fit in the button."
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
selected_fgcolor:
|
||||||
|
name: "Selected foreground color"
|
||||||
|
description: 'Selected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected foreground color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
selected_bgcolor:
|
||||||
|
name: "Selected background color"
|
||||||
|
description: 'Selected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected background color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
unselected_fgcolor:
|
||||||
|
name: "Unselected foreground color"
|
||||||
|
description: 'Unselected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected foreground color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
unselected_bgcolor:
|
||||||
|
name: "Unselected background color"
|
||||||
|
description: 'Unselected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected background color.'
|
||||||
|
default: -1
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -1
|
||||||
|
max: 65535
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
mode: parallel
|
||||||
|
max_exceeded: silent
|
||||||
|
|
||||||
|
variables:
|
||||||
|
haspdevice: !input haspdevice
|
||||||
|
haspname: >-
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
|
||||||
|
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
hasppage: !input hasppage
|
||||||
|
haspbutton: !input haspbutton
|
||||||
|
weather_provider: !input weather_provider
|
||||||
|
forecast_interval: !input forecast_interval
|
||||||
|
forecast_index: !input forecast_index
|
||||||
|
font_select: !input font_select
|
||||||
|
font: '{{ font_select.split(" - ")[0] | int }}'
|
||||||
|
xcen_select: !input xcen_select
|
||||||
|
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
|
||||||
|
ycen_select: !input ycen_select
|
||||||
|
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
|
||||||
|
wrap: !input wrap
|
||||||
|
selected_fgcolor: !input selected_fgcolor
|
||||||
|
selected_bgcolor: !input selected_bgcolor
|
||||||
|
unselected_fgcolor: !input unselected_fgcolor
|
||||||
|
unselected_bgcolor: !input unselected_bgcolor
|
||||||
|
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
|
||||||
|
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
|
||||||
|
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
|
||||||
|
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
|
||||||
|
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
|
||||||
|
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
|
||||||
|
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
|
||||||
|
selectedfg: >-
|
||||||
|
{%- if (selected_fgcolor|int) >= 0 -%}
|
||||||
|
{{ selected_fgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
selectedbg: >-
|
||||||
|
{%- if (selected_bgcolor|int) >= 0 -%}
|
||||||
|
{{ selected_bgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
unselectedfg: >-
|
||||||
|
{%- if (unselected_fgcolor|int) >= 0 -%}
|
||||||
|
{{ unselected_fgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
unselectedbg: >-
|
||||||
|
{%- if (unselected_bgcolor|int) >= 0 -%}
|
||||||
|
{{ unselected_bgcolor }}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set color = namespace() -%}
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
|
||||||
|
{%- set color.source=entity -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
|
||||||
|
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
|
||||||
|
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
|
||||||
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
trigger_variables:
|
||||||
|
haspdevice: !input haspdevice
|
||||||
|
haspname: >-
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
|
||||||
|
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
haspsensor: >-
|
||||||
|
{%- for entity in device_entities(haspdevice) -%}
|
||||||
|
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
|
||||||
|
{{ entity }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
|
||||||
|
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
|
||||||
|
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
|
||||||
|
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input weather_provider
|
||||||
|
- platform: template
|
||||||
|
value_template: "{{ is_state(haspsensor, 'ON') }}"
|
||||||
|
- platform: homeassistant
|
||||||
|
event: start
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{selectedfgtopic}}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{selectedbgtopic}}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{unselectedfgtopic}}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "{{unselectedbgtopic}}"
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_state(haspsensor, 'ON') }}"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- service: weather.get_forecasts
|
||||||
|
target:
|
||||||
|
entity_id: !input weather_provider
|
||||||
|
data:
|
||||||
|
type: "{{forecast_interval}}"
|
||||||
|
response_variable: weather_forecast
|
||||||
|
- variables:
|
||||||
|
temphigh: '{{ weather_forecast[weather_provider]["forecast"][forecast_index]["temperature"] }}'
|
||||||
|
templow: '{{ weather_forecast[weather_provider]["forecast"][forecast_index]["templow"] }}'
|
||||||
|
text: "{{templow|int(default=0)}}° {{temphigh|int(default=0)}}°"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
#########################################################################
|
||||||
|
# Display attribute and apply text style when "RUN ACTIONS" is pressed by the user
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{{-
|
||||||
|
(trigger is not defined)
|
||||||
|
or
|
||||||
|
(trigger.platform is none)
|
||||||
|
or
|
||||||
|
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
|
||||||
|
or
|
||||||
|
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
|
||||||
|
-}}
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{jsoncommandtopic}}"
|
||||||
|
payload: >-
|
||||||
|
[
|
||||||
|
"{{haspobject}}.font={{font}}",
|
||||||
|
"{{haspobject}}.xcen={{xcen}}",
|
||||||
|
"{{haspobject}}.ycen={{ycen}}",
|
||||||
|
"{{haspobject}}.isbr={{isbr}}",
|
||||||
|
"{{haspobject}}.pco={{selectedfg}}",
|
||||||
|
"{{haspobject}}.bco={{selectedbg}}",
|
||||||
|
"{{haspobject}}.pco2={{unselectedfg}}",
|
||||||
|
"{{haspobject}}.bco2={{unselectedbg}}",
|
||||||
|
"{{haspobject}}.txt=\"{{text}}\""
|
||||||
|
]
|
||||||
|
#########################################################################
|
||||||
|
# Update forecast if our weather provider changed state
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == weather_provider) }}'
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{commandtopic}}.txt"
|
||||||
|
payload: '"{{text}}"'
|
||||||
|
#########################################################################
|
||||||
|
# Catch triggers fired by incoming MQTT messages
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: '{{ trigger.platform == "mqtt" }}'
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply selected foreground color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == selectedfgtopic) and ((selected_fgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{commandtopic}}.pco"
|
||||||
|
payload: "{{trigger.payload}}"
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply selected background color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == selectedbgtopic) and ((selected_bgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{commandtopic}}.bco"
|
||||||
|
payload: "{{trigger.payload}}"
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply unselected foreground color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == unselectedfgtopic) and ((unselected_fgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{commandtopic}}.pco2"
|
||||||
|
payload: "{{trigger.payload}}"
|
||||||
|
#########################################################################
|
||||||
|
# Theme: Apply unselected background color on change
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (trigger.topic == unselectedbgtopic) and ((unselected_bgcolor|int) == -1) }}"
|
||||||
|
sequence:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "{{commandtopic}}.bco2"
|
||||||
|
payload: "{{trigger.payload}}"
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the current temperature from a weather provider, coloured icon only"
|
name: "HASPone p[x].b[y] displays the current temperature from a weather provider, coloured icon only"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ variables:
|
|||||||
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
|
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
|
||||||
temperature: '{{ state_attr(weather_provider, "temperature") }}'
|
temperature: '{{ state_attr(weather_provider, "temperature") }}'
|
||||||
icon: >-
|
icon: >-
|
||||||
{%- set temp = temperature|int -%}
|
{%- set temp = temperature|int(default=0) -%}
|
||||||
{%- if temp <= thermometer_quarter_threshold|int -%}
|
{%- if temp <= thermometer_quarter_threshold|int -%}
|
||||||
|
|
||||||
{%- elif temp < thermometer_half_threshold|int -%}
|
{%- elif temp < thermometer_half_threshold|int -%}
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] displays the current temperature from a weather provider with icon and colors"
|
name: "HASPone p[x].b[y] displays the current temperature from a weather provider with icon and colors"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
@ -224,10 +224,10 @@ variables:
|
|||||||
{%- if roundtemp == true -%}
|
{%- if roundtemp == true -%}
|
||||||
{{- state_attr(weather_provider, "temperature") | round(default=0) -}}
|
{{- state_attr(weather_provider, "temperature") | round(default=0) -}}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{{- state_attr(weather_provider, "temperature") -}}
|
{{- state_attr(weather_provider, "temperature") | float(default=0) -}}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
icon: >-
|
icon: >-
|
||||||
{%- set temp = temperature|int -%}
|
{%- set temp = temperature|int(default=0) -%}
|
||||||
{%- if temp <= thermometer_quarter_threshold|int -%}
|
{%- if temp <= thermometer_quarter_threshold|int -%}
|
||||||
|
|
||||||
{%- elif temp < thermometer_half_threshold|int -%}
|
{%- elif temp < thermometer_half_threshold|int -%}
|
||||||
@ -310,7 +310,7 @@ variables:
|
|||||||
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
|
||||||
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
|
||||||
tempcolor: >-
|
tempcolor: >-
|
||||||
{%- set temp = temperature|int -%}
|
{%- set temp = temperature|int(default=0) -%}
|
||||||
{%- if temp <= thermometer_quarter_threshold|int -%}
|
{%- if temp <= thermometer_quarter_threshold|int -%}
|
||||||
{%- set color = thermometer_empty_color -%}
|
{%- set color = thermometer_empty_color -%}
|
||||||
{%- elif temp < thermometer_half_threshold|int -%}
|
{%- elif temp < thermometer_half_threshold|int -%}
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone p[x].b[y] performs an action when pressed"
|
name: "HASPone p[x].b[y] performs an action when pressed"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone Remove MQTT discovery messages"
|
name: "HASPone Remove MQTT discovery messages"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone Theme Dark on Light"
|
name: "HASPone Theme Dark on Light"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone Theme Light on Dark Blue"
|
name: "HASPone Theme Light on Dark Blue"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ variables:
|
|||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
selected_foreground_brightness: "255"
|
selected_foreground_brightness: "255"
|
||||||
selected_foreground_color: "[255, 255, 255]"
|
selected_foreground_color: "[255, 255, 255]"
|
||||||
selected_background_brightness: "1"
|
selected_background_brightness: "32"
|
||||||
selected_background_color: "[0, 0, 255]"
|
selected_background_color: "[0, 0, 255]"
|
||||||
unselected_foreground_brightness: "224"
|
unselected_foreground_brightness: "224"
|
||||||
unselected_foreground_color: "[255, 255, 255]"
|
unselected_foreground_color: "[255, 255, 255]"
|
||||||
|
@ -2,7 +2,7 @@ blueprint:
|
|||||||
name: "HASPone Theme Light on Dark"
|
name: "HASPone Theme Light on Dark"
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
## Blueprint Version: `1.05.00`
|
## Blueprint Version: `1.06.00`
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
|
75
esphome/haspone.yaml
Normal file
75
esphome/haspone.yaml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# Example ESPhome configuration for use with the HASPone hardware
|
||||||
|
|
||||||
|
substitutions:
|
||||||
|
device_name: "haspone"
|
||||||
|
friendly_name: "HASPone hardware for ESPhome"
|
||||||
|
project_version: "0.0.1"
|
||||||
|
|
||||||
|
esphome:
|
||||||
|
name: ${device_name}
|
||||||
|
friendly_name: ${friendly_name}
|
||||||
|
comment: "http://haswitchplate.com"
|
||||||
|
project:
|
||||||
|
name: "esphome.${device_name}"
|
||||||
|
version: ${project_version}
|
||||||
|
on_boot:
|
||||||
|
then:
|
||||||
|
- switch.turn_on: switch_lcdpower # Power up the Nextion on boot
|
||||||
|
|
||||||
|
esp8266:
|
||||||
|
board: d1_mini
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
api:
|
||||||
|
|
||||||
|
ota:
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
|
||||||
|
web_server:
|
||||||
|
port: 80
|
||||||
|
|
||||||
|
# HASPone switch controls power to the Nextion. Set HIGH at power on to enable the device at boot.
|
||||||
|
switch:
|
||||||
|
- platform: gpio
|
||||||
|
id: switch_lcdpower
|
||||||
|
name: "${friendly_name} Nextion Power"
|
||||||
|
pin: D6 #GPIO12
|
||||||
|
restore_mode: ALWAYS_ON
|
||||||
|
internal: false
|
||||||
|
|
||||||
|
# UART for HASPone communication to Nextion. This will utilize software serial and might not work well for TFT updates.
|
||||||
|
uart:
|
||||||
|
id: uart_nextion
|
||||||
|
tx_pin: D4 #GPIO2
|
||||||
|
rx_pin: D7 #GPIO13
|
||||||
|
baud_rate: 115200
|
||||||
|
|
||||||
|
# Nextion display device
|
||||||
|
display:
|
||||||
|
- platform: nextion
|
||||||
|
id: display_nextion
|
||||||
|
uart_id: uart_nextion
|
||||||
|
on_touch:
|
||||||
|
then:
|
||||||
|
lambda: |-
|
||||||
|
ESP_LOGD("nextion.on_touch", "Nextion touch event detected!");
|
||||||
|
ESP_LOGD("nextion.on_touch", "Page Id: %i", page_id);
|
||||||
|
ESP_LOGD("nextion.on_touch", "Component Id: %i", component_id);
|
||||||
|
ESP_LOGD("nextion.on_touch", "Event type: %s", touch_event ? "Press" : "Release");
|
||||||
|
|
||||||
|
# Nextion backlight control
|
||||||
|
number:
|
||||||
|
- platform: template
|
||||||
|
id: number_brightness
|
||||||
|
name: "${friendly_name} Nextion Brightness"
|
||||||
|
min_value: 0
|
||||||
|
max_value: 100
|
||||||
|
step: 1
|
||||||
|
initial_value: 100
|
||||||
|
optimistic: true
|
||||||
|
set_action:
|
||||||
|
- lambda: id(display_nextion)->set_backlight_brightness(x/100);
|
3
esphome/readme.md
Normal file
3
esphome/readme.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# HASPone for ESPhome
|
||||||
|
|
||||||
|
Here you'll find an example ESPhome configuration for use with the HASPone hardware, this should be compatible with existing ESPhome-native Nextion projects for a 2.8" panel.
|
BIN
images/HASP PCB Back.png
Normal file
BIN
images/HASP PCB Back.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 149 KiB |
BIN
images/HASP PCB Front and Back.png
Normal file
BIN
images/HASP PCB Front and Back.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 279 KiB |
BIN
images/HASP PCB Front.png
Normal file
BIN
images/HASP PCB Front.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"d1_mini": {
|
"d1_mini": {
|
||||||
"version": "1.05",
|
"version": "1.06",
|
||||||
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Arduino_Sketch/HASwitchPlate.ino.d1_mini.bin"
|
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate.ino.d1_mini.bin"
|
||||||
},
|
},
|
||||||
"NX3224T024_011R": {
|
"NX3224T024_011R": {
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate.tft"
|
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate.tft"
|
||||||
},
|
},
|
||||||
"NX3224K024_011R": {
|
"NX3224K024_011R": {
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate-Enhanced.tft"
|
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate-Enhanced.tft"
|
||||||
},
|
},
|
||||||
"NX3224F024_011R": {
|
"NX3224F024_011R": {
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate-Discovery.tft"
|
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate-Discovery.tft"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user