mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 22:48:10 +01:00
Create base touchscreen component and refactor ektf2232 (#3083)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
parent
3a62455948
commit
ef832becf1
16 changed files with 224 additions and 159 deletions
|
@ -188,6 +188,7 @@ esphome/components/tmp102/* @timsavage
|
||||||
esphome/components/tmp117/* @Azimath
|
esphome/components/tmp117/* @Azimath
|
||||||
esphome/components/tof10120/* @wstrzalka
|
esphome/components/tof10120/* @wstrzalka
|
||||||
esphome/components/toshiba/* @kbx81
|
esphome/components/toshiba/* @kbx81
|
||||||
|
esphome/components/touchscreen/* @jesserockz
|
||||||
esphome/components/tsl2591/* @wjcarpenter
|
esphome/components/tsl2591/* @wjcarpenter
|
||||||
esphome/components/tuya/binary_sensor/* @jesserockz
|
esphome/components/tuya/binary_sensor/* @jesserockz
|
||||||
esphome/components/tuya/climate/* @jesserockz
|
esphome/components/tuya/climate/* @jesserockz
|
||||||
|
|
|
@ -341,15 +341,15 @@ class DisplayBuffer {
|
||||||
// Internal method to set display auto clearing.
|
// Internal method to set display auto clearing.
|
||||||
void set_auto_clear(bool auto_clear_enabled) { this->auto_clear_enabled_ = auto_clear_enabled; }
|
void set_auto_clear(bool auto_clear_enabled) { this->auto_clear_enabled_ = auto_clear_enabled; }
|
||||||
|
|
||||||
|
virtual int get_height_internal() = 0;
|
||||||
|
virtual int get_width_internal() = 0;
|
||||||
|
DisplayRotation get_rotation() const { return this->rotation_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void vprintf_(int x, int y, Font *font, Color color, TextAlign align, const char *format, va_list arg);
|
void vprintf_(int x, int y, Font *font, Color color, TextAlign align, const char *format, va_list arg);
|
||||||
|
|
||||||
virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
|
virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
|
||||||
|
|
||||||
virtual int get_height_internal() = 0;
|
|
||||||
|
|
||||||
virtual int get_width_internal() = 0;
|
|
||||||
|
|
||||||
void init_internal_(uint32_t buffer_length);
|
void init_internal_(uint32_t buffer_length);
|
||||||
|
|
||||||
void do_update_();
|
void do_update_();
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
|
|
||||||
from esphome import pins, automation
|
|
||||||
from esphome.components import i2c
|
|
||||||
from esphome.const import CONF_HEIGHT, CONF_ID, CONF_ROTATION, CONF_WIDTH
|
|
||||||
|
|
||||||
CODEOWNERS = ["@jesserockz"]
|
|
||||||
DEPENDENCIES = ["i2c"]
|
|
||||||
|
|
||||||
ektf2232_ns = cg.esphome_ns.namespace("ektf2232")
|
|
||||||
EKTF2232Touchscreen = ektf2232_ns.class_(
|
|
||||||
"EKTF2232Touchscreen", cg.Component, i2c.I2CDevice
|
|
||||||
)
|
|
||||||
TouchPoint = ektf2232_ns.struct("TouchPoint")
|
|
||||||
TouchListener = ektf2232_ns.class_("TouchListener")
|
|
||||||
|
|
||||||
EKTF2232Rotation = ektf2232_ns.enum("EKTF2232Rotation")
|
|
||||||
|
|
||||||
CONF_EKTF2232_ID = "ektf2232_id"
|
|
||||||
CONF_INTERRUPT_PIN = "interrupt_pin"
|
|
||||||
CONF_RTS_PIN = "rts_pin"
|
|
||||||
CONF_ON_TOUCH = "on_touch"
|
|
||||||
|
|
||||||
ROTATIONS = {
|
|
||||||
0: EKTF2232Rotation.ROTATE_0_DEGREES,
|
|
||||||
90: EKTF2232Rotation.ROTATE_90_DEGREES,
|
|
||||||
180: EKTF2232Rotation.ROTATE_180_DEGREES,
|
|
||||||
270: EKTF2232Rotation.ROTATE_270_DEGREES,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def validate_rotation(value):
|
|
||||||
value = cv.string(value)
|
|
||||||
if value.endswith("°"):
|
|
||||||
value = value[:-1]
|
|
||||||
return cv.enum(ROTATIONS, int=True)(value)
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
|
||||||
cv.Schema(
|
|
||||||
{
|
|
||||||
cv.GenerateID(): cv.declare_id(EKTF2232Touchscreen),
|
|
||||||
cv.Required(CONF_INTERRUPT_PIN): cv.All(
|
|
||||||
pins.internal_gpio_input_pin_schema
|
|
||||||
),
|
|
||||||
cv.Required(CONF_RTS_PIN): pins.gpio_output_pin_schema,
|
|
||||||
cv.Optional(CONF_HEIGHT, default=758): cv.int_,
|
|
||||||
cv.Optional(CONF_WIDTH, default=1024): cv.int_,
|
|
||||||
cv.Optional(CONF_ROTATION, default=0): validate_rotation,
|
|
||||||
cv.Optional(CONF_ON_TOUCH): automation.validate_automation(single=True),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.extend(i2c.i2c_device_schema(0x15))
|
|
||||||
.extend(cv.COMPONENT_SCHEMA)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
|
||||||
await cg.register_component(var, config)
|
|
||||||
await i2c.register_i2c_device(var, config)
|
|
||||||
|
|
||||||
interrupt_pin = await cg.gpio_pin_expression(config[CONF_INTERRUPT_PIN])
|
|
||||||
cg.add(var.set_interrupt_pin(interrupt_pin))
|
|
||||||
rts_pin = await cg.gpio_pin_expression(config[CONF_RTS_PIN])
|
|
||||||
cg.add(var.set_rts_pin(rts_pin))
|
|
||||||
|
|
||||||
cg.add(
|
|
||||||
var.set_display_details(
|
|
||||||
config[CONF_WIDTH],
|
|
||||||
config[CONF_HEIGHT],
|
|
||||||
config[CONF_ROTATION],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_ON_TOUCH in config:
|
|
||||||
await automation.build_automation(
|
|
||||||
var.get_touch_trigger(), [(TouchPoint, "touch")], config[CONF_ON_TOUCH]
|
|
||||||
)
|
|
|
@ -111,10 +111,7 @@ void EKTF2232Touchscreen::loop() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGV(TAG, "Touch %d: (x=%d, y=%d)", i, tp.x, tp.y);
|
this->defer([this, tp]() { this->send_touch_(tp); });
|
||||||
this->touch_trigger_->trigger(tp);
|
|
||||||
for (auto *listener : this->touch_listeners_)
|
|
||||||
listener->touch(tp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esphome/components/i2c/i2c.h"
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/components/touchscreen/touchscreen.h"
|
||||||
#include "esphome/core/automation.h"
|
#include "esphome/core/automation.h"
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
@ -15,25 +16,9 @@ struct EKTF2232TouchscreenStore {
|
||||||
static void gpio_intr(EKTF2232TouchscreenStore *store);
|
static void gpio_intr(EKTF2232TouchscreenStore *store);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TouchPoint {
|
using namespace touchscreen;
|
||||||
uint16_t x;
|
|
||||||
uint16_t y;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TouchListener {
|
class EKTF2232Touchscreen : public Touchscreen, public Component, public i2c::I2CDevice {
|
||||||
public:
|
|
||||||
virtual void touch(TouchPoint tp) = 0;
|
|
||||||
virtual void release();
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EKTF2232Rotation : uint8_t {
|
|
||||||
ROTATE_0_DEGREES = 0,
|
|
||||||
ROTATE_90_DEGREES,
|
|
||||||
ROTATE_180_DEGREES,
|
|
||||||
ROTATE_270_DEGREES,
|
|
||||||
};
|
|
||||||
|
|
||||||
class EKTF2232Touchscreen : public Component, public i2c::I2CDevice {
|
|
||||||
public:
|
public:
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
@ -42,19 +27,9 @@ class EKTF2232Touchscreen : public Component, public i2c::I2CDevice {
|
||||||
void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
|
void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
|
||||||
void set_rts_pin(GPIOPin *pin) { this->rts_pin_ = pin; }
|
void set_rts_pin(GPIOPin *pin) { this->rts_pin_ = pin; }
|
||||||
|
|
||||||
void set_display_details(uint16_t width, uint16_t height, EKTF2232Rotation rotation) {
|
|
||||||
this->display_width_ = width;
|
|
||||||
this->display_height_ = height;
|
|
||||||
this->rotation_ = rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_power_state(bool enable);
|
void set_power_state(bool enable);
|
||||||
bool get_power_state();
|
bool get_power_state();
|
||||||
|
|
||||||
Trigger<TouchPoint> *get_touch_trigger() const { return this->touch_trigger_; }
|
|
||||||
|
|
||||||
void register_listener(TouchListener *listener) { this->touch_listeners_.push_back(listener); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void hard_reset_();
|
void hard_reset_();
|
||||||
bool soft_reset_();
|
bool soft_reset_();
|
||||||
|
@ -64,12 +39,6 @@ class EKTF2232Touchscreen : public Component, public i2c::I2CDevice {
|
||||||
EKTF2232TouchscreenStore store_;
|
EKTF2232TouchscreenStore store_;
|
||||||
uint16_t x_resolution_;
|
uint16_t x_resolution_;
|
||||||
uint16_t y_resolution_;
|
uint16_t y_resolution_;
|
||||||
|
|
||||||
uint16_t display_width_;
|
|
||||||
uint16_t display_height_;
|
|
||||||
EKTF2232Rotation rotation_;
|
|
||||||
Trigger<TouchPoint> *touch_trigger_ = new Trigger<TouchPoint>();
|
|
||||||
std::vector<TouchListener *> touch_listeners_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ektf2232
|
} // namespace ektf2232
|
||||||
|
|
48
esphome/components/ektf2232/touchscreen.py
Normal file
48
esphome/components/ektf2232/touchscreen.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import i2c, touchscreen
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
|
||||||
|
ektf2232_ns = cg.esphome_ns.namespace("ektf2232")
|
||||||
|
EKTF2232Touchscreen = ektf2232_ns.class_(
|
||||||
|
"EKTF2232Touchscreen",
|
||||||
|
touchscreen.Touchscreen,
|
||||||
|
cg.Component,
|
||||||
|
i2c.I2CDevice,
|
||||||
|
)
|
||||||
|
|
||||||
|
CONF_EKTF2232_ID = "ektf2232_id"
|
||||||
|
CONF_INTERRUPT_PIN = "interrupt_pin"
|
||||||
|
CONF_RTS_PIN = "rts_pin"
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(EKTF2232Touchscreen),
|
||||||
|
cv.Required(CONF_INTERRUPT_PIN): cv.All(
|
||||||
|
pins.internal_gpio_input_pin_schema
|
||||||
|
),
|
||||||
|
cv.Required(CONF_RTS_PIN): pins.gpio_output_pin_schema,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(i2c.i2c_device_schema(0x15))
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await i2c.register_i2c_device(var, config)
|
||||||
|
await touchscreen.register_touchscreen(var, config)
|
||||||
|
|
||||||
|
interrupt_pin = await cg.gpio_pin_expression(config[CONF_INTERRUPT_PIN])
|
||||||
|
cg.add(var.set_interrupt_pin(interrupt_pin))
|
||||||
|
rts_pin = await cg.gpio_pin_expression(config[CONF_RTS_PIN])
|
||||||
|
cg.add(var.set_rts_pin(rts_pin))
|
39
esphome/components/touchscreen/__init__.py
Normal file
39
esphome/components/touchscreen/__init__.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
from esphome.components import display
|
||||||
|
from esphome import automation
|
||||||
|
from esphome.const import CONF_ON_TOUCH
|
||||||
|
|
||||||
|
CODEOWNERS = ["@jesserockz"]
|
||||||
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
|
touchscreen_ns = cg.esphome_ns.namespace("touchscreen")
|
||||||
|
|
||||||
|
Touchscreen = touchscreen_ns.class_("Touchscreen")
|
||||||
|
TouchRotation = touchscreen_ns.enum("TouchRotation")
|
||||||
|
TouchPoint = touchscreen_ns.struct("TouchPoint")
|
||||||
|
TouchListener = touchscreen_ns.class_("TouchListener")
|
||||||
|
|
||||||
|
CONF_DISPLAY = "display"
|
||||||
|
CONF_TOUCHSCREEN_ID = "touchscreen_id"
|
||||||
|
|
||||||
|
|
||||||
|
TOUCHSCREEN_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_DISPLAY): cv.use_id(display.DisplayBuffer),
|
||||||
|
cv.Optional(CONF_ON_TOUCH): automation.validate_automation(single=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def register_touchscreen(var, config):
|
||||||
|
disp = await cg.get_variable(config[CONF_DISPLAY])
|
||||||
|
cg.add(var.set_display(disp))
|
||||||
|
|
||||||
|
if CONF_ON_TOUCH in config:
|
||||||
|
await automation.build_automation(
|
||||||
|
var.get_touch_trigger(),
|
||||||
|
[(TouchPoint, "touch")],
|
||||||
|
config[CONF_ON_TOUCH],
|
||||||
|
)
|
|
@ -4,12 +4,12 @@ import esphome.config_validation as cv
|
||||||
from esphome.components import binary_sensor
|
from esphome.components import binary_sensor
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
from .. import ektf2232_ns, CONF_EKTF2232_ID, EKTF2232Touchscreen, TouchListener
|
from .. import touchscreen_ns, CONF_TOUCHSCREEN_ID, Touchscreen, TouchListener
|
||||||
|
|
||||||
DEPENDENCIES = ["ektf2232"]
|
DEPENDENCIES = ["touchscreen"]
|
||||||
|
|
||||||
EKTF2232Button = ektf2232_ns.class_(
|
TouchscreenBinarySensor = touchscreen_ns.class_(
|
||||||
"EKTF2232Button", binary_sensor.BinarySensor, TouchListener
|
"TouchscreenBinarySensor", binary_sensor.BinarySensor, TouchListener
|
||||||
)
|
)
|
||||||
|
|
||||||
CONF_X_MIN = "x_min"
|
CONF_X_MIN = "x_min"
|
||||||
|
@ -32,8 +32,8 @@ def validate_coords(config):
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(EKTF2232Button),
|
cv.GenerateID(): cv.declare_id(TouchscreenBinarySensor),
|
||||||
cv.GenerateID(CONF_EKTF2232_ID): cv.use_id(EKTF2232Touchscreen),
|
cv.GenerateID(CONF_TOUCHSCREEN_ID): cv.use_id(Touchscreen),
|
||||||
cv.Required(CONF_X_MIN): cv.int_range(min=0, max=2000),
|
cv.Required(CONF_X_MIN): cv.int_range(min=0, max=2000),
|
||||||
cv.Required(CONF_X_MAX): cv.int_range(min=0, max=2000),
|
cv.Required(CONF_X_MAX): cv.int_range(min=0, max=2000),
|
||||||
cv.Required(CONF_Y_MIN): cv.int_range(min=0, max=2000),
|
cv.Required(CONF_Y_MIN): cv.int_range(min=0, max=2000),
|
||||||
|
@ -47,7 +47,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await binary_sensor.register_binary_sensor(var, config)
|
await binary_sensor.register_binary_sensor(var, config)
|
||||||
hub = await cg.get_variable(config[CONF_EKTF2232_ID])
|
hub = await cg.get_variable(config[CONF_TOUCHSCREEN_ID])
|
||||||
cg.add(
|
cg.add(
|
||||||
var.set_area(
|
var.set_area(
|
||||||
config[CONF_X_MIN],
|
config[CONF_X_MIN],
|
|
@ -1,9 +1,9 @@
|
||||||
#include "ektf2232_binary_sensor.h"
|
#include "touchscreen_binary_sensor.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ektf2232 {
|
namespace touchscreen {
|
||||||
|
|
||||||
void EKTF2232Button::touch(TouchPoint tp) {
|
void TouchscreenBinarySensor::touch(TouchPoint tp) {
|
||||||
bool touched = (tp.x >= this->x_min_ && tp.x <= this->x_max_ && tp.y >= this->y_min_ && tp.y <= this->y_max_);
|
bool touched = (tp.x >= this->x_min_ && tp.x <= this->x_max_ && tp.y >= this->y_min_ && tp.y <= this->y_max_);
|
||||||
|
|
||||||
if (touched) {
|
if (touched) {
|
||||||
|
@ -13,7 +13,7 @@ void EKTF2232Button::touch(TouchPoint tp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EKTF2232Button::release() { this->publish_state(false); }
|
void TouchscreenBinarySensor::release() { this->publish_state(false); }
|
||||||
|
|
||||||
} // namespace ektf2232
|
} // namespace touchscreen
|
||||||
} // namespace esphome
|
} // namespace esphome
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../ektf2232.h"
|
#include "esphome/components/touchscreen/touchscreen.h"
|
||||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ektf2232 {
|
namespace touchscreen {
|
||||||
|
|
||||||
class EKTF2232Button : public binary_sensor::BinarySensor, public TouchListener {
|
class TouchscreenBinarySensor : public binary_sensor::BinarySensor, public TouchListener {
|
||||||
public:
|
public:
|
||||||
/// Set the touch screen area where the button will detect the touch.
|
/// Set the touch screen area where the button will detect the touch.
|
||||||
void set_area(int16_t x_min, int16_t x_max, int16_t y_min, int16_t y_max) {
|
void set_area(int16_t x_min, int16_t x_max, int16_t y_min, int16_t y_max) {
|
||||||
|
@ -23,5 +23,5 @@ class EKTF2232Button : public binary_sensor::BinarySensor, public TouchListener
|
||||||
int16_t x_min_, x_max_, y_min_, y_max_;
|
int16_t x_min_, x_max_, y_min_, y_max_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ektf2232
|
} // namespace touchscreen
|
||||||
} // namespace esphome
|
} // namespace esphome
|
18
esphome/components/touchscreen/touchscreen.cpp
Normal file
18
esphome/components/touchscreen/touchscreen.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include "touchscreen.h"
|
||||||
|
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace touchscreen {
|
||||||
|
|
||||||
|
static const char *const TAG = "touchscreen";
|
||||||
|
|
||||||
|
void Touchscreen::send_touch_(TouchPoint tp) {
|
||||||
|
ESP_LOGV(TAG, "Touch (x=%d, y=%d)", tp.x, tp.y);
|
||||||
|
this->touch_trigger_.trigger(tp);
|
||||||
|
for (auto *listener : this->touch_listeners_)
|
||||||
|
listener->touch(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace touchscreen
|
||||||
|
} // namespace esphome
|
58
esphome/components/touchscreen/touchscreen.h
Normal file
58
esphome/components/touchscreen/touchscreen.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
#include "esphome/core/automation.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace touchscreen {
|
||||||
|
|
||||||
|
struct TouchPoint {
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t state;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TouchListener {
|
||||||
|
public:
|
||||||
|
virtual void touch(TouchPoint tp) = 0;
|
||||||
|
virtual void release() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TouchRotation {
|
||||||
|
ROTATE_0_DEGREES = 0,
|
||||||
|
ROTATE_90_DEGREES = 90,
|
||||||
|
ROTATE_180_DEGREES = 180,
|
||||||
|
ROTATE_270_DEGREES = 270,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Touchscreen {
|
||||||
|
public:
|
||||||
|
void set_display(display::DisplayBuffer *display) {
|
||||||
|
this->display_ = display;
|
||||||
|
this->display_width_ = display->get_width_internal();
|
||||||
|
this->display_height_ = display->get_height_internal();
|
||||||
|
this->rotation_ = static_cast<TouchRotation>(display->get_rotation());
|
||||||
|
}
|
||||||
|
|
||||||
|
Trigger<TouchPoint> *get_touch_trigger() { return &this->touch_trigger_; }
|
||||||
|
|
||||||
|
void register_listener(TouchListener *listener) { this->touch_listeners_.push_back(listener); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Call this function to send touch points to the `on_touch` listener and the binary_sensors.
|
||||||
|
void send_touch_(TouchPoint tp);
|
||||||
|
|
||||||
|
uint16_t display_width_;
|
||||||
|
uint16_t display_height_;
|
||||||
|
display::DisplayBuffer *display_;
|
||||||
|
TouchRotation rotation_;
|
||||||
|
Trigger<TouchPoint> touch_trigger_;
|
||||||
|
std::vector<TouchListener *> touch_listeners_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace touchscreen
|
||||||
|
} // namespace esphome
|
|
@ -439,6 +439,7 @@ CONF_ON_TAG = "on_tag"
|
||||||
CONF_ON_TAG_REMOVED = "on_tag_removed"
|
CONF_ON_TAG_REMOVED = "on_tag_removed"
|
||||||
CONF_ON_TIME = "on_time"
|
CONF_ON_TIME = "on_time"
|
||||||
CONF_ON_TIME_SYNC = "on_time_sync"
|
CONF_ON_TIME_SYNC = "on_time_sync"
|
||||||
|
CONF_ON_TOUCH = "on_touch"
|
||||||
CONF_ON_TURN_OFF = "on_turn_off"
|
CONF_ON_TURN_OFF = "on_turn_off"
|
||||||
CONF_ON_TURN_ON = "on_turn_on"
|
CONF_ON_TURN_ON = "on_turn_on"
|
||||||
CONF_ON_VALUE = "on_value"
|
CONF_ON_VALUE = "on_value"
|
||||||
|
|
|
@ -20,7 +20,7 @@ def find_all(a_str, sub):
|
||||||
# Optimization: If str is not in whole text, then do not try
|
# Optimization: If str is not in whole text, then do not try
|
||||||
# on each line
|
# on each line
|
||||||
return
|
return
|
||||||
for i, line in enumerate(a_str.split('\n')):
|
for i, line in enumerate(a_str.split("\n")):
|
||||||
column = 0
|
column = 0
|
||||||
while True:
|
while True:
|
||||||
column = line.find(sub, column)
|
column = line.find(sub, column)
|
||||||
|
@ -592,6 +592,8 @@ def lint_inclusive_language(fname, match):
|
||||||
include=["*.h", "*.tcc"],
|
include=["*.h", "*.tcc"],
|
||||||
exclude=[
|
exclude=[
|
||||||
"esphome/components/binary_sensor/binary_sensor.h",
|
"esphome/components/binary_sensor/binary_sensor.h",
|
||||||
|
"esphome/components/button/button.h",
|
||||||
|
"esphome/components/climate/climate.h",
|
||||||
"esphome/components/cover/cover.h",
|
"esphome/components/cover/cover.h",
|
||||||
"esphome/components/display/display_buffer.h",
|
"esphome/components/display/display_buffer.h",
|
||||||
"esphome/components/fan/fan.h",
|
"esphome/components/fan/fan.h",
|
||||||
|
@ -606,8 +608,6 @@ def lint_inclusive_language(fname, match):
|
||||||
"esphome/components/stepper/stepper.h",
|
"esphome/components/stepper/stepper.h",
|
||||||
"esphome/components/switch/switch.h",
|
"esphome/components/switch/switch.h",
|
||||||
"esphome/components/text_sensor/text_sensor.h",
|
"esphome/components/text_sensor/text_sensor.h",
|
||||||
"esphome/components/climate/climate.h",
|
|
||||||
"esphome/components/button/button.h",
|
|
||||||
"esphome/core/component.h",
|
"esphome/core/component.h",
|
||||||
"esphome/core/gpio.h",
|
"esphome/core/gpio.h",
|
||||||
"esphome/core/log.h",
|
"esphome/core/log.h",
|
||||||
|
@ -666,7 +666,10 @@ run_checks(LINT_POST_CHECKS, "POST")
|
||||||
for f, errs in sorted(errors.items()):
|
for f, errs in sorted(errors.items()):
|
||||||
bold = functools.partial(styled, colorama.Style.BRIGHT)
|
bold = functools.partial(styled, colorama.Style.BRIGHT)
|
||||||
bold_red = functools.partial(styled, (colorama.Style.BRIGHT, colorama.Fore.RED))
|
bold_red = functools.partial(styled, (colorama.Style.BRIGHT, colorama.Fore.RED))
|
||||||
err_str = (f"{bold(f'{f}:{lineno}:{col}:')} {bold_red('lint:')} {msg}\n" for lineno, col, msg in errs)
|
err_str = (
|
||||||
|
f"{bold(f'{f}:{lineno}:{col}:')} {bold_red('lint:')} {msg}\n"
|
||||||
|
for lineno, col, msg in errs
|
||||||
|
)
|
||||||
print_error_for_file(f, "\n".join(err_str))
|
print_error_for_file(f, "\n".join(err_str))
|
||||||
|
|
||||||
if args.print_slowest:
|
if args.print_slowest:
|
||||||
|
|
|
@ -313,7 +313,7 @@ binary_sensor:
|
||||||
then:
|
then:
|
||||||
- lambda: 'ESP_LOGI("ar1:", "%d", x);'
|
- lambda: 'ESP_LOGI("ar1:", "%d", x);'
|
||||||
- platform: xpt2046
|
- platform: xpt2046
|
||||||
xpt2046_id: touchscreen
|
xpt2046_id: xpt_touchscreen
|
||||||
id: touch_key0
|
id: touch_key0
|
||||||
x_min: 80
|
x_min: 80
|
||||||
x_max: 160
|
x_max: 160
|
||||||
|
@ -327,6 +327,16 @@ binary_sensor:
|
||||||
sx1509: sx1509_hub
|
sx1509: sx1509_hub
|
||||||
number: 3
|
number: 3
|
||||||
|
|
||||||
|
- platform: touchscreen
|
||||||
|
id: touch_key1
|
||||||
|
x_min: 0
|
||||||
|
x_max: 100
|
||||||
|
y_min: 0
|
||||||
|
y_max: 100
|
||||||
|
on_press:
|
||||||
|
- logger.log: "Touched"
|
||||||
|
|
||||||
|
|
||||||
climate:
|
climate:
|
||||||
- platform: tuya
|
- platform: tuya
|
||||||
id: tuya_climate
|
id: tuya_climate
|
||||||
|
@ -509,7 +519,7 @@ external_components:
|
||||||
- source: ../esphome/components
|
- source: ../esphome/components
|
||||||
components: ["sntp"]
|
components: ["sntp"]
|
||||||
xpt2046:
|
xpt2046:
|
||||||
id: touchscreen
|
id: xpt_touchscreen
|
||||||
cs_pin: 17
|
cs_pin: 17
|
||||||
irq_pin: 16
|
irq_pin: 16
|
||||||
update_interval: 50ms
|
update_interval: 50ms
|
||||||
|
@ -526,12 +536,12 @@ xpt2046:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
ESP_LOGI("main", "args x=%d, y=%d, touched=%s", x, y, (touched ? "touch" : "release"));
|
ESP_LOGI("main", "args x=%d, y=%d, touched=%s", x, y, (touched ? "touch" : "release"));
|
||||||
ESP_LOGI("main", "member x=%d, y=%d, touched=%d, x_raw=%d, y_raw=%d, z_raw=%d",
|
ESP_LOGI("main", "member x=%d, y=%d, touched=%d, x_raw=%d, y_raw=%d, z_raw=%d",
|
||||||
id(touchscreen).x,
|
id(xpt_touchscreen).x,
|
||||||
id(touchscreen).y,
|
id(xpt_touchscreen).y,
|
||||||
(int) id(touchscreen).touched,
|
(int) id(xpt_touchscreen).touched,
|
||||||
id(touchscreen).x_raw,
|
id(xpt_touchscreen).x_raw,
|
||||||
id(touchscreen).y_raw,
|
id(xpt_touchscreen).y_raw,
|
||||||
id(touchscreen).z_raw
|
id(xpt_touchscreen).z_raw
|
||||||
);
|
);
|
||||||
|
|
||||||
button:
|
button:
|
||||||
|
@ -541,3 +551,13 @@ button:
|
||||||
name: Safe Mode Button
|
name: Safe Mode Button
|
||||||
- platform: shutdown
|
- platform: shutdown
|
||||||
name: Shutdown Button
|
name: Shutdown Button
|
||||||
|
|
||||||
|
touchscreen:
|
||||||
|
- platform: ektf2232
|
||||||
|
interrupt_pin: GPIO36
|
||||||
|
rts_pin: GPIO5
|
||||||
|
display: inkplate_display
|
||||||
|
on_touch:
|
||||||
|
- logger.log:
|
||||||
|
format: Touch at (%d, %d)
|
||||||
|
args: ["touch.x", "touch.y"]
|
||||||
|
|
|
@ -231,12 +231,3 @@ switch:
|
||||||
register_type: coil
|
register_type: coil
|
||||||
address: 2
|
address: 2
|
||||||
bitmask: 1
|
bitmask: 1
|
||||||
|
|
||||||
ektf2232:
|
|
||||||
interrupt_pin: GPIO36
|
|
||||||
rts_pin: GPIO5
|
|
||||||
rotation: 90
|
|
||||||
on_touch:
|
|
||||||
- logger.log:
|
|
||||||
format: Touch at (%d, %d)
|
|
||||||
args: ["touch.x", "touch.y"]
|
|
||||||
|
|
Loading…
Reference in a new issue