Skip to content

Commit

Permalink
Merge pull request #25 from thor0215/patch-1
Browse files Browse the repository at this point in the history
Update xcelEndpoint.py - Add new endpoint config for swVer 3.2.39
  • Loading branch information
zaknye authored Apr 9, 2024
2 parents b89b5ff + 2a2e5ab commit c9e8e36
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 22 deletions.
41 changes: 41 additions & 0 deletions xcel_itron2mqtt/configs/endpoints_3_2_39.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
- Instantaneous Demand:
url: '/upt/1/mr/1/r'
tags:
value:
entity_type: sensor
device_class: power
unit_of_measurement: W
- Current Summation Received:
url: '/upt/1/mr/2/rs/1/r/1'
tags:
timePeriod:
- duration:
entity_type: sensor
device_class: timestamp
value_template: '{{ as_datetime( value ) }}'
- start:
entity_type: sensor
device_class: timestamp
value_template: '{{ as_datetime( value ) }}'
value:
entity_type: sensor
device_class: energy
unit_of_measurement: Wh
state_class: total
- Current Summation Delivered:
url: '/upt/1/mr/3/rs/1/r/1'
tags:
timePeriod:
- duration:
entity_type: sensor
device_class: timestamp
value_template: '{{ as_datetime( value ) }}'
- start:
entity_type: sensor
device_class: timestamp
value_template: '{{ as_datetime( value ) }}'
value:
entity_type: sensor
device_class: energy
unit_of_measurement: Wh
state_class: total
File renamed without changes.
12 changes: 7 additions & 5 deletions xcel_itron2mqtt/xcelEndpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ def parse_response(response: str, tags: dict) -> dict:
for val_items in v:
for k2, v2 in val_items.items():
search_val = f'{IEEE_PREFIX}{k2}'
value = root.find(f'.//{search_val}').text
readings_dict[f'{k}{k2}'] = value
if root.find(f'.//{search_val}') is not None:
value = root.find(f'.//{search_val}').text
readings_dict[f'{k}{k2}'] = value
else:
search_val = f'{IEEE_PREFIX}{k}'
value = root.find(f'.//{IEEE_PREFIX}{k}').text
readings_dict[k] = value
if root.find(f'.//{IEEE_PREFIX}{k}') is not None:
value = root.find(f'.//{IEEE_PREFIX}{k}').text
readings_dict[k] = value

return readings_dict

Expand Down Expand Up @@ -178,4 +180,4 @@ def run(self) -> None:
Returns: None
"""
reading = self.get_reading()
self.process_send_mqtt(reading)
self.process_send_mqtt(reading)
35 changes: 18 additions & 17 deletions xcel_itron2mqtt/xcelMeter.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,10 @@ def __init__(self, name: str, ip_address: str, port: int, creds: Tuple[str, str]

# Create a new requests session based on the passed in ip address and port #
self.requests_session = self.setup_session(creds, ip_address)

# List to store our endpoint objects in
self.endpoints_list = self.load_endpoints('endpoints.yaml')

# Set to uninitialized
self.initalized = False

@retry(stop=stop_after_attempt(15),
wait=wait_exponential(multiplier=1, min=1, max=15),
before_sleep=before_sleep_log(logger, logging.WARNING),
Expand Down Expand Up @@ -93,17 +90,22 @@ def setup(self) -> None:
# Send homeassistant a new device config for the meter
self.send_mqtt_config()

# The swVer will dictate which version of endpoints we use
endpoints_file_ver = 'default' if str(self._swVer) != '3.2.39' else '3_2_39'
# List to store our endpoint objects in
self.endpoints_list = self.load_endpoints(f'configs/endpoints_{endpoints_file_ver}.yaml')

# create endpoints from list
self.endpoints = self.create_endpoints(self.endpoints_list, self.device_info)

# ready to go
self.initalized = True

def get_hardware_details(self, hw_info_url: str, hw_names: list) -> dict:
"""
Queries the meter hardware endpoint at the ip address passed
to the class.
Queries the meter hardware endpoint at the ip address passed
to the class.
Returns: dict, {<element name>: <meter response>}
"""
query_url = f'{self.url}{hw_info_url}'
Expand All @@ -114,7 +116,7 @@ def get_hardware_details(self, hw_info_url: str, hw_names: list) -> dict:
hw_info_dict = {}
for name in hw_names:
hw_info_dict[name] = root.find(f'.//{IEEE_PREFIX}{name}').text

return hw_info_dict

@staticmethod
Expand All @@ -131,7 +133,7 @@ def setup_session(creds: tuple, ip_address: str) -> requests.Session:
session.mount('https://{ip_address}', CCM8Adapter())

return session

@staticmethod
def load_endpoints(file_path: str) -> list:
"""
Expand All @@ -141,20 +143,20 @@ def load_endpoints(file_path: str) -> list:
"""
with open(file_path, mode='r', encoding='utf-8') as file:
endpoints = yaml.safe_load(file)

return endpoints

def create_endpoints(self, endpoints: dict, device_info: dict) -> None:
# Build query objects for each endpoint
query_obj = []
for point in endpoints:
for endpoint_name, v in point.items():
request_url = f'{self.url}{v["url"]}'
query_obj.append(xcelEndpoint(self.requests_session, self.mqtt_client,
query_obj.append(xcelEndpoint(self.requests_session, self.mqtt_client,
request_url, endpoint_name, v['tags'], device_info))

return query_obj

@staticmethod
def get_mqtt_port() -> int:
"""
Expand All @@ -167,7 +169,7 @@ def get_mqtt_port() -> int:
# If environment variable for MQTT port is set, use that
# if not, use the default
mqtt_port = int(env_port) if env_port else 1883

return mqtt_port

@staticmethod
Expand Down Expand Up @@ -241,4 +243,3 @@ def run(self) -> None:
sleep(self.POLLING_RATE)
for obj in self.endpoints:
obj.run()

0 comments on commit c9e8e36

Please sign in to comment.