تستر پینگ ESP8266 – Evolution

من به تازگی نوشتن در مورد تستر پینگ ESP8266+ESPHome خود را به پایان رساندم – و متوجه شدم که از آنجایی که من فقط از 43٪ رم و 48٪ حافظه FLASH استفاده می کنم – توقف در آنجا جرم است – از این رو این مقاله کوتاه است.
دستگاه پینگ ها را از شبکه می خواند و به لطف ESPHome WebUI (یعنی صفحه وب دستگاه قابل دسترسی از طریق مرورگر) انتخاب آدرس های IP داخلی و خارجی برای پینگ آسان است. شما یک زمان پینگ قابل مشاهده، آدرس IP در حال پینگ و تعداد خطا دریافت میکنید که میتوانید هر زمان که بخواهید در WebUI بازنشانی شود.
و همه اینها از دستگاهی با قیمت کمتر از بسیاری از ESP32 ها، حتی شامل LED WS2812 و صفحه نمایش استاندارد I2c SSD1306 128*64 OLED. من انتظار داشتم که برخی از آیتم های بررسی اکنون وارد شوند، اما وقتی نشد، شروع به تعجب کردم که آیا این واحد می تواند در این مدت ارتقا یابد.
البته همین الان یک تاریخچه 200 پینگ ذخیره شده در دستگاه (زمان، IP، زمان پینگ برای هر پینگ) اضافه کردم. پینگها در RAM ذخیره میشوند و RAM مورد استفاده را از حدود 43% به 47% افزایش دادهاند، افزایش استفاده از FLASH به سختی در 48% از کمی بیش از 47% قابل توجه است. اطلاعات از هر مشتری قدیمی MQTT بازیابی می شود.
این البته به یک کنترل WebUI جدید نیاز دارد تا صف را در حین خواندن متوقف کند، بنابراین یک عکس فوری WebUI جدید. به این نتیجه رسیدم که بهتر است پروژه اصلی را همان طور که هست رها کنم و تغییرات و اضافات را اینجا قرار دهم. توجه داشته باشید که پس از راهاندازی، به کامپیوتری با ESPHome نیازی ندارد – فقط کار میکند.

من شک ندارم که در یک مقطع زمانی میل به اضافه کردن بیشتر خواهم داشت – آن همه حافظه آزاد که هیچ کاری انجام نمی دهند …
در همین حال – دستگاه قرار است از کارگزار MQTT من در 192.168.1.20 و با اعتبار ورود من استفاده کند. وقتی این را کامپایل میکنید – فایل اسرار ESPHome خود را بررسی کنید (نه دستیار خانگی، فایل اسرار موجود در پوشه ESPHome).
فقط به عنوان مثال، این فایل اسرار من است (جزئیات برای محافظت از افراد بی گناه تغییر کرده است) – من فقط یک رمز عبور برای سرویس دهی به چندین SSID دارم زیرا این یک خانه بزرگ است.
wifi_ssid: "myoffice" wifi_password: "xxxxxxxx" uk_wifi_ssid: "office" uk_wifi_password: "xxxxxxxxy" wifi_ssid2: "black" wifi_ssid3: "mlo" wifi_ssid4: "outside" wifi_ssid5: "wififorus" wifi_ssid6: "petes" wifi_ssid7: "comfast" mqtt_broker: 192.168.1.20 mqtt_username: aaaaa mqtt_password: bbbbbb abrobot_ota_password: ccccccccccccccccc ttgo_ota_password: ccccccccccc car_data_write_key: "blah1231blahblah" car_data_read_key: "moreblah123blahblah"
و اکنون، کد YAML برای آخرین تستر پینگ
substitutions:
device_name: oled-test
friendly_name: ESP8266 Ping Tester with ESPHome
device_version: "0.16"
code_source: "https://tech.scargill.net"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
libraries:
- ESPping@1.0.5
includes:
-
on_boot:
priority: -100
then:
- light.turn_on:
id: rgb_led
red: 100%
green: 40%
blue: 0%
esp8266:
board: nodemcuv2
restore_from_flash: true
logger:
level: DEBUG
api:
reboot_timeout: 0s
mqtt:
broker: !secret mqtt_broker
username: !secret mqtt_username
password: !secret mqtt_password
id: mqtt_client
discovery: false
discover_ip: false
web_server:
version: 3
sorting_groups:
- id: web_group_controls
name: "Controls"
sorting_weight: 10
- id: web_group_sensors
name: "Sensors"
sorting_weight: 20
ota:
- platform: esphome
wifi:
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_password
- ssid: !secret wifi_ssid2
password: !secret wifi_password
- ssid: !secret wifi_ssid3
password: !secret wifi_password
- ssid: !secret wifi_ssid4
password: !secret wifi_password
- ssid: !secret wifi_ssid5
password: !secret wifi_password
power_save_mode: none
post_connect_roaming: true
ap:
ssid: "${device_name} Fallback"
password: "12345678"
captive_portal:
preferences:
flash_write_interval: 10s
# ==================================================
# GLOBALS
# ==================================================
globals:
- id: ping_state
type: int
restore_value: no
initial_value: "0"
- id: ping_ms
type: int
restore_value: no
initial_value: "0"
- id: heartbeat
type: bool
restore_value: no
initial_value: "false"
# Persistent ping target IP
- id: ip1
type: int
restore_value: yes
initial_value: "192"
- id: ip2
type: int
restore_value: yes
initial_value: "168"
- id: ip3
type: int
restore_value: yes
initial_value: "1"
- id: ip4
type: int
restore_value: yes
initial_value: "1"
# Persistent failure counter
- id: failed_ping_count
type: uint32_t
restore_value: yes
initial_value: "0"
# Reset switch state
- id: reset_switch_state
type: bool
initial_value: 'false'
# In-RAM ping history. These arrays are deliberately not restored to flash.
- id: history_sequence
type: uint32_t[200]
restore_value: no
- id: history_ms
type: uint16_t[200]
restore_value: no
- id: history_status
type: uint8_t[200]
restore_value: no
- id: history_ip1
type: uint8_t[200]
restore_value: no
- id: history_ip2
type: uint8_t[200]
restore_value: no
- id: history_ip3
type: uint8_t[200]
restore_value: no
- id: history_ip4
type: uint8_t[200]
restore_value: no
- id: history_index
type: uint8_t
restore_value: no
initial_value: '0'
- id: history_count
type: uint16_t
restore_value: no
initial_value: '0'
- id: history_sequence_number
type: uint32_t
restore_value: no
initial_value: '0'
- id: history_paused
type: bool
restore_value: no
initial_value: 'false'
# ==================================================
# FONT
# ==================================================
font:
- file: "gfonts://Roboto"
id: font_small
size: 12
- file: "gfonts://Roboto"
id: font_heading
size: 14
# ==================================================
# I2C OLED
# ==================================================
i2c:
sda: D2
scl: D1
# ==================================================
# OLED DISPLAY
# ==================================================
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
update_interval: 2s
lambda: |-
// OLED disabled
if (!id(oled_display).state) {
it.fill(COLOR_OFF);
return;
}
// Header
it.print(0, 0, id(font_heading), "PING TEST v${device_version}");
it.horizontal_line(0,15,128);
// Heartbeat
if (id(heartbeat)) {
it.print(118, 0, id(font_small), "*");
}
// Ping status
if (id(ping_state) == 0) {
it.print(0, 20, id(font_small), "SETTING UP");
} else if (id(ping_state) == 1) {
it.printf(
0, 20,
id(font_small),
"OK %d ms",
id(ping_ms)
);
} else {
if (id(ping_ms) > 500) {
it.printf(
0, 20,
id(font_small),
"FAILED %d ms",
id(ping_ms)
);
} else {
it.print(0, 20, id(font_small), "** FAILED **");
}
}
// Target IP
it.printf(
0, 36,
id(font_small),
"%d.%d.%d.%d",
id(ip1),
id(ip2),
id(ip3),
id(ip4)
);
// Persistent failure counter
char fail_text[20];
sprintf(
fail_text,
"Failures: %d",
(int) id(failed_ping_count)
);
int fail_width;
int x_offset;
int baseline;
int height;
id(font_small).measure(
fail_text,
&fail_width,
&x_offset,
&baseline,
&height
);
it.print(
128 - fail_width,
50,
id(font_small),
fail_text
);
# ==================================================
# RGB LED
# ==================================================
light:
- platform: neopixelbus
id: rgb_led
type: GRB
variant: WS2812
pin: D6
num_leds: 1
name: "RGB LED"
web_server:
sorting_group_id: web_group_controls
sorting_weight: 100
gamma_correct: 1.0
initial_state:
brightness: 26%
restore_state: all
# ==================================================
# TEXT SENSORS
# ==================================================
text_sensor:
- platform: template
name: "Firmware Version"
web_server:
sorting_group_id: web_group_sensors
sorting_weight: 30
lambda: |-
return {"${device_version}"};
update_interval: 60s
- platform: template
name: "code_source"
web_server:
sorting_group_id: web_group_sensors
sorting_weight: 40
lambda: |-
return {"${code_source}"};
update_interval: 60s
# ==================================================
# PING TARGET DROPDOWN
# ==================================================
select:
- platform: template
name: "Ping Target"
id: ping_target
web_server:
sorting_group_id: web_group_controls
sorting_weight: 10
optimistic: true
restore_value: true
initial_option: "Manual / Custom"
options:
- "Manual / Custom"
- "Google DNS - 8.8.8.8"
- "Google DNS - 8.8.4.4"
- "Cloudflare - 1.1.1.1"
- "Cloudflare - 1.0.0.1"
- "Quad9 - 9.9.9.9"
- "Quad9 - 149.112.112.112"
- "OpenDNS - 208.67.222.222"
- "OpenDNS - 208.67.220.220"
- "AdGuard - 94.140.14.14"
- "AdGuard - 94.140.15.15"
- "Router - 192.168.1.1"
- "Router - 192.168.0.1"
- "Router - 192.168.1.254"
- "Router - 192.168.0.254"
- "Local - 10.0.0.1"
- "Local - 10.10.0.1"
- "Local - 10.10.10.1"
- "Local - 172.16.0.1"
- "Local - 172.16.1.1"
on_value:
then:
- lambda: |-
if (x == "Google DNS - 8.8.8.8") {
id(ip1) = 8;
id(ip2) = 8;
id(ip3) = 8;
id(ip4) = 8;
} else if (x == "Google DNS - 8.8.4.4") {
id(ip1) = 8;
id(ip2) = 8;
id(ip3) = 4;
id(ip4) = 4;
} else if (x == "Cloudflare - 1.1.1.1") {
id(ip1) = 1;
id(ip2) = 1;
id(ip3) = 1;
id(ip4) = 1;
} else if (x == "Cloudflare - 1.0.0.1") {
id(ip1) = 1;
id(ip2) = 0;
id(ip3) = 0;
id(ip4) = 1;
} else if (x == "Quad9 - 9.9.9.9") {
id(ip1) = 9;
id(ip2) = 9;
id(ip3) = 9;
id(ip4) = 9;
} else if (x == "Quad9 - 149.112.112.112") {
id(ip1) = 149;
id(ip2) = 112;
id(ip3) = 112;
id(ip4) = 112;
} else if (x == "OpenDNS - 208.67.222.222") {
id(ip1) = 208;
id(ip2) = 67;
id(ip3) = 222;
id(ip4) = 222;
} else if (x == "OpenDNS - 208.67.220.220") {
id(ip1) = 208;
id(ip2) = 67;
id(ip3) = 220;
id(ip4) = 220;
} else if (x == "AdGuard - 94.140.14.14") {
id(ip1) = 94;
id(ip2) = 140;
id(ip3) = 14;
id(ip4) = 14;
} else if (x == "AdGuard - 94.140.15.15") {
id(ip1) = 94;
id(ip2) = 140;
id(ip3) = 15;
id(ip4) = 15;
} else if (x == "Router - 192.168.1.1") {
id(ip1) = 192;
id(ip2) = 168;
id(ip3) = 1;
id(ip4) = 1;
} else if (x == "Router - 192.168.0.1") {
id(ip1) = 192;
id(ip2) = 168;
id(ip3) = 0;
id(ip4) = 1;
} else if (x == "Router - 192.168.1.254") {
id(ip1) = 192;
id(ip2) = 168;
id(ip3) = 1;
id(ip4) = 254;
} else if (x == "Router - 192.168.0.254") {
id(ip1) = 192;
id(ip2) = 168;
id(ip3) = 0;
id(ip4) = 254;
} else if (x == "Local - 10.0.0.1") {
id(ip1) = 10;
id(ip2) = 0;
id(ip3) = 0;
id(ip4) = 1;
} else if (x == "Local - 10.10.0.1") {
id(ip1) = 10;
id(ip2) = 10;
id(ip3) = 0;
id(ip4) = 1;
} else if (x == "Local - 10.10.10.1") {
id(ip1) = 10;
id(ip2) = 10;
id(ip3) = 10;
id(ip4) = 1;
} else if (x == "Local - 172.16.0.1") {
id(ip1) = 172;
id(ip2) = 16;
id(ip3) = 0;
id(ip4) = 1;
} else if (x == "Local - 172.16.1.1") {
id(ip1) = 172;
id(ip2) = 16;
id(ip3) = 1;
id(ip4) = 1;
}
- component.update: ping_ip1
- component.update: ping_ip2
- component.update: ping_ip3
- component.update: ping_ip4
# ==================================================
# PING IP ADDRESS
# ==================================================
number:
- platform: template
name: "Ping IP 1"
id: ping_ip1
web_server:
sorting_group_id: web_group_controls
sorting_weight: 20
min_value: 0
max_value: 255
step: 1
mode: box
lambda: |-
return id(ip1);
set_action:
- lambda: |-
id(ip1) = (int)x;
- select.set:
id: ping_target
option: "Manual / Custom"
- platform: template
name: "Ping IP 2"
id: ping_ip2
web_server:
sorting_group_id: web_group_controls
sorting_weight: 30
min_value: 0
max_value: 255
step: 1
mode: box
lambda: |-
return id(ip2);
set_action:
- lambda: |-
id(ip2) = (int)x;
- select.set:
id: ping_target
option: "Manual / Custom"
- platform: template
name: "Ping IP 3"
id: ping_ip3
web_server:
sorting_group_id: web_group_controls
sorting_weight: 40
min_value: 0
max_value: 255
step: 1
mode: box
lambda: |-
return id(ip3);
set_action:
- lambda: |-
id(ip3) = (int)x;
- select.set:
id: ping_target
option: "Manual / Custom"
- platform: template
name: "Ping IP 4"
id: ping_ip4
web_server:
sorting_group_id: web_group_controls
sorting_weight: 50
min_value: 0
max_value: 255
step: 1
mode: box
lambda: |-
return id(ip4);
set_action:
- lambda: |-
id(ip4) = (int)x;
- select.set:
id: ping_target
option: "Manual / Custom"
# ==================================================
# PING FAILURE COUNTER SENSOR
# ==================================================
sensor:
- platform: template
name: "Ping Failures"
id: failed_ping_counter_sensor
web_server:
sorting_group_id: web_group_sensors
sorting_weight: 10
accuracy_decimals: 0
update_interval: 5s
lambda: |-
return (float) id(failed_ping_count);
- platform: template
name: "Ping History Length"
id: ping_history_length_sensor
web_server:
sorting_group_id: web_group_sensors
sorting_weight: 20
accuracy_decimals: 0
update_interval: 5s
lambda: |-
return (float) id(history_count);
# ==================================================
# OLED ON/OFF SWITCH
# ==================================================
switch:
- platform: template
name: "OLED Display"
id: oled_display
web_server:
sorting_group_id: web_group_controls
sorting_weight: 90
restore_mode: RESTORE_DEFAULT_ON
optimistic: true
turn_on_action:
- lambda: |-
// OLED enabled
turn_off_action:
- lambda: |-
// OLED disabled
- platform: template
name: "Reset Ping Counter"
icon: "mdi:gesture-tap"
web_server:
sorting_group_id: web_group_controls
sorting_weight: 80
id: this_dummy_switch_id
lambda: |-
return id(reset_switch_state);
turn_on_action:
- globals.set:
id: reset_switch_state
value: 'true'
- lambda: |-
id(failed_ping_count) = 0;
- component.update: failed_ping_counter_sensor
- delay: 150ms
- switch.turn_off: this_dummy_switch_id
turn_off_action:
- globals.set:
id: reset_switch_state
value: 'false'
- platform: template
name: "Clear Ping History"
icon: "mdi:delete-sweep"
web_server:
sorting_group_id: web_group_controls
sorting_weight: 70
id: clear_ping_history
optimistic: true
turn_on_action:
- lambda: |-
id(history_index) = 0;
id(history_count) = 0;
id(history_sequence_number) = 0;
char topic[24];
for (int n = 0; n 500) {
id(failed_ping_count)++;
}
if (id(ping_ms) > 500) {
id(ping_state) = 2;
history_result = 2;
} else {
id(ping_state) = 1;
history_result = 1;
}
auto call = id(rgb_led).turn_on();
bool local_target =
(id(ip1) == 192 &&
id(ip2) == 168);
if (local_target) {
if (id(ping_ms)
To get the history info from MQTT – the following subscribes are available:
pinger/1
pinger/2
pinger/3
…
pinger/200
pinger/latest
pinger/count
pinger/status
For a quick check just subscribe to pinger/#




