Open sharky-os opened 2 years ago
Could be this unit: https://www.primus-ofenshop.com/wp-content/uploads/Brunner-EAS-3-Bedienungsanleitung.pdf
An implementation would most likely require matching hardware
I do not have an adapter for EOS3, but a Java script which processes the broadcast messages from Brunner EOS3. Can anybody create an adpater out of it? Recommended: EOS3 Firmware 3.25 or newer.
console.log( "Skript Kachelofen Temperatur Version 1.16 started..." );
const cBrunnerEAS3HeizraumTemperatur = "javascript.0.BrunnerEAS3.HeizraumTemperatur";
const cBrunnerEAS3AbbrandStatus = "javascript.0.BrunnerEAS3.AbbrandtStatus";
const cBrunnerEAS3Broadcast = "javascript.0.BrunnerEAS3.Broadcast";
const cBrunnerEAS3Broadcast2 = "javascript.0.BrunnerEAS3.Broadcast2";
const cBrunnerEAS3LetzterAbbrand = "javascript.0.BrunnerEAS3.LetzterAbbrand";
const cBrunnerEAS3LetzterAbbrandMS = "javascript.0.BrunnerEAS3.LetzterAbbrandMS";
const cPortNumberEAS3Broadcast = 45454;
// Status Brunner:
// -1 - Status nicht verfügbar. WLAN unterbrochen
// 0 - Türe offen
// 1 - Abrand start
// 2- Abbrand Stufe 2...
// 5 - Abbrand Ende
// 6 - Fehler/Timeout, Abbrandt Start wurde nicht erkannt
// 7 - Alles vorbei... Aus.
createState( cBrunnerEAS3HeizraumTemperatur, 0, false, {name: 'Brunner Kamin Brennraum Temperatur', type: 'number', unit: '°C'});
createState( cBrunnerEAS3AbbrandStatus, 0, false, {name: 'Brunner Kamin Abbrandt Status', type: 'number', unit: ''});
createState( cBrunnerEAS3Broadcast, "Init", true, {name: 'Brunner Kamin Broadcast', type: 'string', unit: ''});
// createState( cBrunnerEAS3Broadcast2, 0, false, {name: 'Brunner Kamin Broadcast2', type: 'string', unit: ''});
createState( cBrunnerEAS3LetzterAbbrand, formatDate(Date.now(), "TT.MM.JJJJ SS:mm"), false, {name: 'Brunner letzter Abbrand', type: 'string', unit: ''});
createState( cBrunnerEAS3LetzterAbbrandMS, Date.now(), false, {name: 'Brunner letzter Abbrand', type: 'number', unit: ''});
// Require dgram module.
var dgram = require('dgram');
// Create udp server socket object.
var server = dgram.createSocket("udp4");
// Mit der FW-Version 3.25 ist ein weiterer Parameter hinzugekommen. Bedeutung noch unklar. RegExpr. musste daher angepasst werden
var re = /<bdle eas.+stat="(\d+)">(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\-?\d+);(\d+);(\d+);(\d+);?(\d*).+;<\/bdle>/;
// Port Nummer der Brunner EAS3 Abbrandt Steuerung
server.bind( cPortNumberEAS3Broadcast );
// When udp server receive message.
server.on("message", function ( message ) {
// Create output message.
var sMessage = message.toString()
var resultArray = re.exec( sMessage );
if( resultArray != null ) {
// console.log( resultArray );
// Array Index 0 enthält den ganzen match, ab 1 dann den Inhalt der Klammern
// Idnex 1 Status, Idnex 14 Temperatur (letzter Wert in Aufzählung)
setState( cBrunnerEAS3HeizraumTemperatur, parseInt( resultArray[14] ) );
var iAbbrandStatus = parseInt( resultArray[1] );
var iAbbrandStatusAlt = getState( cBrunnerEAS3AbbrandStatus ).val;
if( iAbbrandStatus >= 2 && iAbbrandStatusAlt >=0 && iAbbrandStatusAlt < 2 )
{
// Ein Abbrand ist zu Ende gegangen. Zeit merken
setState( cBrunnerEAS3LetzterAbbrandMS, Date.now() );
setState( cBrunnerEAS3LetzterAbbrand, formatDate(Date.now(), "TT.MM.JJJJ SS:mm") );
}
setState( cBrunnerEAS3AbbrandStatus, iAbbrandStatus );
setState( cBrunnerEAS3Broadcast, sMessage, true );
}
else {
// console.log( "Udp receive unknown message : " + sMessage + "\n" );
// setState( cBrunnerEAS3Broadcast2, sMessage, true );
}
});
// When udp server started and listening.
server.on('listening', function () {
// Get and print udp server listening ip address and port number in log console.
var address = server.address();
console.log('UDP Server started and listening on ' + address.address + ":" + address.port);
});
/*
var s = '<bdle eas="0" pin="0" cmd="410" stat="7">0;1;1;52;2;0;0;319;1;-10;0;0;45;</bdle>'
var resultArray = re.exec( s );
if( resultArray != null ) {
console.log( "Skript Test:" + resultArray );
setState( cBrunnerEAS3HeizraumTemperatur, parseInt( resultArray[12] ) );
setState( cBrunnerEAS3AbbrandStatus, parseInt( resultArray[0] ) );
}
else {
// console.log( "Udp receive unknown message : " + message + "\n" );
}
*/
// schedule("*/5 * * * *", function () { // Abfrage alle 5 Min
// Schedule funktioniert bei zyklischem Aufrufen nicht bei Zeitumstellungen. Wird nicht oder zu oft aufgerufen!! Daher setInterval verwenden
setInterval( function () {
// Wenn wir für mehr als 6 Minuten keine Verbindung mehr zur Brunner EAS 3 hatten, dann
// haben wir die Verbindung verloren!
if( getState( cBrunnerEAS3HeizraumTemperatur ).val > -99 )
{
if( Date.now() - getState( cBrunnerEAS3HeizraumTemperatur ).lc > 6 * 60 * 1000 )
{
setState( cBrunnerEAS3HeizraumTemperatur, -99, false );
setState( cBrunnerEAS3AbbrandStatus, -1, false );
setState( cBrunnerEAS3Broadcast, "Timeout, EAS3 connection lost!, false" );
}
}
}, 5 * 60 * 1000 );
// close connection if script stopped
onStop( function () {
server.close();
log("Close Socket...")
}, 2000 /*ms*/);
Thank you JR-Home
Your tips enabled me to read in the data streams provided by EAS3. I used NodeRed "UDP listen node" to capture, analyze and store the data. (The easier way for programming dummies).
@JR-Home how do you connect to the system? The shown IP address from the app is not connectable.
@JR-Home how do you connect to the system? The shown IP address from the app is not connectable.
I do not "connect" to the EAS3, I only receive the broadcast messages which are cyclically send by EAS3.
Ok ;) so how do you receive the signals? There's no API or anything that I know of.
Ok ;) so how do you receive the signals? There's no API or anything that I know of.
Correct. There is no API documentation. I have done reverse engineering by packet inspection with wireshark.
Do you have a working solution i could use? How would the setup look like. I would pay for getting a push notification as soon as i can put new wood in the oven 😂 the app is the worst I've ever seen🙈
Thank you JR-Home
Your tips enabled me to read in the data streams provided by EAS3. I used NodeRed "UDP listen node" to capture, analyze and store the data. (The easier way for programming dummies).
Hi. Would you share your node red flow? Would be awesome
I designed a flow for home assistant myself and published it here: https://github.com/thorstenfleischmann/brunner-eas3-node-red-home-assistant-connect/
Just for your interest: With the info from JR-Home I created a Homebridge plugin which provides the EAS device to Apple HomeKit as a temperature sensor: https://www.npmjs.com/package/homebridge-brunner-eas
@JR-Home do you have a new version of the script?
I added some parameter to the js. Now it works with the Version 3.37
console.log( "Skript Kachelofen Temperatur Version 3.37 started..." );
const cBrunnerEAS3HeizraumTemperatur = "javascript.0.BrunnerEAS3.HeizraumTemperatur";
const cBrunnerEAS3Version = "javascript.0.BrunnerEAS3.Version";
const cBrunnerEAS3VersionParameter = "javascript.0.BrunnerEAS3.VersionParameter";
const cBrunnerEAS3VerlAbbrand = "javascript.0.BrunnerEAS3.S+";
const cBrunnerEAS3Oeko = "javascript.0.BrunnerEAS3.Oeko";
const cBrunnerEAS3Drosselklappe = "javascript.0.BrunnerEAS3.Drosselklappe";
const cBrunnerEAS3Display = "javascript.0.BrunnerEAS3.DisplayBri";
const cBrunnerEAS3Summer = "javascript.0.BrunnerEAS3.Summer";
const cBrunnerEAS3NLH = "javascript.0.BrunnerEAS3.NLH";
const cBrunnerEAS3Heizeinsatz = "javascript.0.BrunnerEAS3.Heizeinsatz";
const cBrunnerEAS3AbbrandStatus = "javascript.0.BrunnerEAS3.AbbrandtStatus";
const cBrunnerEAS3Broadcast = "javascript.0.BrunnerEAS3.Broadcast";
const cBrunnerEAS3Broadcast2 = "javascript.0.BrunnerEAS3.Broadcast2";
const cBrunnerEAS3LetzterAbbrand = "javascript.0.BrunnerEAS3.LetzterAbbrand";
const cBrunnerEAS3LetzterAbbrandMS = "javascript.0.BrunnerEAS3.LetzterAbbrandMS";
const cPortNumberEAS3Broadcast = 45454;
// Status Brunner:
// -1 - Status nicht verfügbar. WLAN unterbrochen
// 0 - Türe offen
// 1 - Abrand start
// 2- Abbrand Stufe 2...
// 5 - Abbrand Ende
// 6 - Fehler/Timeout, Abbrandt Start wurde nicht erkannt
// 7 - Alles vorbei... Aus.
createState( cBrunnerEAS3HeizraumTemperatur, 0, false, {name: 'Brunner Kamin Brennraum Temperatur', type: 'number', unit: '°C'});
createState( cBrunnerEAS3AbbrandStatus, 0, false, {name: 'Brunner Kamin Abbrandt Status', type: 'number', unit: ''});
createState( cBrunnerEAS3Version, 0, true, {name: 'Brunner EAS 3 Version', type: 'number', unit: ''});
createState( cBrunnerEAS3VersionParameter, 0, true, {name: 'Brunner EAS 3 Version Parameter', type: 'number', unit: ''});
createState( cBrunnerEAS3VerlAbbrand, 0, true, {name: 'Brunner EAS 3 Verlängerter Abbrand S+', type: 'number', unit: ''});
createState( cBrunnerEAS3Oeko, 0, true, {name: 'Brunner EAS 3 Öko-Abbrand ', type: 'number', unit: ''});
createState( cBrunnerEAS3Drosselklappe, 0, true, {name: 'Brunner EAS 3 Drosselklappe aktiviert', type: 'number', unit: ''});
createState( cBrunnerEAS3Display, 0, true, {name: 'Brunner EAS 3 Hintergrund-Beleuchtung', type: 'number', unit: '%'});
createState( cBrunnerEAS3Summer, 0, true, {name: 'Brunner EAS 3 Intensität (Frequenz bzw. Lautstärke) des Summers', type: 'number', unit: ''});
createState( cBrunnerEAS3NLH, 0, true, {name: 'Brunner EAS 3 Anzeige der Hinweise zum Nachlegen', type: 'number', unit: ''});
createState( cBrunnerEAS3Heizeinsatz, 0, true, {name: 'Brunner EAS 3 Aktuelle Heizeinsatznummer', type: 'number', unit: ''});
/* Heizeinsätze mit Nummer
1. HKD 2, HKD 2.2, HKD 2.2 k
2. SK, HKD 2.6 k SK
3. HKD 4, HKD 4.1
4. HKD 5, HKD 5.1
5. HKD 6, HKD 6.1, HKD 2.6
6. B4
7. B5, B6
8. HWM
9. HKD 4sk, HKD 4w
10. Kamin-Kessel, Kamin-Kessel Eck
11. RF 55, RF 55.1
12. RF 66, RF 66.1
13. Kompakt-Kamin
14. Stil-Kamin
15. Eck-Kamin
16. 180° Kamin
17. Grundofen*
18. HF 5
19. HF 7
20. HF10 / HF10w / HFG10 / HWM-HF10
21. HF15, HF 15w, HFG15
22. HF10sk
23. SF7
24. SF10
25. SF10sk, SF20sk
26. B7, B8
27. Herdkessel
28. KKE 33
29. HKD 2.2 XL
30. HKD 2.2 XL SK / HKD 2.2 SK
31. KSO 25 / KSO 33
32. WF 33
33. GOT / GOT+GOF flach
34. WF 25
35. HKD 7/8/9/10/11/12
36. Architektur Kessel
37. WF 50
38. GOT / GOT+GOF Eck
39. Panorama
40. GOT / GOT+GOF Tunnel
41. Architektur
42. DF 33
43. KFR
44. HKD3
45. Scandinavian
46. BKH
*/
createState( cBrunnerEAS3Broadcast, "Init", true, {name: 'Brunner Kamin Broadcast', type: 'string', unit: ''});
// createState( cBrunnerEAS3Broadcast2, 0, false, {name: 'Brunner Kamin Broadcast2', type: 'string', unit: ''});
createState( cBrunnerEAS3LetzterAbbrand, formatDate(Date.now(), "TT.MM.JJJJ SS:mm"), false, {name: 'Brunner letzter Abbrand', type: 'string', unit: ''});
createState( cBrunnerEAS3LetzterAbbrandMS, Date.now(), false, {name: 'Brunner letzter Abbrand', type: 'number', unit: ''});
// Require dgram module.
var dgram = require('dgram');
// Create udp server socket object.
var server = dgram.createSocket("udp4");
var re = /<bdle eas.+stat="(\d+)">(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\d+);(\-?\d+);(\d+);(\d+);(\d+);(\d+);<\/bdle>/;
// Port Nummer der Brunner EAS3 Abbrandt Steuerung
server.bind( cPortNumberEAS3Broadcast);
// When udp server receive message.
server.on("message", function ( message ) {
// Create output message.
var sMessage = message.toString()
var resultArray = re.exec( sMessage );
if( resultArray != null ) {
//console.log( resultArray );
// Array Index 0 enthält den ganzen match, ab 1 dann den Inhalt der Klammern
// Idnex 1 Status, Idnex 14 Temperatur (letzter Wert in Aufzählung)
setState( cBrunnerEAS3HeizraumTemperatur, parseInt( resultArray[14] ) );
setState( cBrunnerEAS3VerlAbbrand, parseInt( resultArray[2] ));
setState( cBrunnerEAS3Oeko, parseInt( resultArray[3] ));
setState( cBrunnerEAS3Drosselklappe, parseInt( resultArray[4] ));
setState( cBrunnerEAS3Display, parseInt( resultArray[5] ));
setState( cBrunnerEAS3Summer, parseInt( resultArray[6] ));
setState( cBrunnerEAS3NLH, parseInt( resultArray[7] ));
setState( cBrunnerEAS3Heizeinsatz, parseInt( resultArray[15] ));
setState( cBrunnerEAS3Version, parseInt( resultArray[9] ));
setState( cBrunnerEAS3VersionParameter, parseInt( resultArray[10] ));
var iAbbrandStatus = parseInt( resultArray[1] );
var iAbbrandStatusAlt = getState( cBrunnerEAS3AbbrandStatus ).val;
if( iAbbrandStatus >= 2 && iAbbrandStatusAlt >=0 && iAbbrandStatusAlt < 2 )
{
// Ein Abbrand ist zu Ende gegangen. Zeit merken
setState( cBrunnerEAS3LetzterAbbrandMS, Date.now() );
setState( cBrunnerEAS3LetzterAbbrand, formatDate(Date.now(), "TT.MM.JJJJ SS:mm") );
}
setState( cBrunnerEAS3AbbrandStatus, iAbbrandStatus );
setState( cBrunnerEAS3Broadcast, sMessage, true );
//console.log("EAS Breadcast "+sMessage)
}
else {
// console.log( "Udp receive unknown message : " + sMessage + "\n" );
// setState( cBrunnerEAS3Broadcast2, sMessage, true );
}
});
// When udp server started and listening.
server.on('listening', function () {
// Get and print udp server listening ip address and port number in log console.
var address = server.address();
console.log('UDP Server started and listening on ' + address.address + ":" + address.port);
});
// Schedule funktioniert bei zyklischem Aufrufen nicht bei Zeitumstellungen. Wird nicht oder zu oft aufgerufen!! Daher setInterval verwenden
setInterval( function () {
// Wenn wir für mehr als 6 Minuten keine Verbindung mehr zur Brunner EAS 3 hatten, dann
// haben wir die Verbindung verloren!
if( getState( cBrunnerEAS3HeizraumTemperatur ).val > -99 )
{
if( Date.now() - getState( cBrunnerEAS3HeizraumTemperatur ).lc > 6 * 60 * 1000 )
{
setState( cBrunnerEAS3HeizraumTemperatur, -99, false );
setState( cBrunnerEAS3AbbrandStatus, -1, false );
setState( cBrunnerEAS3Broadcast, "Timeout, EAS3 connection lost!, false" );
}
}
}, 5 * 60 * 1000 );
// close connection if script stopped
onStop( function () {
server.close();
log("Close Socket...")
}, 2000 /*ms*/);
What kind of device or service you would like to see an adapter for? EAS 3 Wlan Brunner
Is the device connected to the internet or only in the local network available? only local
Is an official App or Website available? https://play.google.com/store/apps/details?id=de.brunner.apps.eas3&hl=de&gl=US https://apps.apple.com/de/app/brunner-eas3/id1588084582
Is an official API including documentation available? no
Are other libraries for an integration available? no
Is this device already integrated in other Smart Home systems? no
Is this device already integrated in homebridge? Might the ham adapter together with the homebridge plugin be sufficient? no
Additional context The EAS sends broadcast udp packet unencrypted in locale network. here is a wireshark recording
bdle eas="0" pin="0" cmd="410" stat="1">0;1;1;80;2;0;0;319;1;16384;0;0;32;</bdle Here is a short excerpt of the data. Each number is information from the oven. For example: 319 = firmware version, 32 = combustion chamber temperature, state = combustion status, the 3rd zero status of the door, etc.
I would like to help and provide everything I have read.
`
After you created the issue vote for yourself in the first post of the issue using the "+1"/"Thumbs up" button