def GetConfiguration(self): # Message width self.logger_message_width = Configurator.GetOption( self.globalConfig, [LOGGER_CONFIG_KEY, LOGGER_MESSAGE_WIDTH_KEY], LOGGER_MESSAGE_WIDTH_DEFAULT) # File level self.file_log_level = Configurator.GetOption( self.globalConfig, [LOGGER_CONFIG_KEY, LOGGER_FILE_LEVEL_KEY], LOGGER_DEFAULT_LEVEL) # Console level self.console_log_level = Configurator.GetOption( self.globalConfig, [LOGGER_CONFIG_KEY, LOGGER_CONSOLE_LEVEL_KEY], LOGGER_DEFAULT_LEVEL)
def FrequencyFormatter(value, options): # Get value in hertz result = value # Add unit if cf.GetOption(options, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_KEY, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_DEFAULT): result = str(value) + 'hz' return result
def TimeFormatter(value, options): # Get value in milliseconds result = value # Add unit if cf.GetOption(options, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_KEY, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_DEFAULT): result = str(value) + 'ms' return result
def ByteFormatter(value, options): # Get value in bytes asked_size = cf.GetOption(options, VALUEFORMATTER_OPTIONS_SIZE_KEY) decimals = cf.GetOption(options, VALUEFORMATTER_OPTIONS_DECIMALS_KEY) if asked_size and asked_size in BYTE_SIZES: powOf1024 = BYTE_SIZES.index(asked_size) else: powOf1024 = math.floor(math.log(value, 1024)) result = str(round(value / (math.pow(1024, powOf1024)), decimals)) # Add unit if cf.GetOption(options, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_KEY, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_DEFAULT): result = result + BYTE_SIZES[powOf1024] return result
def LoadRequirements(self): # Here I load sensors and commands # I have a dict with {'sensors':[SENSORS],'commands':[COMMANDS]} # SENSORS and COMMANDS have the same format as the configutaration.yaml so I # tell to LoadSensor and LoadCommands what to load with the usual method for requirements in self.requirements: sensors = cf.GetOption(requirements, SETTINGS_REQUIREMENTS_SENSOR_KEY) commands = cf.GetOption(requirements, SETTINGS_REQUIREMENTS_COMMAND_KEY) if sensors: self.LoadEntities(sensors, SENSOR_NAME_SUFFIX, loadingRequirements=True) if commands: self.LoadEntities(commands, COMMAND_NAME_SUFFIX, loadingRequirements=True) self.requirements.remove(requirements)
def GetValueFormatterOptionForTopic( self, valueTopic): # Return the ValueFormat options for the passed topic VFoptions = self.GetOption(self.consts.VALUE_FORMAT_OPTION_KEY) # if the options are not in a list: specified options are for every topic if type(VFoptions) is not list: return VFoptions else: # I have the same structure (topic with wildcard and configs) that I have for the topic settings in discovery for topicOptions in VFoptions: optionTopic = cf.GetOption(topicOptions, "topic") if optionTopic == "*" or optionTopic == valueTopic: return topicOptions return None return None
def PrepareDiscoveryPayloads(self): discovery_data = [] # Check if Discovery is enabled if self.GetOption([ self.consts.CONFIG_DISCOVERY_KEY, self.consts.DISCOVERY_ENABLE_KEY ], False) is not False: # Okay need auto discovery # Not for don't send sensors if self.GetOption('dont_send') is True: return # Don't send if disabled in config prefix = self.GetOption([ self.consts.CONFIG_DISCOVERY_KEY, self.consts.DISCOVERY_DISCOVER_PREFIX_KEY ], self.consts.DISCOVERY_DISCOVER_PREFIX_DEFAULT) preset = self.GetOption([ self.consts.CONFIG_DISCOVERY_KEY, self.consts.DISCOVERY_PRESET_KEY ]) entity_preset_data = None if preset: # Check here if I have an entry in the discovery file for this topic and use that data (PLACE IN 'sensor_data') entity_preset_data = cf.GetOption( self.settings, [self.consts.SETTINGS_DISCOVERY_KEY, preset]) # THIS for topic in self.outTopics: # discoveryData: {name, config_topic, payload} # print(topic) data = self.PrepareTopicDiscoveryData( topic['topic'], self.consts.TYPE_TOPIC_OUT, prefix, preset, entity_preset_data) if data: discovery_data.append(data) for topic in self.inTopics: # discoveryData: {name, config_topic, payload} data = self.PrepareTopicDiscoveryData( topic, self.consts.TYPE_TOPIC_IN, prefix, preset, entity_preset_data) if data: discovery_data.append(data) return discovery_data
def GetFormattedValue(value, valueType, options=None): if options == None: options = ValueFormatter.Options() # Default will be used if valueType == ValueFormatter.TYPE_NONE: # No edit needed return value elif valueType == ValueFormatter.TYPE_BYTE: return ValueFormatter.ByteFormatter(value, options) elif valueType == ValueFormatter.TYPE_TIME: return ValueFormatter.TimeFormatter(value, options) elif valueType == ValueFormatter.TYPE_FREQUENCY: return ValueFormatter.FrequencyFormatter(value, options) elif valueType == ValueFormatter.TYPE_PERCENTAGE: if cf.GetOption( options, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_KEY, VALUEFORMATTER_OPTIONS_UNIT_OF_MEASUREMENT_DEFAULT): return str(value) + '%' else: return value else: return value
def LoadEntities(self, entitiesToAdd, name_suffix, loadingRequirements=False): # From configs I read sensors list and I give the names to the sensors manager which will initialize them # and will keep trace of who is the mqtt_client and the logger of the sensor # self.entityManager.PostInitializeEntities() if entitiesToAdd: for entity in entitiesToAdd: # I load the sensor and if I need some requirements, I save them to the list # Additional check to not load double if I am loading requirements if not (loadingRequirements and entity in self.loadedEntities): settings = self.entityManager.LoadEntity( name_suffix, entity, self.monitor_id, self.config, self.mqttClient, self.config['send_interval'], self.logger) requirements = cf.GetOption(settings, SETTINGS_REQUIREMENTS_KEY) if requirements: self.requirements.append(requirements) self.loadedEntities.append(entity)
def PrepareTopicDiscoveryData(self, topic, entity_model, prefix, preset, entity_preset_data): payload = {} topicSettings = None # Warning ! Discovery configuration for a single topic could be in: entity settings; user configuration # DISCOVERY DATA FROM ENTITY SETTINGS # Look for custom discovery settings for this sensor, topic and preset: if entity_preset_data: for discoveryTopic in entity_preset_data: dtTopic = cf.GetOption(discoveryTopic, "topic") if (dtTopic == topic or dtTopic == "*") and cf.GetOption( discoveryTopic, self.consts.SETTINGS_DISCOVERY_PRESET_PAYLOAD_KEY): # Found dict for this topic in this sensor for this preset: Place in the payload topicSettings = discoveryTopic payload = cf.GetOption( discoveryTopic, self.consts. SETTINGS_DISCOVERY_PRESET_PAYLOAD_KEY).copy() # Check for Advanced information topic if I don't send advanced infomration: PS THIS IS USELESS CAUSE THIS TOPIC WON'T BE IN OUTTOPIC IN THAT CASE BUT IT'S BETTER TO CHECK # If I don't send advanced_information and the topic settings says the topic is advanced, I return None because this entity won't send any message on this topic if self.GetOption( self.consts.ADVANCED_INFO_OPTION_KEY, False) == False and cf.GetOption(topicSettings, [ self.consts.SETTINGS_DISCOVERY_KEY, self.consts.SETTINGS_DISCOVERY_ADVANCED_TOPIC_KEY ], False) == True: return None # DISCOVERY DATA FROM USER CONFIGURATION in entityConfig -> discovery -> settings # Take user_discovery_config not from options( thaht includes also monitors discovery config but oly from entity configs user_discovery_config = cf.ReturnAsList( cf.GetOption(self.entityConfigs, [ self.consts.ENTITY_DISCOVERY_KEY, self.consts.ENTITY_DISCOVERY_PAYLOAD_KEY ]), None) if user_discovery_config: for user_topic_config in user_discovery_config: dtTopic = cf.GetOption(user_topic_config, "topic") if not dtTopic or dtTopic == topic or dtTopic == "*": # Copy all the configuration I have in the payload for key, value in user_topic_config.items(): if key != "topic": # Avoid topic because is a non-payload information but only to recognise settings payload[key] = value # If I have to disable, return None if cf.GetOption(topicSettings, self.consts.SETTINGS_DISCOVERY_PRESET_DISABLE_KEY, False): return None # Do I have the name in the preset settings or do I set it using the default topic ? if not 'name' in payload: payload['name'] = topic.replace("/", "_") # Check and add this only if has option true if self.GetOption([ self.consts.CONFIG_DISCOVERY_KEY, self.consts.DISCOVERY_NAME_PREFIX_KEY ], self.consts.DISCOVERY_NAME_PREFIX_DEFAULT): payload['name'] = self.brokerConfigs['name'] + \ " - " + payload['name'] # Prepare the part of the config topic after the prefix and the sensortype topic_component = self.TopicRemoveBadCharacters( self.SelectTopic(topic)) payload['device'] = self.GetDiscoveryDeviceData() # Unique hashed payload['unique_id'] = hashlib.md5( (self.SelectTopic(topic)).encode('utf-8')).hexdigest() if (entity_model == self.consts.TYPE_TOPIC_OUT): # Do I have the type in the sensor preset settings or do I set it to 'sensor' ? entity_type = cf.GetOption( topicSettings, self.consts.SETTINGS_DISCOVERY_PRESET_TYPE_KEY, "sensor") # Send the topic where the Sensor will send his state payload['expire_after'] = self.GetOption([ self.consts.CONFIG_DISCOVERY_KEY, self.consts.DISCOVERY_EXPIRE_AFTER_KEY ], self.consts.DISCOVERY_EXPIRE_AFTER_DEFAULT) payload['state_topic'] = self.SelectTopic(topic) else: # Do I have the type in the sensor preset settings or do I set it to 'sensor' ? entity_type = cf.GetOption( topicSettings, self.consts.SETTINGS_DISCOVERY_PRESET_TYPE_KEY, "switch") # Send the topic where the Switch will receive the message payload['command_topic'] = self.SelectTopic(topic) # Compose the topic that will be used to send the disoovery configuration config_send_topic = self.consts.AUTODISCOVERY_TOPIC_CONFIG_FORMAT.format( prefix, entity_type, topic_component) return { "name": topic, "config_topic": config_send_topic, "payload": dict(payload) }
def IsDiscoveryEnabled(self): return cf.GetOption(self.brokerConfigs, [ self.consts.CONFIG_DISCOVERY_KEY, self.consts.DISCOVERY_ENABLE_KEY ], False)
def GetOption(self, path, defaultReturnValue=None): return cf.GetOption(self.options, path, defaultReturnValue)