Skip to content

Commit

Permalink
Add text entity
Browse files Browse the repository at this point in the history
  • Loading branch information
Johboh committed Jan 21, 2024
1 parent 1285014 commit a648e29
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ In your existing `idf_component.yml` or in a new `idf_component.yml` next to you
```
dependencies:
johboh/HomeAssistantEntities:
version: ">=6.1.2"
version: ">=6.1.3"
```

### Examples
Expand Down
2 changes: 1 addition & 1 deletion examples/espidf/actuators/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
dependencies:
johboh/HomeAssistantEntities:
#version: ">=6.1.2"
#version: ">=6.1.3"
# Remove path and enable version to use HomeAssistantEntities from repository
path: ../../../../
2 changes: 1 addition & 1 deletion examples/espidf/sensors/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
dependencies:
johboh/HomeAssistantEntities:
#version: ">=6.1.2"
#version: ">=6.1.3"
# Remove path and enable version to use HomeAssistantEntities from repository
path: ../../../../
2 changes: 1 addition & 1 deletion idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "6.1.2"
version: "6.1.3"
description: Library for providing sensors and actuators to Home Assistant using MQTT.
url: https://github.com/Johboh/HomeAssistantEntities
dependencies:
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"name": "Johan Böhlin"
},
"version": "6.1.2",
"version": "6.1.3",
"license": "MIT",
"repository":
{
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=HomeAssistantEntities
version=6.1.2
version=6.1.3
author=Johan Böhlin <github@johboh.dev>
maintainer=Johan Böhlin <github@johboh.dev>
sentence=Library for providing sensors and actuators to Home Assistant using MQTT.
Expand Down
4 changes: 2 additions & 2 deletions src/entities/HaEntityString.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include <string>

/**
* @brief Represent a raw String sensor with a state topic on which you post your string.
* Also see [HaEntityJson] which is very similar. TODO(johboh): merge?
* @brief Represent a raw String sensor with a state topic on which you post your string. From HA, read only. See
* [HaEntityText] for a read/write version. Also see [HaEntityJson] which is very similar. TODO(johboh): merge?
*/
class HaEntityString : public HaEntity {
public:
Expand Down
60 changes: 60 additions & 0 deletions src/entities/HaEntityText.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "HaEntityText.h"
#include <HaUtilities.h>
#include <nlohmann/json.hpp>

#define COMPONENT "text"
#define OBJECT_ID "text"
#define OBJECT_ID_TEXT "text"

HaEntityText::HaEntityText(HaBridge &ha_bridge, std::string name, std::string child_object_id,
Configuration configuration)
: _name(homeassistantentities::trim(name)), _ha_bridge(ha_bridge), _child_object_id(child_object_id),
_configuration(configuration) {}

void HaEntityText::publishConfiguration() {
nlohmann::json doc;

if (!_name.empty()) {
doc["name"] = _name;
} else {
doc["name"] = nullptr;
}

doc["min"] = _configuration.min_text_length;
doc["max"] = _configuration.max_text_length;
doc["force_update"] = _configuration.force_update;
if (_configuration.is_password) {
doc["mode"] = "password";
} else {
doc["mode"] = "text";
}

if (_configuration.with_state_topic) {
doc["state_topic"] = _ha_bridge.getTopic(HaBridge::TopicType::State, COMPONENT, OBJECT_ID, _child_object_id);
}

doc["command_topic"] = _ha_bridge.getTopic(HaBridge::TopicType::Command, COMPONENT, _child_object_id, OBJECT_ID_TEXT);

_ha_bridge.publishConfiguration(COMPONENT, OBJECT_ID, _child_object_id, doc);
}

void HaEntityText::republishState() {
if (_str) {
publishText(*_str);
}
}

void HaEntityText::publishText(std::string &str) {
if (!_configuration.with_state_topic) {
return;
}
_str = str;
_ha_bridge.publishMessage(_ha_bridge.getTopic(HaBridge::TopicType::State, COMPONENT, OBJECT_ID, _child_object_id),
str);
}

bool HaEntityText::setOnText(std::function<void(std::string)> callback) {
return _ha_bridge.remote().subscribe(
_ha_bridge.getTopic(HaBridge::TopicType::Command, COMPONENT, _child_object_id, OBJECT_ID_TEXT),
[callback](std::string topic, std::string message) { callback(message); });
}
81 changes: 81 additions & 0 deletions src/entities/HaEntityText.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef __HA_ENTITY_STRING_H__
#define __HA_ENTITY_STRING_H__

#include <HaBridge.h>
#include <HaEntity.h>
#include <cstdint>
#include <optional>
#include <string>

/**
* @brief Represent a raw Text sensor/acturator that can be written and read from Home Assistant.
* Also see [HaEntityString].
*/
class HaEntityText : public HaEntity {
public:
struct Configuration {
// The minimum size of a text being set or received.
uint8_t min_text_length = 0;
// The maximum size of a text being set or received (maximum is 255).
uint8_t max_text_length = 255;
// if true, supports publishing the state. Else, write only text.
bool with_state_topic = false;
// true to indicate to HA that this is a password.
bool is_password = false;
/**
* In Home Assistant, trigger events even if the sensor's state hasn't changed. Useful if you want
* to have meaningful value graphs in history or want to create an automation that triggers on every incoming state
* message (not only when the sensor’s new state is different to the current one).
*/
bool force_update = false;
};

/**
* @brief Construct a new Ha Entity Text object
*
* @param name this is the human readable name that will be used for the entity in Home Assistant. If a device is set
* when creating the [HaBridge], the friendly named displayed in the UI will be the device name plus this name.
* Example: if device name is "Bathroom" and entity name "text", friendly name will be "Bathroom text". If no
* device, friendly name will be just "text". If a device is set, this name can be left empty if this entity is the
* one main entity (or only) entity of this device. See
* https://developers.home-assistant.io/docs/core/entity/#entity-naming for more
* information.
* @param child_object_id optional child identifier for this entity in case there are several sensors of the same
* entity type for the same node ID. Example: If you have a lock for the node ID "door", the home asisstant
* configuration path will be "homeassistant/binary_sensor/door/lock/config". This works if you only have one lock on
* your door, but if you have two locks, you want to add a child object ID to them. By setting the child_object_id to
* say "upper", the configuration will be "homeassistant/binary_sensor/door/lock/upper/config". This also apply for
* all state/command topics and so on. Leave as empty string for no child object ID. Valid characters
* are [a-zA-Z0-9_-] (machine readable, not human readable)
*/
HaEntityText(HaBridge &ha_bridge, std::string name, std::string child_object_id, Configuration configuration);

public:
void publishConfiguration() override;
void republishState() override;

/**
* @brief Publish the text.
* with_state in constructor must be set.
*
* @param str the text to publish.
*/
void publishText(std::string &str);

/**
* @brief Set callback for receving callbacks when there is a new text that should be set.
*/
bool setOnText(std::function<void(std::string)> callback);

private:
std::string _name;
bool _force_update;
HaBridge &_ha_bridge;
std::string _child_object_id;
Configuration _configuration;

private:
std::optional<std::string> _str;
};

#endif // __HA_ENTITY_STRING_H__

0 comments on commit a648e29

Please sign in to comment.