Plant 3.0 and Reef-pi

haley-pi

New Member
View Badges
Joined
Aug 14, 2020
Messages
15
Reaction score
7
Location
ottawa
Rating - 0%
0   0   0
Hey everyone,

has anyone had any luck controlling the fluval 3.0 to the reef Pi?

I get short power outrages, and their internal timers apparently can’t handle remembering the time if they have been unplugged... something that my old $10 timer and computers from the 80’s had no problem with.

thanks
 
OP
OP
H

haley-pi

New Member
View Badges
Joined
Aug 14, 2020
Messages
15
Reaction score
7
Location
ottawa
Rating - 0%
0   0   0
That is defiantly a wealth of info.
If you've ever dealt with Fluval before, you'll know they like to void warranties for literally anything. I'm worried hooking it up this was will give them cause to do that. I think doing it via imitating the app might be a better way. I was able to decompile the app, but unfortunately it's written in java, which I have never coded in, its also written to work on android, which I don't have.

anyone here think they can help me figure out what the calls are?
 
OP
OP
H

haley-pi

New Member
View Badges
Joined
Aug 14, 2020
Messages
15
Reaction score
7
Location
ottawa
Rating - 0%
0   0   0
So I connected my computer to it’s Bluetooth.

did absolutely nothing special. Just clicked the Bluetooth icon on my computer, and paired with the light.... and the light broke.

well, the Bluetooth broke. It wouldn’t connect to the app anymore. I was able to get an exchange, but I don’t think I will be trying to continue to work on this project.

Fluvals inability to make a solid light that can handle even slight variations from the norm, has made me too scared to try anything with it.

way to go Fluval.
 

Ranjib

7500 Club Member
View Badges
Joined
Apr 16, 2016
Messages
9,848
Reaction score
17,081
Location
Pleasant Hill, Concord
Rating - 0%
0   0   0
So I connected my computer to it’s Bluetooth.

did absolutely nothing special. Just clicked the Bluetooth icon on my computer, and paired with the light.... and the light broke.

well, the Bluetooth broke. It wouldn’t connect to the app anymore. I was able to get an exchange, but I don’t think I will be trying to continue to work on this project.

Fluvals inability to make a solid light that can handle even slight variations from the norm, has made me too scared to try anything with it.

way to go Fluval.
if you dont have any other choices, just rip out those controls and and control it straight via reef-pi. Put a mosfet or some other led driver if required and just control it with pi or pca9685 pwm signals
 

Bigtrout

Valuable Member
View Badges
Joined
Dec 16, 2018
Messages
1,189
Reaction score
2,826
Rating - 0%
0   0   0
if you dont have any other choices, just rip out those controls and and control it straight via reef-pi. Put a mosfet or some other led driver if required and just control it with pi or pca9685 pwm signals
Thats effectively what I have done with 2 beamswork fixtures on my 75. They didnt have fancy controls to start, but thanks to reef-pi they do now!!!
 
OP
OP
H

haley-pi

New Member
View Badges
Joined
Aug 14, 2020
Messages
15
Reaction score
7
Location
ottawa
Rating - 0%
0   0   0
if you dont have any other choices, just rip out those controls and and control it straight via reef-pi. Put a mosfet or some other led driver if required and just control it with pi or pca9685 pwm signals
I ended up buying a small Aquasky. I was able to grab some packet logging. Anyone think they could help me decipher it? I have no experience with Bluetooth.
 
OP
OP
H

haley-pi

New Member
View Badges
Joined
Aug 14, 2020
Messages
15
Reaction score
7
Location
ottawa
Rating - 0%
0   0   0
So I was able to write a python script that control's the light, my problem is reef-pi doesn't seem to have anyway of communicating.

I was originally going to set the Lighting to an a analog-file driver, and adjust my script to work with that. However, Reef-pi doesn't seem to let me do that.

Any idea how I can get around that?

Here is the data the Python script needs:

Code:
{'r': 0, 'g': 0, 'b': 0, 'w': 0}

The Aqausky only has 5 settings for each colour, so 0 is off, 5 is max.
 

lucidity14

New Member
View Badges
Joined
Apr 27, 2021
Messages
1
Reaction score
0
Location
Canada
Rating - 0%
0   0   0
So I was able to write a python script that control's the light, my problem is reef-pi doesn't seem to have anyway of communicating.

I was originally going to set the Lighting to an a analog-file driver, and adjust my script to work with that. However, Reef-pi doesn't seem to let me do that.

Any idea how I can get around that?

Here is the data the Python script needs:

Code:
{'r': 0, 'g': 0, 'b': 0, 'w': 0}

The Aqausky only has 5 settings for each colour, so 0 is off, 5 is max.
I’m looking to reverse engineer the Fluval Plant 3.0 light, and you seem to have quite a head start! Would you be willing to share your script, maybe put it on GitHub?

Also I’d love to find out how you accomplished packet logging?
 

TurtleReef

New Member
View Badges
Joined
May 23, 2022
Messages
1
Reaction score
3
Location
South Louisiana
Rating - 0%
0   0   0
If anyone is still looking for this , this python script will get you going

#!/usr/bin/env python3
import sys

"""
API SPECIFICATION
There are a lot of commands defined in the decompiled APK; see CommUtil.java for the full list. But this is an exhaustive list that covers lots of different hardware. At the moment only on/off and brightness per-channel are implemented here.
COMMAND STRUCTURE
Every command message begins with a header (0x68), followed by a single command byte, then whatever arguments for that command, followed by a CRC byte. This is then encrypted per below before being sent over BLE.
BLE MESSAGE ENCRYPTION SCHEME
A random key (lrand48()) is generated with each message. Then that key is used to XOR the rest of the message. The random key is itself stored in a header, where it is XOR'd with a fixed value (0x54).
The wrapped, encrypted format is:
[IV] [Length] [Key] [byte1, byte2, ...]
Where IV is always 0x54, length is the number of bytes after the key XOR'd with the IV, and the key is a random number XOR'd with the IV.
When sending messages to the device, there's no need to generate a random if you don't want to. You can just use a fixed number like zero.
"""

def ble_encode(b):
raw_len = len(b)
rand = 0
encoded_bytes = bytearray([0x54, (raw_len + 1) ^ 0x54, rand ^ 0x54])
for byte in b:
encoded_bytes.append(byte ^ rand)

return encoded_bytes

def ble_decode(b):
iv = b[0]
length = b[1] ^ iv
key = b[2] ^ iv

decoded_bytes = bytearray()
for i in range(3, len(b)):
decoded_bytes.append(b ^ key)

return decoded_bytes

# The last byte of a message is a CRC value that is just every byte XOR'd in order.
def crc(cmd):
check = 0
for i in range(0, len(cmd)):
check = check ^ cmd
return check

def buildMessage(raw_bytes):
raw_msg = bytearray(raw_bytes)
# Prepend message header (0x68), aka FRM_HDR in apk source code
msg = bytearray([0x68])
msg.extend(raw_msg)
msg.append(crc(msg))
print("Dec message: ", msg.hex())
enc_msg = ble_encode(msg)
print("Enc message: ", enc_msg.hex())
return enc_msg

def getPowerOnMessage():
# Power:
# CMD_SWITCH (0x03), [0|1]
return buildMessage([0x03, 0x01])


def getPowerOffMessage():
# Power:
# CMD_SWITCH (0x03), [0|1]
return buildMessage([0x03, 0x00])

# Sets the brightness of one or more channels
# Level: 0-1000 (0x03E8) -- note this is two bytes and is big-endian
# Channels not specified will not be modified.
def getBrightnessMessage(red=False, blue=False, cwhite=False, pwhite=False, wwhite=False):
# Channel brightness message format:
# CMD_CTRL (0x04), <16-bit red>, <16-bit blue>, <16-bit cwhite>, <16-bit pwhite>, <16-bit wwhite>
# Notes: Values set to 0xFFFF will not modify anything.
# Legal range is 0x0000-0x03E8, big-endian.

def consider(color):
nop = b'\xff\xff'
if color is False:
return nop
elif color < 0 or color > 1000:
print("fatal: brightness values must be between 0-1000")
sys.exit(1)
else:
return color.to_bytes(2, byteorder='big')

cmd = bytearray([0x04])
cmd.extend(consider(red))
cmd.extend(consider(blue))
cmd.extend(consider(cwhite))
cmd.extend(consider(pwhite))
cmd.extend(consider(wwhite))

return buildMessage(cmd)


def main():
# Examples:
print("Power on")
getPowerOnMessage()
print("Power off")
getPowerOffMessage()
print("Blue to 950")
getBrightnessMessage(blue=950)
print("All off, red to 1000")
getBrightnessMessage(red=1000, blue=0, wwhite=0, pwhite=0, cwhite=0)

#For i in sys.stdin:
# print(ble_decode(bytes.fromhex(i)).hex())

if __name__ == '__main__':
main()
 

HAVE YOU EVER KEPT A RARE/UNCOMMON FISH, CORAL, OR INVERT? SHOW IT OFF IN THE THREAD!

  • Yes!

    Votes: 32 45.7%
  • Not yet, but I have one that I want to buy in mind!

    Votes: 9 12.9%
  • No.

    Votes: 26 37.1%
  • Other (please explain).

    Votes: 3 4.3%
Back
Top