twocolors / esphome-native-api Goto Github PK
View Code? Open in Web Editor NEWThis project forked from bradleywehmeier/esphome-native-api
License: MIT License
This project forked from bradleywehmeier/esphome-native-api
License: MIT License
Are you planning to implement noise encryption and token (key) auth?
Im totally confused about the usage of setState. How do i send an outbound command to the ESP to toggle a switch? The example provided is unfortunately very vague.
I have tried for hours to get it to work in various ways but at best only got all Switches to toggle at the same. I added each entity to an array set as a listener for an event emitter but this never worked properly.
What is the way to send a state change to the ESP board outside of the "entity.on" code block?
can you please provide a functioning example? are event emitters even required for this?
I have an issue with one of my user, I end up with an exception in:
buildMessage(messageId, bytes) {
return pb[id_to_type[messageId]].deserializeBinary(bytes);
}
2023-12-24T09:16:37.803Z [err] [ManagerDrivers] [Driver:esphome-wizard] [PhysicalDevice:vattenfall] [Client] Received an error: TypeError: Cannot read properties of undefined (reading 'deserializeBinary')
at PlaintextFrameHelper.buildMessage (/app/node_modules/@2colors/esphome-native-api/lib/utils/frameHelper.js:37:42)
at PlaintextFrameHelper.deserialize (/app/node_modules/@2colors/esphome-native-api/lib/utils/plaintextFrameHelper.js:45:30)
at PlaintextFrameHelper.onData (/app/node_modules/@2colors/esphome-native-api/lib/utils/plaintextFrameHelper.js:55:36)
at Socket.<anonymous> (/app/node_modules/@2colors/esphome-native-api/lib/utils/plaintextFrameHelper.js:7:47)
at Socket.emit (node:events:517:28)
at addChunk (node:internal/streams/readable:368:12)
at readableAddChunk (node:internal/streams/readable:341:9)
at Readable.push (node:internal/streams/readable:278:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23)
I suppose the problem come from an unexpected message type.
Possible to add a check + throw an exception including the messageId?
I can submit a pull request if needed.
Hey,
I use your api for ESP Home in IO Broker. In my thermostats I use the select entity to switch the mode. See the configuration:
select:
In IO Broker i got the following warning. Also I got no entity in the folder.
2023-10-12 21:20:50.307 - warn: esphome.0 (15961) Please submit git issue with all information from next line
2023-10-12 21:20:50.308 - warn: esphome.0 (15961) DeviceType Select | State-Keys {"key":2395909485,"state":"Schedule","missingState":false} | [entityStateConfig] {"config":{"objectId":"schedules","key":2395909485,"name":"Schedules","uniqueId":"heizung-gastwcselectschedules","icon":"mdi:calendar","optionsList":["Manual","Schedule","Holiday"],"disabledByDefault":false,"entityCategory":0},"name":"Schedules","type":"Select","unit":""}
Does anybody know this fault and can help me?
Many Greets
Please forgive my lack of understanding about this API and Javascript programming in general but im having pretty difficult time implementing this API in a real world project.
It was not clear in the beginning how to push state changes to the modules but then someone mentioned using switchCommandService
rather than setState
. So i got that to work by using an Emitter in the Client.on('newEntity'
code block but this is where things get a little weird.
If the ESP client goes offline, resets or otherwise stops responding, then the problem is with the stagnant emitter that gets lost in the old client connection. I have tried many many ways to fix this issue but all attempts to use the removeEventListener
function fail, even if i use global variables and functions. This leaves only one option and that is to use the removeAllListeners()
function to kill all listeners (including those used by other APIs!!) and then disconnect all ESP client connections so that the listeners will be recreated and reconnect to all ESP devices. This is really undesirable because important updates or commands could be lost during this process.
I hate this workaround but i dont see any other options, ive been at this for days, im ready to give up...
esp: function () { // currently testing for outgoing signaling
espInit(); // start the init sequence
function espInit() { // create a new client for every ESP device in the local object
for (let x = 0; x < cfg.esp.length; x++) {
espClient.push(clientNew(x));
state.esp.entities.push([]); // create entity array for each ESP device
clientConnect(x);
}
}
function clientConnect(x) { // client connection function, ran for each ESP device
espClient[x].connect();
espClient[x].on('newEntity', entity => {
let exist = 0;
for (let e = 0; e < state.esp.entities[x].length; e++) { // scan for this entity in the entity list
if (state.esp.entities[x][e].id == entity.id) exist++;
}
if (exist == 0) // dont add this entity if its already in the list
state.esp.entities[x].push({ name: entity.config.objectId, type: entity.type, id: entity.id });
log("new esp connected, " + entity.config.objectId, 2);
if (entity.type === "Switch") { // if this is a switch, register the emitter
// log("setting entity: " + id + " to " + state, 0, 0)
em.on(entity.config.objectId, function (id, state) { // emitter for this connection
entity.connection.switchCommandService({ key: id, state: state });
});
}
entity.on('state', (data) => {
for (let y = 0; y < state.esp.entities[x].length; y++) {
if (state.esp.entities[x][y].id == data.key) { // identify this entity request with local object
// log("esp data: " + state.esp.entities[x][y].name + " state: " + data.state, 2, 0)
for (let a = 0; a < state.udp.length; a++) { // scan all the UDP clients and find which one cares about this entity
for (let b = 0; b < state.udp[a].esp.length; b++) { // scan each UDP clients registered ESP entity list
if (state.udp[a].esp[b] == state.esp.entities[x][y].name) { // if there's a match, send UDP client the data
udp.send("E" + JSON.stringify({ id: state.esp.entities[x][y].name, state: data.state }), state.udp[a].port);
break;
}
}
}
}
}
});
});
espClient[x].on('error', (error) => {
console.log(error);
log("ESP module went offline, resetting ESP system", 2, 2);
reset(); // if there's a connection problem, start reset sequence
});
}
function clientNew(x) { // create new object for every ESP device
return new Client({
host: cfg.esp[x].ip,
port: 6053,
encryptionKey: cfg.esp[x].key,
reconnect: true,
reconnectInterval: 2000,
pingInterval: 3000,
pingAttempts: 3
})
}
function reset() {
em.emit('ws-disconnect'); // close and reset websocket service (because removeAllListeners)
em.removeAllListeners(); // remove all event listeners
for (let c = 0; c < espClient.length; c++) espClient[c].disconnect(); // disconnect every client
espClient = []; // delete all client objects
setTimeout(() => { espInit(); }, 1000); // reconnect to every device
}
},
thank you solving discovery functionality.
I have one issue providing an interface, as system can have multiple network cards allowing to bind is an nice feature.
Using 0.0.0.0 as interface works well, 127.0.0.1 also has no issue (no devices found as expected)
discovery = new Discovery({interface: '0.0.0.0'});
When I call the function with an interface ip address I get an error:
discovery = new Discovery({interface: '192.168.10.107'});
support bluetooth ...
Hello, I'm using this great API to connect Homey (home automation hub) to ESPhome devices.
Mostly working out great for the usages I need, but I get the rejection below often.
Seems it doesn't have any consequence, but still pollute my statistics.
I don't understand the concept of rejection, so I hav' no idea how to fix it.
Any idea?
The stack trace doesn't provide any information about the message failing, maybe additionnal logs would be usefull.
Error: sendMessage timeout
at Timeout.<anonymous> (/app/node_modules/@2colors/esphome-native-api/lib/connection.js:201:20)
at listOnTimeout (node:internal/timers:569:17)
at process.processTimers (node:internal/timers:512:7)
Hello guys,
I just noticed that even if I ernable the "initializeListEntities: true" flag on connection, I do not receive all the "newEntity" event.
I jsut provide an extract of my device configuration:
- id: heater_4
platform: template
name: "Heater 4"
optimistic: true
restore_mode: ALWAYS_OFF
on_turn_on:
then:
lambda: !lambda |-
if (!id(apply_delay_4).is_running()) {
id(apply_delay_4).execute();
}
on_turn_off:
then:
lambda: !lambda |-
if (!id(apply_delay_4).is_running()) {
id(apply_delay_4).execute();
}
- id: relay_1
platform: gpio
pin: GPIO16
disabled_by_default: true
restore_mode: ALWAYS_OFF
on_turn_on:
then:
- script.execute: max_heating_delay_1
on_turn_off:
then:
- script.stop: max_heating_delay_1
heater_4 will trigger a newEntity event, but not relay_1 ...
Any idea why? should I add something in my yaml to trigger it?
Thank you
more in esphome/aioesphomeapi@5a8c0d8
discovery return empty list
rewrite ...
Using auto discovery it looks like we get the Gateway address instead of Device-IP:
// Listener for discovered devices
discovery.on('info', async (message) => {
try {
this.log.debug(`Discovery message ${JSON.stringify(message)}`);
} catch (e) {
this.log.error(`[deviceDiscovery handler] ${e}`);
}
});
Which is my Gateway address, this happens for every device found with AutoDiscovery
In addition, I want to use the bind interface option, type definitions seems to be missing or not in line with documentation?
discovery = new Discovery(
// @ts-ignore Type definition of export is incorrect, according to documentation interface can be set https://github.com/twocolors/esphome-native-api#discovery-1
{
interface : this.config.discoveryListeningAddress ? this.config.discoveryListeningAddress: '0.0.0.0'
});
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.