Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite desk_height_sensor.h as external component #96

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions packages/esphome/Flexispot_E7_MQTT_control.yaml
Original file line number Diff line number Diff line change
@@ -11,8 +11,11 @@ esphome:
comment: ${device_name}
platform: ESP8266 # TODO Change to your platform
board: d1_mini # TODO Change to your board
includes:
- desk_height_sensor.h

external_components:
- source: components
components:
- loctek

wifi:
ssid: !secret wifi_ssid
@@ -86,14 +89,11 @@ sensor:
- platform: uptime
name: Uptime

- platform: custom
lambda: |-
auto desk_height_sensor = new DeskHeightSensor(id(desk_uart));
App.register_component(desk_height_sensor);
return {desk_height_sensor};
sensors:
- platform: loctek
uart_id: desk_uart
height:
id: "desk_height"
name: Desk Height
name: Height
unit_of_measurement: cm
accuracy_decimals: 1
icon: "mdi:counter"
Empty file.
180 changes: 180 additions & 0 deletions packages/esphome/components/loctek/loctek.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#include "loctek.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"

namespace esphome {
namespace loctek {

static const char *const TAG = "loctek";

void LoctekComponent::loop() {
while (available() > 0)
{
byte incomingByte = read();
// ESP_LOGD("DEBUG", "Incoming byte is: %08x", incomingByte);

// First byte, start of a packet
if (incomingByte == 0x9b)
{
// Reset message length
this->msg_len_ = 0;
this->valid_ = false;
}

// Second byte defines the message length
if (this->history_[0] == 0x9b)
{
this->msg_len_ = (int) incomingByte;
}

// Third byte is message type
if (this->history_[1] == 0x9b)
{
this->msg_type_ = incomingByte;
}

// Fourth byte is first height digit, if msg type 0x12 & msg len 7
if (this->history_[2] == 0x9b)
{

if (this->msg_type_ == 0x12 && (this->msg_len_ == 7 || this->msg_len_ == 10))
{
// Empty height
if (incomingByte == 0)
{
//ESP_LOGD("DEBUG", "Height 1 is EMPTY -> 0x%02x", incomingByte);
//deskSerial.write(command_wakeup, sizeof(command_wakeup));
}
else if (this->hex_to_int(incomingByte) == 0)
{
//ESP_LOGD("DEBUG", "Invalid height 1 -> 0x%02x", incomingByte);
//deskSerial.write(command_wakeup, sizeof(command_wakeup));
}
else
{
this->valid_ = true;
// ESP_LOGD("DEBUG", "Height 1 is: 0x%02x", incomingByte);
}
}
}

// Fifth byte is second height digit
if (this->history_[3] == 0x9b)
{
if (this->valid_ == true)
{
//ESP_LOGD("DEBUG", "Height 2 is: 0x%02x", incomingByte);
}
}

// Sixth byte is third height digit
if (this->history_[4] == 0x9b)
{
if (this->valid_ == true)
{
int height1 = this->hex_to_int(this->history_[1]) * 100;
int height2 = this->hex_to_int(this->history_[0]) * 10;
int height3 = this->hex_to_int(incomingByte);
if (height2 != 100)
{
float finalHeight = height1 + height2 + height3;
if (this->is_decimal(this->history_[0]))
{
finalHeight = finalHeight / 10;
}
this->value_ = finalHeight;
// ESP_LOGD("DeskHeightSensor", "Current height is: %f", finalHeight);
}
}
}

// Save byte buffer to history arrary
this->history_[4] = this->history_[3];
this->history_[3] = this->history_[2];
this->history_[2] = this->history_[1];
this->history_[1] = this->history_[0];
this->history_[0] = incomingByte;

// End byte
if (incomingByte == 0x9d)
{
if (this->value_ && this->value_ != this->lastPublished_)
{
this->height_->publish_state(this->value_);
this->lastPublished_ = this->value_;
}
}
}
}

void LoctekComponent::dump_config() {

ESP_LOGCONFIG(TAG, "Loctek:");

if (this->is_failed()) {
ESP_LOGE(TAG, "Communication with Loctek failed!");
}

LOG_SENSOR(" ", "HEIGHT", this->height_);

this->check_uart_settings(9600);
}

bool LoctekComponent::is_decimal(byte b) {
return (b & 0x80) == 0x80;
}

int LoctekComponent::hex_to_int(byte s)
{
std::bitset<8> b(s);

if (b[0] && b[1] && b[2] && b[3] && b[4] && b[5] && !b[6])
{
return 0;
}
if (not b[0] && b[1] && b[2] && !b[3] && !b[4] && !b[5] && !b[6])
{
return 1;
}
if (b[0] && b[1] && !b[2] && b[3] && b[4] && !b[5] && b[6])
{
return 2;
}
if (b[0] && b[1] && b[2] && b[3] && !b[4] && !b[5] && b[6])
{
return 3;
}
if (not b[0] && b[1] && b[2] && !b[3] && !b[4] && b[5] && b[6])
{
return 4;
}
if (b[0] && !b[1] && b[2] && b[3] && !b[4] && b[5] && b[6])
{
return 5;
}
if (b[0] && !b[1] && b[2] && b[3] && b[4] && b[5] && b[6])
{
return 6;
}
if (b[0] && b[1] && b[2] && !b[3] && !b[4] && !b[5] && !b[6])
{
return 7;
}
if (b[0] && b[1] && b[2] && b[3] && b[4] && b[5] && b[6])
{
return 8;
}
if (b[0] && b[1] && b[2] && b[3] && !b[4] && b[5] && b[6])
{
return 9;
}
if (!b[0] && !b[1] && !b[2] && !b[3] && !b[4] && !b[5] && b[6])
{
return 10;
}
return 0;
}

} // namespace loctek
} // namespace esphome
43 changes: 43 additions & 0 deletions packages/esphome/components/loctek/loctek.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include <bitset>
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"
#include "esphome/core/component.h"

namespace esphome {
namespace loctek {

class LoctekComponent : public Component, public uart::UARTDevice {
public:
LoctekComponent() = default;
void set_height(sensor::Sensor *height) { height_ = height; }

void setup() override {};
void loop() override;
void dump_config() override;

float get_setup_priority() const override { return setup_priority::DATA; }

protected:
float height_val_ = 0.0;

float value_ = 0;
float lastPublished_ = -1;
unsigned long history_[5];

int msg_len_ = 0;
unsigned long msg_type_;
bool valid_ = false;

sensor::Sensor *height_{nullptr};

int hex_to_int(byte s);
bool is_decimal(byte b);

void publish_nans_();
void set_values_(const uint8_t *buffer);
};

} // namespace loctek
} // namespace esphome
41 changes: 41 additions & 0 deletions packages/esphome/components/loctek/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import uart, sensor
from esphome.const import (
CONF_ID,
CONF_HEIGHT,
DEVICE_CLASS_EMPTY,
UNIT_CENTIMETER,
STATE_CLASS_MEASUREMENT
)

DEPENDENCIES = ["uart"]
CODEOWNERS = ["@phntxx"]

loctek_ns = cg.esphome_ns.namespace("loctek")
loctekCore = loctek_ns.class_("LoctekComponent", uart.UARTDevice, cg.Component)

CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(loctekCore),
cv.Optional(CONF_HEIGHT): sensor.sensor_schema(
unit_of_measurement=UNIT_CENTIMETER,
accuracy_decimals=1,
device_class=DEVICE_CLASS_EMPTY,
state_class=STATE_CLASS_MEASUREMENT
)
}
)
.extend(cv.COMPONENT_SCHEMA)
.extend(uart.UART_DEVICE_SCHEMA)
)

async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await uart.register_uart_device(var, config)

if height_config := config.get(CONF_HEIGHT):
sens = await sensor.new_sensor(height_config)
cg.add(var.set_height(sens))
Loading