TCP Integration - How to increase scan interval

I have implemented a TCP integration and all works well EXCEPT the fact that the connection to the remote server takes place once every 30 seconds.
Adding “scan_interval: 5” (for connecting every 5 seconds) has no effect whatsoever!

Looking at the TCP integration in the HA source at “…core/homeassistant/components/tcp” shows that “scan_interval” is not considered at all.

So, is there any way to change the default 30 seconds?

Here’s part of my configuration.yaml:

sensor:
  - platform: tcp
    name: plcschneider
    host: x.x.x.x
    port: 55555
    timeout: 5
    payload: "batteries"
    value_template: "{{ value }}"
  - platform: template
    scan_interval: 5
    sensors:
      plc_is_alive_counter:
        friendly_name: PLC IsAlive counter
        value_template: "{{ (states('sensor.plcschneider1') | from_json).bt.isalive.counter}}"
      plc_gen1_volts:
        friendly_name: PLC Generator 1 volts
        value_template: "{{ (states('sensor.plcschneider1') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V"  
..........

I’m going to assume this PLC is on your local network and not a public resource, so spamming it every 5 seconds is not an issue.

If your sensor is YAML only and you can’t do this from the Settings → Devices & Services page: How to set a custom scan_interval

Then your only option is to use the update entity action in an automation triggered by a time pattern trigger.

triggers:
  - trigger: time_pattern
    seconds: "/5"
actions:
  - action: homeassistant.update_entity
    data:
      entity_id: sensor.plcschneider

Also you should be using the new template integration instead of the legacy template sensor platform.

configuration.yaml (not sensors.yaml)

template:
  - sensor:
      - name: PLC IsAlive counter
        unique_id: plc_is_alive_counter
        state: "{{ (states('sensor.plcschneider1') | from_json).bt.isalive.counter}}"
      - name: PLC Generator 1 volts
        unique_id: plc_gen1_volts
        state: "{{ (states('sensor.plcschneider1') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V"
        device_class: voltage
        state_class: measurement # (if you want long term statistics)

The unique ids will allow re-configuration from the frontend GUI. E.g. changing the name, entity_id, precision, icon, etc… If you don’t want that you can leave them out.

The template sensors will update whenever sensor.plcschneider updates (every 5 seconds if you use the automation).

Man, you saved me!!!
I cant thank you enough. I set the interval to 2 seconds and now it works PERFECTLY (yes, the TCP server/service is running locally in my network)

As for the second part: please help me out, I dont understand what you are saying.

Repeating my first post, here’s part of my configuration.yaml (not sensors.yaml):

sensor:
  - platform: tcp
    name: plcschneider
    host: x.x.x.x
    port: 55555
    timeout: 5
    payload: "batteries"
    value_template: "{{ value }}"
  - platform: template
    scan_interval: 5
    sensors:
      plc_is_alive_counter:
        friendly_name: PLC IsAlive counter
        value_template: "{{ (states('sensor.plcschneider1') | from_json).bt.isalive.counter}}"
      plc_gen1_volts:
        friendly_name: PLC Generator 1 volts
        value_template: "{{ (states('sensor.plcschneider1') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V"  
..........

What I understand is that you are suggesting a new type of format?
Does this mean that my configuration wont work at some point (ie, Home Assistant upgrade?)
If yes, do I simply change to the format you propose and nothing else need to be changed?

The legacy template platform will continue to work, there are no plans to depreciate it, yet. However it does not get any new features, like state_class which is needed for long term statistics and the energy dashboard in particular.

Best to use the new template integration for all new template sensors.

In your case your configuration.yaml file would change to:

sensor: # this is the sensor integration, where your legacy template sensors were
  - platform: tcp
    name: plcschneider
    host: x.x.x.x
    port: 55555
    timeout: 5
    payload: "batteries"
    value_template: "{{ value }}"

template:  # this is the new template integration
  - sensor:
      - name: PLC IsAlive counter
        unique_id: plc_is_alive_counter
        state: "{{ (states('sensor.plcschneider') | from_json).bt.isalive.counter}}"
      - name: PLC Generator 1 volts
        unique_id: plc_gen1_volts
        state: "{{ (states('sensor.plcschneider') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V"
        device_class: voltage
        state_class: measurement # (if you want long term statistics)

Ok, I will try to convert to the new format.
However, your proposal does not include the host and port.
How do I define these?
How does the new format know/declare that a tcp connection to IP:port must take place?

The TCP sensor has not changed. It is still there under the sensor integration.

I am sorry, but I sincerely do not understand:

These are the first lines of my sensors (showing 2, I have more under them) :

sensor:
  - platform: tcp
    name: plcschneider
    host: x.x.x.x
    port: 55555
    timeout: 5
    payload: "batteries"
    value_template: "{{ value }}"
  - platform: template
    scan_interval: 5
    sensors:
      plc_is_alive_counter:
        friendly_name: PLC IsAlive counter
        value_template: "{{ (states('sensor.plcschneider1') | from_json).bt.isalive.counter}}"
      plc_gen1_volts:
        friendly_name: PLC Generator 1 volts
        value_template: "{{ (states('sensor.plcschneider1') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V" 

Following is your suggestion.
Where are “tcp”, “host” and “port” declared?

template:  # this is the new template integration
  - sensor:
      - name: PLC IsAlive counter
        unique_id: plc_is_alive_counter
        state: "{{ (states('sensor.plcschneider') | from_json).bt.isalive.counter}}"
      - name: PLC Generator 1 volts
        unique_id: plc_gen1_volts
        state: "{{ (states('sensor.plcschneider') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V"
        device_class: voltage
        state_class: measurement # (if you want long term statistics)

sensor:
  - platform: tcp   ###### <---- LOOK HERE THIS HAS NOT MOVED ########
    name: plcschneider
    host: x.x.x.x
    port: 55555
    timeout: 5
    payload: "batteries"
    value_template: "{{ value }}"

template:
  - sensor:
      - name: PLC IsAlive counter
        unique_id: plc_is_alive_counter
        state: "{{ (states('sensor.plcschneider') | from_json).bt.isalive.counter}}"
      - name: PLC Generator 1 volts
        unique_id: plc_gen1_volts
        state: "{{ (states('sensor.plcschneider') | from_json).bt.batteries.gen1_volts}}"
        unit_of_measurement: "V"
        device_class: voltage
        state_class: measurement # (if you want long term statistics)

The TCP sensor is still under the sensor integration. It still creates sensor.plcschneider which the template sensors use.

I am afraid it doesnt work.
How do you troubleshoot this? Is there a log where the errors would show?
Under “developert tools”, typing “plc_is_alive_counter” does not show any entity existing, whereas ith the old method it does

Go to Developer Tools → Templates and paste this in the template editor, what does it return:

{{ states('sensor.plcschneider') }}

For

{{ states('sensor.plcschneider') }}`

I get:

{
  "bt": {
    "isalive": {
      "counter": 19953
    },
    "batteries": {
      "gen1_volts": 12.4,
      "gen2_volts": 12.4,
      "service_volts": 26.1,
      "service_amps": 11.6,
      "service_amps_charge": 16.6,
      "engines_volts": 0,
      "engines_alternator_sb": 0,
      "engines_alternator_port": 0
    }
  }
}

However, in “Developer Tools” “States”, “plc_is_alive_counter” does not exist no do any of the rest of “unique_id” exist.
(when using the old format all of course exist)