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