Closed adrusa closed 1 year ago
@adrusa Hello, I want to use sensor values in .yaml to sent over UDP direct to a server. UDP sending is working, bud how to access the sensor values? maybe you can help me
Hi,
I am unsure about both questions. Accessing sensor data in lambda can be very easy. Example:
sensor:
# Raw sensor
- platform: victron_ble
victron_ble_id: MySmartShunt
name: "Battery voltage"
type: BATTERY_VOLTAGE
id: shunt_BATTERY_VOLTAGE
# Template sensor
- platform: template
name: "Template Sensor"
lambda: |-
return id(shunt_BATTERY_VOLTAGE).state;
update_interval: 60s
Maybe @adrusa and @strom-peter can provide an example yaml of the problem?
Hello, and thanks for the input, bud i don't know how to start the UDP-script from sensors.... with the button, sending is working
script:
- id: send_udp
parameters:
val: float
then:
- lambda: |-
int port = 5000;
std::string host = "192.168.178.48";
std::string msg = "measurement ";
msg.append("tag=");
msg.append(to_string(val));
ESP_LOGI("send_udp", "msg= %s", msg.c_str());
int sock = ::socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in destination, source;
destination.sin_family = AF_INET;
destination.sin_port = htons(port);
destination.sin_addr.s_addr = inet_addr(host.c_str());
int n_bytes = ::sendto(sock, msg.c_str(), msg.length(), 0, reinterpret_cast<sockaddr*>(&destination), sizeof(destination));
ESP_LOGD("lambda", "Sent %s to %s:%d in %d bytes", msg.c_str(), host.c_str(), port, n_bytes);
::close(sock);
# for testing UDP
button:
- platform: template
id: button_udp_sender
name: "Send UDP Command"
on_press:
- script.execute:
id: send_udp
val: 123.45
esp32_ble_tracker:
victron_ble:
- id: MySmartShunt
mac_address: ${smart_shunt_mac_address}
bindkey: ${smart_shunt_encryption_key}
on_battery_monitor_message:
- logger.log: "Message from Battery Monitor."
# do I need globals??
globals:
- id: battU
type: float
sensor:
# Raw sensor
- platform: victron_ble
victron_ble_id: MySmartShunt
name: "Battery voltage"
type: BATTERY_VOLTAGE
id: shunt_BATTERY_VOLTAGE
# Template sensor
- platform: template
name: "Template Sensor"
lambda: |-
ESP_LOGI("Template sensor", "Value: %f", id(shunt_BATTERY_VOLTAGE).state);
// send to UDP ????
return id(shunt_BATTERY_VOLTAGE).state;
update_interval: 10s
Hi @strom-peter,
I can suggest four possible solutions:
Use on_battery_monitor_message
and script.execute
:
victron_ble:
- id: MySmartShunt
mac_address: ${smart_shunt_mac_address}
bindkey: ${smart_shunt_encryption_key}
on_battery_monitor_message:
- script.execute:
id: send_udp
# 0.01 V to 1 V
val: !lambda return 0.01f * message->battery_voltage;
Use on_battery_monitor_message
and lambda
:
victron_ble:
- id: MySmartShunt
mac_address: ${smart_shunt_mac_address}
bindkey: ${smart_shunt_encryption_key}
on_battery_monitor_message:
- lambda: id(send_udp)->execute(0.01f * message->battery_voltage);
Use sensor
and script.execute
:
sensor:
- platform: victron_ble
victron_ble_id: MySmartShunt
name: "Battery voltage"
type: BATTERY_VOLTAGE
id: shunt_BATTERY_VOLTAGE
on_value:
then:
- script.execute:
id: send_udp
val: !lambda return x;
Interval every 10 second just sent the last known value.
interval:
- interval: 10s
then:
lambda: |-
if(!std::isnan(id(shunt_BATTERY_VOLTAGE).state)) {
id(send_udp)->execute(id(shunt_BATTERY_VOLTAGE).state);
}
Solution 1-3 generates an UDP package as soon as a new value is received via Bluetooth. So very often.
Using on_battery_monitor_message
has advantages if you don't need the sensor component and your device has performance or memory consumption issues. Using the sensor
is cleaner implementation.
Solution 4 is a bit dumb and will also generate values if no new values are found by the Sensor, but it will not generate too many UDP packages.
I am unsure about your use case so I am hoping one of the solutions is suited.
@Fabian-Schmidt, many thanks, for fast and competent replay,
I want to readout 4 mppt-charger and send data to influxdb over UDP to visualization data in Grafana. With your help, now 2 chargers works, the other 2 I have to wire up..... I use: on_battery_monitor_message and lambda
victron_ble:
- id: mppt01
submit_sensor_data_asap: true
mac_address: ${mppt01_mac_address}
bindkey: ${mppt01_encryption_key}
on_solar_charger_message:
- lambda: |-
id(send_udp)->execute("mppt01_battU", 0.01f * message->battery_voltage);
id(send_udp)->execute("mppt01_battI", 0.1f * message->battery_current);
id(send_udp)->execute("mppt01_pvPower", message->pv_power);
id(send_udp)->execute("mppt01_yieldToday", 0.01f * message->yield_today);
- id: mppt02
submit_sensor_data_asap: true
mac_address: ${mppt02_mac_address}
bindkey: ${mppt02_encryption_key}
on_solar_charger_message:
- lambda: |-
id(send_udp)->execute("mppt02_battU", 0.01f * message->battery_voltage);
id(send_udp)->execute("mppt02_battI", 0.1f * message->battery_current);
id(send_udp)->execute("mppt02_pvPower", message->pv_power);
id(send_udp)->execute("mppt02_yieldToday", 0.01f * message->yield_today);
@adrusa Can you please share an example configuration so I can assist you?
I was trying to make a template sensor out of some of the sensors here. While it is possible for me to use filters and lambda to return the desired value, that means I will lose the raw data generated by the sensor. The help I need is to create a template sensor out of one of the sensors, but return both the raw data and the templated sensor for use in home assistance. Any help is welcome. I recognised I can do this easily in HA, but I don't want to add additional template to HA. Thank you.