Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardware support: LNK2 Wifi Module #178

Open
DotNet2Web opened this issue May 23, 2023 · 23 comments
Open

Hardware support: LNK2 Wifi Module #178

DotNet2Web opened this issue May 23, 2023 · 23 comments

Comments

@DotNet2Web
Copy link

When starting a zone on the controller an error occurs

Error: Status request failed with wrong response! Requested 01 but got 00: {‘type’: ‘NotAcknowledgeResponse’, ‘commandEcho’: 57, ‘NAKCode’: 4}

Log:

`Logger: homeassistant.helpers.script.websocket_api_script
Source: custom_components/rainbird/switch.py:96
Integration: Rainbird
First occurred: 21 mei 2023 om 12:42:48 (1 occurrences)
Last logged: 21 mei 2023 om 12:42:48

websocket_api script: Error executing script. Unexpected error for call_service at pos 1: Status request failed with wrong response! Requested 01 but got 00: {'type': 'NotAcknowledgeResponse', 'commandEcho': 57, 'NAKCode': 4}
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 452, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 685, in _async_call_service_step
await service_task
File "/usr/src/homeassistant/homeassistant/core.py", line 1849, in async_call
task.result()
File "/usr/src/homeassistant/homeassistant/core.py", line 1889, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 809, in handle_service
await service.entity_service_call(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 798, in entity_service_call
future.result() # pop exception if have
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 980, in async_request_call
await coro
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 838, in _handle_entity_call
await result
File "/config/custom_components/rainbird/switch.py", line 117, in async_start_zone
await self.async_turn_on(duration=zone_run_time)
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1034, in async_turn_on
await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/rainbird/switch.py", line 96, in turn_on
response = self._controller.irrigate_zone(int(self._zone), int(duration // 60))
File "/usr/local/lib/python3.10/site-packages/pyrainbird/init.py", line 136, in irrigate_zone
response = self._process_command(
File "/usr/local/lib/python3.10/site-packages/pyrainbird/init.py", line 202, in _process_command
response = self.command(cmd, *args)
File "/usr/local/lib/python3.10/site-packages/pyrainbird/init.py", line 188, in command
raise Exception(
Exception: Status request failed with wrong response! Requested 01 but got 00:
{'type': 'NotAcknowledgeResponse', 'commandEcho': 57, 'NAKCode': 4}`

Version Information:

Home Assistant 2023.5.3
Supervisor 2023.04.1
Operating System 10.1
Frontend-versie: 20230503.3 - latest

Rainbird:
ESP-RZXe
Firmware: 2.9
LNK2 WiFi Module

Could you please add support of this device into the integration.

@allenporter
Copy link
Owner

If you can give examples of the app running the mitm proxy i'm happy to add support for these

@DotNet2Web
Copy link
Author

I tried did but was not succesful doing it.

if you could tell me what and how to set up the mitm proxy then we can sort it out.

@allenporter
Copy link
Owner

https://github.com/allenporter/pyrainbird/blob/main/CONTRIBUTING.md has a little bit of information. Happy to help if you have a more specific question/issue

@DotNet2Web
Copy link
Author

I will give it a go today.

First of all I need to understand how I can setup the virtual environment on my windows machine. I found a MITM tutorial on the homeassistant forum that Im going to follow.

@allenporter
Copy link
Owner

I recommend using mitm with the rainbird app for what it's worth to capture the traffic of valid requests/ responses.

@DotNet2Web
Copy link
Author

DotNet2Web commented Jul 9, 2023

PyTest results:
image

Next:
image

And then I'm lost, I open the rainbird app on my phone and start an irregation but nothing happens in the proxy.

I need to add the proxy between the rainbird controller, any suggestions?

@allenporter
Copy link
Owner

You need to configure your smart phone to use your computer as a proxy, something like described here https://gaikwadchetan93.medium.com/monitoring-modifying-android-app-network-traffic-via-mitm-proxy-part-1-886f6324f705

@DotNet2Web
Copy link
Author

DotNet2Web commented Jul 11, 2023

Got up and running now, I'm capturing the traffic from my iphone to the controller.

From a terminal I run this: mitmproxy -s examples/mitm_rainbird.py

mitmproxy starts capturing all trafic.

When accessing the controller from the app, it captures for example this request:

Request:
{ "id": 1, "jsonrpc": "2.0", "method": "requestWeatherAndStatus", "params": { "Country": "NL", "StickId": "MY_STICKID", "ZipCode": "MY_ZIPCODE" } }

Response:
{ "result": { "Weather": { "city": "My_City", "timeZoneId": "Europe/Amsterdam", "forecast": [ {}, { "dateTime": 1689116400, "high": 23.0, "chanceofrain": 87, "precip": 0.0157, "low": 18.0, "icon": "10d", "description": "rain" }, { "dateTime": 1689202800, "high": 22.0, "chanceofrain": 80, "precip": 0.0315, "low": 17.0, "icon": "10d", "description": "rain" }, { "dateTime": 1689289200, "high": 21.0, "chanceofrain": 89, "precip": 0.1535, "low": 16.0, "icon": "10d", "description": "rain" }, { "dateTime": 1689375600, "high": 21.0, "chanceofrain": 88, "precip": 0.0512, "low": 16.0, "icon": "10d", "description": "rain" }, { "dateTime": 1689462000, "high": 22.0, "chanceofrain": 75, "precip": 0.0236, "low": 18.0, "icon": "10d", "description": "rain" }, { "dateTime": 1689548400, "high": 22.0, "chanceofrain": 0, "precip": 0.0, "low": 17.0, "icon": "01d", "description": "clear sky" } ], "location": "MY_ZIPCODE", "timeZoneRawOffset": 3600 }, "ForecastedRain": {}, "DuplicateMac": false, "StickId": "MY_STICKID", "Controller": {}, "ConnectedStatus": [ { "Status": 0, "CompanyId": 0, "Enabled": true, "Params": {}, "Name": "Alarm.com" }, { "Status": 0, "CompanyId": 1, "Enabled": true, "Params": {}, "Name": "Amazon Alexa" }, { "Status": 0, "CompanyId": 2, "Enabled": true, "Params": {}, "Name": "Google Assistant" }, { "Status": 0, "CompanyId": 3, "Enabled": false, "Params": {}, "Name": "Flume" } ] }, "id": 1, "jsonrpc": "2.0" }

But when I start an irrigation run it return a response that could not be parsed so mitmproxy falls back to raw.

@allenporter
Copy link
Owner

Ok great! Now you've got the harness all setup. That first request is to their cloud API so it's simple to decide.

The requests to the rainbird need to be decoded with the password. You should see some environment variables in the mitm code that you need to set which should enable decoding of device packets.

Once you have that going you should see some partial decoding of the events, which we can then look closer at to figure out the exact way the need to be encoded / decoded into specific commands and responses.

@allenporter
Copy link
Owner

RAINBIRD_PASSWORD is the environment variable needed for mitm to decode.

@allenporter
Copy link
Owner

@DotNet2Web
Copy link
Author

Setting the Rainbird_password in the python script and capturing its request/response still shows the same octet-stream that cant be decoded.

I scrolled through all response to find one or more that make some sense but they are all still in binary.

@allenporter
Copy link
Owner

allenporter commented Jul 12, 2023

Ok I worry maybe the password didn't work. Can you share how you set the environment variable? (Minus the actual password)

@DotNet2Web
Copy link
Author

In the examples/mitm_rainbird.py script, I just replace the value of the environment variable into my controller pwd.

image

So within the array between the two quotes I place my password.

Then I save the file and start mitmproxy using this command from a terminal:

mitmproxy -s examples/mitm_rainbird.py

@allenporter
Copy link
Owner

allenporter commented Jul 12, 2023

OK if you do it that way then set passwd = "MY_WORKING_CONTROLLER_PASSWORD" otherwise its looking in the environment variables for your password which won't be set.

@DotNet2Web
Copy link
Author

DotNet2Web commented Jul 29, 2023

Done, sorry for the late response was on a vacation trip.

Changed the way of setting the pwd in the script, like you said.
Then I took the same steps and run the mitmproxy.

Still none understandable response. The one thing that is different now is that mitmproxy detects its HEX instead of falling back to raw.

Any advice ?

@allenporter
Copy link
Owner

I'm not sure what you mean. is it worth sharing a little more detail? If its detecting as hex, perhaps its what we're looking for. You'll have a request and a response in hex that looks something like this: https://github.com/allenporter/pyrainbird/blob/main/tests/testdata/current_queue_me3.yaml

In that example file (and see others in that directory) you have the hex on top and the decoded message on the bottom, and so we want to start with the hex requests and figure out how to decode it (i can help do that)

@DotNet2Web
Copy link
Author

StartedIrrigationRequest.txt
StartedIrrigationResponse.txt

This is the first request / response when I started an irrigation run for a zone.

@allenporter
Copy link
Owner

OK wasn't exactly the format I was expecting, but i see what you mean about it being raw hex. I worry this is the encrypted payload. I'm having trouble understanding this hex dump in the context of what mitmproxy shows when i use it myself. Perhaps you can hare more detail about the command you run or screenshots if using it in interactive mode, etc.

@DotNet2Web
Copy link
Author

@allenporter, any way I can send the screenshots and screen capture to you ?

@allenporter
Copy link
Owner

You can attach to the issue or email [email protected]

@salvoM
Copy link

salvoM commented Aug 18, 2023

Hey guys can you please update the issue as I'm trying myself to understand how can i make it work with this LNK2 module.

@allenporter RAINBIRD_PASSWORD to is the local Access Point Wi-Fi password?

@allenporter
Copy link
Owner

It's the password for the device so you can decode the packets intercepted by the proxy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants