Vinnerliste
Populært innhold
Viser innholdet med mest poeng fra 13. juli 2022 i alle områder
-
Tenkte jeg skulle poste min variant av @stigvisin PID-kontroller for mangfoldets skyld. I korte trekk har jeg en skrevet en klasse som jeg har i /pyscript/modules som ivaretar alt av terskelverdier for av/på og timere. Opplever i blant at PID-regulatoren er litt vel trigger-happy i begynnelsen av timen siden timeestimatet er veldig følsomt for (filtrert) sanntidseffekt etter timeskift, så for laster som jeg ikke vil skru av og på så ofte venter jeg til slutten av timen (f.eks. minutt 40), og har timeout til timen er omme. from datetime import datetime registered_triggers = [] class Device(): def __init__(self, threshold, state_entity, timer_entity, timeout, earliest_shutoff = 0): self.state_entity = state_entity self.timer_entity = timer_entity self.timeout = timeout # Timeout in seconds. If -1, timeout until next hour self.earliest_shutoff = earliest_shutoff # Minute of earliest shutoff state.setattr(f"{self.state_entity}.threshold", threshold) state.setattr(f"{self.state_entity}.timeout", timeout) state.setattr(f"{self.state_entity}.earliest_shutoff", earliest_shutoff) @state_trigger(f"{self.timer_entity}") def check_timer(value = None): '''Turn back on when timer elapsed after upcrossing threshold''' thr = state.getattr(self.state_entity)["threshold"] s = state.get(self.state_entity) t = state.get(self.timer_entity) c = float(pyscript.regulator_electric_power) if c > thr and t == 'idle' and s == 'off': self.turn_on() registered_triggers.append(check_timer) def turn_on(self): state.set(self.state_entity, "on") def turn_off(self): state.set(self.state_entity, "off") def check_threshold(self): thr = state.getattr(self.state_entity)["threshold"] s = state.get(self.state_entity) c = float(pyscript.regulator_electric_power) t = state.get(self.timer_entity) # Turn device off if c <= thr and s == 'on' and self.check_earliest_shutoff(): self.turn_off() if self.timeout != 0: self.start_timer() # Turn device back on if above threshold and timer elapsed if c > thr and t == 'idle' and s == 'off': self.turn_on() def start_timer(self): t = self.timeout if t == -1: # Timeout rest of hour t = self.calculate_timeout_until_next_hour() timer.start(entity_id = self.timer_entity, duration = t) def check_earliest_shutoff(self): '''Check if minute count is high enough to turn off device''' m = datetime.now().minute return m >= self.earliest_shutoff def calculate_timeout_until_next_hour(self): '''For devices with timeout == -1''' now = datetime.now() m, s = now. minute, now.second return 3600 - (m*60+s) Så har jeg et python-script der jeg instansierer Device-objektene og oppdaterer regulatoren. Klipper ned litt her for å unngå unødvendig repetisjon: # [...Setup of simple_pid...] laundry = Device(threshold = 0.9, state_entity="pyscript.laundry_floor_pid_output", timer_entity="timer.laundry_floor_timer", timeout = 5*60) # [...repeat for other devices...] @state_trigger("pyscript.electricity_estimated_hour_consumption") def update_regulator(): global pid global laundry, toilet, bath, entrance, dehumidifier, water_heater last_c = float(pyscript.regulator_electric_power) c = pid(float(pyscript.electricity_estimated_hour_consumption)) if round(c, 2) != last_c: pyscript.regulator_electric_power.old = last_c pyscript.regulator_electric_power = round(c, 2) laundry.check_threshold() # [...repeat for other devices...] Dessverre støtter ikke Pyscript @state_trigger inni en klasse ennå såvidt jeg vet, så @state_trigger(laundry.timer_entity) må dessverre gjentas for hver timer utenfor klassen som vist over. "Outputen" fra alt dette er egentlig state_entity (altså pyscript.laundry_floor_pid_output), som jeg bruker der jeg ivaretar andre betingelser for av/på (basert på strømpris osv.)1 poeng
Vinnerlisten er satt til Oslo/GMT+01:00