Xcel Energy ITron Gen 5 Riva

Ok. Hoping for some help as I’ve been working on this for nearly a month. Here’s where I stand (version: Home Assistant 2023.1.7):

  1. I have communication to the meter.
  2. When I’m in my home assistant config directory this command returns a value.
    sudo curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.1.134:8081/upt/1/mr/1/r --cert cert.pem --key key.pem 2>&1 | grep -o '<value>.*</value>' 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'
    949
  3. This is my command_line.yaml:
- sensor:
    unique_id: xcel_meter
    name: Xcel Meter
    command: "OPENSSL_CONF=/home/homeassistant/.homeassistant/xcel/openssl.conf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.>
    unit_of_measurement: "kWh"
    value_template: "{{ float(value) | multiply(0.001) | round(3) if is_number(value) }}"
    device_class: 'energy'
    state_class: 'total_increasing'
    scan_interval: 5 #in seconds
    command_timeout: 5 #in seconds

- sensor:
    unique_id: xcel_meter_load
    name: Xcel Meter Load
    command: "OPENSSL_CONF=/home/homeassistant/.homeassistant/xcel/openssl.conf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.>
    value_template: "{{ float(value) if is_number(value_json) }}"
    unit_of_measurement: "W"
    device_class: 'power'
    scan_interval: 5 #in seconds
    command_timeout: 5 #in seconds
  1. This is my configuration.yaml:
# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

# Text to speech
tts:
  - platform: google_translate

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
command_line: !include command_line.yaml

I do see this error also.
2023-12-09 12:59:09.397 ERROR (MainThread) [homeassistant.setup] Setup failed for command_line: No setup or config entry setup function defined.

I just can’t for the life of me get a working sensor to show up or get it added to the energy dashboard. Doing various changes in the configuation.yaml I was at one point to see the sensor to add to the energy dashboard, but it would throw an error.

Appreciate any help or ideas.

How are you running home assistant? Is it the supervised container?

  1. I found it helpful to get a terminal in the container that HA is running in (IIRC, it was a similar container, like ssh) to run the curl command.

  2. I have been thinking we should have one curl command that just gets the response without trying to convert any of it to numbers. That would let you log any errors the meter is trying to tell us, and you can debug your value template easier.

I’m running HA on a raspi - installed as a stand alone - if that answers your question. I think the problem lies with that error for the command_line issue, perhaps.

Logger: homeassistant.setup
Source: setup.py:248
First occurred: December 9, 2023 at 12:59:09 PM (1 occurrences)
Last logged: December 9, 2023 at 12:59:09 PM

Setup failed for command_line: No setup or config entry setup function defined.

I am getting the following errors in my log files:

 * Command failed (with return code 1): OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/3/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'
 * Command failed (with return code 1): OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/1/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '([+-]?[0-9]+)'
 * Command failed (with return code 1): OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/2/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'

Here is my yaml which I have in a separate command_line.yaml file and running on Home Assistant 2023.12.3 with HA running on HassIO in a VM on my Unraid server:

- sensor:
    unique_id: xcel_meter_power
    name: "Smart Electric Meter Power"
    #command: "OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/1/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'"
    command: "OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/1/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '([+-]?[0-9]+)'"
    unit_of_measurement: "W"
    device_class: "power"
    scan_interval: 5
    command_timeout: 5

- sensor:
    unique_id: xcel_meter_consumption
    name: "Smart Electric Meter Consumption"
    command: "OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/3/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'"
    unit_of_measurement: "kWh"
    value_template: "{{ value | multiply(0.001) | round(3)}}"
    device_class: "energy"
    state_class: "total_increasing"
    #scan_interval: 86400
    scan_interval: 5
    command_timeout: 5
- sensor:
    unique_id: xcel_meter_productiion
    name: "Smart Electric Meter Production"
    command: "OPENSSL_CONF=/config/xcelcerts/myown/openssl.cnf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.2.203:8081/upt/1/mr/2/r --cert /config/xcelcerts/myown/cert.pem --key /config/xcelcerts/myown/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'"
    unit_of_measurement: "kWh"
    value_template: "{{ value | multiply(0.001) | round(3)}}"
    device_class: "energy"
    state_class: "total_increasing"
    #scan_interval: 86400
    scan_interval: 5
    command_timeout: 5

Any thoughts on what is causing the return code 1 error? Is there any way to test the API calls to the meter in Postman?

@MacGyver33 I am getting the same error now that I have my syntax corrected.

UPDATE: No real explanation, but this has since self-corrected after a recent reboot. I now have communication with my meter.

Thank you to everyone in this thread for their experience and support. I have been getting my power consumption steadily for a few days now that I have everything configured correctly.

My lessons-learned:

  • Configure HA using the XceltoMQTT add-on. This is the way.
  • Per Xcel support, the meter does not respond to ICMP, so do not spin your wheels trying to ping the meter for communication. Use nmap to confirm the target and open port. My router does not accurately report the connection status because the Itron seems so locked down, but its been reporting solid since configured properly.
  • Make sure you have Mosquito MQTT installed in HA or you will never detect the meter as an MQTT device :man_facepalming:.

Next Quests:

  • How can I read my gas consumption from Xcel? I’ve seen where this can be measured with an ESP32+magnetometer, but isn’t this being read remotely as well? This thread discusses capturing the SCM messages that the meter readers pick up when driving through. Any suggestions on the best way to do this today?
  • Tracking Power costs? Anyone have this configured for Xcel?
  • Tracking Water. This should be more straightforward with something like Flo.

The rtl sdr solution was working for me. I broke it at some point and I haven’t found the fix. But that one is still dumb and the serial number is on the meter. So it is easy to find. This thread started with me trying to figure that out.

Thank you @jeffeb3 ! I’m going to go ahead and get the dongle to test it out. I saw Aurora Water replaced my meter last year, so I will see if it can be pulled the same way.

Update: @jeffeb3, would you be willing to assist with some of your rtl sdr config? I have the add-on configured, dongle installed, but not sure about some of the config. Getting an error on the “format” of the gas readings config. Not sure if this is the appropriate place to discuss, so added to the other thread.

Update 2: SOLVED. Issue was the protocol needed is SCM, but was set for SCM+ Next I need to pop the cover on my water meter!

Hey folks, I’m trying to set this up on my home assistant yellow and I’m having the same SSL issue that has been reported. I’ve skimmed the thread (it’s long :D), and seen what others are doing… so here’s my setup (hopefully I’m not missing something):

I’ve got the smart meter connected to my wifi and added the LFDI and relevant data to my XCel account

I manually copied the scripts from the relevant /addons_config/directory, made a directory under /config called /certs and put them there.

I used the native MQTT integration from HASS, currently it shows no devices or entities

I created a directory under config called xcelcerts and created an openssl.conf file in that directory. Here’s the contents of that conf file:

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

I created a command_line.yaml in the config directory, and it’s contents are (copied from another post in this thread):

command_line:
- sensor:
    unique_id: xcel_meter_power
    name: "Smart Electric Meter Power"
    command: "OPENSSL_CONF=/config/xcelcerts/openssl.conf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.198.11:8081/upt/1/mr/1/r --cert /config/certs/cert.pem --key /config/certs/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '([+-]?[0-9]+)'"
    unit_of_measurement: "W"
    device_class: "power"
    scan_interval: 5
    command_timeout: 5

- sensor:
    unique_id: xcel_meter_consumption
    name: "Smart Electric Meter Consumption"
    command: "OPENSSL_CONF=/config/xcelcerts/openssl.conf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.198.11:8081/upt/1/mr/3/r --cert /config/certs/cert.pem --key /config/certs/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'"
    unit_of_measurement: "kWh"
    value_template: "{{ value | multiply(0.001) | round(3)}}"
    device_class: "energy"
    state_class: "total_increasing"
    #scan_interval: 86400
    scan_interval: 5
    command_timeout: 5
- sensor:
    unique_id: xcel_meter_productiion
    name: "Smart Electric Meter Production"
    command: "OPENSSL_CONF=/config/xcelcerts/openssl.conf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.198.11:8081/upt/1/mr/2/r --cert /config/certs/cert.pem --key /config/certs/key.pem 2>&1 | grep -o '<value>.*</value>' | grep -Eo '[0-9]+'"
    unit_of_measurement: "kWh"
    value_template: "{{ value | multiply(0.001) | round(3)}}"
    device_class: "energy"
    state_class: "total_increasing"
    #scan_interval: 86400
    scan_interval: 5
    command_timeout: 5

I added the line to the bottom of my configuration.yaml:

command_line: !include command_line.yaml

I still get the SSL error and I’m confused as to why. Can anyone help? Is there a single, comprehensive write-up for this somewhere that covers everything step by step?

Here’s the exact error output from the add-on logs tab:

-----------------------------------------------------------
 Please, share the above information when looking for help
 or support in, e.g., GitHub, forums or the Discord chat.
-----------------------------------------------------------
s6-rc: info: service base-addon-banner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service base-addon-log-level: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service base-addon-log-level successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service init-xcel-itron-mqtt: starting
[16:24:32] INFO: Initializing Xcel iTron2MQTT
s6-rc: info: service init-xcel-itron-mqtt successfully started
s6-rc: info: service xcel-itron-mqtt: starting
s6-rc: info: service xcel-itron-mqtt successfully started
s6-rc: info: service legacy-services: starting
[16:24:33] INFO: Starting Xcel iTron2MQTT
s6-rc: info: service legacy-services successfully started
Connected to MQTT Broker!
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
                       ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 386, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 1042, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.12/site-packages/urllib3/connection.py", line 414, in connect
    self.sock = ssl_wrap_socket(
                ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/ssl_.py", line 453, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/ssl_.py", line 495, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/ssl.py", line 1046, in _create
    self.do_handshake()
  File "/usr/local/lib/python3.12/ssl.py", line 1321, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:1000)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.198.11', port=8081): Max retries exceeded with url: /sdev/sdi (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:1000)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/xcel_itron2mqtt/main.py", line 79, in <module>
    meter = xcelMeter(INTEGRATION_NAME, ip_address, port_num, creds)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/xcel_itron2mqtt/xcelMeter.py", line 67, in __init__
    details_dict = self.get_hardware_details(hw_info_url, hw_info_names)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/xcel_itron2mqtt/xcelMeter.py", line 97, in get_hardware_details
    x = self.requests_session.get(query_url, verify=False, timeout=4.0)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 600, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/adapters.py", line 563, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.198.11', port=8081): Max retries exceeded with url: /sdev/sdi (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:1000)')))
[16:24:38] INFO: Service Xcel iTron2MQTe exited with code 1 (by signal 0)
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service xcel-itron-mqtt: stopping
s6-rc: info: service xcel-itron-mqtt successfully stopped
s6-rc: info: service init-xcel-itron-mqtt: stopping
s6-rc: info: service init-xcel-itron-mqtt successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service base-addon-log-level: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service base-addon-log-level successfully stopped
s6-rc: info: service base-addon-banner: stopping
s6-rc: info: service base-addon-banner successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped

Even after I overcome the SSL error, do I need to add things to MQTT?

Removed/reinstalled the add-on, used the newly generated LDFI and now it seems like it’s up and stable. :crossed_fingers:

so it randomly seems to just stop functioning, even though watchdog is enabled, obviously causing data to be missed. Anyone solved this on HA OS?

When it stops working, then if I start it, it doesn’t pull in the data it missed.

See the topic over at TimeoutError: The read operation timed out · Issue #4 · wingrunr21/hassio-xcel-itron-mqtt · GitHub

I worked around the issue with an automation that checks and starts the automation every 5 minutes.

description: ""
trigger:
  - platform: time_pattern
    minutes: /5
condition:
  - condition: state
    entity_id: binary_sensor.xcel_itron_mqtt_running
    state: "off"
action:
  - service: hassio.addon_start
    metadata: {}
    data:
      addon: 513749ae_xcel-itron-mqtt
mode: single

You do have to enable the supervisor entity that privides the status of the addon binary_sensor.xcel_itron_mqtt_running

New to HASS, can you help me understand where I dump this YAML and how I ensure/create the binary_sensor?

Is this YAML for your automation?

Yup. Just the automation YAML.

The binary sensor should be found under the same device as update.xcel_itron_mqtt_update. Id you search for that entity, select the device info under the three dot menu of the entity, then you can find the binary sensor under “entities not shown”, select it and enable it.

Thank you for the help. I see the binary_sensor there, I copy/pasta’d your automation YAML. When I look at that sensor in the GUI, I see this:

I feel like the “unavailable” message shouldn’t be there, but I’ll ask anyway: is this expected behavior?

I saw that it wasn’t enabled. I’ve enabled it and the entity is now showing as up. Thank you for coming with me on this journey :smiley:

Spoke too soon I guess… Now I’m getting a new error:

ERROR: Got unexpected response from the API: Service not enabled
Traceback (most recent call last):
  File "/opt/xcel_itron2mqtt/main.py", line 79, in <module>
    meter = xcelMeter(INTEGRATION_NAME, ip_address, port_num, creds)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/xcel_itron2mqtt/xcelMeter.py", line 57, in __init__
    self.mqtt_client = self.setup_mqtt(self.mqtt_server_address, self.mqtt_port)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/xcel_itron2mqtt/xcelMeter.py", line 181, in setup_mqtt
    client.connect(mqtt_server_address, mqtt_port)
  File "/usr/local/lib/python3.12/site-packages/paho/mqtt/client.py", line 912, in connect
    self.connect_async(host, port, keepalive,
  File "/usr/local/lib/python3.12/site-packages/paho/mqtt/client.py", line 978, in connect_async
    raise ValueError('Invalid host.')
ValueError: Invalid host.

Only change that’s happened is enabling that binary sensor and updating HASS.

From the HASS Yellow I can still nc to the meter:

image

I can curl from the HASS yellow to the meter:

OPENSSL_CONF=/config/xcelcerts/openssl.conf /usr/bin/curl --ciphers ECDHE-ECDSA-AES128-CCM8 --insecure --url https://192.168.198.11:8081/upt/1/mr/2/r --cert /config/certs/cert.pem --key /config/certs/key.pem 2>&1 
<Reading
     xmlns="urn:ieee:std:2030.5:ns"
     href="/upt/1/mr/2/r">
    <qualityFlags>01</qualityFlags>
    <timePeriod>
        <duration>1</duration>
        <start>1707173725</start>
    </timePeriod>
    <value>0</value>
</Reading>

MQTT is up and running. I’ll try to reboot the box… maybe that will fix it?

strange… rebooted the box now it’s working again :confused:

For those of you that really want to do cost tracking and live in Colorado with Xcel energy you should review this page https://www.xcelenergy.com/company/rates_and_regulations/rates/rate_books
Then select the summary of electric tab. This will give you the all cost that includes everything you see on your bill in an easy to read way. It would be great if we could scrape the data and have it automatically update a price for these tariffs. I use that page all the time for my work. There is also one for gas.

3 Likes

Thank you for sharing this. Super helpful!

I use a device from gridinsight. it is very similar to the RTL-SDR integration. Both device should be able to pick up Xcel gas meters in colorado. Most residential in the Denver area are an itron 40g which send a signal about once every 5 minutes.

Which ever device you use you will need to divide by 100 to get into cubic feet. The reading is in hundred of cubic feet. Also on your gas bill will be an adjustment factor, probably around 0.85. You will need to multiply your reading by this number to get data that matches your bill.

1 Like

Sorry I can’t be much help on the RTL-SDR device as I don’t have one. My device plugs into my home assistants USB port and is treated as if it is a serial device. So I just do some parsing of the serial device string.

1 Like