Compare commits

...

7 Commits

Author SHA1 Message Date
LuBeDa 25a11f2099 disabled bitmap_screen
3 years ago
LuBeDa d81ac698f6 bluescreen
3 years ago
LuBeDa d01c63f96f "bluescreen on Boot"
3 years ago
LuBeDa 79587a7c64 test
3 years ago
LuBeDa eb036800ad
Update ehtmxv2-special.yaml
3 years ago
LuBeDa e7abf1958d new test
3 years ago
LuBeDa 918137dfb1 issue #20
3 years ago

@ -21,6 +21,9 @@ jobs:
- file: tests/ehtmxv2-template.yaml - file: tests/ehtmxv2-template.yaml
name: EHMTX template name: EHMTX template
manifest_filename: ehtmxv2-template-manifest.json manifest_filename: ehtmxv2-template-manifest.json
- file: tests/ehtmxv2-special.yaml
name: EHMTX template 8266
manifest_filename: ehtmxv2-special-template-manifest.json
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout source code - name: Checkout source code

@ -4,6 +4,7 @@ namespace esphome
{ {
EHMTX::EHMTX() : PollingComponent(POLLINGINTERVAL) EHMTX::EHMTX() : PollingComponent(POLLINGINTERVAL)
{ {
ESP_LOGD(TAG, "Constructor start");
this->show_display = true; this->show_display = true;
this->display_gauge = false; this->display_gauge = false;
this->display_indicator = 0; this->display_indicator = 0;
@ -24,11 +25,13 @@ namespace esphome
this->next_action_time = 0; this->next_action_time = 0;
this->last_scroll_time = 0; this->last_scroll_time = 0;
this->screen_pointer = MAXQUEUE; this->screen_pointer = MAXQUEUE;
this->is_running = false;
for (uint8_t i = 0; i < MAXQUEUE; i++) for (uint8_t i = 0; i < MAXQUEUE; i++)
{ {
this->queue[i] = new EHMTX_queue(this); this->queue[i] = new EHMTX_queue(this);
} }
ESP_LOGD(TAG, "Constructor finish");
} }
void EHMTX::set_time_format(std::string s) void EHMTX::set_time_format(std::string s)
@ -106,35 +109,35 @@ namespace esphome
void EHMTX::bitmap_screen(std::string text, int lifetime, int screen_time) void EHMTX::bitmap_screen(std::string text, int lifetime, int screen_time)
{ {
ESP_LOGD(TAG, "bitmap screen: lifetime: %d screen_time: %d", lifetime, screen_time); ESP_LOGD(TAG, "bitmap screen: lifetime: %d screen_time: %d", lifetime, screen_time);
const size_t CAPACITY = JSON_ARRAY_SIZE(256); // const size_t CAPACITY = JSON_ARRAY_SIZE(256);
StaticJsonDocument<CAPACITY> doc; // StaticJsonDocument<CAPACITY> doc;
deserializeJson(doc, text); // deserializeJson(doc, text);
JsonArray array = doc.as<JsonArray>(); // JsonArray array = doc.as<JsonArray>();
// extract the values // // extract the values
uint16_t i = 0; // uint16_t i = 0;
for (JsonVariant v : array) // for (JsonVariant v : array)
{ // {
uint16_t buf = v.as<int>(); // uint16_t buf = v.as<int>();
unsigned char b = (((buf)&0x001F) << 3); // unsigned char b = (((buf)&0x001F) << 3);
unsigned char g = (((buf)&0x07E0) >> 3); // Fixed: shift >> 5 and << 2 // unsigned char g = (((buf)&0x07E0) >> 3); // Fixed: shift >> 5 and << 2
unsigned char r = (((buf)&0xF800) >> 8); // shift >> 11 and << 3 // unsigned char r = (((buf)&0xF800) >> 8); // shift >> 11 and << 3
Color c = Color(r, g, b); // Color c = Color(r, g, b);
this->bitmap[i++] = c; // this->bitmap[i++] = c;
} // }
EHMTX_queue *screen = this->find_free_queue_element(); // EHMTX_queue *screen = this->find_free_queue_element();
screen->text = ""; // screen->text = "";
screen->endtime = this->clock->now().timestamp + lifetime * 60; // screen->endtime = this->clock->now().timestamp + lifetime * 60;
screen->mode = MODE_BITMAP_SCREEN; // screen->mode = MODE_BITMAP_SCREEN;
screen->screen_time_ = screen_time; // screen->screen_time_ = screen_time;
for (auto *t : on_add_screen_triggers_) // for (auto *t : on_add_screen_triggers_)
{ // {
t->process("bitmap", (uint8_t)screen->mode); // t->process("bitmap", (uint8_t)screen->mode);
} // }
screen->status(); // screen->status();
} }
uint8_t EHMTX::find_icon(std::string name) uint8_t EHMTX::find_icon(std::string name)
@ -269,14 +272,17 @@ namespace esphome
if (this->clock->now().is_valid()) if (this->clock->now().is_valid())
{ {
ESP_LOGD(TAG, "time sync => start running"); ESP_LOGD(TAG, "time sync => start running");
this->bitmap_screen("[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63519,63519,63519,63519,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63519,0,0,0,0,2016,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,63488,0,63488,0,0,0,63519,0,0,0,0,2016,2016,0,0,0,65514,0,65514,0,0,0,31,0,0,0,64512,0,0,64512,0,63488,63488,0,63488,63488,0,0,63519,63519,63519,0,0,2016,0,2016,0,65514,0,65514,0,65514,0,31,31,31,0,0,0,64512,64512,0,0,63488,63488,63488,63488,63488,0,0,63519,0,0,0,0,2016,0,2016,0,65514,0,65514,0,65514,0,0,31,0,0,0,0,64512,64512,0,0,0,63488,63488,63488,0,0,0,63519,63519,63519,63519,0,2016,0,2016,0,65514,0,65514,0,65514,0,0,0,31,31,0,64512,0,0,64512,0,0,0,63488,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]",1,10); this->bitmap_screen("[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63519,63519,63519,63519,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63519,0,0,0,0,2016,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,63488,0,63488,0,0,0,63519,0,0,0,0,2016,2016,0,0,0,65514,0,65514,0,0,0,31,0,0,0,64512,0,0,64512,0,63488,63488,0,63488,63488,0,0,63519,63519,63519,0,0,2016,0,2016,0,65514,0,65514,0,65514,0,31,31,31,0,0,0,64512,64512,0,0,63488,63488,63488,63488,63488,0,0,63519,0,0,0,0,2016,0,2016,0,65514,0,65514,0,65514,0,0,31,0,0,0,0,64512,64512,0,0,0,63488,63488,63488,0,0,0,63519,63519,63519,63519,0,2016,0,2016,0,65514,0,65514,0,65514,0,0,0,31,31,0,64512,0,0,64512,0,0,0,63488,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]", 1, 10);
this->clock_screen(14 * 24 * 60, this->clock_time, false, C_RED, C_GREEN, C_BLUE); this->clock_screen(14 * 24 * 60, this->clock_time, false, C_RED, C_GREEN, C_BLUE);
this->date_screen(14 * 24 * 60, (int)this->clock_time / 2, false, C_RED, C_GREEN, C_BLUE); this->date_screen(14 * 24 * 60, (int)this->clock_time / 2, false, C_RED, C_GREEN, C_BLUE);
this->is_running = true; this->is_running = true;
} }
} }
else
{
}
} }
void EHMTX::force_screen(std::string icon_name, int mode) void EHMTX::force_screen(std::string icon_name, int mode)
{ {
for (uint8_t i = 0; i < MAXQUEUE; i++) for (uint8_t i = 0; i < MAXQUEUE; i++)
@ -348,53 +354,59 @@ namespace esphome
void EHMTX::remove_expired_queue_element() void EHMTX::remove_expired_queue_element()
{ {
time_t ts = this->clock->now().timestamp; if (this->clock->now().is_valid())
std::string infotext;
for (size_t i = 0; i < MAXQUEUE; i++)
{ {
if ((this->queue[i]->endtime > 0) && (this->queue[i]->endtime < ts)) std::string infotext;
time_t ts = this->clock->now().timestamp;
for (size_t i = 0; i < MAXQUEUE; i++)
{ {
this->queue[i]->endtime = 0; if ((this->queue[i]->endtime > 0) && (this->queue[i]->endtime < ts))
if (this->queue[i]->mode != MODE_EMPTY)
{ {
ESP_LOGD(TAG, "remove expired queue element: slot %d: mode: %d icon_name: %s text: %s", i, this->queue[i]->mode, this->queue[i]->icon_name.c_str(), this->queue[i]->text.c_str()); this->queue[i]->endtime = 0;
for (auto *t : on_expired_screen_triggers_) if (this->queue[i]->mode != MODE_EMPTY)
{ {
infotext = ""; ESP_LOGD(TAG, "remove expired queue element: slot %d: mode: %d icon_name: %s text: %s", i, this->queue[i]->mode, this->queue[i]->icon_name.c_str(), this->queue[i]->text.c_str());
switch (this->queue[i]->mode) for (auto *t : on_expired_screen_triggers_)
{ {
case MODE_EMPTY: infotext = "";
break; switch (this->queue[i]->mode)
case MODE_BLANK: {
break; case MODE_EMPTY:
case MODE_CLOCK: break;
infotext = "clock"; case MODE_BLANK:
break; break;
case MODE_DATE: case MODE_CLOCK:
infotext = "clock"; infotext = "clock";
break; break;
case MODE_FULL_SCREEN: case MODE_DATE:
infotext = "full screen " + this->queue[i]->icon_name; infotext = "clock";
break; break;
case MODE_ICON_SCREEN: case MODE_FULL_SCREEN:
case MODE_RAINBOW_ICON: infotext = "full screen " + this->queue[i]->icon_name;
infotext = this->queue[i]->icon_name.c_str(); break;
break; case MODE_ICON_SCREEN:
case MODE_RAINBOW_TEXT: case MODE_RAINBOW_ICON:
case MODE_TEXT_SCREEN: infotext = this->queue[i]->icon_name.c_str();
infotext = "TEXT"; break;
break; case MODE_RAINBOW_TEXT:
default: case MODE_TEXT_SCREEN:
break; infotext = "TEXT";
break;
case MODE_BITMAP_SCREEN:
infotext = "BITMAP";
break;
default:
break;
}
t->process(this->queue[i]->icon_name, infotext);
} }
t->process(this->queue[i]->icon_name, infotext);
} }
this->queue[i]->mode = MODE_EMPTY;
} }
this->queue[i]->mode = MODE_EMPTY;
} }
} }
} }
void EHMTX::tick() void EHMTX::tick()
{ {
this->hue_++; this->hue_++;
@ -406,10 +418,10 @@ namespace esphome
esphome::hsv_to_rgb(this->hue_, 0.8, 0.8, red, green, blue); esphome::hsv_to_rgb(this->hue_, 0.8, 0.8, red, green, blue);
this->rainbow_color = Color(uint8_t(255 * red), uint8_t(255 * green), uint8_t(255 * blue)); this->rainbow_color = Color(uint8_t(255 * red), uint8_t(255 * green), uint8_t(255 * blue));
time_t ts = this->clock->now().timestamp; if (this->is_running && this->clock->now().is_valid())
if (this->is_running)
{ {
time_t ts = this->clock->now().timestamp;
if (millis() - this->last_scroll_time >= this->scroll_interval) if (millis() - this->last_scroll_time >= this->scroll_interval)
{ {
this->scroll_step++; this->scroll_step++;
@ -868,11 +880,13 @@ namespace esphome
{ {
this->display = disp; this->display = disp;
this->show_display = true; this->show_display = true;
ESP_LOGD(TAG, "set_display");
} }
void EHMTX::set_clock(time::RealTimeClock *clock) void EHMTX::set_clock(time::RealTimeClock *clock)
{ {
this->clock = clock; this->clock = clock;
ESP_LOGD(TAG, "set_clock");
} }
void EHMTX::draw_day_of_week() void EHMTX::draw_day_of_week()
@ -940,10 +954,6 @@ namespace esphome
{ {
ESP_LOGCONFIG(TAG, "weekstart: sunday"); ESP_LOGCONFIG(TAG, "weekstart: sunday");
} }
if (this->clock->now().is_valid())
{
this->is_running = true;
}
} }
void EHMTX::add_icon(EHMTX_Icon *icon) void EHMTX::add_icon(EHMTX_Icon *icon)

@ -20,7 +20,7 @@ const uint8_t MAXICONS = 90;
const uint8_t TEXTSCROLLSTART = 8; const uint8_t TEXTSCROLLSTART = 8;
const uint8_t TEXTSTARTOFFSET = (32 - 8); const uint8_t TEXTSTARTOFFSET = (32 - 8);
const uint16_t POLLINGINTERVAL = 1000; const uint16_t POLLINGINTERVAL = 250;
static const char *const EHMTX_VERSION = "Version: 2023.5.0 beta"; static const char *const EHMTX_VERSION = "Version: 2023.5.0 beta";
static const char *const TAG = "EHMTXv2"; static const char *const TAG = "EHMTXv2";
enum show_mode : uint8_t { MODE_EMPTY = 0,MODE_BLANK = 1, MODE_CLOCK = 2, MODE_DATE = 3, MODE_FULL_SCREEN = 4, MODE_ICON_SCREEN = 5, MODE_TEXT_SCREEN = 6 , MODE_RAINBOW_ICON = 7,MODE_RAINBOW_TEXT = 8, MODE_RAINBOW_CLOCK = 9,MODE_RAINBOW_DATE=10,MODE_BITMAP_SCREEN=11 }; enum show_mode : uint8_t { MODE_EMPTY = 0,MODE_BLANK = 1, MODE_CLOCK = 2, MODE_DATE = 3, MODE_FULL_SCREEN = 4, MODE_ICON_SCREEN = 5, MODE_TEXT_SCREEN = 6 , MODE_RAINBOW_ICON = 7,MODE_RAINBOW_TEXT = 8, MODE_RAINBOW_CLOCK = 9,MODE_RAINBOW_DATE=10,MODE_BITMAP_SCREEN=11 };
@ -37,7 +37,7 @@ namespace esphome
class EHMTX : public PollingComponent, public api::CustomAPIDevice { class EHMTX : public PollingComponent, public api::CustomAPIDevice {
protected: protected:
float get_setup_priority() const override { return esphome::setup_priority::BEFORE_CONNECTION; } float get_setup_priority() const override { return esphome::setup_priority::LATE; }
uint8_t brightness_; uint8_t brightness_;
uint32_t boot_anim=0; uint32_t boot_anim=0;
uint8_t screen_pointer; uint8_t screen_pointer;

@ -16,6 +16,7 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ["display", "light", "api"] DEPENDENCIES = ["display", "light", "api"]
AUTO_LOAD = ["ehmtxv2"] AUTO_LOAD = ["ehmtxv2"]
AUTO_LOAD = ["json"]
IMAGE_TYPE_RGB565 = 4 IMAGE_TYPE_RGB565 = 4
MAXFRAMES = 110 MAXFRAMES = 110
MAXICONS = 90 MAXICONS = 90
@ -354,15 +355,15 @@ async def to_code(config):
disp = await cg.get_variable(config[CONF_MATRIXCOMPONENT]) disp = await cg.get_variable(config[CONF_MATRIXCOMPONENT])
cg.add(var.set_display(disp)) cg.add(var.set_display(disp))
ehmtxtime = await cg.get_variable(config[CONF_TIMECOMPONENT])
cg.add(var.set_clock(ehmtxtime))
f = await cg.get_variable(config[CONF_DEFAULT_FONT_ID]) f = await cg.get_variable(config[CONF_DEFAULT_FONT_ID])
cg.add(var.set_default_font(f)) cg.add(var.set_default_font(f))
f = await cg.get_variable(config[CONF_special_FONT_ID]) f = await cg.get_variable(config[CONF_special_FONT_ID])
cg.add(var.set_special_font(f)) cg.add(var.set_special_font(f))
ehmtxtime = await cg.get_variable(config[CONF_TIMECOMPONENT])
cg.add(var.set_clock(ehmtxtime))
cg.add(var.set_brightness(config[CONF_BRIGHTNESS])) cg.add(var.set_brightness(config[CONF_BRIGHTNESS]))
cg.add(var.set_scroll_interval(config[CONF_SCROLLINTERVAL])) cg.add(var.set_scroll_interval(config[CONF_SCROLLINTERVAL]))
cg.add(var.set_rainbow_interval(config[CONF_SCROLLINTERVAL])) cg.add(var.set_rainbow_interval(config[CONF_SCROLLINTERVAL]))

@ -0,0 +1,160 @@
substitutions:
devicename: ehmtxv2
friendly_name: LED Matrix
board: d1_mini_lite
matrix_pin: GPIO12
external_components:
- source:
type: local
path: ../components
components: [ ehmtxv2 ]
esphome:
comment: "EHMTXv2 TEXT from LuBeDa 8266"
name: $devicename
on_boot:
lambda: |-
id(rgb8x32)->show_indicator(255,100,50,2);
id(rgb8x32)->hide_indicator();
id(rgb8x32)->show_alarm(255,0,150,3);
id(rgb8x32)->hide_alarm();
id(rgb8x32)->icon_screen("error","Hallo Text",false,237,20,100,200,150);
id(rgb8x32)->force_screen("error");
id(rgb8x32)->del_screen("error");
id(rgb8x32)->del_screen("error",5);
id(rgb8x32)->rainbow_icon_screen("error","Hallo Text",true,237,20);
id(rgb8x32)->get_status();
id(rgb8x32)->set_display_on();
id(rgb8x32)->set_display_off();
id(rgb8x32)->hold_screen();
id(rgb8x32)->show_gauge(100,0,200);
id(rgb8x32)->hide_gauge();
id(rgb8x32)->set_clock_color(200,100,50);
id(rgb8x32)->set_today_color(200,100,50);
id(rgb8x32)->set_weekday_color(200,100,50);
id(rgb8x32)->full_screen("scale");
id(rgb8x32)->rainbow_icon_screen("error","Oh ein Text");
id(rgb8x32)->text_screen("text",30);
id(rgb8x32)->rainbow_text_screen("text",30);
id(rgb8x32)->clock_screen(30,5);
id(rgb8x32)->rainbow_clock_screen(30,5);
id(rgb8x32)->date_screen(30,5);
id(rgb8x32)->rainbow_date_screen(30,5);
id(rgb8x32)->blank_screen(30,5);
id(rgb8x32)->set_brightness(20);
id(rgb8x32)->bitmap_screen("[31,31,31,63488,63488,63488,31,31,63488,31,31,31,31,31,63488,63488,63488,31,31,63488,63488,63488,63488,31,31,63488,31,31,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,63488,31,63488,63488,31,63488,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,63488,31,63488,31,63488,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,63488,31,63488,31,31,31,63488,31,31,31,31,63488,63488,63488,63488,63488,31,63488,31,31,31,31,63488,63488,63488,63488,63488,31,63488,63488,63488,63488,31,31,63488,31,31,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,63488,31,31,31,63488,31,31,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,31,31,63488,31,31,63488,31,31,31,63488,31,31,31,31,63488,31,31,31,63488,31,63488,63488,63488,63488,31,63488,31,31,31,63488,31,63488,31,31,31,63488,31,63488,31,31,31,63488,31,31]",2,10);
esp8266:
board: $board
font:
- file: EHMTXv2.ttf
size: 16
id: default_font
glyphs: |
!?"%()+*=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnÖÄÜöäüopqrstuvwxyz@<>ß§€/
binary_sensor:
- platform: status
name: "$devicename Status"
logger:
level: WARN
api:
sensor:
ota:
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
light:
- platform: neopixelbus
id: ehmtx_light
type: GRB
internal: true
variant: WS2812
pin: $matrix_pin
num_leds: 256
color_correct: [30%, 30%, 30%]
gamma_correct: 2.0
name: "$devicename Light"
restore_mode: ALWAYS_OFF
time:
- platform: homeassistant
id: ehmtx_time
display:
- platform: addressable_light
id: ehmtx_display
addressable_light_id: ehmtx_light
width: 32
height: 8
pixel_mapper: |-
if (y % 2 == 0) {
return (y * 32) + x;
}
return (y * 32) + (31 - x);
rotation: 0°
update_interval: 16ms
auto_clear_enabled: true
lambda: |-
id(rgb8x32)->tick();
id(rgb8x32)->draw();
ehmtxv2:
id: rgb8x32
icons2html: true
matrix_component: ehmtx_display
time_component: ehmtx_time
time_format: "%H:%M"
date_format: "%d.%m."
show_seconds: false
clock_interval: 90
scroll_interval: 120
frame_interval: 210
rtl: true
default_font_id: default_font
special_font_id: default_font
icons:
- id: error
lameid: 40530
- id: scale
file: scale.gif
resize: 32x8
- id: sleep8x32
url: https://user-images.githubusercontent.com/16407309/224850723-634c9b2d-55d9-44f2-9f93-765c0485b090.gif
on_next_screen:
- homeassistant.event:
event: esphome.new_screen
data_template:
iconname: !lambda "return icon.c_str();"
text: !lambda "return text.c_str();"
on_add_screen:
- homeassistant.event:
event: esphome.new_screen
data_template:
iconname: !lambda "return icon.c_str();"
mode: !lambda "return mode;"
on_next_clock:
- homeassistant.event:
event: esphome.new_screen
data_template:
iconname: "Hallo"
on_expired_screen:
- homeassistant.event:
event: esphome.new_screen
data_template:
iconname: !lambda "return icon.c_str();"
text: !lambda "return text.c_str();"
on_icon_error:
- homeassistant.event:
event: esphome.new_screen
data_template:
iconname: !lambda "return icon.c_str();"
Loading…
Cancel
Save