def _read_opc(self): desired_states = [] opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password']) opc_tags = [ self.config['OPC_STORAGE']['tag_control'], ] values = opcclient.read(opc_tags) value = values[0] for i in range(len(self.config['WINDOWS'])): # process current state ctrl_id = self.config['WINDOWS'][i]['opc']['ctrl'] # opc reading may be disabled for this window if ctrl_id is not None: try: state = int(value[2*ctrl_id:2*ctrl_id+2]) except KeyError: logging.getLogger().error("Error getting state for window {}, {}"\ .format(ctrl_id, self.config['WINDOWS'][i]['name'])) state = 0 else: state = None desired_states.append(state) return desired_states
def __init__(self): # call parent constructor super().__init__() # setup OPC interface if not self.config['OPC_STORAGE']['enabled']: raise Exception("Astrotime needs OPC storage enabled") self.opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password'])
class Astrotime(StandardScript): HORIZON = '-7' # -6=civil twilight def __init__(self): # call parent constructor super().__init__() # setup OPC interface if not self.config['OPC_STORAGE']['enabled']: raise Exception("Astrotime needs OPC storage enabled") self.opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password']) def process(self): try: # determine sunset # get sun position o = ephem.Observer() # Vienna: 48 degree north; 16 degree east o.lat, o.long, o.date = '48:13', '16:22', datetime.datetime.utcnow() o.horizon = self.HORIZON sunset = ephem.localtime(o.next_setting(ephem.Sun())) logging.getLogger().info("Setting sunset to {}".format(sunset.strftime("%H:%M:%S"))) # store to OPC data point self.save_opc(sunset) except Exception as e: logging.getLogger().error(traceback.format_exc()) raise def save_opc(self, sunset): # setup values if 'tag_sunset' in self.config['OPC_STORAGE'] and \ self.config['OPC_STORAGE']['tag_sunset'] is not None: opc_tags = [self.config['OPC_STORAGE']['tag_sunset']] types = ['float'] values = [sunset.hour*3600 + sunset.minute*60 + sunset.second] # write data to OPC self.opcclient.write(opc_tags, types, values)
def __init__(self): # call parent constructor super().__init__() # setup OPC interface if self.config['OPC_STORAGE']['enabled']: self.opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password']) # setup power calculator self.calculator = PowerCalculator(self.config)
def __init__(self): # call parent constructor super().__init__() # setup OPC interface if self.config['OPC_STORAGE']['enabled']: self.opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password']) # setup mqtt connection if self.config['MQTT_STORAGE']['enabled']: self.mqtt = mqtt.Client() # quick and dirty: we assume to be connected before we finished email parsing... #self.mqtt.on_connect = self._on_mqtt_connect if 'user' in self.config['MQTT_STORAGE']: self.mqtt.username_pw_set(self.config['MQTT_STORAGE']['user'], self.config['MQTT_STORAGE']['password']) self.mqtt.connect(self.config['MQTT_STORAGE']['host'], self.config['MQTT_STORAGE']['port']) self.mqtt.loop_start() # setup data members self.data = None
class Zamg(StandardScript): def __init__(self): # call parent constructor super().__init__() # setup OPC interface if self.config['OPC_STORAGE']['enabled']: self.opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password']) # setup mqtt connection if self.config['MQTT_STORAGE']['enabled']: self.mqtt = mqtt.Client() # quick and dirty: we assume to be connected before we finished email parsing... #self.mqtt.on_connect = self._on_mqtt_connect if 'user' in self.config['MQTT_STORAGE']: self.mqtt.username_pw_set(self.config['MQTT_STORAGE']['user'], self.config['MQTT_STORAGE']['password']) self.mqtt.connect(self.config['MQTT_STORAGE']['host'], self.config['MQTT_STORAGE']['port']) self.mqtt.loop_start() # setup data members self.data = None def process_csv(self, csv): try: decoder = CsvDecoder(self.config) decoder.decode(csv) # process data self.sun_today = 0 # loop through data for row in decoder.data: # is this timestamp fitting? timediff = (row['date']-datetime.datetime.utcnow()).total_seconds() # is data not older than 1 hour? if timediff > -3600: # sum minutes of remaining sun for today if row['date'].date() == datetime.datetime.utcnow().date(): self.sun_today += row['sun'] # is this the most recent timestamp? if timediff <= 0: # store this data row as our best guess self.data = row except Exception as e: logging.getLogger().error(traceback.format_exc()) raise def set_opc(self, temperature, sun): # setup values opc_tags = [] types = [] values = [] if 'tag_temperature' in self.config['OPC_STORAGE'] and \ self.config['OPC_STORAGE']['tag_temperature'] is not None: # save temperature to OPC opc_tags.append(self.config['OPC_STORAGE']['tag_temperature']) types.append('float') values.append(temperature) if 'tag_sunpower' in self.config['OPC_STORAGE'] and \ self.config['OPC_STORAGE']['tag_sunpower'] is not None: # save sunpower to OPC opc_tags.append(self.config['OPC_STORAGE']['tag_sunpower']) types.append('float') values.append(sun) # write data to OPC if len(opc_tags): self.opcclient.write(opc_tags, types, values) def set_file(self, temperature, sun): config = configparser.ConfigParser() # read existing file data if os.path.isfile(self.config['FILE_STORAGE']['filename']): config.read(self.config['FILE_STORAGE']['filename']) config[self.scriptname] = {} config[self.scriptname]['Temperature'] = str(temperature) config[self.scriptname]['SunPower'] = str(sun) with open(self.config['FILE_STORAGE']['filename'], 'w') as configfile: config.write(configfile) def set_mqtt(self, temperature, sun, sun_today): # publish values to MQTT broker path = self.config['MQTT_STORAGE']['prefix']+"zamg" self.mqtt.publish(path+"/temperature", temperature, retain=True) self.mqtt.publish(path+"/sun", sun, retain=True) self.mqtt.publish(path+"/sun_today", sun_today) self.mqtt.publish(path+"/last_update", str(datetime.datetime.now()), retain=True) def process_mail(self): # check for entered configuration if len(self.config['EMAIL']['servername']) == 0: logging.getLogger().error("Please configure config file. Aborting.") return logging.getLogger().info("Retrieval from mail server " + self.config['EMAIL']['servername']) try: # setup mail parser mailparser = MailParser(self.config) mailparser.add_csvobserver(self.process_csv) # start retrieval mailparser.parse() except Exception as e: logging.getLogger().error(traceback.format_exc()) def process_data(self): # if retrieval succeeded we have valid data now if self.data: logging.getLogger().info("Set temperature: {}, sun: {:2f}" .format(self.data['temperature'], self.data['sun']/60)) # store temperature and sun power if self.config['OPC_STORAGE']['enabled']: self.set_opc(self.data['temperature'], self.data['sun']/60) if self.config['FILE_STORAGE']['enabled']: self.set_file(self.data['temperature'], self.data['sun']/60) if self.config['MQTT_STORAGE']['enabled']: self.set_mqtt(self.data['temperature'], self.data['sun']/60, self.sun_today)
class SunPower(StandardScript): def __init__(self): # call parent constructor super().__init__() # setup OPC interface if self.config['OPC_STORAGE']['enabled']: self.opcclient = OpcClient(self.config['OPC_STORAGE']['url'], self.config['OPC_STORAGE']['password']) # setup power calculator self.calculator = PowerCalculator(self.config) def process(self): try: # process effective angles self.calculator.process(self.config['WINDOWS']) # store power values if self.config['OPC_STORAGE']['enabled']: self.save_opc() if self.config['FILE_STORAGE']['enabled']: self.save_file() except Exception as e: logging.getLogger().error(traceback.format_exc()) raise return self.calculator.power_values def save_opc(self): # store OPC requests opc_tags = [] types = [] values = [] # setup values for i in range(len(self.config['WINDOWS'])): if self.config['WINDOWS'][i]['opc']['power'] is not None: opc_tags.append(self.config['WINDOWS'][i]['opc']['power']) types.append('float') values.append(self.calculator.power_values[i]) # write data to OPC if len(opc_tags) > 0: self.opcclient.write(opc_tags, types, values) def save_file(self): config = configparser.ConfigParser() # read existing file data if os.path.isfile(self.config['FILE_STORAGE']['filename']): try: config.read(self.config['FILE_STORAGE']['filename']) except configparser.ParsingError as e: logging.getLogger().error("Error parsing file storage: " + str(e)) # recreate data of this script config['sunpower'] = {} for i in range(len(self.config['WINDOWS'])): config['sunpower'][self.config['WINDOWS'][i]['name']] = \ str(self.calculator.power_values[i]) # save data file with open(self.config['FILE_STORAGE']['filename'], 'w') as configfile: config.write(configfile)