elgatho
(Chris)
December 20, 2024, 5:12pm
1
I’m trying to read values from the device over modbus, with esphome.
From debug i have
[16:35:01][I][:057]: Lambda incoming value=10752.000000 - data array size is 2
[16:35:01][I][:058]: Sensor properties: adress = 0xB4C, offset = 0x0 value type=3
[16:35:01][I][:061]: data[0]=0x00 (42)
[16:35:01][I][:061]: data[0]=0x3FF00000 (0)
[16:35:01][I][:065]: Sensor value: = 42
How to get data from sensor?
sensor:
- platform: modbus_controller
modbus_controller_id: Heater
name: "External temp"
id: temperature_outside
register_type: holding
address: 0x0b4c
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
result = 1075,2
is it possible to get this data without lambda?
Karosm
(Karosm)
December 20, 2024, 7:52pm
3
You haven’t posted any lambda. Post your complete yaml for best support…
elgatho
(Chris)
December 20, 2024, 9:26pm
4
now i’m using lambda like that
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
I’m just wounering if it’s possible to do it without lambda
nickrout
(Nick Rout)
December 21, 2024, 4:32am
6
I don’t believe so, why anyway?
elgatho
(Chris)
December 21, 2024, 11:50am
7
ok go it, last thing.
I’m getting value of the sensor
- platform: modbus_controller
modbus_controller_id: mbd
name: "temp comfort boiler"
id: temperature_boil_komfort
register_type: holding
address: 0x0b67
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[3] << 8 | data[2];
return value ;
I’m trying to change temp with command
select:
- platform: modbus_controller
id: onoffsel1
name: "Temp comfort boiler set"
address: 0x0b67
value_type: U_WORD
entity_category: config
icon: "mdi:toggle-switch"
optionsmap:
"45": 45
"46": 46
But when i set value
46 - temp is set 1177,6
45 - temp is set 1152
Any idea?
Karosm
(Karosm)
December 21, 2024, 3:29pm
8
It would be more productive if you post a link to your devices modbus protocol.
elgatho
(Chris)
December 21, 2024, 3:34pm
9
unfortunatley, vendor don’t wan’t to share that information, so everything is reverse engineering
Karosm
(Karosm)
December 21, 2024, 3:46pm
10
So what are you getting out from modbus sensor with U-WORD without that lambda?
Maybe it’s FP32 from two registers? Or something else…
What you know about those registers after reverse engineering?
Edit:
46 is 0x002E in hex
0x2E00 is 11776 in decimal
So you have swapped hi and low byte.
elgatho
(Chris)
December 22, 2024, 7:09pm
11
what i got so far
esphome:
name: ${device}
platform: ESP8266
board: d1_mini
logger:
baud_rate: 0
status_led:
pin: GPIO2
uart:
id: mod_bus
tx_pin: TX
rx_pin: RX
baud_rate: 9600
stop_bits: 1
parity: NONE
modbus:
id: modbus1
modbus_controller:
- id: kospel
address: 101
modbus_id: modbus1
setup_priority: -11
update_interval: 20s
command_throttle: 1s
allow_duplicate_commands: true
number:
- platform: modbus_controller
id: config_temp_boil_komf
name: "Ustaw temp komfortowa boilera"
address: 0x0b67
value_type: U_WORD
entity_category: config
icon: "mdi:toggle-switch"
min_value: 35
max_value: 50
lambda: |-
int value = data[3] << 8 | data[2];
value = value / 10;
return value ;
write_lambda: |-
int int_value = static_cast<int>(x * 10);
return (int_value << 8) | (int_value >> 8);
- platform: modbus_controller
id: config_temp_boil_eko
name: "Ustaw temp ekonomiczna boilera"
address: 0x0b66
value_type: U_WORD
entity_category: config
icon: "mdi:toggle-switch"
min_value: 30
max_value: 45
lambda: |-
int value = data[1] << 8 | data[0];
value = value / 10;
return value ;
write_lambda: |-
int int_value = static_cast<int>(x * 10);
return (int_value << 8) | (int_value >> 8);
sensor:
- platform: total_daily_energy
name: "Kospel zużycie energii dzienne"
id: kospel_daily_power_usage
power_id: power
unit_of_measurement: kWh
icon: mdi:calendar-clock
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura w na zewnątrz"
id: temperature_outside
register_type: holding
address: 0x0b4c
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int16_t value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boiler"
id: temperature_boil
register_type: holding
address: 0x0b4a
device_class: temperature
value_type: S_WORD
unit_of_measurement: "°C"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura Wejścia"
id: temperature_in
register_type: holding
address: 0x0b48
value_type: S_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura Wyjścia"
id: temperature_out
register_type: holding
address: 0x0b49
value_type: S_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[3] << 8 | data[2];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura zadana układu"
id: temperature_factor
register_type: holding
address: 0x0b44
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera min"
id: temperature_boil_min
register_type: holding
address: 0x0bbe
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[2] << 8 | data[1];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera max"
id: temperature_boil_max
register_type: holding
address: 0x0bbf
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[2] << 8 | data[1];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera komfortowa"
id: temperature_boil_komfort
register_type: holding
address: 0x0b67
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[3] << 8 | data[2];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Temperatura boilera ekonomiczna"
id: temperature_boil_ekonomiczna
register_type: holding
address: 0x0b66
value_type: U_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Ciśnienie w układzie"
id: presaure
register_type: holding
address: 0x0b4e
value_type: S_WORD
unit_of_measurement: "bar"
accuracy_decimals: 1
device_class: pressure
filters:
- multiply: 0.01
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Przepływ"
id: flow
register_type: holding
address: 0x0b4f
value_type: U_WORD
device_class: volume_flow_rate
unit_of_measurement: "l/min"
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[item->offset+1] << 8 | data[item->offset];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Moc"
id: power
register_type: holding
address: 0x0b46
value_type: S_WORD
unit_of_measurement: "kW"
device_class: power
accuracy_decimals: 1
filters:
- multiply: 0.1
lambda: |-
int value = data[1] << 8 | data[0];
return value ;
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Wejścia binarne"
internal: true
id: wb
register_type: holding
address: 0x0b51
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Wejścia binarne rw_flagi_1"
internal: true
id: wbrwf1
register_type: holding
address: 0x0b55
binary_sensor:
- platform: template
name: "[WB] CO_YES_NO"
lambda: |-
uint16_t value = (int(id(wbrwf1).state) & 0xFF00) >> 8 | (int(id(wbrwf1).state) & 0x00FF);
return ((value >> 4) & 1);
- platform: template
name: "[WB] Pompa"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return (value & 1);
- platform: template
name: "[WB] Pompa cyrkulacyjna"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 1) & 1);
- platform: template
name: "[WB] Wejscie sygnału nadrzędnego"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 3) & 1);
- platform: template
name: "[WB] Wejście regulatora pokojowego"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 4) & 1);
- platform: template
name: "[WB] Fun"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 6) & 1);
- platform: template
name: "[WB] CO"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 7) & 1);
- platform: template
name: "[WB] CWU"
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
return ((value >> 8) & 1);
#Konfiguracja
text_sensor:
- platform: modbus_controller
modbus_controller_id: kospel
name: "Tryb pracy boilera"
id: tryb_pracy_boilera
register_type: holding
address: 0x0b30
raw_encode: HEXBYTES
lambda: |-
uint16_t value = data[1] << 8 | data[0];
switch (value) {
case 0: return std::string("Ekonomiczny");
case 1: return std::string("Przeciw zamarzanie");
case 2: return std::string("Komfortowy");
default: return std::string("Unknown");
}
return x;
- platform: modbus_controller
modbus_controller_id: kospel
name: "Tryb pracy kotła"
id: tryb_pracy_kotla
register_type: holding
address: 0x0b32
raw_encode: HEXBYTES
lambda: |-
uint16_t value = data[1] << 8 | data[0];
switch (value) {
case 0: return std::string("Ekonomiczny");
case 1: return std::string("Przeciw zamarzanie");
case 2: return std::string("Komfortowy");
case 3: return std::string("Komfortowy minus");
case 4: return std::string("Komfortowy plus");
case 64: return std::string("Grzanie pokoju");
default: return std::string("Unknown");
}
return x;
- platform: modbus_controller
modbus_controller_id: kospel
name: "[WB] Zawór TDR"
id: tdr
register_type: holding
address: 0x0b51
raw_encode: HEXBYTES
lambda: |-
uint16_t value = (int(id(wb).state) & 0xFF00) >> 8 | (int(id(wb).state) & 0x00FF);
value = ((value >> 2) & 1);
switch (value) {
case 0: return std::string("co");
case 1: return std::string("cwu");
default: return std::string("Unknown");
}
return x;
- platform: template
name: "[WB] Zima"
lambda: |-
uint16_t value = (int(id(wbrwf1).state) & 0xFF00) >> 8 | (int(id(wbrwf1).state) & 0x00FF);
int zima = ((value >> 5) & 1);
int lato = ((value >> 3) & 1);
if (zima == 1 && lato == 1) {
return std::string("Tryb zimowy");
} else if (lato == 1 && zima == 0) {
return std::string("Tryb letni");
} else {
return std::string("Kocioł wyłączony");
}
I’m struggling with command to set winter/summer/off
To set winter to on, bit 5 needs to be 1, bit 3 needs to be 1
To set summer mode bit 5 needs to be 0, bit 3 needs to be 1
To Off system, mode bit 5 needs to be 0, bit 3 needs to be 0
i wrote below select command, but for me mistery is how to modify two bits at once
select:
- platform: modbus_controller
id: onoffsel1
name: "Boiler mode set"
address: 0x0b55
value_type: U_WORD
entity_category: config
icon: "mdi:toggle-switch"
optionsmap:
"Winter": 2
"Summer": 1
"Off": 0
lambda: |-
uint16_t value = (int(id(wbrwf1).state) & 0xFF00) >> 8 | (int(id(wbrwf1).state) & 0x00FF);
int winter= ((value >> 5) & 1);
int summer = ((value >> 3) & 1);
int tryb = 0;
if (winter== 1 && summer== 1) {
return std::string("Zima");
} else if (summer== 1 && winter== 0) {
return std::string("summer");
} else {
return std::string("off");
}
write_lambda: |-
if (value == 0) {
} else if (value == 1) {
} else if (value == 2) {
}
return reg; // Return the modified register value
Thank you very much for support
Karosm
(Karosm)
December 22, 2024, 7:19pm
12
Give a whole byte if other bits are not changing. What are the bits 0,1,2,4,6,7?
elgatho
(Chris)
December 22, 2024, 7:31pm
13
seems that you are asking for?
[20:29:44][I][:349]: Lambda incoming value=13209.000000 - data array size is 2
[20:29:44][I][:350]: Sensor properties: adress = 0xB55, offset = 0x0 value type=1
[20:29:44][I][:353]: data[0]=---- (0)
[20:29:44][I][:353]: data[0]=---- (1072693248)
[20:29:44][I][:357]: Sensor value: = 39219
Thank you !
Karosm
(Karosm)
December 22, 2024, 7:38pm
14
I didn’t understand a bit…
elgatho
(Chris)
December 22, 2024, 7:57pm
15
ok any idea how to read whole address?
Karosm
(Karosm)
December 22, 2024, 8:01pm
16
I don’t follow you anymore. Read or write? Which address?
elgatho
(Chris)
December 22, 2024, 8:07pm
17
Ok i have it:)
For Off is 0x0013
For summer mode 0x001B
For winter is 0x0033
Question, How to write it using select?
13 00010011
1b 00011011
33 00110011
Karosm
(Karosm)
December 22, 2024, 8:18pm
18
I have never tried select, either just like that in hex or if it really wants int,
optionsmap:
“Winter”: 19
“Summer”: 27
“Off”: 51
elgatho
(Chris)
December 29, 2024, 12:11pm
19
Thank you for your support,
I’ve created repository on github for Kospel heater over modbus.
1 Like