def add_sensor_thermal_impact(self, target, event): """Set a target sensor that will be affected by the current source sensor values Args: target(str): Name of the target sensor event(str): Source event causing the thermal impact to trigger """ if target in self._th_sensor_t and event in self._th_sensor_t[target]: raise ValueError("Thread already exists") with self._graph_ref.get_session() as session: rel_details = GraphReference.get_sensor_thermal_rel( session, self._server_key, relationship={ "source": self.name, "target": { "attribute": "name", "value": '"{}"'.format(target) }, "event": event, }, ) if rel_details: self._launch_thermal_sensor_thread(target, rel_details["rel"]["event"])
def _target_sensor(self, target, event): """Keep updating the target sensor based on the relationship between this sensor and the target; This function waits for the thermal event switch and exits when the connection between source & target is removed; Args: target(str): name of the target sensor event(str): name of the event that enables thermal impact """ with self._graph_ref.get_session() as session: while True: self._s_thermal_event.wait() rel_details = GraphReference.get_sensor_thermal_rel( session, self._server_key, relationship={ "source": self.name, "target": { "attribute": "name", "value": '"{}"'.format(target) }, "event": event, }, ) # shut down thread upon relationship removal if not rel_details: del self._th_sensor_t[target][event] return rel = rel_details["rel"] causes_heating = rel["action"] == "increase" source_sensor_status = (operator.eq if rel["event"] == "down" else operator.ne) bound_op = operator.lt if causes_heating else operator.gt arith_op = operator.add if causes_heating else operator.sub # if model is specified -> use the runtime mappings if "model" in rel and rel["model"]: calc_new_sv = arith_op arith_op = lambda sv, _: calc_new_sv( sv, self._calc_approx_value(json.loads(rel["model"]), int(self.sensor_value) * 10), ) source_sensor_status = operator.ne # verify that sensor value doesn't go below room temp if causes_heating or rel[ "pauseAt"] > ISystemEnvironment.get_ambient(): pause_at = rel["pauseAt"] else: pause_at = ISystemEnvironment.get_ambient() # update target sensor value with self._s_file_locks.get_lock(target), open( os.path.join(self._s_dir, target), "r+") as sf_handler: current_value = int(sf_handler.read()) change_by = (int(rel["degrees"]) if "degrees" in rel and rel["degrees"] else 0) new_sensor_value = arith_op(current_value, change_by) # Source sensor status activated thermal impact if source_sensor_status(int(self.sensor_value), 0): needs_update = bound_op(new_sensor_value, pause_at) if not needs_update and bound_op( current_value, pause_at): needs_update = True new_sensor_value = int(pause_at) if needs_update: logger.info( "Current sensor value (%s°) will be updated to %s°", current_value, int(new_sensor_value), ) sf_handler.seek(0) sf_handler.truncate() sf_handler.write(str(new_sensor_value)) time.sleep(int(rel["rate"]))
def _target_storage(self, controller, target, hd_type, event): with self._graph_ref.get_session() as session: while True: self._s_thermal_event.wait() # target if hd_type == HDComponents.CacheVault: target_attr = "serialNumber" target_value = '"{}"'.format(target) elif hd_type == HDComponents.PhysicalDrive: target_attr = "DID" target_value = target else: raise ValueError("Unknown hardware component!") rel_details = GraphReference.get_sensor_thermal_rel( session, self._server_key, relationship={ "source": self._s_name, "target": { "attribute": target_attr, "value": target_value }, "event": event, }, ) if not rel_details: del self._th_storage_t[target][event] return rel = rel_details["rel"] causes_heating = rel["action"] == "increase" source_sensor_status = (operator.eq if rel["event"] == "down" else operator.ne) # if model is specified -> use the runtime mappings if "model" in rel and rel["model"]: rel["degrees"] = self._calc_approx_value( json.loads(rel["model"]), int(self.sensor_value) * 10) source_sensor_status = operator.ne if source_sensor_status(int(self.sensor_value), 0): updated, new_temp = GraphReference.add_to_hd_component_temperature( session, target={ "server_key": self._server_key, "controller": controller, "attribute": target_attr, "value": target_value, "hd_type": hd_type.name, }, temp_change=rel["degrees"] * 1 if causes_heating else -1, limit={ "lower": ISystemEnvironment.get_ambient(), "upper": rel["pauseAt"] if causes_heating else None, }, ) if updated: logger.info("temperature sensor was updated to %s°", new_temp) time.sleep(rel["rate"])