mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 12:15:33 +01:00
Add support for wl-134 (#3569)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
06ac4980ba
commit
4ac72d7d08
@ -254,6 +254,7 @@ esphome/components/wake_on_lan/* @willwill2will54
|
||||
esphome/components/web_server_base/* @OttoWinter
|
||||
esphome/components/whirlpool/* @glmnet
|
||||
esphome/components/whynter/* @aeonsablaze
|
||||
esphome/components/wl_134/* @hobbypunk90
|
||||
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
|
||||
esphome/components/xiaomi_mhoc303/* @drug123
|
||||
esphome/components/xiaomi_mhoc401/* @vevsvevs
|
||||
|
0
esphome/components/wl_134/__init__.py
Normal file
0
esphome/components/wl_134/__init__.py
Normal file
31
esphome/components/wl_134/text_sensor.py
Normal file
31
esphome/components/wl_134/text_sensor.py
Normal file
@ -0,0 +1,31 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import text_sensor, uart
|
||||
from esphome.const import (
|
||||
ICON_FINGERPRINT,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@hobbypunk90"]
|
||||
DEPENDENCIES = ["uart"]
|
||||
CONF_RESET = "reset"
|
||||
|
||||
wl134_ns = cg.esphome_ns.namespace("wl_134")
|
||||
Wl134Component = wl134_ns.class_(
|
||||
"Wl134Component", text_sensor.TextSensor, cg.Component, uart.UARTDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
text_sensor.text_sensor_schema(
|
||||
Wl134Component,
|
||||
icon=ICON_FINGERPRINT,
|
||||
)
|
||||
.extend({cv.Optional(CONF_RESET, default=False): cv.boolean})
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await text_sensor.new_text_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
cg.add(var.set_do_reset(config[CONF_RESET]))
|
||||
await uart.register_uart_device(var, config)
|
111
esphome/components/wl_134/wl_134.cpp
Normal file
111
esphome/components/wl_134/wl_134.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "wl_134.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace wl_134 {
|
||||
|
||||
static const char *const TAG = "wl_134.sensor";
|
||||
static const uint8_t ASCII_CR = 0x0D;
|
||||
static const uint8_t ASCII_NBSP = 0xFF;
|
||||
static const int MAX_DATA_LENGTH_BYTES = 6;
|
||||
|
||||
void Wl134Component::setup() { this->publish_state(""); }
|
||||
|
||||
void Wl134Component::loop() {
|
||||
while (this->available() >= RFID134_PACKET_SIZE) {
|
||||
Wl134Component::Rfid134Error error = this->read_packet_();
|
||||
if (error != RFID134_ERROR_NONE) {
|
||||
ESP_LOGW(TAG, "Error: %d", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Wl134Component::Rfid134Error Wl134Component::read_packet_() {
|
||||
uint8_t packet[RFID134_PACKET_SIZE];
|
||||
packet[RFID134_PACKET_START_CODE] = this->read();
|
||||
|
||||
// check for the first byte being the packet start code
|
||||
if (packet[RFID134_PACKET_START_CODE] != 0x02) {
|
||||
// just out of sync, ignore until we are synced up
|
||||
return RFID134_ERROR_NONE;
|
||||
}
|
||||
|
||||
if (!this->read_array(&(packet[RFID134_PACKET_ID]), RFID134_PACKET_SIZE - 1)) {
|
||||
return RFID134_ERROR_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (packet[RFID134_PACKET_END_CODE] != 0x03) {
|
||||
return RFID134_ERROR_PACKET_END_CODE_MISSMATCH;
|
||||
}
|
||||
|
||||
// calculate checksum
|
||||
uint8_t checksum = 0;
|
||||
for (uint8_t i = RFID134_PACKET_ID; i < RFID134_PACKET_CHECKSUM; i++) {
|
||||
checksum = checksum ^ packet[i];
|
||||
}
|
||||
|
||||
// test checksum
|
||||
if (checksum != packet[RFID134_PACKET_CHECKSUM]) {
|
||||
return RFID134_ERROR_PACKET_CHECKSUM;
|
||||
}
|
||||
|
||||
if (static_cast<uint8_t>(~checksum) != static_cast<uint8_t>(packet[RFID134_PACKET_CHECKSUM_INVERT])) {
|
||||
return RFID134_ERROR_PACKET_CHECKSUM_INVERT;
|
||||
}
|
||||
|
||||
Rfid134Reading reading;
|
||||
|
||||
// convert packet into the reading struct
|
||||
reading.id = this->hex_lsb_ascii_to_uint64_(&(packet[RFID134_PACKET_ID]), RFID134_PACKET_COUNTRY - RFID134_PACKET_ID);
|
||||
reading.country = this->hex_lsb_ascii_to_uint64_(&(packet[RFID134_PACKET_COUNTRY]),
|
||||
RFID134_PACKET_DATA_FLAG - RFID134_PACKET_COUNTRY);
|
||||
reading.isData = packet[RFID134_PACKET_DATA_FLAG] == '1';
|
||||
reading.isAnimal = packet[RFID134_PACKET_ANIMAL_FLAG] == '1';
|
||||
reading.reserved0 = this->hex_lsb_ascii_to_uint64_(&(packet[RFID134_PACKET_RESERVED0]),
|
||||
RFID134_PACKET_RESERVED1 - RFID134_PACKET_RESERVED0);
|
||||
reading.reserved1 = this->hex_lsb_ascii_to_uint64_(&(packet[RFID134_PACKET_RESERVED1]),
|
||||
RFID134_PACKET_CHECKSUM - RFID134_PACKET_RESERVED1);
|
||||
|
||||
ESP_LOGV(TAG, "Tag id: %012lld", reading.id);
|
||||
ESP_LOGV(TAG, "Country: %03d", reading.country);
|
||||
ESP_LOGV(TAG, "isData: %s", reading.isData ? "true" : "false");
|
||||
ESP_LOGV(TAG, "isAnimal: %s", reading.isAnimal ? "true" : "false");
|
||||
ESP_LOGV(TAG, "Reserved0: %d", reading.reserved0);
|
||||
ESP_LOGV(TAG, "Reserved1: %d", reading.reserved1);
|
||||
|
||||
char buf[20];
|
||||
sprintf(buf, "%03d%012lld", reading.country, reading.id);
|
||||
this->publish_state(buf);
|
||||
if (this->do_reset_) {
|
||||
this->set_timeout(1000, [this]() { this->publish_state(""); });
|
||||
}
|
||||
|
||||
return RFID134_ERROR_NONE;
|
||||
}
|
||||
|
||||
uint64_t Wl134Component::hex_lsb_ascii_to_uint64_(const uint8_t *text, uint8_t text_size) {
|
||||
uint64_t value = 0;
|
||||
uint8_t i = text_size;
|
||||
do {
|
||||
i--;
|
||||
|
||||
uint8_t digit = text[i];
|
||||
if (digit >= 'A') {
|
||||
digit = digit - 'A' + 10;
|
||||
} else {
|
||||
digit = digit - '0';
|
||||
}
|
||||
value = (value << 4) + digit;
|
||||
} while (i != 0);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Wl134Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "WL-134 Sensor:");
|
||||
LOG_TEXT_SENSOR("", "Tag", this);
|
||||
// As specified in the sensor's data sheet
|
||||
this->check_uart_settings(9600, 1, esphome::uart::UART_CONFIG_PARITY_NONE, 8);
|
||||
}
|
||||
} // namespace wl_134
|
||||
} // namespace esphome
|
63
esphome/components/wl_134/wl_134.h
Normal file
63
esphome/components/wl_134/wl_134.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace wl_134 {
|
||||
|
||||
class Wl134Component : public text_sensor::TextSensor, public Component, public uart::UARTDevice {
|
||||
public:
|
||||
enum Rfid134Error {
|
||||
RFID134_ERROR_NONE,
|
||||
|
||||
// from library
|
||||
RFID134_ERROR_PACKET_SIZE = 0x81,
|
||||
RFID134_ERROR_PACKET_END_CODE_MISSMATCH,
|
||||
RFID134_ERROR_PACKET_CHECKSUM,
|
||||
RFID134_ERROR_PACKET_CHECKSUM_INVERT
|
||||
};
|
||||
|
||||
struct Rfid134Reading {
|
||||
uint16_t country;
|
||||
uint64_t id;
|
||||
bool isData;
|
||||
bool isAnimal;
|
||||
uint16_t reserved0;
|
||||
uint32_t reserved1;
|
||||
};
|
||||
// Nothing really public.
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
|
||||
void set_do_reset(bool do_reset) { this->do_reset_ = do_reset; }
|
||||
|
||||
private:
|
||||
enum DfMp3Packet {
|
||||
RFID134_PACKET_START_CODE,
|
||||
RFID134_PACKET_ID = 1,
|
||||
RFID134_PACKET_COUNTRY = 11,
|
||||
RFID134_PACKET_DATA_FLAG = 15,
|
||||
RFID134_PACKET_ANIMAL_FLAG = 16,
|
||||
RFID134_PACKET_RESERVED0 = 17,
|
||||
RFID134_PACKET_RESERVED1 = 21,
|
||||
RFID134_PACKET_CHECKSUM = 27,
|
||||
RFID134_PACKET_CHECKSUM_INVERT = 28,
|
||||
RFID134_PACKET_END_CODE = 29,
|
||||
RFID134_PACKET_SIZE
|
||||
};
|
||||
|
||||
bool do_reset_;
|
||||
|
||||
Rfid134Error read_packet_();
|
||||
uint64_t hex_lsb_ascii_to_uint64_(const uint8_t *text, uint8_t text_size);
|
||||
};
|
||||
|
||||
} // namespace wl_134
|
||||
} // namespace esphome
|
Loading…
Reference in New Issue
Block a user