mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
from typing import Dict, Union
|
|
from epc_data.attributes.attribute_utils import clean_description, remove_punctuation
|
|
|
|
|
|
class MainheatControlAttributes:
|
|
# These systems allow for the automatic regulation of temperature
|
|
THERMOSTATIC_CONTROL_KEYWORDS = [
|
|
'room thermostats',
|
|
'appliance thermostats',
|
|
'trvs',
|
|
'room thermostat',
|
|
'temperature zone control',
|
|
'time and temperature zone control',
|
|
'no thermostatic control'
|
|
]
|
|
|
|
# These systems provide a way to store and manage energy usage
|
|
CHARGING_SYSTEM_KEYWORDS = [
|
|
'charging system',
|
|
'automatic charge control',
|
|
'manual charge control',
|
|
'flat rate charging',
|
|
'high heat retention storage heaters'
|
|
]
|
|
|
|
# These systems are mainly focused on on/off operations
|
|
SWITCH_SYSTEM_KEYWORDS = [
|
|
'programmer',
|
|
'flow switch',
|
|
'bypass'
|
|
]
|
|
|
|
# These keywords indicate a lack of control system
|
|
NO_CONTROL_SYSTEM_KEYWORDS = [
|
|
'no time or thermostatic control',
|
|
'none'
|
|
]
|
|
|
|
# These systems provide control specifically for Domestic Hot Water
|
|
DHW_CONTROL_KEYWORDS = [
|
|
'dhw only'
|
|
]
|
|
|
|
# This system indicates the use of community heating
|
|
COMMUNITY_HEATING_KEYWORDS = [
|
|
'use of community heating'
|
|
]
|
|
|
|
MULTIPLE_ROOM_THERMOSTATS_PHRASES = [
|
|
'at least two room stats',
|
|
'at least two room thermostats'
|
|
]
|
|
|
|
def __init__(self, description: str):
|
|
self.description: str = clean_description(description.lower())
|
|
|
|
self.nodata = not description or any(keyword in self.description for keyword in self.NO_CONTROL_SYSTEM_KEYWORDS)
|
|
|
|
if not self.nodata and not any(
|
|
self._keyword_in_description(keywords)
|
|
for keywords in [
|
|
self.THERMOSTATIC_CONTROL_KEYWORDS,
|
|
self.CHARGING_SYSTEM_KEYWORDS,
|
|
self.SWITCH_SYSTEM_KEYWORDS,
|
|
self.DHW_CONTROL_KEYWORDS,
|
|
self.COMMUNITY_HEATING_KEYWORDS
|
|
]
|
|
):
|
|
raise ValueError('Invalid description')
|
|
|
|
def _keyword_in_description(self, keywords):
|
|
return any(keyword in self.description for keyword in keywords)
|
|
|
|
def process(self) -> Dict[str, Union[str, bool]]:
|
|
result: Dict[str, Union[str, bool]] = {
|
|
"thermostatic_control": self._find_keyword(self.THERMOSTATIC_CONTROL_KEYWORDS),
|
|
"charging_system": self._find_keyword(self.CHARGING_SYSTEM_KEYWORDS),
|
|
"switch_system": self._find_keyword(self.SWITCH_SYSTEM_KEYWORDS),
|
|
"no_control": self._find_keyword(self.NO_CONTROL_SYSTEM_KEYWORDS),
|
|
"dhw_control": self._find_keyword(self.DHW_CONTROL_KEYWORDS),
|
|
"community_heating": self._find_keyword(self.COMMUNITY_HEATING_KEYWORDS),
|
|
"multiple_room_thermostats": any(
|
|
phrase in self.description for phrase in self.MULTIPLE_ROOM_THERMOSTATS_PHRASES),
|
|
}
|
|
|
|
return result
|
|
|
|
def _find_keyword(self, keywords):
|
|
description_words = set(self.description.split())
|
|
|
|
# Sort keywords by length, longest first. This ensures that 'time and temperature zone control'
|
|
# will be checked before 'temperature zone control' if both are present in the keywords list
|
|
keywords.sort(key=len, reverse=True)
|
|
|
|
for keyword in keywords:
|
|
keyword_words = set(keyword.split())
|
|
if keyword_words.issubset(description_words):
|
|
return keyword
|
|
|
|
# If no keyword is found, try again after removing punctuation
|
|
description_without_punct = remove_punctuation(self.description)
|
|
description_words_without_punct = set(description_without_punct.split())
|
|
|
|
for keyword in keywords:
|
|
keyword_words = set(keyword.split())
|
|
if keyword_words.issubset(description_words_without_punct):
|
|
return keyword
|
|
|
|
return None
|