mikelawrence / senseme-hacs

Haiku with SenseME fan integration for Home Assistant
MIT License
21 stars 14 forks source link

i6 Support #5

Open theOrakle opened 4 years ago

theOrakle commented 4 years ago

Hey Mike,

Not sure if you remember me, but I'm glad you added it to HACS. I finally have my i6 installed and cannot get it to be detected.

Interested in add i6 support?

theOrakle commented 4 years ago

Also note - It only discovered for a second...

2020-04-22 15:54:31 DEBUG (MainThread) [aiosenseme.discovery] Listening on 10.0.16.100
2020-04-22 15:54:31 DEBUG (MainThread) [aiosenseme.discovery] Discovery broadcast on 10.0.16.100
2020-04-22 15:54:32 DEBUG (MainThread) [aiosenseme.discovery] Discovered 0 fans
2020-04-22 15:54:32 DEBUG (MainThread) [aiosenseme.discovery] Broadcaster task cancelled
2020-04-22 15:54:32 DEBUG (MainThread) [aiosenseme.discovery] Listener closed on 10.0.16.100
2020-04-22 15:55:12 DEBUG (MainThread) [aiosenseme.discovery] Listening on 10.0.16.100
2020-04-22 15:55:12 DEBUG (MainThread) [aiosenseme.discovery] Discovery broadcast on 10.0.16.100
2020-04-22 15:55:13 DEBUG (MainThread) [aiosenseme.discovery] Discovered 0 fans
2020-04-22 15:55:13 DEBUG (MainThread) [aiosenseme.discovery] Broadcaster task cancelled
2020-04-22 15:55:13 DEBUG (MainThread) [aiosenseme.discovery] Listener closed on 10.0.16.100
mikelawrence commented 4 years ago

I do remember you from a while ago. I do not have a i6 fan so I have personally never seen it work but there may be somebody out there using my component with an i6 fan and we will just never know. Big Ass Fans website says it has SenseME so it should work.

So these log messages are left after you try to add the senseme integration via HACS and it gives you a dialog stating no devices found correct? Sometimes SenseME fans do not respond to discovery requests so trying add the senseme integration multiple times over say 5-10 minutes. If this doesn't work try the following.

Do you have access to a Linux machine virtual or computer with Python available? If so type the following...

pip3 install aiosenseme aiosensme --debug -d

This will execute a SenseME fan discovery using my aiosenseme library and it will print out a bunch of debug information. It will also attempt discovery multiple times unlike the adding the senseme integration.

theOrakle commented 4 years ago

Here is the output, not really any help though.

DEBUG:aiosenseme.discovery:Added coroutine callback DEBUG:aiosenseme.discovery:Listening on 10.0.16.100 DEBUG:aiosenseme.discovery:Discovery broadcast on 10.0.16.100 DEBUG:aiosenseme.discovery:Discovery broadcast on 10.0.16.100 DEBUG:aiosenseme.discovery:Discovery broadcast on 10.0.16.100 DEBUG:aiosenseme.discovery:Discovery broadcast on 10.0.16.100 DEBUG:aiosenseme.discovery:Broadcaster task cancelled

mikelawrence commented 4 years ago

Hmmm. I noticed the same IP Address shows up for both of these tests. Are you running Home Assistant in a Virtual Machine or Docker container? Do you know your fan's IP Address? Are the two IP Addresses on the same network? Have you connected the Haiku App (iOS or Android) to your fan?

It is possible that the i6 doesn't respond to the same broadcast packet and port. The guy that hacked the SenseME protocol originally analyzed the traffic on his iPhone from the Haiku App.

theOrakle commented 4 years ago

Here is my setup:

I did tcpdump looking for udp traffic from the fan (tcpdump -lv udp)

f4patio.<redacted>.com.mdns > 224.0.0.251.mdns: 0*- [0q] 3/0/1 _api._tcp.local. PTR i6._api._tcp.local., i6._api._tcp.local. (Cache flush) SRV PatioFan.local.:31415 0 0, i6._api._tcp.local. (Cache flush) TXT "firmware version=1.3.3" "uuid=<redacted>" "api version=1" "model=i6" (224)
f4patio.<redacted>.com.mdns > 224.0.0.251.mdns: 0*- [0q] 3/0/1 _http._tcp.local. PTR i6._http._tcp.local., i6._http._tcp.local. (Cache flush) SRV PatioFan.local.:31416 0 0, i6._http._tcp.local. (Cache flush) TXT "path=FW000018" (152)
theOrakle commented 4 years ago

Both ports advertised are open:

root@net:~ # nmap f4patio -p 31415,31416
Starting Nmap 7.70 ( https://nmap.org ) at 2020-04-22 20:23 CDT
Nmap scan report for f4patio (10.0.16.111)
Host is up (0.0074s latency).
rDNS record for 10.0.16.111: f4patio.<redacted>.com

PORT      STATE SERVICE
31415/tcp open  unknown
31416/tcp open  boinc
MAC Address: 24:6F:28:D4:AF:90 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 1.12 seconds
theOrakle commented 4 years ago

Interestingly enough, I can netcat into the port:

root@ham:/opt/homeassistant/bin # nc f4patio 31415
??"??????now??*??????????8???????????"??????now????????????8???????????"??????now????????????8?????????

Every time you nee "now...", I was turning on & off the fan.

I also tried referencing it directly via aiosenseme...

root@ham:/opt/homeassistant/bin # ./aiosenseme -n f4patio
Fan/Room/IP address 'f4patio' not found
root@ham:/opt/homeassistant/bin # ./aiosenseme -n 10.0.16.111
Fan/Room/IP address '10.0.16.111' not found
mikelawrence commented 4 years ago

Well you are definitely well versed in networking. I have never used tcpdump so I tried it on my Home Assistant development platform which is running on WSL. Just my luck it doesn't work and it is a known issue with WSL.

Here is a description of how the SenseME protocol works in the aiosenseme library. Discovery sends a UDP broadcast packet containing <ALL;DEVICE;ID;GET> to port 31415. Fans that detect this packet respond with (Studio Beam Fan;DEVICE;ID;11:22:EE:FF:00:00;FAN,HAIKU,SENSEME). Keep in mind these strings are formatted utf-8.

Once a fan sends a response the aiosenseme library connects to the same port via TCP and sends <Studio Beam Fan;GETALL>. The fan then responds with a lot of parameters formatted like (Studio Beam Fan;DEVICE;BEEPER;ON)(Studio Beam Fan;DEVICE;INDICATORS;ON).

In your tcpdump I recognize some of the information but not the format. For instance path=FW000018. This is the name of the firmware variable which comes in my library as (FW;NAME;FW000003) and (FW;FW000003;2.5.0).

When I netcat to one of my fans following your example except I turned the fan on and then set the speed to 1 using the Haiku app on my phone.

nc 172.20.3.39 31415
(Studio Beam Fan;FAN;PWR;ON)(Studio Beam Fan;FAN;SPD;ACTUAL;4)(Studio Beam Fan;FAN;PWR;ON)(Studio Beam Fan;FAN;SPD;ACTUAL;4)(Studio Beam Fan;FAN;PWR;ON)(Studio Beam Fan;FAN;SPD;ACTUAL;1)(Studio Beam Fan;FAN;PWR;ON)(Studio Beam Fan;FAN;SPD;ACTUAL;1)

This makes sense to me.

And finally for reference, even when you specify an IP address to connect to a fan using the aiosenseme command line it still uses discovery to find a fan that matches the specified address.

theOrakle commented 4 years ago

Is there any way I can side step discovery and go straight to the fan on port 31415 just to test the i6 fan? I'm looking through the code now, but any insight would be helpful.

I'm not sure why discover is not working and want to see if it is environmental or i6 related.

mikelawrence commented 4 years ago

There is a way but I would need to work on it this afternoon or tonight. It would require installing the aiosenseme library locally (pip -e directory).

Just looking at the difference between my netcat and yours make me think Big Ass Fans is doing something different in the i6 fans. Did you try netcat on port 31416? This port is not used by the aiosenseme library.

mikelawrence commented 4 years ago

I have created a branch of the aiosenseme library here to help you test.

You need to clone/download this repository to your raspberry pi and type in the following when you are in the repository's directory...

python3 setup.py sdist
pip3 install -e .
aiosenseme --debug --name "Fan name" --ip 10.0.16.111

Not sure how much python you know so I'll explain what is going on. The first line is the standard mechanism for creating a pip installable library. The second line will install the local aiosenseme library instead of the one PyPi. The last line shows how to connect with your fan via IP address and Name and is explained by the readme file on Github.

When you want to go back to normal aiosenseme library type this...

pip3 install aiosenseme

I could have spent more time hacking up the aiosensme library so that you could just run a single python file but this was quick easy.

theOrakle commented 4 years ago

Dude, you are awesome...

So I ran it twice, the first time light/fan was off, the second time, both were on, but the same result.

DEBUG:aiosenseme.fan:Gabe: Connecting
DEBUG:aiosenseme.fan:Gabe: Connected
DEBUG:aiosenseme.fan:Gabe: Status update
Gabe
  Model: Haiku Fan without light, FW Version: None
  IP Addr: 10.0.16.111, MAC Addr: 01:23:45:67:89:AB
  Token: None
State: Fan is off, Light is off, Whoosh: off
DEBUG:aiosenseme.fan:Gabe: Listener task cancelled
DEBUG:aiosenseme.fan:Gabe: Updater task cancelled
theOrakle commented 4 years ago

There is a way but I would need to work on it this afternoon or tonight. It would require installing the aiosenseme library locally (pip -e directory).

Just looking at the difference between my netcat and yours make me think Big Ass Fans is doing something different in the i6 fans. Did you try netcat on port 31416? This port is not used by the aiosenseme library.

Sorry - I missed this before. I did try to nc into 31416 and no dice. I don't see it chattering on the network either. I'll take another run at it now.

theOrakle commented 4 years ago
root@ham:/opt/homeassistant/config/scripts/shell # nc 10.0.16.111 31416
/
HTTP/1.1 500 Internal Server Error

^C
root@ham:/opt/homeassistant/config/scripts/shell # nc 10.0.16.111 31416
GET /

HTTP/1.1 410 Gone

I'll need to get my hacking game face on... and take a look at calls my phone is making to the (I can only assume) REST API.

theOrakle commented 4 years ago

Ok,

The phone app is still talking on 31415, it is a different app as well.

image

I'm going to eat then I'll dig into the content of the packets...

mikelawrence commented 4 years ago

Dude, you are awesome...

So I ran it twice, the first time light/fan was off, the second time, both were on, but the same result.

DEBUG:aiosenseme.fan:Gabe: Connecting
DEBUG:aiosenseme.fan:Gabe: Connected
DEBUG:aiosenseme.fan:Gabe: Status update
Gabe
  Model: Haiku Fan without light, FW Version: None
  IP Addr: 10.0.16.111, MAC Addr: 01:23:45:67:89:AB
  Token: None
State: Fan is off, Light is off, Whoosh: off
DEBUG:aiosenseme.fan:Gabe: Listener task cancelled
DEBUG:aiosenseme.fan:Gabe: Updater task cancelled

Looks like it connected but there was no response. This also happens when the fan name is wrong.

There is a slight change to the discovery code that will show any response including malformed responses. Just make sure you pull the latest code from the i6-test branch.

aiosenseme --debug -d

If the fan responds in any way you will get a debug message like "Received "something" from ip address on ip address

Good luck!