Smarter Wifi iKettle 2 script for Domoticz

Python and python framework
ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter iKettle 2 script for Domoticz

Post by ben53252642 » Friday 29 July 2016 23:35

I got the UK version on Amazon

https://www.amazon.co.uk/gp/product/B01 ... UTF8&psc=1

Says £99.99

A week ago I paid £83.33

Exact same link....

They seem to have changed the pricing on the coffee machine too, I paid £119.83 and its now £143.99.

https://www.amazon.co.uk/gp/product/B01 ... UTF8&psc=1

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter iKettle 2 script for Domoticz

Post by trixwood » Friday 29 July 2016 23:44

Sometimes you're lucky :-)

I am living in holland, so those links was the best I could find for my region at this time of writing. I should have mentioned that.

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter iKettle 2 script for Domoticz

Post by trixwood » Saturday 30 July 2016 0:30

From

https://github.com/AdenForshaw/smarter- ... fee-api.py

And this is from the coffe machine parts..

Code: Select all

if return_code =="\x03\x00~":
	success=1
	message="brewing"
elif return_code=="\x03\x01~":
	message="already brewing"
elif return_code=="\x03\x05~":
	message="no carafe"
elif return_code=="\x03\x06~":
	message="no water"
elif return_code=="\x03i~":
	success=1
	message="reset"
So it looks like
root@Domoticz:~/smarter# python kettle.py "status" | od -t x1
0000000 03 00 7e 0a
0000004
The 00 also means something for the ikettle, I suspect... well we see tuesday evening...


Ofcourse you can build one yourself, an diy-ikettle i mean :-)

https://www.hackster.io/lahorde/from-a- ... tle-d2b3f7

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter iKettle 2 script for Domoticz

Post by ben53252642 » Saturday 30 July 2016 6:26

.
Last edited by ben53252642 on Saturday 30 July 2016 23:31, edited 2 times in total.

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter iKettle 2 script for Domoticz

Post by trixwood » Saturday 30 July 2016 7:36

way cool!

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter iKettle 2 script for Domoticz

Post by ben53252642 » Saturday 30 July 2016 23:20

Trixwood, thanks for your help. I've finished the script (see my first post). The only thing I couldn't figure out was setting the temperature, if you find out how to do that please let me know. :D

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by trixwood » Wednesday 03 August 2016 18:41

Which firmware do you use? Your script is only half working. On/Off base does not work.

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Wednesday 03 August 2016 23:58

latest firmware version, set print b down the bottom of the script and check the binary output when you put the kettle on and off the base,

Let me know if you see different values, I know there are different values on the coffee machine, it was just a matter of recording them all. Pls copy and past the binary when its on and off so I can compare it add into the script. :D

Does on / off work from the script?

Also note I had to try the firmware update about 3x before it finally succeeded (which appeared to happen when I tried the update again while ignoring the request to power cycle the unit).

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Friday 05 August 2016 11:10

Trixwood, did you get it working?

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by trixwood » Friday 05 August 2016 11:12

iKettle 2.0 Smarter Coffee Controller & Protocol Analyser

Extended script from above with all functionality and bug fixes. Except the domoticz part.

Implemented
* Some Smarter Coffee Commands
* console to analyse procotol including help system
* monitor
* command line control

Not yet implemented
* domoticz sync
* some messages processing
* procotol emulator
* protocol man-in-middle relayer

Code: Select all

#!/usr/bin/python
# -*- coding: utf8 -*-
import socket
import sys
import struct
import random

iBrewVersion = "White Tea Edition v0.06 © 2016 TRiXWooD"


#------------------------------------------------------
# iBrew DEFAULT USER SETTINGS
#
#------------------------------------------------------

#iKettle 2 or Smarter Coffee Host
host = '10.0.0.93';

#Domoticz Monitor
#format: "HOST:PORT" or "USERNAME:PASSWORD@HOST:PORT"
domoticz = "USERNAME:PASSWORD@10.0.0.1:8090"


#------------------------------------------------------
# iBrew PROTOCOL
#
# Protocol information to iKettle 2.0 or Smarter Coffee
# Devices (500 lines of ugly code)
#------------------------------------------------------
#
#    References:
#    https://github.com/Jamstah/libsmarteram2/wiki/Protocol-documentation
#    https://github.com/ian-kent/ikettle2/tree/master/protocol
#    https://github.com/athombv/am.smarter/blob/master/node_modules/ikettle2.0/ikettle2.0.js
#    https://github.com/athombv/am.smarter/blob/master/node_modules/coffee/index.js
#    https://github.com/AdenForshaw/smarter-coffee-api/blob/master/smarter-coffee-api.py
#    https://www.pentestpartners.com/blog/hacking-a-wi-fi-coffee-machine-part-1/
#    https://www.hackster.io/lahorde/from-a-14-kettle-to-an-ikettle-d2b3f7
#
#    https://github.com/nanab/smartercoffee/blob/master/sendcommand.py
#
#

class iBrewProtocol:
    def base(self):
        print
        print "Smarter iKettle 2.0 & Smarter Coffee Protocol"
        print "_____________________________________________"
        print
        print "Smarter uses a binary message protocol,"
        print "either via UDP or TCP on port 2081"
        print
        print "Messages (commands and responses) use the syntax:"
        print
        print "    <ID>[ARGUMENTS]<TAIL>"
        print
        print ""
        print "The tail is always 7e or ~ in ASCII"
        print
        print "Arguments use this syntax:"
        print
        print "    <ARGUMENT>   is a single mandatory byte"
        print "    <[ARGUMENT]> is a single optional byte"
        print "    <ARGUMENT>{0,32} is mandatory, between 0 and 32 bytes"
        print
        print "Everything else, including spurious } characters, are ASCII literals"
        print
        print "Use messages command to list all messages"
        print

    def messages(self):
        print
        print "♨ ☕ ID Command Message Description"
        print "____________________________________"
        print "    02 Set the machine time"
        print "    05 Set network SSID"
        print "    07 Set WiFi password"
        print "✕   07 Start brewing Coffee???)"
        print "♨   0d Scan for WiFi networks"
        print "    10 Reset ???"
        print "♨   15 Turn on"
        print "♨   16 Turn off"
        print "♨   20 Boiling Turn on"
        print "♨   21 Boiling Turn on"
        print "♨   22 Boiling Turn on"
        print "♨   23 Boiling Turn on ???"
        print "♨   28 ???"
        print "♨   2c Calibrate Water Sensor"
        print "    32 ???"
        print "✕ ☕ 35 Set strength of the coffee to brew"
        print "✕ ☕ 36 Set number of cups to brew"
        print "✕ ☕ 37 ???"
        print "✕ ☕ 3c Toggle the Grinder on/off"
        print "✕ ☕ 3e Turn on the hotplate"
        print "✕ ☕ 40 Updating schedules ???"
        print "✕ ☕ 41 Requesting schedules ???"
        print "✕ ☕ 43 Schedules ???"
        print "✕ ☕ 4a Turn off the hot plate"
        print "♨ ☕ 64 Get Identify of device"
        print "♨   69 ???"
        print "♨   6a Get Firmware Info WiFi module"
        print "    6d Firmware Update"
        print
        print "♨ ☕ ID Response Message Description"
        print "___________________________________"
        print "♨ ☕ 03 Status"
        print "    0c Complete WiFi setup"
        print "♨   0e List of WiFi networks"
        print "♨   29 ???"
        print "♨   14 Device status"
        print "♨   2d Calibrate completed"
        print "♨ ☕ 65 Identify of device"
        print "♨ ☕ 6b Firmware Indo WiFi module"
        
        print
        print "Legend:"
        print "  ♨ iKettle 2"
        print "  ☕ Smarter Coffee"
        print

    def calibration(self):
        print
        print "Calibration:"
        print
        print "      If the kettle is on the base during calibration, the numbers change to be higher,"
        print "      but the differences between levels seem the same. This means that the water level"
        print "      detection is probably weight based and that calibration is done at the base,"
        print "      which then remembers the weight for \'off base\'. To detect an empty kettle,"
        print "      the connecting device must account for the weight of the kettle itself."

    def coffeebrewing(self):
        print
        print "Coffee Brewing:"
        print
        print "      Between setting the number of cups, the strength of the coffee and start of brewing"
        print "      atleast 500ms is recommended."


    def message(self,id):
        print "________________________________________________"
        if id == '02':
            print "Message 02: Set Time"
            print "  ?"
            print
            print "Arguments: <Seconds><Minutes><Hours><Unknown><Day><Month><Century><Year>"
            print "Note: Unknown is Day of week index?"
        
        elif id == '03':
            #Fix
            print "d"
        elif id == '05':
            print "Message 05: Set network SSID"
            print "  ?"
            print
            print "Argument: <SSID>{0,32}"
            print "Note: SSID is between 0 and 32 characters"
        elif id == '07':
            print "Message 07: Set WiFi password"
            print "  ?"
            print
            print "Argument: <password>{0,32}"
            print "Note: password is between 0 and 32 characters"
            print
            print "Message 07: Start brewing Coffee???"
            print " ?"
        elif id == '0c':
            print "Message 0c: WiFi setup finished"
            print "  ?"
            print
            print "No information available on message"
        elif id == '0d':
            print "Message 0d: Scan for WiFi networks"
            print "  ?"
            print
            print "Returns: Message 0e"
            print
            print "Example raw code: 0d 7e"
        elif id == '0e':
            print "Message 0e: List of WiFi network"
            print "  ?"
            print
            print "Arguments: <SSID>{0,32},-<db>{2}}"
            print "Note: SSID is between 0 and 32 characters"
            print "      Sending message 0c without previous SSID/password messages will reset WiFi to factory settings"
            print "      -db is the signal strength in dBm format"
            print
            print "Examples: MyWifi,-56}"
            print "          MyWifi,-56}OtherWifi,-82}"
        elif id == '10':
            print "Message 10: Reset ???"
            print "  ?"
            print
            print "No information available on message"
        elif id == '14':
            print "Message 14: Device status"
            print " ?"
            print
            print "Arguments: <status><temperature><waterHighbits><waterLowbits><unknown>"
            self.calibration()
            
            #FIX
        
        #    1	0x00	Device Status. 0=Ready. 1=Boiling. 2=Keep warm. 3=Cycle finished. 4=Baby cooling.
        #    2	0x28	Temperature in Celsius. 0x7f = Not on base.
        #    3	0x07	Water level (high bits), see below.
        #    4	0xf7	Water level (low bits), see below.
        #    5	0x00	Unknown, possibly reserved. Only seen 0x00 on the iKettle 2.0
        
        elif id == '15':
            print "Message 15: Turn On"
            print "  ?"
            print
            print "Argument: <temperature>"
            print
            print "Example raw code: 15 ?? 7e"
        elif id == '16':
            print "Message 16: Turn Off"
            print "  ♨ iKettle 2.0"
            print
            print "Example raw code: 16 7e"
        elif id == '20':
            print "Message 20: Turn On"
            print "  ♨ iKettle 2.0"
            print
            print "Example raw code: 22 7e"
        elif id == '21':
            print "Message 21: Turn On"
            print "  ♨ iKettle 2.0"
            print
            print "Arguments: <[<temperature><[time]>]>"
            print
            print "Keep Warm between 5 and 20 minutes, 0 for normal on"
            print
            print "Example raw code: 21 7e"
            print "                  21 50 00 7e"
            print "                  21 30 05 7e"
            print "                  21 44 7e"
        elif id == '22':
            print "Message 22: Turn On"
            print "  ♨ iKettle 2.0"
            print
            print "Example raw code: 22 7e"
        elif id == '23':
            print "Message 23: Turn On"
            print "  ♨ iKettle 2.0"
            print
            print "Example raw code: 23 7e"
        elif id == '28':
            print "Message 28: ???"
            print "  ♨ iKettle 2.0"
            print
            print "No information available on message"
        elif id == '29':
            print "Message 29: Reply on 28???"
            print "  ♨ iKettle 2.0"
            print
            print "29 00 7e"
            print "29 08 01 5f .. .. xx 7e"
            print "29 01 01 5f 00 00 10 00 19 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7d 7e"
            print
            print "No information available on message"

        elif id == '2c':
            print "Message 2c: Calibrate Water Sensor"
            print "  ♨ iKettle 2 Only"
            print
            print "Example raw code: 2c 7e"
            self.calibration()
        elif id == '2d':
            print "Message 2c: Calibrate finished"
            print "  ♨ iKettle 2 Only"
            print
            print "Arguments: <unkownArgument><unkownArgument>"
            print
            print "Example raw code: 2c ?? ?? 7e"
            self.calibration()
        elif id == '32':
            print "Message 32: ???"
            print "  ?"
            print
            print "var brewing = new Buffer('3212130001117e', 'hex');"
            print "var doneBrewing = new Buffer('3206130001117e', 'hex');"
        elif id == '35':
            print "Message 35: Set strength of the coffee to brew"
            print "  ☕ Smarter Coffee Only"
            print
            print "Argument: <strength>"
            print
            print "strength:"
            print "00 Weak"
            print "01 Medium"
            print "02 Strong"
            print
            print "Example code: 35 01 7e"
            self.coffeebrewing()
        elif id == '36':
            print "Message 36: Set number of cups to brew"
            print "  ☕ Smarter Coffee Only"
            print
            print "Argument: <numberOfCups>"
            print "Note: numberOfCups must be between 1 and 12"
            print
            print "Example code: 36 03 7e"
            self.coffeebrewing()
        elif id == '37':
            print "Message 37: ???"
            print "  ☕ Smarter Coffee Only"
            print
            print "No information available on message"
        elif id == '3c':
            print "Message 3c: Toggle the Grinder on/off"
            print "  ☕ Smarter Coffee Only"
            print
            print "Example raw code: 3c 7e"
        elif id == '3e':
            print "Message 3e: Turn on the hotplate"
            print "  ☕ Smarter Coffee Only"
            print
            print "Argument: <numberOfMinutes>"
            print "Note: It is hardcoded in app with 5"
            print "      valid values are 0 to 30???"
            print
            print "unknownArgument:"
            print "05 Default"
            print
            print "Example raw code: 3e 05 7e"
        elif id == '40':
            print "Message 40: Updating schedules ???"
            print "  ☕ Smarter Coffee Only"
            print
            print "No information available on message"
        elif id == '41':
            print "Message 41: Requesting schedules ???"
            print "  ☕ Smarter Coffee Only"
            print
            print "No information available on message"
        elif id == '43':
            print "Message 43: schedules ???"
            print "  ☕ Smarter Coffee Only"
            print
            print "No information available on message"
        elif id == '4a':
            print "Message 4a: Turn off the hotplate"
            print "  ☕ Smarter Coffee Only"
            print
            print "Example raw code: 4a 7e"
        elif id == '64':
            print "Message 64: Identify Device"
            print "  ♨ iKettle 2.0 & ☕ Smarter Coffee"
            print
            print "Note: Is used for auto discovery over UDP broadcast (after device setup is complete)"
            print "      This fails on some/most routers, which don't propagate UDP broadcasts"
            print
            print "Example raw code: 64 7e"
        elif id == '65':
            print "Message 65: Response Identify Device"
            print "  ♨ iKettle 2.0 & ☕ Smarter Coffee"
            print
            print "Arguments: <deviceType> <sdkVersion>"
            print
            print "deviceType:"
            print "01 iKettle 2.0"
            print "02 iSmarter Coffee"
            print
            print "sdkVersion:"
            print "13 Firmware v19 (?)"
            print
            print "Example raw code: 65 01 13 7e"
        elif id == 69:
            print "Message 69: ???"
            print "  ♨ iKettle 2.0"
            print
            print "returns with 0 arguments 03 04 7e"
            print "returns with 1 argument 03 00 7e"
        elif id == '6a':
            print "Message 6a: Get firmware version of WiFi module"
            print "  ♨ iKettle 2.0"
            print
            print "Example raw code: 6a 7e"
        elif id == '6b':
            print "Message 6b: Firmware version of WiFi module"
            print "  ♨ iKettle 2.0"
            print
            print "Note: iKettle 2.0 returns:"
            print "      AT+GMRAT version:0.40.0.0(Aug  8 2015 14:45:58)SDK version:1.3.0compile time:Aug  8 2015 17:19:38OK"
        elif id == '6d':
            print "Message 6d: Firmware Update"
            print "  ?"
            print
            print "Note: Disables wifi and creates a 'iKettle Update' network"
            print "      a hard device reset (hold power button for 10 seconds) required to fix"
            print
            print "Example raw code: 6d 7e"
        else:
            print 'No information available on message ID: ', id
        print

    def all(self):
        self.base()
        self.messages()
        self.message("02")
        self.message("03")
        self.message("05")
        self.message("07")
        self.message("0c")
        self.message("0d")
        self.message("0e")
        self.message("10")
        self.message("13")
        self.message("14")
        self.message("15")
        self.message("16")
        self.message("20")
        self.message("21")
        self.message("22")
        self.message("23")
        self.message("28")
        self.message("29")
        self.message("2c")
        self.message("2d")
        self.message("32")
        self.message("35")
        self.message("36")
        self.message("37")
        self.message("3c")
        self.message("3e")
        self.message("40")
        self.message("41")
        self.message("43")
        self.message("4a")
        self.message("64")
        self.message("65")
        self.message("69")
        self.message("6a")
        self.message("6b")
        self.message("6d")


#------------------------------------------------------
# iBrew CLIENT
#
# Client to iKettle 2.0 or Smarter Coffee Devices
#------------------------------------------------------

class iBrewClient:

    port = 2081

    command_off  = '\x16'
    command_on   = '\x21'
    command_info = '\x64'
    
    # Coffee Commands (not tested)
    command_grinder        = '\x3c'
    command_hotplate_off   = '\x4a'
    command_hotplate_on    = '\x3e\x05'
    command_number_of_cups = '\x36'
    command_strength       = '\x35'
    
    # iKettle Commands
    command_calibrate      = '\x2c'
    
    # Response messages
    message_status               = '\x03'
    message_wifi_setup_finished  = '\x0c'
    message_wifi_list            = '\x0e'
    message_unknown              = '\x29'
    message_calibration_finished = '\x2d'
    message_status_device        = '\x14'
    message_device_info          = '\x65'
    message_wifi_firmware        = '\x6b'
    
    tail = '\x7e'
    offbase = '\x7f'
    
    statusKettle = {
        0x00 : "Ready",
        0x01 : "Boiling",
        0x02 : "Keep Warm",
        0x03 : "Cycle Finished",
        0x04 : "Baby Cooling",
    }
    
    statusCommand = {
        0x00 : "Success",
        0x01 : "Busy",
        0x04 : "Failed",
        0x05 : "No Carafe",
        0x06 : "No Water",
        0x69 : "Invalid Command",
        0xff : "Unknown"
    }

    #------------------------------------------------------
    # NETWORK CONNECTION: iKettle 2.0 & Smarter Coffee
    #------------------------------------------------------

    def connect(self, host):
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error, msg:
            print 'iBrew: Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
            return False
        try:
            self.socket.connect((host, self.port))
        except socket.error, msg:
            print 'iBrew: Failed to connect to host (' + host + ') Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
        self.log = False
        self.read()
        self.info()
        self.host = host

    def __init__(self,host, auto_connect = "True"):
        if auto_connect:
            self.connect(host)

    def __del__(self):
        self.socket.close()

    #------------------------------------------------------
    #  NETWORK PROTOCOL: iKettle 2.0 & Smarter Coffee
    #------------------------------------------------------

    # read a protocol message
    def read_message(self,socket):
        try:
            message = ""
            i = 0
            
            # let the buffer of the os handle this
            data = self.socket.recv(1)
            while data != self.tail:
                message += data
                data = self.socket.recv(1)
                i += 1
            message += data
            return message
        except socket.error, msg:
            print 'iBrew: Failed to read message. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]

    # read a protocol message and decode it to internal variables
    def read(self):
        message = self.read_message(self.socket)
        
        # Command Status
        if message[0] == self.message_status:
            self.status_command = struct.unpack('B',message[1])[0]
            if not self.statusCommand.has_key(self.status_command):
                self.status_command = 0xff
        
        # Calibration
        elif message[0] == self.message_calibration_finished:
            self.calibration = struct.unpack('B',message[2])[0] + 256 * struct.unpack('B',message[1])[0]
        
        # Device Status
        elif message[0] == self.message_status_device:
            #self.unknown      = struct.unpack('B',message[5])[0]
            self.status      = struct.unpack('B',message[1])[0]
            self.temperature = struct.unpack('B',message[2])[0]
            self.waterlevel  = struct.unpack('B',message[4])[0] + 256 * struct.unpack('B',message[3])[0]
            if self.temperature == self.offbase:
                self.onbase = False
            else:
                self.onbase = True
                
        # Device Info
        elif message[0] == self.message_device_info:
            self.isSmarterCoffee = False
            self.isKettle2 = False
            if struct.unpack('B',message[1])[0] == 1:
                self.isKettle2 = True
                self.device = "iKettle 2.0"
            if struct.unpack('B',message[1])[0] == 2:
                self.isSmarterCoffee = True
                self.device = "SmarterCoffee"
            self.version = struct.unpack('B',message[2])[0]

        if self.log:
            self.print_message_received(message)

        return message

    # send a protocol message and wait's for response...
    def send(self,message):
        try:
            if len(message) > 0 and message[len(message)-1] == self.tail:
                self.socket.send(message)
                if self.log:
                    self.print_message_send(message)
            elif len(message) > 0:
                self.socket.send(message+self.tail)
                if self.log:
                    self.print_message_send(message+self.tail)
            else:
                return

        except socket.error, msg:
            print 'iBrew: Failed to send message. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
        
        # keep reading until we got the response message
        # if a message does not generate a response... we're in deep shit... FIX!
        x = self.read()
        while x[0] == self.message_status_device:
            x = self.read()
        return x

    #------------------------------------------------------
    #  NETWORK CONVERTERS: iKettle 2.0 & Smarter Coffee
    #------------------------------------------------------

    # Convert raw data to hex string without 0x seperated by spaces
    def message_to_string(self,message):
        raw = ""
        for x in range(0,len(message)):
            y = struct.unpack('B',message[x])[0]
            if y < 0x10:
               raw += "0"
            raw += hex(y)[2:4] + " "
        return raw

    # Convert hex string without 0x input maybe seperated by spaces or not
    def string_to_message(self,code):
        message = ""
        
        if len(code) > 2 and code[2] != " ":
            if len(code) % 2 == 0:
                try:
                    message = code.decode("hex")
                except:
                    print "iBrew: Invalid Input: Error encoding hex \'" + code + "\'"
            else:
                print "iBrew: Invalid Input: Missing character on position: " + str(len(code)+1)
        elif len(code) % 3 == 2:
            for x in range(0,(len(code) / 3)+1):
                if x > 0:
                    if code[x*3-1] != ' ':
                        print "iBrew: Invalid Input: Expected space character on position: " + str(x*3)
                        break
                s = code[x*3]+code[x*3+1]
                try:
                    message +=  s.decode("hex")
                except:
                    print "iBrew: Invalid Input: Error encoding hex \'" + s + "\' on position: " + str(x*3+1)
        else:
            print "iBrew: Invalid Input: Missing character on position: " + str(len(code)+1)
        return message


    #------------------------------------------------------
    # CONVERTERS: iKettle 2.0
    #------------------------------------------------------

    def cups(self):
        s = cups_string()
        if s == "Empty" or s == "Not enough water":
            return 0
        if s == "Full":
            return 7
        return s[1]

    # Fix Check value's
    def cups_string(self):
        if self.waterlevel < 850:
            return "Empty"
        elif self.waterlevel >=  850 and self.waterlevel < 1050:
            return "Not enough water"
        elif self.waterlevel >= 1050 and self.waterlevel < 1380:
            return "1 Cups"
        elif self.waterlevel >= 1400 and self.waterlevel < 1600:
            return "2 Cups"
        elif self.waterlevel >= 1600 and self.waterlevel < 1800:
            return "3 Cups"
        elif self.waterlevel >= 1800 and self.waterlevel < 2000:
            return "4 Cups"
        elif self.waterlevel >= 2000 and self.waterlevel < 2200:
            return "5 Cups"
        elif self.waterlevel >= 2200 and self.waterlevel < 2500:
            return "6 Cups"
        elif self.waterlevel >= 2500:
            return "Full"

    #------------------------------------------------------
    # PRINT: iKettle 2.0 & Smarter Coffee
    #------------------------------------------------------

    def print_message_send(self,message):
        print "iBrew: Message Send " + self.message_to_string(message)
        if message[0] == self.command_grinder:
            print "       Toggle Grinder"
        elif message[0] == self.command_hotplate_off:
            print "       Turn Hotplate On"
        elif message[0] == self.command_hotplate_on:
            print "       Turn Hotplate Off"
        elif message[0] == self.command_number_of_cups:
            print "       Set Number of Cups to Brew"
        elif message[0] == self.command_strength:
            print "       Set Strength"
        elif message[0] == self.command_on:
            print "       Turn On"
        elif message[0] == self.command_off:
            print "       Turn Off"
        elif message[0] == self.command_info:
            print "       Get Device Info"
        elif message[0] == self.command_calibrate:
            print "       Calibrate Waterlevel"
        else:
            print "       Unknown Command"

    def print_message_received(self,message):
        if message[0] != self.message_status_device:
            print "iBrew: Message Received: " + self.message_to_string(message)
        if message[0] == self.message_status:
            print "       Action Status: " + self.statusCommand[self.status_command]
        elif message[0] == self.message_wifi_setup_finished :
            print '       Wifi Not Implemented'
        elif message[0] == self.message_wifi_list:
            print '       Wifi Not Implemented'
        elif message[0] == self.message_wifi_firmware:
            print '       Wifi Firmware Not Implemented'
        elif message[0] == self.message_unknown:
            print '       Unknown Message Not Implemented'
        elif message[0] == self.message_device_info:
            print "       Device Info: " + self.device + " Firmware v" + str(self.version)
        elif message[0] == self.message_calibration_finished:
            print "       Calibration Base Value: " +  str(self.calibration)
        elif message[0] != self.message_status_device:
            print "       Unknown Reply Message"

    def print_status(self):
        print
        if self.isKettle2 == True:
            if self.onbase:
                print 'Status      ', self.statusKettle[self.status]
                print 'Kettle       On Base'
                print 'Temperature ', self.temperature, 'ºC'
                print 'Water level ', self.waterlevel, ' (', self.cups_string(), ')'
            else:
                print 'Status      ', self.statusKettle[self.status]
                print 'Kettle      Not On Base'
        if self.isSmarterCoffee == True:
            print 'Status      ', self.statusCoffee[self.status]
        print

    def print_short_status(self):
        if self.isKettle2 == True:
            if self.onbase:
                print "iBrew: " + self.statusKettle[self.status] + " On Base (" + str(self.temperature) + "ºC, " + str(self.waterlevel) + " ["+ self.cups_string() + "])"
            else:
                print "iBrew: " + self.statusKettle[self.status] + " Not On Base"
        if self.isSmarterCoffee == True:
            print "iBrew: " + self.statusCoffee[self.status]

    def print_connect_status(self):
        print "iBrew: Connected to " + self.device + " Firmware v" + str(self.version) + " (" + self.host + ")"

    #------------------------------------------------------
    # COMMANDS: iKettle 2.0 & Smarter Coffee
    #------------------------------------------------------

    def info(self):
        self.send(self.command_info)
  
    #------------------------------------------------------
    # COMMANDS: iKettle 2.0
    #------------------------------------------------------

    def calibrate(self):
        self.send(self.command_calibrate)

    def off(self):
        self.send(self.command_off)
    
    def on(self):
        self.send(self.command_on)

    #------------------------------------------------------
    # COMMANDS: Smarter Coffee
    #------------------------------------------------------

    def hotplate_off(self):
        if self.isSmarterCoffee == True:
            self.send(self.command_hotplate_off)
        else:
            print 'iBrew: The device does not have a hotplate'

    def hotplate_on(self):
        if self.isSmarterCoffee == True:
            self.send(self.command_hotplate_on)
            print 'iBrew: The device does not have a hotplate'

    def grinder(self):
        if self.isSmarterCoffee == True:
            self.send(self.command_grinder)
        else:
            print 'iBrew: The device does not have a grinder'

    def number_of_cups(self,number):
        if self.isSmarterCoffee == True:
            if number < 1 or number > 12:
                print 'iBrew: Invalid Number of Cups: ',number
            self.send(self.command_grinder+str(number))
        else:
            print 'iBrew: The device does not let you choose the number of cups to brew'

    def coffee_strength(self,strength):
        if self.isSmarterCoffee == True:
            if strength == "weak":
                number = 0
            elif strength == "medium":
                number = 1
            elif strength == "strong":
                number = 2
            else:
                print 'iBrew: Invalid Strength: ',strength
            if number:
                self.send(self.command_strength+str(number))
        else:
            print 'iBrew: The device does not let you choose the coffee strength'

    def raw(self,code):
        self.send(self.string_to_message(code))


#------------------------------------------------------
# iBrew CONSOLE
#
# Console for iKettle 2.0 or Smarter Coffee Devices
#
# Note that the device status is the only message not
# printed in raw format...
#------------------------------------------------------

class iBrewConsole:

    def introduction(self):
        print
        print "For list of commands type: help and press enter"
        print "Press enter for status update and press ctrl-c to quit"
        print
    
    def help(self):
        print
        print "  [data]       Send raw data to device"
        print "  cups [nr]    ☕ Set number of cups"
        print "  calibrate    ♨ Calibrates Waterlevel"
        print "  examples     Show examples of commands"
        print "  grinder      ☕ Toggle grinder"
        print "  help         This help"
        print "  hotplate off ☕ Turn hotplate off"
        print "  hotplate on  ☕ Turn hotplate on"
        print "  info         Device info"
        print "  messages     List all protocol messages"
        print "  message [id] List protocol messages detail"
        print "  off          Turn off"
        print "  on           Turn on"
        print "  protocol     Print protocol structure"
        print "  quit         Quit console"
        print "  status       Show status"
        print "  strength [s] ☕ Set strength coffee (weak, medium or strong)"
        print
        print "  ☕ Smarter Coffee Only"
        print "  ♨ iKettle 2.0 Only"
        print
    
    def examples(self):
        print
        print "Example:"
        print "  off            iKettle 2.0 Stop boiling"
        print "  messages       Show all protocol messages"
        print "  message 3e     Show protocol message 3a, turn hotplate on"
        print "  167E           Send iKettle 2.0 raw off"
        print "  21 30 05 7e    Send iKettle 2.0 raw on"
        print "  strength weak  Set SmarterCoffee coffee strength to weak"
        print "  cups 3         Set SmarterCoffee number of cups to brew"
        print

    def joke(self):
        teajokes = [["What do you call a talkative drink?","Chai tea."],
                      ["How long does it take to brew Chinese tea?","Oolong time."],
                      ["When shouldn't you drink a hot beverage?","If it's not your cup of tea."],
                      ["How does Moses make his tea?","Hebrews it."],
                      ["What drink do goalies hate?","Penal-tea."],
                      ["How do you ask a dinosaur to lunch?","Tea Rex?"],
                      ["What does a worry wart drink?","Safe-Tea."],
                      ["Why did the hipster burn his tongue?","Because he drank his tea before it was cool."],
                      ["What drink brings you down to earth?","Gravi-Tea."],
                      ["What do sophisticated fish drink?","Salt-Tea."],
                      ["Why did the tea bag have to do it's laundry?","Because it was stained."],
                      ["What kind of music do teapots like?","Jasmine."],
                      ["Why must you be careful of tea at night?","Because it might mug you."],
                      ["What does a tea bag do when it's tired?","It seeps."],
                      ["Why did the teapot get in trouble?","Because he was naughtea."],
                      ["What did the teapot wear to bed?","A nightea"],
                      ["What happens when an old teapot laughs too hard?","It teas its pants."],
                      ["It is time to get this par tea started!","Right?"],
                      ["Hello Brew-TEA-Full!!!","Your kettle"],
                      ["I love to drink tea each day","It brings out my inner tranquili-Tea"],
                      ["Today!","Full of creativi-Tea"],
                      ["It tends to break the ice very easily","Flirt-Tea."],
                      ["When your kettle is too","Chat-Tea"],
                      ["Where there is tea","There is hope!"],
                      ["If tea is the drink of love","Then brew on!"],
                      ["It really is a serious problem","If tea can’t fix it."],
                      ]
                
        coffeejokes =  [["Why are men are like coffee?"," The best ones are rich, hot, and can keep you up all night!"],
                        ["Why is a bad cup of coffee the end of a marriage?","Because it's GROUNDS for divorce!"],
                        ["What do you call sad coffee?","Despresso"],
                        ["Did you know it's a sin for a woman to make coffee?","In the bible it says He-brews"],
                        ["Why Coffee is better than a Woman?","Coffee goes down easier!"],
                        ["They call me \"coffee\"","Cause I grind so fine."],
                        ["Hold the sugar please","You're sweet enough for the both of us"],
                        ["So I've Been thinking about you a latte","Your coffee grinder"],
                        ["How do you look so good before coffee?","Your coffee machine"],
                       ]
        joke = random.choice(teajokes+coffeejokes)
        print "\n      \'" + joke[0] + "\'\n                  -- " + joke[1] + "\n"

    def __init__(self,host):
        client = iBrewClient(host)
        client.print_connect_status()
        client.print_status()
        self.joke()
        client.log = True
        self.introduction()
        cursor = client.host + ":" + client.device + "$"
        lastreply = ""
        while True:
            try:
                input = raw_input(cursor).lower()
                if input == "on":
                    client.on()
                elif input == "off":
                    client.off()
                elif input == "hotplate on":
                    client.hotplate_on()
                elif input == "hotplate off":
                    client.hotplate_off()
                elif input == "grinder":
                    client.grinder()
                elif input[0:9] == "strength ":
                    if input[9:14] == "weak":
                        client.coffee_strength("weak")
                    if input[9:16] == "strong":
                        client.coffee_strength("strong")
                    if input[9:16] == "medium":
                        client.coffee_strength("medium")
                elif input[0:5] == "cups ":
                    # FIX THIS
                    client.cups(3)
                elif input == "exit" or input =="quit":
                    sys.exit()
                elif input == "joke":
                    print
                    self.joke()
                    print
                elif input == "help":
                    self.help()
                elif input == "info":
                    client.info()
                elif input == "calibrate":
                    client.calibrate()
                elif input == "examples":
                    self.examples()
                elif input == "protocol":
                    iBrewProtocol().base()
                elif input == "messages":
                    iBrewProtocol().messages()
                elif input[0:8] == "message ":
                    iBrewProtocol().message(input[8:11])
                elif len(input) > 0 and input != "status":
                    client.send(client.string_to_message(str(input)))
                client.read()
                if input == "status":
                    client.print_status()
                else:
                    client.print_short_status()
            except:
                print
                break


#------------------------------------------------------
# iBrew MONITOR
#
# Monitors iKettle 2.0 or Smarter Coffee Devices
#------------------------------------------------------

class iBrewMonitor:
    def __init__(self,host):
        client = iBrewClient(host)
        client.print_connect_status()
        print "iBrew: Press ctrl-c to quit"
        lastreply = ""
        while True:
            try:
                reply = client.read()
                if lastreply == reply:
                    pass
                else:
                    lastreply = reply
                client.print_short_status()
            except:
                print
                break;


#------------------------------------------------------
# iBrew DOMOTICZ BRIDGE
#
# Bridges the gap between Domoticz and iKettle 2.0 or
# Smarter Coffee Devices
#------------------------------------------------------

class iBrewDomoticzBridge:
    def __init__(self,host):
        client = iBrewClient(host)
        client.print_connect_status()
        print "iBrew: Press ctrl-c to quit"
        lastreply = ""
        while True:
            try:
                reply = client.read()
                if lastreply == reply:
                    pass
                else:
                    lastreply = reply
                
                # PUT CODE DOMOTIZ HERE
                
                client.print_short_status()
            except:
                print
                break;


#------------------------------------------------------
# iBrew EMULATES
#
# Emulates iKettle 2.0 or a Smarter Coffee Device
#------------------------------------------------------
"""
    def server(self,type):
        print "iBrew: Not Implemented"

    def emulate(self,type):
        print "iBrew: Not Implemented"

    def relay(self):
        print "iBrew: Not Implemented"
"""


#------------------------------------------------------
# iBrew COMMAND LINE
#
# Command line access for iKettle 2.0 or Smarter Coffee
# Device
#------------------------------------------------------

class iBrewCommandLine:

    def help(self):
        print "iBrew ☕ Smarter Coffee & ♨ iKettle 2.0 Control"
        print iBrewVersion
        print
        print 'Usage:'
        print '  iBrew.py [option] (host)'
        print
        print '[options]'
        print '  console'
        print '  cups [number]'
        print '  domoticz [options] (connect)'
        print '  emulate [kettle, coffee]'
        print '  grinder'
        print '  hotplate off'
        print '  hotplate on'
        print '  monitor'
        print '  off'
        print '  on'
        print '  protocol'
        print '  raw [data]'
        print '  relay'
        print '  status'
        print '  strength [weak, medium or strong]'
        print

    def __init__(self,host):
        # Lower Case Arguments
        arguments = len(sys.argv) - 1
        if arguments >= 1:
            arg1 = sys.argv[1].lower()
        if arguments >= 2:
            arg2 = sys.argv[2].lower()
        if arguments >= 3:
            arg3 = sys.argv[3].lower()

        # No arguments display help
        if arguments == 0:
            self.help()
            sys.exit()

        # Set the device host if in arguments
        if arguments == 4:
            host = arg3
        elif arguments == 3:
            host = arg2

        # Preform action!
        if arguments >= 1:
            if arg1 == "on":
                iBrewClient(host).on()
            elif arg1 == "off":
                iBrewClient(host).off()
            elif arg1 == "status":
                iBrewClient(host).print_status()
            elif arg1 == "grinder":
                iBrewClient(host).grinder()
            elif arg1 == "protocol":
                iBrewProtocol().all()
            elif arg1 == "monitor":
                iBrewMonitor(host)
            elif arg1 == "console":
                iBrewConsole(host)
            elif arg1 == "relay":
                iBrewServer(host).relay()
            elif arg1 == "domoticz":
                iBrewDomoticzBridge(host)
            elif arguments >= 2:
                if arg1 == "raw":
                    iBrewClient(host).raw(arg2)
                elif arg1 == "hotplate" and arg2 == "on":
                    iBrewClient(host).hotplate_on()
                elif arg1 == "hotplate" and arg2 == "off":
                    iBrewClient(host).hotplate_off()
                elif arg1 == "strength":
                    iBrewClient(host).coffee_strength(arg2)
                elif arg1 == "cups":
                    # FIX WRONG IP{UT
                    iBrewClient(host).number_of_cups(arg2)
                elif arg1 == "emulate" and arg2 == "kettle":
                    iBrewClient(host,False).emulate("kettle")
                elif arg1 == "emulate" and arg2== "coffee":
                    iBrewClient(host,False).emulate("coffee")
                else:
                    self.help()
                    print 'iBrew: Invalid option: ',arg1
                    print
            else:
                self.help()
                print 'iBrew: Invalid option: ',arg1
                print


#------------------------------------------------------
# MAIN
#
# Start any program you like default is command line
#------------------------------------------------------

iBrewCommandLine(host)
#iBrewMonitor(host)
#iBrewConsole(host)
Last edited by trixwood on Friday 05 August 2016 15:57, edited 5 times in total.

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Friday 05 August 2016 11:16

Woah that's impressive! I'll try it out on the kettle and coffee machine. :)

Cheers :)

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Friday 05 August 2016 11:18

Also check this here, I submitted a bunch of extra codes for the coffee machine status in pollingStatusMessage.py.

https://github.com/nanab/smartercoffee

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by trixwood » Friday 05 August 2016 11:28

I am now writing a man in the middle/emulation, so we can see what the phone app is sending and what the device sends back... saves a lot of trouble i think... cuz could not find out how to set temperature... :-?

Anway.. very alpha... but it runs with my kettle...

Probably will fail on the coffee machine... i do not think the status message is the same there...

change

Code: Select all

    def print_message_received(self,message):
        if message[0] != self.message_status_device:
            print "iBrew: Message Received: " + self.message_to_string(message)
        if message[0] == self.message_status:
            print "       Action Status: " + self.statusCommand[self.status_command]
        elif message[0] == self.message_wifi_setup_finished :
            print '       Wifi Not Implemented'
        elif message[0] == self.message_wifi_list:
            print '       Wifi Not Implemented'
        elif message[0] == self.message_wifi_firmware:
            print '       Wifi Firmware Not Implemented'
        elif message[0] == self.message_unknown:
            print '       Unknown Message Not Implemented'
        elif message[0] == self.message_device_info:
            print "       Device Info: " + self.device + " Firmware v" + str(self.version)
        elif message[0] == self.message_calibration_finished:
            print "       Calibration Base Value: " +  str(self.calibration)
        elif message[0] != self.message_status_device:
            print "       Unknown Reply Message"
into

Code: Select all

    def print_message_received(self,message):    
        print "iBrew: Message Received: " + self.message_to_string(message)
        if message[0] == self.message_status:
            print "       Action Status: " + self.statusCommand[self.status_command]
        elif message[0] == self.message_wifi_setup_finished :
            print '       Wifi Not Implemented'
        elif message[0] == self.message_wifi_list:
            print '       Wifi Not Implemented'
        elif message[0] == self.message_wifi_firmware:
            print '       Wifi Firmware Not Implemented'
        elif message[0] == self.message_unknown:
            print '       Unknown Message Not Implemented'
        elif message[0] == self.message_device_info:
            print "       Device Info: " + self.device + " Firmware v" + str(self.version)
        elif message[0] == self.message_calibration_finished:
            print "       Calibration Base Value: " +  str(self.calibration)
        else:
            print "       Unknown Reply Message"
to see the raw status codes....

i disable them... there where way to many of them :-)

anyway busy on the relay part... hopefully as we are man in the middle we can see what is going on...

Code: Select all

MacBook-Pro:Documents Tristan$ ./iBrew.py console
iBrew: Connected to iKettle 2.0 Firmware v19 (10.0.0.93)

Status       Ready
Kettle       On Base
Temperature  47 ºC
Water level  2065  ( 5 Cups )


      'Hello Brew-TEA-Full!!!'
                  -- Your kettle


For list of commands type: help and press enter
Press enter for status update and press ctrl-c to quit

10.0.0.93:iKettle 2.0$help

  [data]       Send raw data to device
  cups [nr]    ☕ Set number of cups
  examples     Show examples of commands
  grinder      ☕ Toggle grinder
  help         This help
  hotplate off ☕ Turn hotplate off
  hotplate on  ☕ Turn hotplate on
  messages     List all protocol messages
  message [id] List protocol messages detail
  off          Turn off
  on           Turn on
  protocol     Print protocol structure
  quit         Quit console
  status       Show status
  strength [s] ☕ Set strength coffee (weak, medium or strong)

  ☕ Smarter Coffee Only
  ♨ iKettle 2.0 Only

iBrew: Ready On Base (47ºC, 2065 [5 Cups])
10.0.0.93:iKettle 2.0$on
iBrew: Message Send 21 7e 
iBrew: Message Received 14 00 2f 08 10 00 7e 
iBrew: Message Received 14 00 2f 08 11 00 7e 
iBrew: Message Received 14 00 2f 08 11 00 7e 
iBrew: Message Received 14 00 2f 08 10 00 7e 
iBrew: Message Received 14 00 2f 08 0f 00 7e 
iBrew: Message Received 14 00 2f 08 11 00 7e 
iBrew: Message Received 14 00 2f 08 10 00 7e 
iBrew: Message Received 14 00 2f 08 10 00 7e 
iBrew: Message Received 03 00 7e 
iBrew: Ready On Base (47ºC, 2064 [5 Cups])
10.0.0.93:iKettle 2.0$off
iBrew: Message Send 16 7e 
iBrew: Message Received 14 01 2f 08 10 00 7e 
iBrew: Message Received 14 01 2f 08 0d 00 7e 
iBrew: Message Received 03 00 7e 
iBrew: Boiling On Base (47ºC, 2061 [5 Cups])
10.0.0.93:iKettle 2.0$21 7e
iBrew: Message Send 21 7e 
iBrew: Message Received 14 00 2f 08 0d 00 7e 
iBrew: Message Received 14 00 2f 08 0d 00 7e 
iBrew: Message Received 14 00 2f 08 0e 00 7e 
iBrew: Message Received 14 00 2f 08 0e 00 7e 
iBrew: Message Received 14 00 2f 08 0e 00 7e 
iBrew: Message Received 03 00 7e 
iBrew: Ready On Base (47ºC, 2062 [5 Cups])
10.0.0.93:iKettle 2.0$off
iBrew: Message Send 16 7e 
iBrew: Message Received 14 01 2f 08 0d 00 7e 
iBrew: Message Received 14 01 2f 08 0d 00 7e 
iBrew: Message Received 14 01 30 08 0c 00 7e 
iBrew: Message Received 03 00 7e 
iBrew: Boiling On Base (48ºC, 2060 [5 Cups])
10.0.0.93:iKettle 2.0$exit
Ow btw.. i emulated a kettle, and the app responded! i have only implemented two simulated responses... so i am hopeful that it will work the man in the middle protocol analyzer ;-) I can now relay messages to the kettle (with some network tinkering)

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Saturday 06 August 2016 11:52

Trixwood, I'm having some sort of success with controlling the temperature (I think).

Try sending this to your kettle: \x15\x20\x00\x7e

I believe the "20" number is somehow temperature related, I got it by packet capturing traffic from the Android app locally to the kettle.

The highest number that 20 will go to is 64 on my kettle which seems to fully boil it... and 64 hex = 100 decimal!!

Now I've just got to wait for the kettle to cool down a bit so I can keep testing it... lol :D

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Saturday 06 August 2016 12:17

Yep I can confirm for sure that this \x15\x20\x00\x7e controls the temperature

This boiled the kettle to exactly 50 degrees \x15\x32\x00\x7e (32hex = 50 decimal)

:)

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by trixwood » Saturday 06 August 2016 18:03

Cool,

I found out some commands just by trying, I am setting up a network sniffer (never done that)...
i got wireshark, connected my kettle to my notebooks wifi and a cable for the rest of the network,
i can read the messages from my script to the kettle, now I
have to somehow passthrough my main network through my notebook...
how did you do that?

2b 7e

will get you your calibration base without calibration...
I thik the kettle holds 1.8l full so I was wondering with that base value if it was possible to deduct that.

I think I will open a github repo for this...
anyway I can not sniff the coffee machine... so any feedback would be welcome :-)


any from the other source you mentioned...

Start brweing coffee:
33" + cupsHex + strengthHex + hotPlateHex + grindHex + "7e"

Start with current settings:
37 7e

Hotplate
hotPlateHex = "3e" + timeValue + "7e"
timevalue 5 minutes or higher

?????
The status message of the coffee should look like
14 ?? TEMP WATER WATER CUPS

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by trixwood » Saturday 06 August 2016 18:27

Also found out that if your directly connected to your kettle

it will send a 03 00 7e (command success) before any other reply message, while connected through the network it skips this message...

github repo

https://github.com/Tristan79/iBrew

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Saturday 06 August 2016 20:30

Trixwood I found the best tool for seeing the packets between the phone and the kettle is this Android app which I installed on a $99 rooted android tablet.

https://play.google.com/store/apps/deta ... ture&hl=en

Far easier to do the packet capture directly on the device.

After the packet capture theres an option for viewing it in hex in the app which I had to pick to be able to see what was going on.

trixwood
Posts: 510
Joined: Friday 18 March 2016 8:20
Target OS: -
Domoticz version: Offline
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by trixwood » Saturday 06 August 2016 21:33

No android here. I figure it out... :-) Never wrote a server before, never done packet inspection... :-)

But please share your coffee codes (like status 0x14 reply). I will put it in the code...
I am refactoring it... and putting it on github...

ben53252642
Posts: 425
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Smarter Wifi iKettle 2 script for Domoticz

Post by ben53252642 » Sunday 07 August 2016 7:47

Sure, I've not fully completed the coffee machine yet, still learning from it. I'll post up the codes once I have it figured out.

Also you can run Android easily in a virtual machine.

http://www.osboxes.org/android-x86/

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests