Skip to content

Instantly share code, notes, and snippets.

@pergolafabio
Forked from dries007/README.md
Created August 17, 2021 06:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pergolafabio/0a38ac0df27f5e0b951a0423df9d30d2 to your computer and use it in GitHub Desktop.
Save pergolafabio/0a38ac0df27f5e0b951a0423df9d30d2 to your computer and use it in GitHub Desktop.
Dobiss Domotica / Home Automation Protocols

Dobiss Domotica / Home Automation Protocols

This is information related to the Dobiss protocols that I have discovered by probing various things on my devices. My installation is a pair of modules marked "Dobiss Domotics Relay Module single pole 8 channel Model DO4511" connected by a black CAN cable. The button bus is connected to the first module.

WARNING Assume that anything you can touch or probe or poke a wire into is on LIVE VOLTAGE and will kill you if you touch it. I'm not responsible for whatever you decide to do with this information.

In particular make sure of the following: Measure that there is no voltage between the ground and your earch connection.

I used can-utils on Linux to get this information, all packets are in the cansend can_frame format unless otherwise noted.

Pinouts

The CAN bus goes over the black RJ12 connector in the center of the unit, make sure you disable the terminator resistor if you add a cable. You can use an RJ11 (telephone) cable as well, since you only need 3 concuctors and the outermost pins are not used.

This is the pinout for an RJ12 cable:

  1. CAN H
  2. GND (don't forget!)
  3. CAN L

In my setup, I connected these via an unshielded handtwisted cable to the CAN screw terminals of a RS485/CAN HAT from Waveshare.

CAN Protocol

The CAN bus speed is 125kbit/s (sometimes known as "low speed can").

Get State

> 01FCmm01#mmrr
< 01FDFF01#ss
  • mm = module
  • rr = relay 0-7 (or 8-B for the linkout 12v pins)
  • ss = state 0 = off, 1 = on

Examples:

> 01FC0101#0104
< 01FDFF01#00
> 01FC0101#0103
< 01FDFF01#00
> 01FC0101#0102
< 01FDFF01#00
> 01FC0101#0101
< 01FDFF01#00
> 01FC0101#0100
< 01FDFF01#00

Set State

Send to control a relay/output. Note that if a relay is set on the module where the button bus comes in, you won't see the tx message on the CAN bus but you will get the rx message.

> 01FCmm02#mmrrssFFFF
< 0002FF01#mmrrss
  • mm = module
  • rr = relay 0-7 (or 8-B for the linkout 12v pins)
  • ss = state 0 = off, 1 = on (2 = toggle, tx only, rx is always 0 or 1)

Note that the actual modules send along some more bytes (0x64FFFF) but those don't seem to be required for simple on-off operations. Since I don't have dimmers or other modules I cannot test these, but I assume that's what these bytes are for.

Examples:

> 01FC0202#020300FFFF64FFFF
< 0002FF01#020300
> 01FC0202#020400FFFF64FFFF
< 0002FF01#020400
> 01FC0202#020500FFFF64FFFF
< 0002FF01#020500
> 01FC0202#020200FFFF64FFFF
< 0002FF01#020200
> 01FC0202#020100FFFF64FFFF
< 0002FF01#020100
> 01FC0202#020000FFFF64FFFF

Onewire

The button bus is a onewire based bus. Since I can control all of what I need via CAN, I'm not doing further investigation.

import can
# ip link set can0 type can bitrate 125000
# sudo ifconfig can0 txqueuelen 1000
# sudo ifconfig can0 up
bus = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=125000)
MAPPING = {
# name -> (module, relay)
"wc": (1, 0),
"bed": (1, 1),
"hal": (1, 2),
"desk": (1, 3),
"spot1": (1, 4),
"living": (1, 5),
"spot2": (1, 6),
"kitchen": (1, 7),
"pantry": (2, 0),
"bathroom": (2, 1),
"out front": (2, 2),
"out back": (2, 3),
}
STATE = {
"off": 0,
"on": 1,
"toggle": 2,
}
def send(name, state):
if name not in MAPPING:
print("Name", name, "is not known. Options:", ','.join(MAPPING.keys()))
if state not in STATE:
print("Name", name, "is not known. Options:", ','.join(STATE.keys()))
m, r = MAPPING[name]
s = STATE[state]
bus.send(can.Message(arbitration_id=int(f"01FC0{m}02", 16), data=bytes.fromhex(f'0{m}0{r}0{s}FFFF'), is_extended_id=True))
while True:
cmd = input("> ")
name, state = cmd.split(" ", 2)
if name == "all":
for x in MAPPING:
send(x, state)
else:
send(name, state)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment