mirror of
https://github.com/esphome/esphome.git
synced 2025-09-17 18:52:19 +01:00
Add qr code support for displays (#2952)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
committed by
GitHub
parent
ef832becf1
commit
a718ac7ee0
41
esphome/components/qr_code/__init__.py
Normal file
41
esphome/components/qr_code/__init__.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import CONF_ID, CONF_VALUE
|
||||
|
||||
CONF_SCALE = "scale"
|
||||
CONF_ECC = "ecc"
|
||||
|
||||
CODEOWNERS = ["@wjtje"]
|
||||
|
||||
DEPENDENCIES = ["display"]
|
||||
MULTI_CONF = True
|
||||
|
||||
qr_code_ns = cg.esphome_ns.namespace("qr_code")
|
||||
QRCode = qr_code_ns.class_("QrCode", cg.Component)
|
||||
|
||||
qrcodegen_Ecc = cg.esphome_ns.enum("qrcodegen_Ecc")
|
||||
ECC = {
|
||||
"LOW": qrcodegen_Ecc.qrcodegen_Ecc_LOW,
|
||||
"MEDIUM": qrcodegen_Ecc.qrcodegen_Ecc_MEDIUM,
|
||||
"QUARTILE": qrcodegen_Ecc.qrcodegen_Ecc_QUARTILE,
|
||||
"HIGH": qrcodegen_Ecc.qrcodegen_Ecc_HIGH,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(QRCode),
|
||||
cv.Required(CONF_VALUE): cv.string,
|
||||
cv.Optional(CONF_ECC, default="LOW"): cv.enum(ECC, upper=True),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
cg.add_library("wjtje/qr-code-generator-library", "^1.7.0")
|
||||
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
cg.add(var.set_value(config[CONF_VALUE]))
|
||||
cg.add(var.set_ecc(ECC[config[CONF_ECC]]))
|
||||
await cg.register_component(var, config)
|
||||
|
||||
cg.add_define("USE_QR_CODE")
|
55
esphome/components/qr_code/qr_code.cpp
Normal file
55
esphome/components/qr_code/qr_code.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "qr_code.h"
|
||||
#include "esphome/components/display/display_buffer.h"
|
||||
#include "esphome/core/color.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace qr_code {
|
||||
|
||||
static const char *const TAG = "qr_code";
|
||||
|
||||
void QrCode::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "QR code:");
|
||||
ESP_LOGCONFIG(TAG, " Value: '%s'", this->value_.c_str());
|
||||
}
|
||||
|
||||
void QrCode::set_value(const std::string &value) {
|
||||
this->value_ = value;
|
||||
this->needs_update_ = true;
|
||||
}
|
||||
|
||||
void QrCode::set_ecc(qrcodegen_Ecc ecc) {
|
||||
this->ecc_ = ecc;
|
||||
this->needs_update_ = true;
|
||||
}
|
||||
|
||||
void QrCode::generate_qr_code() {
|
||||
ESP_LOGV(TAG, "Generating QR code...");
|
||||
uint8_t tempbuffer[qrcodegen_BUFFER_LEN_MAX];
|
||||
|
||||
if (!qrcodegen_encodeText(this->value_.c_str(), tempbuffer, this->qr_, this->ecc_, qrcodegen_VERSION_MIN,
|
||||
qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true)) {
|
||||
ESP_LOGE(TAG, "Failed to generate QR code");
|
||||
}
|
||||
}
|
||||
|
||||
void QrCode::draw(display::DisplayBuffer *buff, uint16_t x_offset, uint16_t y_offset, Color color, int scale) {
|
||||
ESP_LOGV(TAG, "Drawing QR code at (%d, %d)", x_offset, y_offset);
|
||||
|
||||
if (this->needs_update_) {
|
||||
this->generate_qr_code();
|
||||
this->needs_update_ = false;
|
||||
}
|
||||
|
||||
uint8_t qrcode_width = qrcodegen_getSize(this->qr_);
|
||||
|
||||
for (int y = 0; y < qrcode_width * scale; y++) {
|
||||
for (int x = 0; x < qrcode_width * scale; x++) {
|
||||
if (qrcodegen_getModule(this->qr_, x / scale, y / scale)) {
|
||||
buff->draw_pixel_at(x_offset + x, y_offset + y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace qr_code
|
||||
} // namespace esphome
|
34
esphome/components/qr_code/qr_code.h
Normal file
34
esphome/components/qr_code/qr_code.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/color.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "qrcodegen.h"
|
||||
|
||||
namespace esphome {
|
||||
// forward declare DisplayBuffer
|
||||
namespace display {
|
||||
class DisplayBuffer;
|
||||
} // namespace display
|
||||
|
||||
namespace qr_code {
|
||||
class QrCode : public Component {
|
||||
public:
|
||||
void draw(display::DisplayBuffer *buff, uint16_t x_offset, uint16_t y_offset, Color color, int scale);
|
||||
|
||||
void dump_config() override;
|
||||
|
||||
void set_value(const std::string &value);
|
||||
void set_ecc(qrcodegen_Ecc ecc);
|
||||
|
||||
void generate_qr_code();
|
||||
|
||||
protected:
|
||||
std::string value_;
|
||||
qrcodegen_Ecc ecc_;
|
||||
bool needs_update_ = true;
|
||||
uint8_t qr_[qrcodegen_BUFFER_LEN_MAX];
|
||||
};
|
||||
} // namespace qr_code
|
||||
} // namespace esphome
|
Reference in New Issue
Block a user