Electric meter reading from "Smart Meter Texas"

If you live in Texas and have account with https://www.smartmetertexas.com/home and want to get hourly usage details into your Home Assistant you may want to check this github repository out where it shows how to do that using docker. I will be happy to help!
https://github.com/scadaguru/pysmtreader

This is how Home Assistant shows usage graph:
image

1 Like

So I just stumbled on this, where is the config located for this? I installed using the docker command, but can’t find a config folder and the container fails to start.

If you used docker command shown below then config folder is your current working folder and that should have file called config-example.yaml. Edit that file to match your details as mentioned here https://github.com/scadaguru/pysmtreader and rename it to config.yaml and restart that container.

docker run -d -v ${PWD}/:/config scadaguru/pysmtreader

I am pretty new to docker, but have managed to get portainer running to have a GUI. When running the command, I logged into a terminal and ran

sudo docker run -d -v ${PWD}/:/config scadaguru/pysmtreader

This is what comes up under the portainer screen for the container it created. I don’t have any files called config-example.yaml in /home/clayton. Would they be somewhere else since I ran the command under sudo?

Could you create a file named config.yaml and copy/paste content from here GitHub - scadaguru/pysmtreader: Python application to read https://www.smartmetertexas.com and update content as per your need and then restart container.

I found where the config file was located. I put the config below (sensitive bits obfuscated), and am getting these errors when starting the container.

logs:
    level: debug # debug, info(default), warning, error, critical
    log_file_name: pysmt # without extension, log extension will be added automatically

health_check:
    log_info_line_at: 30 # in minutes, 0: disable

smartmetertexas: # smartmetertexas.com
    base_url: https://smartmetertexas.com/api
    username: ************ # Update with your username to access smartmetertexas.com
    password: *********** # Update with your password to access smartmetertexas.com
    esiid: ************ # Update with your ESSID, you can find from your electric bill or once you login to smartmetertexas.com
    meter_number: ******** # Update with your Meter Number, you can find in your electric bill or once you login to smartmetertexas.com
    poll_interval_minutes: 30 # 0: disable, do set below 30 as smartmetertexas.com will not allow reading more than twice in an hour
    wait_interval_before_ondemand_read_minutes: 5
    force_first_read: False # if true it will attempt to read Smart Meter Texas, otherwise at poll_interval

home_assistant: # Home Assistant access details
    base_url: http://192.168.1.76:8123 # your Home Assistant URL/IP, no slash (/) at the end for example: http://192.168.1.2:8123
    access_token: ***************************************************************************
    ha_entity: sensor.smt_reading # home assistnat entity name to be created

 2020-08-07T22:11:34.252206677Z /bin/helper_common.py:16: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.,
2020-08-07T22:11:34.252240311Z   self.config = yaml.load(open(self.config_folder + 'config.yaml')),
2020-08-07T22:11:34.255531143Z Traceback (most recent call last):,
2020-08-07T22:11:34.255568112Z   File "./main.py", line 131, in <module>,
2020-08-07T22:11:34.255615553Z     meter_read_helper = MeterReadHelper(host_mapped_folder),
2020-08-07T22:11:34.255620410Z   File "./main.py", line 13, in __init__,
2020-08-07T22:11:34.255675334Z     self.__commonHelper = CommonHelper(host_mapped_folder),
2020-08-07T22:11:34.255679925Z   File "/bin/helper_common.py", line 16, in __init__,
2020-08-07T22:11:34.255749136Z     self.config = yaml.load(open(self.config_folder + 'config.yaml')),
2020-08-07T22:11:34.255757754Z   File "/usr/local/lib/python3.8/site-packages/yaml/__init__.py", line 114, in load,
2020-08-07T22:11:34.255994028Z     return loader.get_single_data(),
2020-08-07T22:11:34.256001637Z   File "/usr/local/lib/python3.8/site-packages/yaml/constructor.py", line 49, in get_single_data,
2020-08-07T22:11:34.256246792Z     node = self.get_single_node(),
2020-08-07T22:11:34.256251102Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 36, in get_single_node,
2020-08-07T22:11:34.256466010Z     document = self.compose_document(),
2020-08-07T22:11:34.256469711Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 55, in compose_document,
2020-08-07T22:11:34.256535401Z     node = self.compose_node(None, None),
2020-08-07T22:11:34.256543208Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 84, in compose_node,
2020-08-07T22:11:34.256641596Z     node = self.compose_mapping_node(anchor),
2020-08-07T22:11:34.256649637Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 133, in compose_mapping_node,
2020-08-07T22:11:34.256667329Z     item_value = self.compose_node(node, item_key),
2020-08-07T22:11:34.256670632Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 84, in compose_node,
2020-08-07T22:11:34.256715095Z     node = self.compose_mapping_node(anchor),
2020-08-07T22:11:34.256719598Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 127, in compose_mapping_node,
2020-08-07T22:11:34.256796833Z     while not self.check_event(MappingEndEvent):,
2020-08-07T22:11:34.256804108Z   File "/usr/local/lib/python3.8/site-packages/yaml/parser.py", line 98, in check_event,
2020-08-07T22:11:34.257083369Z     self.current_event = self.state(),
2020-08-07T22:11:34.257086929Z   File "/usr/local/lib/python3.8/site-packages/yaml/parser.py", line 428, in parse_block_mapping_key,
2020-08-07T22:11:34.257235151Z     if self.check_token(KeyToken):,
2020-08-07T22:11:34.257238521Z   File "/usr/local/lib/python3.8/site-packages/yaml/scanner.py", line 115, in check_token,
2020-08-07T22:11:34.257494514Z     while self.need_more_tokens():,
2020-08-07T22:11:34.257497829Z   File "/usr/local/lib/python3.8/site-packages/yaml/scanner.py", line 152, in need_more_tokens,
2020-08-07T22:11:34.257566102Z     self.stale_possible_simple_keys(),
2020-08-07T22:11:34.257571263Z   File "/usr/local/lib/python3.8/site-packages/yaml/scanner.py", line 291, in stale_possible_simple_keys,
2020-08-07T22:11:34.257805989Z     raise ScannerError("while scanning a simple key", key.mark,,
2020-08-07T22:11:34.257828181Z yaml.scanner.ScannerError: while scanning a simple key,
2020-08-07T22:11:34.257850217Z   in "/config/config.yaml", line 22, column 1,
2020-08-07T22:11:34.257852959Z could not find expected ':',
2020-08-07T22:11:34.257855377Z   in "/config/config.yaml", line 23, column 1,
2020-08-07T22:12:55.126233392Z /bin/helper_common.py:16: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.,
2020-08-07T22:12:55.126255112Z   self.config = yaml.load(open(self.config_folder + 'config.yaml')),
2020-08-07T22:12:55.130328147Z Traceback (most recent call last):,
2020-08-07T22:12:55.130339990Z   File "./main.py", line 131, in <module>,
2020-08-07T22:12:55.130383703Z     meter_read_helper = MeterReadHelper(host_mapped_folder),
2020-08-07T22:12:55.130394342Z   File "./main.py", line 13, in __init__,
2020-08-07T22:12:55.130405968Z     self.__commonHelper = CommonHelper(host_mapped_folder),
2020-08-07T22:12:55.130409537Z   File "/bin/helper_common.py", line 16, in __init__,
2020-08-07T22:12:55.130504456Z     self.config = yaml.load(open(self.config_folder + 'config.yaml')),
2020-08-07T22:12:55.130514379Z   File "/usr/local/lib/python3.8/site-packages/yaml/__init__.py", line 114, in load,
2020-08-07T22:12:55.130540245Z     return loader.get_single_data(),
2020-08-07T22:12:55.130546100Z   File "/usr/local/lib/python3.8/site-packages/yaml/constructor.py", line 49, in get_single_data,
2020-08-07T22:12:55.130605962Z     node = self.get_single_node(),
2020-08-07T22:12:55.130611414Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 36, in get_single_node,
2020-08-07T22:12:55.130674800Z     document = self.compose_document(),
2020-08-07T22:12:55.130684848Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 55, in compose_document,
2020-08-07T22:12:55.130721864Z     node = self.compose_node(None, None),
2020-08-07T22:12:55.130732046Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 84, in compose_node,
2020-08-07T22:12:55.130757126Z     node = self.compose_mapping_node(anchor),
2020-08-07T22:12:55.130763386Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 133, in compose_mapping_node,
2020-08-07T22:12:55.130855971Z     item_value = self.compose_node(node, item_key),
2020-08-07T22:12:55.130865719Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 84, in compose_node,
2020-08-07T22:12:55.130898672Z     node = self.compose_mapping_node(anchor),
2020-08-07T22:12:55.130904871Z   File "/usr/local/lib/python3.8/site-packages/yaml/composer.py", line 127, in compose_mapping_node,
2020-08-07T22:12:55.130975649Z     while not self.check_event(MappingEndEvent):,
2020-08-07T22:12:55.130980699Z   File "/usr/local/lib/python3.8/site-packages/yaml/parser.py", line 98, in check_event,
2020-08-07T22:12:55.131061620Z     self.current_event = self.state(),
2020-08-07T22:12:55.131075783Z   File "/usr/local/lib/python3.8/site-packages/yaml/parser.py", line 428, in parse_block_mapping_key,
2020-08-07T22:12:55.131182386Z     if self.check_token(KeyToken):,
2020-08-07T22:12:55.131187074Z   File "/usr/local/lib/python3.8/site-packages/yaml/scanner.py", line 115, in check_token,
2020-08-07T22:12:55.131265919Z     while self.need_more_tokens():,
2020-08-07T22:12:55.131275348Z   File "/usr/local/lib/python3.8/site-packages/yaml/scanner.py", line 152, in need_more_tokens,
2020-08-07T22:12:55.131338076Z     self.stale_possible_simple_keys(),
2020-08-07T22:12:55.131342623Z   File "/usr/local/lib/python3.8/site-packages/yaml/scanner.py", line 291, in stale_possible_simple_keys,
2020-08-07T22:12:55.131446739Z     raise ScannerError("while scanning a simple key", key.mark,,
2020-08-07T22:12:55.131474584Z yaml.scanner.ScannerError: while scanning a simple key,
2020-08-07T22:12:55.131479556Z   in "/config/config.yaml", line 22, column 1,
2020-08-07T22:12:55.131482497Z could not find expected ':',
2020-08-07T22:12:55.131485225Z   in "/config/config.yaml", line 23, column 1,

I tried putting a config.yaml file in /clayton/home/ but it wouldn’t start either. The location of config-example.yaml ended up being at the path below.

/var/lib/docker/overlay2/0faaae71a011e9c363288f419622c18f85be060203dbf9606ec166fa78b03f52/diff/bin

Looks like your config.yaml has some issue on line number 22 and 23.
Check the last two lines of the log you have attached that says could not find expected ‘:’

That is what is odd, there are only 19 lines in the config file. I ran it through yamllint.com and it said it was valid.

So, in my noobishness, I discovered that the container is actually looking for the config.yaml in my home folder and the file that I had put there had the github copyright notice on the bottom causing the error. After removing that and restarting the container it doesn’t fail immediately. It is now pulling data into Home Assistant! Thanks for this! Have you considered making this an addon?

Nice! I will update document on github to make more meaningful. I haven’t created any component for Home Assistance yet so there is some learning curve for me but yeah someday!

@scadaguru,
Looks like the docker image is limited to amd64 and your Dockerfile includes a reference to a bin directory that is not included on your git repository. Any chance of getting this to work for ARM ? I’m trying to run this on a raspberypi 3

Thanks

Hello, as this is the only way I have been able to successfully get my Smart Meter Texas readings in to home assistant, is there any plans to make this compatible with the new energy features?

@scadaguru thank you for writing this needed docker image! It seems to be the only way to work with SMT, thank you! Home Assistant’s energy feature doesn’t take the consumption data as it’s delivered through the API. Would it be possible to change that so it works natively?