ioBroker / AdapterRequests

This Place is used to track the status of new Adapter-Requests.
248 stars 36 forks source link

Brunner EAS3 Wlan "Elektronische Abbrandsteuerung" #761

Open sharky-os opened 1 year ago

sharky-os commented 1 year ago

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

mcm1957 commented 1 year 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

JR-Home commented 1 year ago

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*/);
JoMass commented 1 year ago

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).

maxleistner commented 7 months ago

@JR-Home how do you connect to the system? The shown IP address from the app is not connectable.

JR-Home commented 7 months ago

@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.

maxleistner commented 7 months ago

Ok ;) so how do you receive the signals? There's no API or anything that I know of.

JR-Home commented 7 months ago

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.

maxleistner commented 7 months ago

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🙈

thorstenfleischmann commented 1 month ago

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

thorstenfleischmann commented 1 month ago

I designed a flow for home assistant myself and published it here: https://github.com/thorstenfleischmann/brunner-eas3-node-red-home-assistant-connect/

krischan1410 commented 3 weeks ago

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