diff --git a/include/arke.h b/include/arke.h
index 8726040..087357a 100644
--- a/include/arke.h
+++ b/include/arke.h
@@ -1,155 +1,154 @@
 #pragma once
 #include "inttypes.h"
 
 #ifdef __cplusplus
 extern "C"{
 #endif //__cplusplus
 
 
 typedef enum ArkeMessageType_e {
 	ARKE_NETWORK_CONTROL_COMMAND = 0x00,
 	ARKE_HIGH_PRIORITY_MESSAGE = 0x01,
 	ARKE_MESSAGE = 0x02,
 	ARKE_HEARTBEAT = 0x03,
 	ARKE_MESSAGE_TYPE_MASK = 0x03 << 9
 } ArkeMessageType;
 
 typedef enum ArkeNodeClass_e {
 	ARKE_BROADCAST = 0x0,
 	ARKE_ZEUS = 0x38,
 	ARKE_HELIOS = 0x34,
 	ARKE_CELAENO = 0x30,
 	ARKE_NODE_CLASS_MASK = 0x3f << 3
 } ArkeNodeClass;
 
 
 typedef enum ArkeNetworkCommand_e {
 	ARKE_RESET_REQUEST = 0x00,
 	ARKE_SYNCHRONISATION = 0x01,
 	ARKE_HEARTBEAT_REQUEST = 0x07,
 	ARKE_SUBID_MASK = 0x07
 } ArkeNetworkCommand;
 
 //#define ARKE_SUBID_MASK ARKE_HEARTBEAT_REQUEST
 
 typedef enum ArkeMessageClass_e {
 	ARKE_ZEUS_SET_POINT = 0x38,
 	ARKE_ZEUS_REPORT = 0x39,
 	ARKE_ZEUS_VIBRATION_REPORT = 0x3a,
 	ARKE_ZEUS_CONFIG = 0x3b,
 	ARKE_ZEUS_STATUS = 0x3c,
 	ARKE_ZEUS_CONTROL_POINT = 0x3d,
 	ARKE_HELIOS_SET_POINT = 0x34,
 	ARKE_HELIOS_PULSE_MODE = 0x35,
 	ARKE_CELAENO_SET_POINT = 0x30,
 	ARKE_CELAENO_STATUS = 0x31,
 	ARKE_CELAENO_CONFIG = 0x32
 } ArkeMessageClass;
 
 
 struct ArkeZeusSetPoint_t {
 	uint16_t Humidity;
 	uint16_t Temperature;
 	uint8_t  Wind;
 } __attribute__((packed));
 typedef struct ArkeZeusSetPoint_t ArkeZeusSetPoint;
 
 
 struct ArkeZeusReport_t {
 	uint16_t Humidity:14;
 	uint16_t Temperature1:14;
 	uint16_t Temperature2:12;
 	uint16_t Temperature3:12;
 	uint16_t Temperature4:12;
 } __attribute__((packed));
 typedef struct ArkeZeusReport_t ArkeZeusReport;
 
 
 struct ArkePDConfig_t {
-	uint8_t DeadRegion;
 	uint8_t ProportionalMult;
 	uint8_t DerivativeMult;
-	uint8_t ProportionalDivPower2:4;
-	uint8_t DerivativeDivPower2:4;
+	uint8_t IntegralMult;
+	uint8_t DividerPower;
 } __attribute__((packed));
 
 typedef struct ArkePDConfig_t ArkePDConfig;
 
 struct ArkeZeusConfig_t {
 	ArkePDConfig Humidity;
 	ArkePDConfig Temperature;
 } __attribute__((packed));
 
 typedef struct ArkeZeusConfig_t ArkeZeusConfig;
 
 #define ARKE_FAN_AGING_ALERT (0x4000)
 #define ARKE_FAN_STALL_ALERT (0x8000)
 #define ARKE_FAN_RPM_MASK (0x3fff)
 
 #define ArkeFanAging(status) (((status).fanStatus & ARKE_FAN_AGING_ALERT) != 0x0000)
 #define ArkeFanStall(status) (((status).fanStatus & ARKE_FAN_STALL_ALERT) != 0x0000)
 #define ArkeFanRPM(status) ( (status).fanStatus & ARKE_FAN_RPM_MASK )
 
 typedef uint16_t ArkeFanStatus;
 
 struct ArkeZeusStatus_t {
 	uint8_t       Status;
 	ArkeFanStatus Fan[2];
 } __attribute__((packed));
 typedef struct ArkeZeusStatus_t ArkeZeusStatus;
 
 #define ARKE_ZEUS_IDLE 0x00
 #define ARKE_ZEUS_ACTIVE 0x01
 #define ARKE_ZEUS_CLIMATE_UNCONTROLLED_WD 0x02
 
 struct ArkeZeusControlPoint_t {
 	int16_t Humidity;
 	int16_t Temperature;
 } __attribute__((packed));
 typedef struct ArkeZeusControlPoint_t ArkeZeusControlPoint;
 
 struct ArkeHeliosSetPoint_t {
 	uint8_t Visible;
 	uint8_t UV;
 } __attribute__((packed));
 typedef struct ArkeHeliosSetPoint_t ArkeHeliosSetPoint;
 
 struct ArkeCelaenoSetPoint_t {
 	uint8_t Power;
 } __attribute__((packed));
 typedef struct ArkeCelaenoSetPoint_t  ArkeCelaenoSetPoint;
 
 struct ArkeCelaenoStatus_t {
 	uint8_t  waterLevel;
 	ArkeFanStatus fanStatus;
 } __attribute__((packed));
 typedef struct ArkeCelaenoStatus_t  ArkeCelaenoStatus;
 
 
 typedef enum ArkeCelaenoWaterLevel_e {
 	ARKE_CELAENO_NOMINAL = 0,
 	ARKE_CELAENO_WARNING = (1 << 0),
 	ARKE_CELAENO_CRITICAL = (1 << 1),
 	ARKE_CELAENO_RO_ERROR = (1 << 2)
 } ArkeCelaenoWaterLevel;
 
 #define ArkeCelaenoWaterNominal(status) ( (status).waterLevel == 0 )
 #define ArkeCelaenoWaterWarning(status) ( (status).waterLevel == ARKE_CELAENO_WARNING )
 #define ArkeCelaenoWaterCritical(status) ( ((status).waterLevel & ~(ARKE_CELAENO_CRITICAL | ARKE_CELAENO_RO_ERROR) ) == ARKE_CELAENO_WARNING )
 #define ArkeCelaenoWaterHasRoError(status) (((status).waterLevel & ARKE_CELAENO_RO_ERROR) != 0x00)
 
 
 struct ArkeCelaenoConfig_t {
 	uint16_t RampUpTimeMS;
 	uint16_t RampDownTimeMS;
 	uint16_t MinOnTimeMS;
 	uint16_t DebounceTimeMS;
 } __attribute__((packed));
 
 typedef struct ArkeCelaenoConfig_t ArkeCelaenoConfig;
 
 
 
 #ifdef __cplusplus
 }
 #endif //__cplusplus
diff --git a/src-go/arke/pd_config.go b/src-go/arke/pd_config.go
index 856065b..a3aa7f0 100644
--- a/src-go/arke/pd_config.go
+++ b/src-go/arke/pd_config.go
@@ -1,34 +1,23 @@
 package arke
 
-import "fmt"
-
 type PDConfig struct {
-	DeadRegion              uint8
 	ProportionnalMultiplier uint8
 	DerivativeMultiplier    uint8
-	ProportionalDivider     uint8
-	DerivativeDivider       uint8
+	IntegralMultiplier      uint8
+	DividerPower            uint8
 }
 
 func (c PDConfig) marshall(buffer []byte) error {
-	if c.ProportionalDivider > 15 {
-		return fmt.Errorf("Maximal Proportional Divider is 15")
-	}
-	if c.DerivativeDivider > 15 {
-		return fmt.Errorf("Maximal Derivative Divider is 15")
-	}
-
-	buffer[0] = c.DeadRegion
-	buffer[1] = c.ProportionnalMultiplier
-	buffer[2] = c.DerivativeMultiplier
-	buffer[3] = ((c.DerivativeDivider & 0x0f) << 4) | c.ProportionalDivider&0x0f
+	buffer[0] = c.ProportionnalMultiplier
+	buffer[1] = c.DerivativeMultiplier
+	buffer[2] = c.IntegralMultiplier
+	buffer[3] = c.DividerPower
 	return nil
 }
 
 func (c *PDConfig) unmarshall(buffer []byte) {
-	c.DeadRegion = buffer[0]
-	c.ProportionnalMultiplier = buffer[1]
-	c.DerivativeMultiplier = buffer[2]
-	c.ProportionalDivider = buffer[3] & 0x0f
-	c.DerivativeDivider = (buffer[3] & 0xf0) >> 4
+	c.ProportionnalMultiplier = buffer[0]
+	c.DerivativeMultiplier = buffer[1]
+	c.IntegralMultiplier = buf[2]
+	c.DividerPower = buf[2]
 }
diff --git a/src-go/arke/zeus_test.go b/src-go/arke/zeus_test.go
index f5630c5..af49415 100644
--- a/src-go/arke/zeus_test.go
+++ b/src-go/arke/zeus_test.go
@@ -1,330 +1,310 @@
 package arke
 
 import (
 	"fmt"
 	"math"
 
 	. "gopkg.in/check.v1"
 )
 
 type ZeusSuite struct{}
 
 var _ = Suite(&ZeusSuite{})
 
 type almostEqualChecker struct {
 	*CheckerInfo
 }
 
 var AlmostChecker = &almostEqualChecker{
 	&CheckerInfo{Name: "AlmostEqual", Params: []string{"obtained", "expected", "within"}},
 }
 
 func (c *almostEqualChecker) Check(params []interface{}, names []string) (result bool, error string) {
 	defer func() {
 		if v := recover(); v != nil {
 			result = false
 			error = fmt.Sprint(v)
 		}
 	}()
 	a := params[0].(float32)
 	b := params[1].(float32)
 	bound := params[2].(float64)
 	result = math.Abs(float64(a-b)) <= bound
 	return
 }
 
 func (s *ZeusSuite) TestSetPointIO(c *C) {
 	testData := []struct {
 		Message ZeusSetPoint
 		Buffer  []byte
 	}{
 		{
 			Message: ZeusSetPoint{
 				Humidity:    42,
 				Temperature: 25,
 				Wind:        127,
 			},
 			Buffer: []byte{
 				0xe0, 0x1a, 0x35, 0x19, 0x7f,
 			},
 		},
 	}
 
 	for _, d := range testData {
 		res := make([]byte, 5)
 		written, err := d.Message.Marshall(res)
 		if c.Check(err, IsNil) == false {
 			continue
 		}
 		c.Check(written, Equals, 5)
 		c.Check(res, DeepEquals, d.Buffer)
 	}
 
 	for _, d := range testData {
 		res := ZeusSetPoint{}
 		if c.Check(res.Unmarshall(d.Buffer), IsNil) == false {
 			continue
 		}
 		c.Check(res.Wind, Equals, d.Message.Wind)
 		c.Check(res.Humidity, AlmostChecker, d.Message.Humidity, 0.01)
 		c.Check(res.Temperature, AlmostChecker, d.Message.Temperature, 0.01)
 	}
 
 	m := ZeusSetPoint{}
 	written, err := m.Marshall([]byte{})
 	c.Check(err, ErrorMatches, "Invalid buffer size .*")
 	c.Check(written, Equals, 0)
 	c.Check(m.Unmarshall([]byte{}), ErrorMatches, "Invalid buffer size .*")
 	errorData := []struct {
 		Buffer []byte
 		EMatch string
 	}{
 		{
 			[]byte{
 				0xff, 0xff, 0x00, 0x00, 0x00,
 			},
 			"Invalid humidity value",
 		},
 		{
 			[]byte{
 				0x00, 0x00, 0xff, 0xff, 0x00,
 			},
 			"Invalid temperature value",
 		},
 	}
 
 	for _, d := range errorData {
 		m := ZeusSetPoint{}
 		c.Check(m.Unmarshall(d.Buffer), ErrorMatches, d.EMatch)
 	}
 
 }
 
 func (s *ZeusSuite) TestReportIO(c *C) {
 	testData := []struct {
 		Message ZeusReport
 		Buffer  []byte
 	}{
 		{
 			Message: ZeusReport{
 				Humidity: 40,
 				Temperature: [4]float32{
 					25, 26, 27, 28,
 				},
 			},
 			Buffer: []byte{
 				0x99, 0x99,
 				0x4d, 0x06,
 				0x1a, 0xb0,
 				0x01, 0x1c,
 			},
 		},
 	}
 
 	for _, d := range testData {
 		res := ZeusReport{}
 		if c.Check(res.Unmarshall(d.Buffer), IsNil) == false {
 			continue
 		}
 		c.Check(res.Humidity, AlmostChecker, d.Message.Humidity, 0.01)
 		for i, _ := range res.Temperature {
 			c.Check(res.Temperature[i], AlmostChecker, d.Message.Temperature[i], 0.01)
 		}
 
 	}
 
 	errorData := []struct {
 		Buffer []byte
 		Ematch string
 	}{
 		{
 			[]byte{},
 			"Invalid buffer size .*",
 		},
 		{
 			[]byte{0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 			"Invalid humidity value",
 		},
 		{
 			[]byte{0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
 			"Invalid temperature value",
 		},
 	}
 
 	for _, d := range errorData {
 		m := ZeusReport{}
 		c.Check(m.Unmarshall(d.Buffer), ErrorMatches, d.Ematch)
 	}
 }
 
 func (s *ZeusSuite) TestConfigIO(c *C) {
 	testData := []struct {
 		Message ZeusConfig
 		Buffer  []byte
 	}{
 		{
 			Message: ZeusConfig{
 				Humidity: PDConfig{
-					DeadRegion:              127,
 					ProportionnalMultiplier: 100,
 					DerivativeMultiplier:    50,
-					ProportionalDivider:     1,
-					DerivativeDivider:       2,
+					IntegralMultiplier:      1,
+					DividerPower:            6,
 				},
 				Temperature: PDConfig{
-					DeadRegion:              60,
 					ProportionnalMultiplier: 103,
 					DerivativeMultiplier:    102,
-					ProportionalDivider:     4,
-					DerivativeDivider:       5,
+					IntegralMultiplier:      0,
+					DividerPower:            4,
 				},
 			},
 			Buffer: []byte{
-				127, 100, 50, (2 << 4) | 1, 60, 103, 102, (5 << 4) | 4,
+				100, 50, 1, 6, 103, 102, 0, 4,
 			},
 		},
 	}
 
 	for _, d := range testData {
 		res := ZeusConfig{}
 		if c.Check(res.Unmarshall(d.Buffer), IsNil) == false {
 			continue
 		}
 		c.Check(res, DeepEquals, d.Message)
 	}
 
 	for _, d := range testData {
 		res := make([]byte, 8)
 		n, err := d.Message.Marshall(res)
 		if c.Check(err, IsNil) == false {
 			continue
 		}
 		c.Check(n, Equals, 8)
 		c.Check(res, DeepEquals, d.Buffer)
 	}
 
 	errorData := []struct {
 		Message ZeusConfig
 		Buffer  []byte
 		Ematch  string
 	}{
 		{
 			ZeusConfig{},
 			make([]byte, 0),
 			"Invalid buffer size .*",
 		},
-		{
-			ZeusConfig{
-				Humidity: PDConfig{
-					DerivativeDivider: 16,
-				},
-			},
-			make([]byte, 8),
-			"Maximal Derivative Divider is 15",
-		},
-		{
-			ZeusConfig{
-				Temperature: PDConfig{
-					ProportionalDivider: 16,
-				},
-			},
-			make([]byte, 8),
-			"Maximal Proportional Divider is 15",
-		},
 	}
 
 	for _, d := range errorData {
 		_, err := d.Message.Marshall(d.Buffer)
 		c.Check(err, ErrorMatches, d.Ematch)
 	}
 
 	m := ZeusConfig{}
 	c.Check(m.Unmarshall([]byte{}), ErrorMatches, "Invalid buffer size .*")
 }
 
 func (s *ZeusSuite) TestStatusIO(c *C) {
 	testData := []struct {
 		Message ZeusStatus
 		Buffer  []byte
 	}{
 		{
 			Message: ZeusStatus{
 				Status: ZeusIdle,
 				Fans: [2]FanStatusAndRPM{
 					1200,
 					FanStatusAndRPM(0 | (uint16(FanStalled) << 14)),
 				},
 			},
 			Buffer: []byte{
 				0, 0xb0, 0x04, 0x00, 0x80,
 			},
 		},
 	}
 
 	for _, d := range testData {
 		res := ZeusStatus{}
 		if c.Check(res.Unmarshall(d.Buffer), IsNil) == false {
 			continue
 		}
 		c.Check(res, DeepEquals, d.Message)
 	}
 
 	errorData := []struct {
 		Buffer []byte
 		Ematch string
 	}{
 		{
 			make([]byte, 0),
 			"Invalid buffer size .*",
 		},
 	}
 
 	for _, d := range errorData {
 		m := ZeusStatus{}
 		err := m.Unmarshall(d.Buffer)
 		c.Check(err, ErrorMatches, d.Ematch)
 	}
 
 }
 
 func (s *ZeusSuite) TestControlPointIO(c *C) {
 	testData := []struct {
 		Message ZeusControlPoint
 		Buffer  []byte
 	}{
 		{
 			Message: ZeusControlPoint{
 				Humidity:    1234,
 				Temperature: -275,
 			},
 			Buffer: []byte{
 				0xd2, 0x04, 0xed, 0xfe,
 			},
 		},
 	}
 
 	for _, d := range testData {
 		res := ZeusControlPoint{}
 		if c.Check(res.Unmarshall(d.Buffer), IsNil) == false {
 			continue
 		}
 		c.Check(res, DeepEquals, d.Message)
 	}
 
 	errorData := []struct {
 		Buffer []byte
 		Ematch string
 	}{
 		{
 			make([]byte, 0),
 			"Invalid buffer size .*",
 		},
 	}
 
 	for _, d := range errorData {
 		m := ZeusControlPoint{}
 		err := m.Unmarshall(d.Buffer)
 		c.Check(err, ErrorMatches, d.Ematch)
 	}
 
 }