mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 01:07:45 +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
5 changed files with 206 additions and 0 deletions
|
@ -254,6 +254,7 @@ esphome/components/wake_on_lan/* @willwill2will54
|
||||||
esphome/components/web_server_base/* @OttoWinter
|
esphome/components/web_server_base/* @OttoWinter
|
||||||
esphome/components/whirlpool/* @glmnet
|
esphome/components/whirlpool/* @glmnet
|
||||||
esphome/components/whynter/* @aeonsablaze
|
esphome/components/whynter/* @aeonsablaze
|
||||||
|
esphome/components/wl_134/* @hobbypunk90
|
||||||
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
|
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
|
||||||
esphome/components/xiaomi_mhoc303/* @drug123
|
esphome/components/xiaomi_mhoc303/* @drug123
|
||||||
esphome/components/xiaomi_mhoc401/* @vevsvevs
|
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 a new issue