I am trying to come up with a code to better locate myself within the house.
I use ESPRESENSE, along 10 ESP32 and 3 emitters ( My phone, my watch and a Bluetooth ankle bracelet)
Ideally, I could feed those 6 sensors, and get the most present room outputted.
Per instance:
['hotbox', 'main floor', 'hotbox', 'hotbox', 'hotbox', 'hotbox']
outputs: hotbox
['hotbox', 'main floor', 'livingroom', 'hotbox', 'hotbox', 'hotbox']
outputs: hotbox
['hotbox', 'main floor', 'livingroom', 'livingroom', 'main floor', 'livingroom']
outputs: livingroom
And so on.
Any help would be appreciated!
Also, I understand that I have an EVEN number of sensors, that could lead to a tie.
In that case, the new valueshould take precedence over the existing one if that is posssible.
I have this so far:
{% set braceletroom = states('sensor.b7bracelet1') %}
{% set braceletespresenseroom = states('device_tracker.maxi_bracelet_espresense') | lower%}
{% set watchroom = states('sensor.watch_galaxy4') | lower %}
{% set watchespresenseroom = states('device_tracker.maxi_watch_4_espresense') | lower %}
{% set watchonbody = states('binary_sensor.galaxy_watch_4_on_body_sensor')| lower %}
{% set phoneroom = states('sensor.phone_s24') | lower%}
{% set phoneespresenseroom = states('device_tracker.maxi_phone_s24_espresense') | lower%}
{% set gpslocation = states('device_tracker.phone_maxi') | lower %}
{% set in_home_positions_array = [braceletroom] + [braceletespresenseroom] + [phoneroom] + [phoneespresenseroom] %}
{% if watchonbody == 'on' %}
{% set in_home_positions_array = in_home_positions_array + [watchroom] + [watchespresenseroom] %}
{% endif %}
{% if gpslocation == 'home' and in_home_positions_array | unique | list | length == 1 %}
{{in_home_positions_array | unique | first }}
{% elif in_home_positions_array | unique | list | length > 1 %}
WIP
{% endif %}
{% set lastactiveroom = states('sensor.last_active_room') %}
{% set maxialone = states('binary_sensor.maxi_alone') %}
{% set braceletroom = states('sensor.b7bracelet1') %}
{% set braceletespresenseroom = states('device_tracker.maxi_bracelet_espresense') | lower%}
{% if braceletroom == braceletespresenseroom %}
{% set final_bracelet_room = braceletespresenseroom %}
{% else %}
{% set final_bracelet_room = braceletroom %}
{% endif %}
{% set watchroom = states('sensor.watch_galaxy4') | lower %}
{% set watchespresenseroom = states('device_tracker.maxi_watch_4_espresense') | lower %}
{% set watchonbody = states('binary_sensor.galaxy_watch_4_on_body_sensor')| lower %}
{% if (watchroom == watchespresenseroom) and (watchonbody =="on")%}
{% set final_watch_room = watchespresenseroom %}
{% else %}
{% set final_watch_room = watchroom %}
{% endif %}
{% set phoneroom = states('sensor.phone_s24') | lower%}
{% set phoneespresenseroom = states('device_tracker.maxi_phone_s24_espresense') | lower%}
{% if phoneroom == phoneespresenseroom %}
{% set final_phone_room = phoneespresenseroom %}
{% else %}
{% set final_phone_room = phoneroom %}
{% endif %}
{% set gpslocation = states('device_tracker.phone_maxi') | lower %}
{% set in_home_positions_array = [final_bracelet_room] + [final_phone_room] %}
{% if watchonbody == 'on' %}
{% set in_home_positions_array = in_home_positions_array + [final_watch_room] %}
{% endif %}
{% if maxialone == 'on' %}
{% set in_home_positions_array = in_home_positions_array + [lastactiveroom] %}
{% endif %}
{% if gpslocation == 'home' and in_home_positions_array | unique | list | length == 1 %}
{{in_home_positions_array | unique | first }}
{% elif in_home_positions_array | unique | list | length > 1 %}
{% for rooms in (in_home_positions_array | unique | list) %}
{% set ns.counted_list = ns.counted_list + [{'name': rooms , "amount": in_home_positions_array | select('search', rooms) | list | count }] %}
{% endfor %}
{% endif %}
{% set sorted_list = ns.counted_list|sort(attribute='amount', reverse=true) %}
{{(sorted_list | map(attribute='name')) | list | first }}
I ended up with this code which /seems/ to work.
Any idea on how to improve it is welcomed!
You might have a look at the Bayesian integration.
- Create a Bayesian entity for each location using your various sensors
- These will be binary sensors, but the “probability” attribute of each one will give you a number between 0 and 1 showing how likely you are to be there. (I convert mine to percentages to make them easier to read at a glance - sensor.bedroom_probability etc.)
- A template can then give you the most likely location.
- sensor:
- name: "Highest probability"
state: >
{% set values = [
states('sensor.bedroom_probability') | int,
states('sensor.study_probability') | int,
states('sensor.kitchen_probability') | int,
states('sensor.living_room_probability') | int,
states('sensor.landing_probability') | int,
states('sensor.hallway_probability') | int
] %}
{{ values | max }}