def _receive_and_log(self, data_receiver, connection) -> bytes: """ Receives an answer and logs it, before returning, by pre-pending the tag 'CONFIGURATION'. """ answer = data_receiver.raw_receive(connection, timeout=1) try: decoded_answer = answer.decode() Logging.info("CONFIGURATION:" + decoded_answer) except UnicodeDecodeError: Logging.info("CONFIGURATION: answer is in binary") return answer
def _backup_prev_files(self, current_filepath): """ Moves the previous files to the backup directory. If the backup directory was not specified in the initializer it does nothing. """ if self.backup_dir and not os.path.exists(current_filepath): # new file will be created # move all current files inside the store dir to the backup dir for filename in os.listdir(self.data_dir): shutil.move(src=os.path.join(self.data_dir, filename), dst=os.path.join(self.backup_dir, filename)) Logging.info("moved file %s to the backup " "directory" % filename)
def receive_forever(self): """ Puts the receiver in receiving mode forever. In this mode the receiver blocks until new data is received from the sender. Every time a new chunk of data is received it calls the registered handlers' on_new_data() method. """ while True: # allow reconnecting on error try: Logging.debug("Trying to connect to %s:%s..." % (self._sender_address[0], self._sender_address[1])) with sock.create_connection(self._sender_address, timeout=30) as connection: for handler in self._connection_handlers: handler.on_new_connection(self, connection, self._sender_address) Logging.debug("Connected successfully") while True: try: Logging.info("Waiting for data...") data = self.receive(connection) Logging.info("Received data") for handler in self._data_handlers: handler.on_new_data(data) except InvalidFormatException as error: # data was not correct Logging.warning("Received data with invalid format:" " %s" % str(error)) except ConnectionAbortedError: Logging.warning("connection aborted by the sender") except sock.timeout: Logging.warning("connection timed out") except (sock.herror, sock.gaierror): Logging.error("the address of the sender is not valid") break # leave the function except ConnectionRefusedError: Logging.warning("can not reach the sender") # retry in connecting in 10 seconds Logging.debug( "connection failed: will try to connect in 10 seconds") sleep(10)
def store(self, data: str): """ Stores the data line according to the implementation. """ if not data: # ignore empty message return # the datetime passed to teh adjust_data() and generate_filename() # methods must be the same to avoid incoherency current_datetime = datetime.now() data = self._adjust_data(data, current_datetime) out_filename = self._generate_filename(data, current_datetime) out_filepath = os.path.join(self.data_dir, out_filename) # this must be called before dumping the data to the file self._backup_prev_files(out_filepath) with open(out_filepath, "a") as out_file: out_file.write(data) out_file.write('\n') Logging.info("stored new line in %s" % out_filename)
def run(self, decoder, data_handlers, connection_handlers): """ Runs the application after loading the configuration. If this method is called before loading the configuration a ValueError is raised. :param decoder: decoder to be used :param data_handlers: iterable with all the data handlers to register with the data receiver. :param connection_handlers: iterable with all the connection handlers to register with the data receiver. """ if not self._config: raise ValueError("can not run before loading the configuration") # make terminate signals raise keyboard interrupts signal.signal(signal.SIGTERM, raise_keyboard_interrupt) receiver = DataReceiver((self._config.ip_address, self._config.port), decoder) # register all data handlers for handler in data_handlers: receiver.register_data_handler(handler) # register all connection handlers for handler in connection_handlers: receiver.register_connection_handler(handler) try: Logging.info("Started") receiver.receive_forever() except KeyboardInterrupt: # user pressed Ctrl-C to close the program Logging.info("Closing as requested by user...") except BaseException: Logging.exception("Program will closed due to unexpected error...") Logging.info("Closed")
class ForecastData: data = None args = None verbose = False def __init__(self, api_key, location, update=15, language="EN", fetch=False): args = {} args["apikey"] = api_key args["location"] = location args["language"] = language args["fetch"] = -1 args["sub"] = "fetch" self.args = args self.data_update = 0 self.update_time = update * 60 self.logging = Logging() self.name = "Wunderground" if fetch: self.fetch_data() def check_update(self): if time.time() - self.update_time > self.data_update: self.fetch_data() def fetch_data(self): # Grab data from Weather Underground API req = ( "http://api.wunderground.com/api/%s/conditions/alerts/forecast10day/lang:%s/q/%s.json" % (self.args["apikey"], self.args["language"], quote(self.args["location"]))) self.link = req self.logging.info("Fetching weather data from location: " + str(self.args["location"]), location=self.name) try: response = urlopen(req) except URLError as e: if hasattr(e, 'reason'): self.logging.error(e.reason, location=self.name) elif hasattr(e, 'code'): self.logging.error("Status returned: " + str(e.code), location=self.name) json_data = response.read().decode('utf-8', 'replace') data = json.loads(json_data) try: self.logging.error(data['response']['error']['description'], location=self.name) self.logging.error("Error fetching data, check settings", location=self.name) except KeyError: self.logging.info("Data fetched successfully", location=self.name) self.data = data self.data_update = time.time() def read_current(self): self.check_update() # Assign current conditions to a dictionary try: current = self.data['current_observation'] except KeyError: self.fetch_error() # Collect and merge wind data wind_dir = current['wind_dir'] wind_mph = current['wind_mph'] wind_kph = current['wind_kph'] wind_gust_mph = current['wind_gust_mph'] wind_gust_kph = current['wind_gust_kph'] wind_string_mph = (wind_dir + " " + str(float(wind_mph)) + "mph gusting to " + str(float(wind_gust_mph)) + "mph") wind_string_kph = (wind_dir + " " + str(float(wind_kph)) + "km/h gusting to " + str(float(wind_gust_kph)) + "km/h") wind = wind_dir + " " + str(float(wind_kph)) + "km/h" neerslag = current["precip_today_string"] neerslag = neerslag[neerslag.find("(") + 1:neerslag.find(")")].replace( " ", "") current_dict = { "location": current["display_location"]["full"], "city": current["display_location"]["city"], "condition": current['weather'], "n_condition": self.get_numbered_state(self.convert_icon(current['icon'], True), True), "temp_f": int(round(float(current['temp_f']))), "temp_c": "%.1f" % (float(current['temp_c'])), "humidity": current['relative_humidity'].replace("%", ""), "icon": self.convert_icon(current['icon'], True), "icon_url": current['icon_url'], "wind": wind, "wind_dir": wind_dir, "wind_mph": wind_mph, "wind_kph": wind_kph, "wind_gust_mph": wind_gust_mph, "wind_gust_kph": wind_gust_kph, "wind_string_mph": wind_string_mph, "wind_string_kph": wind_string_kph, "pressure_mb": current['pressure_mb'], "pressure_in": current['pressure_in'], "pressure_trend": current['pressure_trend'], "dewpoint_c": current['dewpoint_c'], "dewpoint_f": current['dewpoint_f'], "heat_index_c": current['heat_index_c'], "heat_index_f": current['heat_index_f'], "windchill_c": current['windchill_c'], "windchill_f": current['windchill_f'], "feelslike_c": current['feelslike_c'], "feelslike_f": current['feelslike_f'], "visibility_mi": current['visibility_mi'], "visibility_km": current['visibility_km'], "prec_hour_in": current['precip_1hr_in'], "prec_hour_cm": current['precip_1hr_metric'], "prec_day_mm": neerslag, "prec_day_cm": current['precip_today_metric'], "timezone": current['local_tz_long'], "sunset": self.get_next_sunset( current['local_tz_long'], current["display_location"]).strftime('%H:%M'), "sunrise": self.get_next_sunrise( current['local_tz_long'], current["display_location"]).strftime('%H:%M'), } return current_dict def read_forecast(self): self.check_update() # Assign forecast to a dictionary forecast_dict = [] try: forecast = self.data['forecast']['simpleforecast']['forecastday'] except KeyError: self.fetch_error() count = 1 for index, node in enumerate(forecast): d = node['date'] if str(node['qpf_allday']['mm']) == "None": node['qpf_allday']['mm'] = "-" conditions = { "day": d['weekday'], "shortdate": str(d['month']) + "/" + str(d['day']) + "/" + str(d['year']), "longdate": d['monthname'] + " " + str(d['day']) + ", " + str(d['year']), "low_f": node['low']['fahrenheit'], "low_c": node['low']['celsius'], "high_f": node['high']['fahrenheit'], "high_c": node['high']['celsius'], "avg_c": "%.0f" % ((float(node['low']['celsius']) + float(node['high']['celsius'])) / 2.0), "avg_f": "%.0f" % ((float(node['low']['fahrenheit']) + float(node['high']['fahrenheit'])) / 2.0), "icon": self.convert_icon(node['icon']), "icon_url": node['icon_url'], "condition": node['conditions'], "n_condition": self.get_numbered_state(self.convert_icon(node['icon'])), "rain_in": node['qpf_allday']['in'], "rain_mm": str(node['qpf_allday']['mm']) + "mm", "snow_in": node['snow_allday']['in'], "snow_cm": str(node['snow_allday']['cm']) + "cm", } forecast_dict.append(conditions) count += 1 return forecast_dict def read_info(self): self.check_update() try: info = self.data['current_observation'] except KeyError: self.fetch_error() info_dict = { "city": info['display_location']['city'], "postal": info['display_location']['zip'], "datetime": info['observation_time'], "location": info['display_location']['full'], "country": info['display_location']['country'], "latitude": info['display_location']['latitude'], "longitude": info['display_location']['longitude'], "elevation": info['display_location']['elevation'], "observation": info['observation_location']['full'], } return info_dict def read_alerts(self): self.check_update() alerts_dict = [] try: alerts = self.data['alerts'] except KeyError: self.fetch_error() for index, node in enumerate(alerts): a = { "start": node['date'], "expires": node['expires'], "description": node['description'], "message": node['message'], } alerts_dict.append(a) return alerts_dict def convert_icon(self, icon, current=False): self.check_update() pattern = re.compile(r'[A-Za-z]+ \d+ (.+):\d+:\d+') time_string = self.data['current_observation']['local_time_rfc822'] hour = int(pattern.search(time_string).group(1)) day_icon_dict = self.get_icons_db() night_icon_dict = self.get_icons_db(day=False) try: if (hour > 20 or hour < 6) and current is True: new_icon = night_icon_dict[icon] else: new_icon = day_icon_dict[icon] except KeyError: self.logging.error( "Icon type doesn't exist. Please report this. [%s]" % str(icon), location=self.name) new_icon = "" return new_icon def get_numbered_state(self, icon, current=False): day_icon_dict = self.get_icons_db() numbered_dict = self.get_icons_db(numbered=True) pattern = re.compile(r'[A-Za-z]+ \d+ (.+):\d+:\d+') time_string = self.data['current_observation']['local_time_rfc822'] hour = int(pattern.search(time_string).group(1)) if (hour > 20 or hour < 6) and current is True: add = 31 else: add = 1 for i in range(len(numbered_dict)): name = numbered_dict[i] if day_icon_dict[name][-1:] == icon[-1:]: return i + add return 20 + add def get_icons_db(self, day=True, numbered=False): if numbered: return [ "chancerain", "sunny", "mostlysunny", "partlycloudy", "mostlycloudy", "rain", "chancesnow", "cloudy", "tstorms", "chancetstorms", "sleet", "snow", "fog", "smoke", "hazy", "flurries", "chanceflurries", "chancesleet", "clear", "partlysunny", "unknown" ] elif day: return { "chancerain": "weather_g", "sunny": "weather_h", "mostlysunny": "weather_b", "partlycloudy": "weather_c", "mostlycloudy": "weather_d", "rain": "weather_i", "chancesnow": "weather_u", "cloudy": "weather_e", "tstorms": "weather_m", "chancetstorms": "weather_k", "sleet": "weather_j", "snow": "weather_q", "fog": "weather_f", "smoke": "weather_n", "hazy": "weather_t", "flurries": "weather_p", "chanceflurries": "weather_s", "chancesleet": "weather_o", "clear": "weather_r", "partlysunny": "weather_l", "unknown": "weather_u" } else: return { "chancerain": "weather_nt_g", "sunny": "weather_nt_a", "mostlysunny": "weather_nt_b", "partlycloudy": "weather_nt_c", "mostlycloudy": "weather_nt_d", "rain": "weather_nt_i", "chancesnow": "weather_nt_u", "cloudy": "weather_nt_e", "tstorms": "weather_nt_m", "chancetstorms": "weather_nt_k", "sleet": "weather_nt_j", "snow": "weather_nt_q", "fog": "weather_nt_f", "smoke": "weather_nt_n", "hazy": "weather_nt_t", "flurries": "weather_nt_p", "chanceflurries": "weather_nt_s", "chancesleet": "weather_nt_o", "clear": "weather_nt_r", "partlysunny": "weather_nt_l", "unknown": "weather_nt_u" } def getCondNames(self, language="EN"): if language == "EN": return [ "chancerain", "sunny", "mostlysunny", "partlycloudy", "mostlycloudy", "rain", "chancesnow", "cloudy", "tstorms", "chancetstorms", "sleet", "snow", "fog", "smoke", "hazy", "flurries", "chanceflurries", "chancesleet", "clear", "partlysunny", "unknown" ] def fetch_error(self): pass def output_data(self, parser): if self.args.sub == "current": current_dict = self.read_current() print(current_dict[self.args.current], file=sys.stdout) elif self.args.sub == "forecast": forecast_dict = self.read_forecast() self.logging.info(forecast_dict[int( self.args.day)][self.args.forecast], location=self.name) elif self.args.sub == "info": info_dict = self.read_info() print(info_dict[self.args.information], file=sys.stdout) elif self.args.sub == "alert": alerts_dict = self.read_alerts() if len(alerts_dict) < 1: print('No alerts to display') sys.exit(10) if self.args.num > len(alerts_dict): self.logging.error('Invalid alert number. Available: %s' % len(alerts_dict), location=self.name) print(alerts_dict[int(self.args.num - 1)][self.args.alert], file=sys.stdout) elif self.args.sub != "fetch": parser.print_usage() def get_next_sunrise(self, timezone, location): tz = pytz.timezone(timezone) obs = self.create_observer(location) sunrise = obs.next_rising(ephem.Sun()).datetime() return pytz.utc.localize(sunrise).astimezone(tz) def get_next_sunset(self, timezone, location): tz = pytz.timezone(timezone) obs = self.create_observer(location) sunset = obs.next_setting(ephem.Sun()).datetime() return pytz.utc.localize(sunset).astimezone(tz) def create_observer(self, loc): user = ephem.Observer() #print(loc) user.lat = loc["latitude"] user.lon = loc["longitude"] user.elevation = float(loc["elevation"]) return user
class Symbol(object): def __init__(self, symbol, s_date=None, e_date=None): self.log=Logging() self.name=symbol self.created=datetime.datetime.utcnow() self.log.info("created {}".format(self.name)) try: self.share=Share(symbol) except: self.log.error("platform is offline or not connecting") if s_date and e_date: self.begin=s_date self.end=e_date try: self.share=Share(symbol) self.data=self.share.get_historical(self.begin, self.end) self.log.refresh("{} data collected".format(self.name)) except: self.log.error("platform is offline or not connecting") def refresh_data(self, s_date=None, e_date=None): if s_date and e_date: try: share=Share(self.name) self.begin=s_date self.end=e_date share.get_historical(s_date, e_date) self.log.refresh("{} data collected".format(self.name)) except: self.log.error("platform is offline or not connecting") def market_cap(self): try: self.market_cap = self.share.get_market_cap() self.log.info("{} market cap refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def earnings_per_share(self): try: self.eps = self.share.get_earnings_share() self.log.info("{} eps refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def moving_average_50(self): try: self.moving_average_50 = self.share.get_50day_moving_average() self.log.info("{} 50 day moving ave refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") #implement TODO def nday_moving_average(self, n): try: self.moving_average_n = None self.log.info("{} {} day moving ave refreshed".format(self.name, n)) except: self.log.error("platform is offline or not connecting") def price_earnings_ratio(self): try: self.price_to_earnings = self.share.get_price_earnings_ratio() self.log.info("{} price to earnings refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def book_value(self): try: self.book = self.share.get_price_book() self.log.info("{} book value refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def year_high(self): try: self.year_high = self.share.get_change_from_year_high() self.log.info("{} year high change refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def year_low(self): try: self.year_low = self.share.get_change_from_year_low() self.log.info("{} year low change refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def target_price(self): try: self.year_target = self.share.get_change_from_year_high() self.log.info("{} year target change refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting") def year_range(self): try: self.year_range = self.share.get_change_from_year_high() self.log.info("{} year range change refreshed".format(self.name)) except: self.log.error("platform is offline or not connecting")
def main(FLAGS): logger = Logging() nn = network.Network() settings = Parameters() greed = Epsilon_Greedy() replay = Replay() #X_state, actor_q_values, actor_vars, critic_..., copy_ops, copy_critic... X_state = tf.placeholder(tf.float32, shape=[ None, settings.input_height, settings.input_width, settings.input_channels ]) #setup both an actor and a 'critic' network -- methodology to predict and play as cost function (y-y') actor_q_values, actor_vars = nn.q_network(X_state, name='q_networks/actor') critic_q_values, critic_vars = nn.q_network(X_state, name='q_networks/critic') copy_ops = [ actor_var.assign(critic_vars[var_name]) for var_name, actor_var in actor_vars.items() ] copy_critic_to_actor = tf.group(*copy_ops) #x_action, q_value X_action = tf.placeholder(tf.int32, shape=[None]) q_value = tf.reduce_sum(critic_q_values * tf.one_hot(X_action, settings.n_outputs), axis=1, keep_dims=True) #y, cost, globalstep, optimzier, training_op, init, saver y = tf.placeholder(tf.float32, shape=[None, 1]) cost = tf.reduce_mean(tf.square(y - q_value)) global_step = tf.Variable(0, trainable=False, name='global_step') optimizer = tf.train.AdamOptimizer(settings.learning_rate) training_op = optimizer.minimize(cost, global_step=global_step) init = tf.global_variables_initializer() saver = tf.train.Saver() logger.info('finished setup') #with tf.Session as sess: ********put this in driver with tf.Session() as sess: # check for saved session if os.path.isfile(settings.checkpoint_path): save.restore(sess, settings.checkpoint_path) else: init.run() while True: step = global_step.eval() if step >= settings.n_steps: break settings.iteration += 1 if settings.done: logger.info('uh oh hit the done!') settings.obs = settings.env.reset() #manufactured 'fast forward' for skip in range(settings.skip_start): obs, reward, settings.done, info = settings.env.step(0) state = network.preprocess_observation(obs, settings.mspacmancolor) #print(reward, settings.done, info) # vector of q values q_values = actor_q_values.eval(feed_dict={X_state: [state]}) # epsilon greedy method to retrieve next action action = greed.e_greedy(q_values, step) # take this action obs, reward, settings.done, info = settings.env.step(action) next_state = network.preprocess_observation( obs, settings.mspacmancolor) # record these actions in replay memory replay.replay_memory.append( (state, action, reward, next_state, 1.0 - settings.done)) state = next_state if settings.iteration < settings.training_start or settings.iteration % settings.training_interval != 0: continue X_state_val, X_action_val, rewards, X_next_state_val, continues = ( replay.sample_memories(settings.batch_size)) next_q_values = actor_q_values.eval( feed_dict={X_state: X_next_state_val}) max_next_q_values = np.max(next_q_values, axis=1, keepdims=True) y_val = rewards + continues * settings.discount_rate * max_next_q_values training_op.run(feed_dict={ X_state: X_state_val, X_action: X_action_val, y: y_val }) if step % settings.copy_steps == 0: #logger.info('copy to critic') copy_critic_to_actor.run() if step % settings.save_steps == 0: logger.info('saving settings of iteration %g' % (settings.iteration)) logger.results('action, reward, done, info: ') print(action, reward, settings.done, info) saver.save(sess, settings.checkpoint_path) logger.info('saving settings of iteration %g' % (settings.iteration)) logger.results('action, reward, done, info:') print(action, reward, settings.done, info) logger.info('program finished')
class setting_handler(Singleton): def __init__(self): try: if self.loadingdone: pass except: self.loadingdone = True self.name = "setting_handler" self.database = main_database() self.logging = Logging() self.http = urllib3.PoolManager() self.settings = {} #self.settings["main_page"] = ["Front page", ["OpenHAB", "Weather"]] self.settings["screen_timeout"] = [ "Screen timeout (min)", [1, 3, 5, 10, 15, 30, "off"] ] self.settings["album_timeout"] = [ "Album timeout (hr)", [1, 3, 5, 10, 15, 30] ] self.settings["message_timeout"] = [ "Message timeout (s)", [10, 30, 60, 120, 300] ] self.settings["toast_timeout"] = [ "Info timeout (s)", [7, 10, 15, 20, 30] ] self.settings["mouse"] = ["Mouse button", ["on", "off"]] self.settings["items_per_page"] = [ "Number of items per page", [6, 8, 9, 12] ] self.settings["sensors_per_page"] = [ "Number of sensor items per page", [6, 8, 9, 12] ] self.settings["screen"] = ["Screen", ["on", "off"]] self.settings["frame"] = ["Photo / Clock", ["photoframe", "clock"]] self.settings["frame_info"] = [ "Frame Info", ["none", "load", "album", "both"] ] self.settings["frame_td"] = [ "Frame Time/Date", ["none", "clock", "date", "both"] ] self.settings["frame_display_time"] = [ "Photo display time", ["short", "medium", "long", "extra long"] ] self.settings["clock_type"] = ["Clock type", ["digital", "analog"]] self.settings["chart_period"] = [ "Default chart period", ["auto", "4 hours", "12 hours", "1 day", "3 days", "1 week"] ] for key, item in self.settings.items(): value = self.database.data["settings"][key] self.settings[key].append(int(value)) settings_c = Settings() self.enable_screen_control = settings_c.get_setting( "main", "enable_screen_control") try: topics = settings_c.get_setting( "main", "mqtt_control_topic").split(",") self.mqtt = mqtt() for topic in topics: self.mqtt.add_listener(topic, self, "received_mqtt_message") except: self.logging.warn("Mqtt not configured for handling settings", location="settings_handler") if self.enable_screen_control in ["pi", "black"]: pass elif self.enable_screen_control == "url": try: self.screen_control_on_url = settings_c.get_setting( "main", "screen_on_url") self.screen_control_off_url = settings_c.get_setting( "main", "screen_off_url") self.settings["screen_control_on_url"] = [ 0, 0, self.screen_control_on_url ] self.settings["screen_control_off_url"] = [ 0, 0, self.screen_control_off_url ] except: self.logging.error( "Add settings 'screen_on_url' and 'screen_off_url' for external url screen control", location="settings_handler") self.enable_screen_control = "black" elif self.enable_screen_control == "cmd": try: self.screen_control_on_cmd = settings_c.get_setting( "main", "screen_on_cmd") self.screen_control_off_cmd = settings_c.get_setting( "main", "screen_off_cmd") self.settings["screen_control_on_cmd"] = [ 0, 0, self.screen_control_on_cmd ] self.settings["screen_control_off_cmd"] = [ 0, 0, self.screen_control_off_cmd ] except: self.logging.error( "Add settings 'screen_on_cmd' and 'screen_off_cmd' for external command screen control", location="settings_handler") self.enable_screen_control = "black" elif self.enable_screen_control != "off": self.logging.error( "Incorrect screen control enable settings, screen control is off", location="settings_handler") self.enable_screen_control = "off" self.settings["main_enable_clock"] = [ 0, 0, settings_c.get_setting("main", "enable_clock") ] self.settings["main_enable_album"] = [ 0, 0, settings_c.get_setting("main", "enable_album") ] if settings_c.get_setting("main", "enable_album") == "0": self.logging.warn("Album not enabled, setting frame to clock", location="settings_handler") self.__set_setting("frame", "clock") elif settings_c.get_setting("main", "enable_clock") == "0": self.logging.warn( "clock not enabled, setting frame to photoframe", location="settings_handler") self.__set_setting("frame", "photoframe") if settings_c.get_setting( "main", "enable_clock") == "0" and settings_c.get_setting( "main", "enable_album") == "0": self.logging.warn( "Album and clock not enabled, turning off screen setting", location="settings_handler") self.__set_setting( "screen", "off" ) ##in this case only the screensaver determines if the screen is turned on or off self.settings["main_screen_control"] = [ 0, 0, self.enable_screen_control ] def get_name(self): return self.name def setting_request(self, request): if request[0] == "setsetting": setting = request[1] if setting == "screen" and self.get_setting( "main_enable_album") == "0" and self.get_setting( "main_enable_clock") == "0": return [ "Enable album or clock to be able to control this setting" ] if setting == "frame" and ( self.get_setting("main_enable_album") == "0" or self.get_setting("main_enable_clock") == "0"): return [ "Enable album and clock to be able to control this setting" ] cur_value = self.settings[setting][2] if cur_value + 1 < len(self.settings[setting][1]): self.settings[setting][2] = cur_value + 1 else: self.settings[setting][2] = 0 self.save_settings() self.logging.write( self.settings[setting][0] + ": " + str(self.settings[setting][1][self.settings[setting][2]]), level=2) return [ self.settings[setting][0] + ": " + str(self.settings[setting][1][self.settings[setting][2]]) ] elif request[0] == "getsetting": return [str(self.get_setting(request[1]))] def set_setting(self, setting, value): if setting == "screen" and self.get_setting( "main_enable_album") == "0" and self.get_setting( "main_enable_clock") == "0": return ["Enable album or clock to be able to control this setting"] if setting == "frame" and (self.get_setting("main_enable_album") == "0" or self.get_setting("main_enable_clock") == "0"): return [ "Enable album and clock to be able to control this setting" ] self.__set_setting(setting, value) def __set_setting(self, setting, value): values = self.settings[setting][1] self.screen_timeout_start = time.time() for i in range(len(values)): if values[i] == value: self.settings[setting][2] = i self.save_settings() def get_settings(self): settings = [] for key, item in self.settings.items(): if (key == "clock_type" ) and self.get_setting("main_enable_clock") == "0": pass elif (key == "album_timeout" or key == "frame_info" or key == "frame_td" or key == "frame_display_time" ) and self.get_setting("main_enable_album") == "0": pass elif key == "frame" and ( self.get_setting("main_enable_album") == "0" or self.get_setting("main_enable_clock") == "0"): pass elif key == "screen" and self.get_setting( "main_enable_album") == "0" and self.get_setting( "main_enable_clock") == "0": pass elif key == "screen" and self.enable_screen_control == "off": pass elif item[0] != 0: settings.append([key, item[0], item[1][item[2]]]) return settings def save_settings(self): for key, item in self.settings.items(): self.database.data["settings"][key] = item[2] self.database.save_datafile() def get_setting(self, setting): value = self.settings[setting][2] if self.settings[setting][0] != 0: return self.translate_setting(setting, self.settings[setting][1][value]) else: return value def translate_setting(self, setting, value): if setting == "frame_display_time": timing = { "short": 5000, "medium": 13000, "long": 20000, "extra long": 60000 } if value == 0: return "short" return timing[value] elif setting == "chart_period": period = { "auto": "auto", "4 hours": "4H", "12 hours": "12H", "1 day": "1D", "3 days": "3D", "1 week": "1W" } if value == 0: return "auto" return period[value] return value def received_mqtt_message(self, topic, payload): try: payload_setting = payload['setting'] for setting in self.settings: if setting == payload_setting: if "cmd" in topic.lower(): self.set_setting(setting, payload[setting]) self.logging.info( "Set setting via mqtt message: %s, %s" % (setting, payload[setting]), location="settings_handler") elif "state" in topic.lower(): val = self.get_setting(setting) topic = topic[0:topic.rfind("/") + 1] + "status" self.mqtt.publish( topic, str({ 'setting': setting, 'value': val })) if payload_setting == "all": topic = topic[0:topic.rfind("/") + 1] + "status" self.mqtt.publish(topic, str(list(self.settings.keys()))) except Exception as e: raise Exception(e)
class mqtt(Singleton): def __init__(self): try: if self.loadingdone: pass except: self.loadingdone = True self.started = True self.logging = Logging() self.name = "mqtt" self.settings_c = Settings() try: self.server = self.settings_c.get_setting("mqtt", "server") self.port = int(self.settings_c.get_setting("mqtt", "port")) self.timeout = int( self.settings_c.get_setting("mqtt", "timeout")) except Exception as e: self.logging.error("Configuration not correct, check settings", location=self.name) self.listeners = [] self.client = mqtt_cl.Client() self.client.on_connect = self.on_connect self.client.on_message = self.on_message self.client.connect(self.server, self.port, self.timeout) self.client.loop_start() self.logging.info("Connected to mqtt broker at: " + self.server, location=self.name) def on_connect(self, client, userdata, flags, rc): self.logging.info("Resubscribing for all listeners at " + self.server, location=self.name) for listen in self.listeners: self.client.subscribe(listen[0]) def on_message(self, client, userdata, msg): self.logging.info("Received message: " + msg.topic + " " + str(msg.payload), location=self.name) if self.started: for listen in self.listeners: topic = listen[0][0:-1] if msg.topic.find(topic) != -1: self.logging.debug("Topic match for %s at %s" % (listen[1].get_name(), listen[0]), location=self.name) try: data = ast.literal_eval(msg.payload.decode("utf-8")) except: data = msg.payload.decode("utf-8") try: p = getattr(listen[1], listen[2]) p(msg.topic, data) except Exception as e: self.logging.error("Error executing: " + str(e), location=self.name) def add_listener(self, topic, class_item, functionname): self.listeners.append([topic, class_item, functionname]) self.client.subscribe(topic) try: name = class_item.get_name() except: name = "unknown" self.logging.info("Added listener for %s at %s" % (name, topic), location=self.name) def publish(self, topic, payload): self.logging.info("Publish %s, %s " % (topic, str(payload)), location=self.name) self.client.publish(topic, payload)
class state_handler(Singleton): def __init__(self): try: if self.loadingdone: pass except: self.loadingdone = True self.openhab = pf_openhab() self.name = "state_handler" self.database = main_database() self.setting_handler = setting_handler() self.message_handler = message_handler() self.logging = Logging() settings_c = Settings() self.host = settings_c.get_setting("main", "hostname") self.port = settings_c.get_setting("main", "port") self.http = urllib3.PoolManager() self.timeouts = {} self.update_timeout("screensaver", 60) self.update_timeout("message", -1) self.screentrigger = 0 self.screen_state = True try: self.im_size = settings_c.get_setting("album", "image_size") self.album_url = settings_c.get_setting("album", "random_picture_url") except Exception as e: self.logging.error("Invalid album settings: " + str(e), location=self.name) self.album_url = "none" try: self.album_info_url = settings_c.get_setting("album", "picture_info_url") if self.album_info_url == None: raise Exception("No data") except: self.logging.warn("No album info url", location=self.name) self.album_info_url = "none" def state_request(self, request): action = request[0] if len(request) > 1: item = request[1] ##handle a button press per type of item: #print(item) if action == "photoframe": if item == "frame": ans = self.setting_handler.set_setting("frame", request[2]) if ans != None: return ans[0] return "Setting saved" elif item == "screen": ans = self.setting_handler.set_setting("screen", request[2]) if ans != None: return ans[0] return "Setting saved" elif item == "trigger": self.screentrigger = time.time() self.refresh_screensaver() self.logging.info("Triggered frame on externally", location=self.name) return "Screen triggered" else: return "none_none" elif action == "icon": icon = self.openhab.get_icon(item) return ["jpg", icon] elif action == "picture": try: if item == "new" and self.album_url != "none": response = requests.get(self.album_url) with Image.open(BytesIO(response.content)) as image: imgByteArr = BytesIO() cover = Image.Image.resize(image, [int(self.im_size.split("x")[0]), int(self.im_size.split("x")[1])]) cover.save(imgByteArr, image.format) return ["jpg", imgByteArr.getvalue()] elif item == "info" and self.album_info_url != "none" and self.album_info_url != "": content = self.http.request('GET', self.album_info_url) return content.data.decode("utf-8") elif item == "info": return "no album info" except Exception as e: self.logging.error("Error occured in processing picture for album %s" %e, location=self.name) return "error" def state_check(self, request): page = [] main_page = request[0] subpage = "none" if len(request) > 1: subpage = request[1] ## get used settings setting_album_timeout = self.setting_handler.get_setting("album_timeout") ##not used setting_popup_timeout = self.setting_handler.get_setting("message_timeout") setting_screen_user = self.setting_handler.get_setting("screen") ##screen on or off main_setting_screen_control = self.setting_handler.get_setting("main_screen_control") current_screen_state = self.get_screen_state() screensaver_page = self.get_screensaver_page() desired_screen_state = "off" desired_page = "unchanged" ##reset old screen trigger if self.screentrigger != 0 and time.time() > self.screentrigger + 5*60: self.screentrigger = 0 ##calculate desired screen state (on / off) ##switching is done depending on configuration if main_page in ["main", "settings", "messages"]: if self.check_timeout("screensaver") and setting_screen_user == "off": desired_screen_state = "off" else: desired_screen_state = "on" elif main_page in ["photoframe", "clock", "black"]: desired_screen_state = setting_screen_user ## check desired screen state for messages self.logging.debug("Unread messages: %s" %(str(self.message_handler.check_unread())), location=self.name) self.logging.debug("Popup flag: %s" %(str(self.message_handler.get_popup_flag())), location=self.name) if self.message_handler.check_unread() and not self.message_handler.get_popup_flag(): self.message_handler.set_popup_active(True) self.message_handler.set_popup_flag() self.logging.info("responding new message", location=self.name) desired_screen_state = "on" new_message = True ###turn on screen and make popup elif not self.check_timeout("message"): desired_screen_state = "on" ##keep screen on for message new_message = False else: new_message = False ##calculate desired page (main, black, album or clock) ##switching is done depending on configuration if main_page in ["main", "settings", "messages"]: if self.check_timeout("screensaver") and setting_screen_user == "on" and screensaver_page != "main": desired_page = screensaver_page elif main_page == "photoframe" and screensaver_page != "album": desired_page = screensaver_page elif main_page == "clock" and screensaver_page != "clock": desired_page = screensaver_page elif main_page == "black" and setting_screen_user == "on": desired_page = screensaver_page self.logging.debug("Show new messages: %s" %(str(new_message)), location=self.name) self.logging.debug("Screensaver page: %s" %(screensaver_page), location=self.name) self.logging.debug("Desired page: %s, desired_screen_state: %s" %(desired_page, desired_screen_state), location=self.name) self.logging.debug("Message timeout: %s, Subpage timeout: %s" %(self.check_timeout("message"), self.check_timeout("screensaver_subpage")), location=self.name) ## switch screen off is desired state is off if desired_screen_state == "off" and main_setting_screen_control != "off" and current_screen_state: ##=="on" return self.switch_off_screen(main_setting_screen_control) elif desired_screen_state == "off" and current_screen_state: ##=="on" link = self.get_desired_page_link("clock") return [link] elif self.screentrigger != 0: self.toggle_screen(state = True) self.screentrigger = 0 self.refresh_screensaver() self.logging.info("turn on screen for trigger", location=self.name) return ["close_return_main"] ##actions when we want the screen on elif new_message: if not current_screen_state: self.toggle_screen(state = "on") ##no need for a page change self.update_timeout("message", self.setting_handler.get_setting("message_timeout") + 2) ##in seconds return ["new_message"] elif self.message_handler.check_toast(): ##even if the screen is off self.logging.write("responding new toast message", level=2, location="item_handle") return ["new_toast"] elif desired_screen_state == "on" and desired_page != "unchanged" and self.check_timeout("message"): ##except when there is a message popup self.toggle_screen(state = setting_screen_user) link = self.get_desired_page_link(desired_page) return [link] elif self.check_timeout("screensaver_subpage") and self.check_timeout("message") and main_page not in ["photoframe", "clock"]: ##except when there is a message popup self.delete_timeout("screensaver_subpage") return ["close_return_main"] elif self.check_timeout("screensaver_subpage") and self.check_timeout("message"): self.delete_timeout("screensaver_subpage") ##if for some reason it end here; return ["no_actionHERE"] def switch_off_screen(self, main_setting_screen_control): self.toggle_screen(state = "off") if main_setting_screen_control == "black": link = self.get_desired_page_link("black") return [link] else: link = self.get_desired_page_link("main") return [link] def get_screensaver_page(self): enable_clock = self.setting_handler.get_setting("main_enable_clock") enable_album = self.setting_handler.get_setting("main_enable_album") setting_album_clock = self.setting_handler.get_setting("frame") ##photoframe or clock when screen is on if enable_album == "1" and setting_album_clock == "photoframe": return "album" elif enable_clock == "1" and setting_album_clock == "clock": return "clock" else: return "main" def get_desired_page_link(self, page): if page == "album": self.logging.info("http://"+self.host+":"+self.port+"/page/photoframe", location=self.name) return "http://"+self.host+":"+self.port+"/page/photoframe" elif page == "clock": type_clock = self.setting_handler.get_setting("clock_type") self.logging.info("http://"+self.host+":"+self.port+"/page/clock/"+type_clock, location=self.name) return "http://"+self.host+":"+self.port+"/page/clock/"+type_clock elif page == "main": main_setting_screen_control = self.setting_handler.enable_screen_control self.logging.info("External screen control: %s, no action, stay on main page" %main_setting_screen_control, location=self.name) return "http://"+self.host+":"+self.port+"/page/maindiv/screensaver" elif page == "black": self.logging.write("http://"+self.host+":"+self.port+"/black", level=2) return "http://"+self.host+":"+self.port+"/page/black" def update_timeout(self, name, delta): ##delta in seconds self.timeouts[name] = time.time() + delta def check_timeout(self, name): if name in self.timeouts: self.logging.debug(("Timeout %s: "%name).ljust(30) + str(time.ctime(int(self.timeouts[name]))), location=self.name) if self.timeouts[name] < time.time(): return True else: return False else: return False def delete_timeout(self, name): if name in self.timeouts: del self.timeouts[name] else: self.logging.debug("Timeout %s not deleted, not existing" %name, location=self.name) def refresh_screensaver(self): to = self.setting_handler.get_setting("screen_timeout") if to == "off": to = 24*60*300 self.logging.info("refreshing screensaver", location=self.name) self.update_timeout("screensaver", int(to)*60) self.delete_timeout("screensaver_subpage") def refresh_screensaver_subpage(self): self.refresh_screensaver() self.logging.info("refreshing screensaver for popup", location=self.name) self.update_timeout("screensaver_subpage", 25) def toggle_screen(self, state = True): screen_control = self.setting_handler.get_setting("main_screen_control") switch = False if str(self.screen_state) != str(state): self.logging.info("Switching screen state: %s, %s" %(str(self.screen_state), str(state)), location=self.name) else: self.logging.debug("Switching screen state: %s, %s" %(str(self.screen_state), str(state)), location=self.name) if (state == "off" or state == "0" or state == False) and self.get_screen_state() == True: state = False self.screen_state = False switch = True elif (state == "on" or state == "1" or state == True) and self.get_screen_state() == False: state = True self.screen_state = True switch = True if screen_control == "pi": if not state: self.logging.write("Turn off screen", level=2) cmd = "echo 1 > /sys/class/backlight/rpi_backlight/bl_power" os.system(cmd) else: self.logging.write("Turn on screen", level=2) cmd = "echo 0 > /sys/class/backlight/rpi_backlight/bl_power" os.system(cmd) elif screen_control == "url" and switch: if not state: self.logging.info("Turn off screen via url", location=self.name) url = self.setting_handler.get_setting("screen_control_off_url") else: self.logging.info("Turn on screen via url", location=self.name) url = self.setting_handler.get_setting("screen_control_on_url") self.logging.debug("Screensaver url: %s" %url, location=self.name) self.http.request('GET', url) elif screen_control == "cmd" and switch: if not state: self.logging.info("Turn off screen via cmd", location=self.name) cmd = self.setting_handler.get_setting("screen_control_off_cmd") else: self.logging.info("Turn on screen via cmd", location=self.name) cmd = self.setting_handler.get_setting("screen_control_on_cmd") self.logging.debug("Screensaver cmd: %s" %cmd, location=self.name) os.system(cmd) def get_screen_state(self): return self.screen_state
class message_handler(Singleton): def __init__(self): try: if self.loadingdone: pass except: self.loadingdone = True self.database = main_database() self.popupflag = False self.popupactive = False self.logging = Logging() self.setting_handler = setting_handler() self.setting_popup_timeout = self.setting_handler.get_setting( "message_timeout") self.page_handler = page_handler.page_handler() self.toast_flag = False self.toast_db = [] self.toast_message = "none" self.toast_sender = "none" self.toast_received = 0 self.mqtt = mqtt() settings_c = Settings() self.mqtt_topics = settings_c.get_setting("messaging", "mqtt_topics").split(",") for topic in self.mqtt_topics: self.mqtt.add_listener(topic, self, "received_mqtt_message") ##send information messages on first run if not self.database.data["settings"]["first_run_messages_flag"]: self.database.data["settings"][ "first_run_messages_flag"] = True message = "On a black screen, clock or photoframe, click on the bottom left corner to return to the main screen. " self.database.data["messages"].append([ time.time(), "HABframe", "Return from screensaver", message, False ]) message = "Thank you for using HABframe!" self.database.data["messages"].append([ time.time(), "HABframe", "welcome message", message, False ]) self.database.save_datafile() self.del_popup_flag() def get_name(self): return "message_handler" def message_request(self, request, data_get): if request[0] == "new": try: if "message" in data_get: message = data_get["message"].replace("@20", "/").replace( "%3B", ":") else: message = request[2].replace("@20", "/").replace("%3B", ":") if "sender" in data_get: sender = data_get["sender"] else: sender = request[1] if "subject" in data_get: subject = data_get["subject"] else: subject = "-" self.new_message(sender, subject, message) return ["Message received"] except Exception as e: self.logging.error("Error in message: " + str(e), location="messages") return ["Invalid new message"] elif request[0] == "message_popup": i = 0 found = False while i < len(self.database.data["messages"]) and not found: message = self.database.data["messages"][i] if not message[-1]: show_message = [i] + message #we want the last unread message #found = True i += 1 n_unread = self.check_amount_unread() times = datetime.datetime.fromtimestamp(float( show_message[1])).strftime('%a %d-%m, %H:%M') return self.page_handler.create_popup("message", { "id": show_message[0], "from": show_message[2], "time": times, "message": show_message[4], "subject": show_message[3], "n_unread": n_unread }, renew_screensaver=False) elif request[0] == "markread_popup": message_id = int(request[1]) self.logging.info("Marking message as read " + str(message_id), location="messages") self.database.data["messages"][message_id][-1] = True self.database.save_datafile() self.popupactive = False self.del_popup_flag() return ["Marked as read"] elif request[0] == "markallread_popup": message_id = int(request[1]) self.logging.info("Marking all messages as read ", location="messages") for i in range(len(self.database.data["messages"])): self.database.data["messages"][i][-1] = True self.database.save_datafile() self.popupactive = False self.del_popup_flag() return ["Marked as read"] elif request[0] == "message_timeout": timeout = self.setting_handler.get_setting("message_timeout") return [str(timeout)] elif request[0] == "toast_timeout": timeout = self.setting_handler.get_setting("toast_timeout") return [str(timeout)] elif request[0] == "delete_popup": message_id = int(request[1]) del (self.database.data["messages"][message_id]) self.logging.info("Deleting message: " + str(message_id), location="messages") if len(self.database.data["messages"]) == 0: self.database.data["messages"] = [] #self.database.data["messages"].append([time.time(), "none", "message database is empty", True]) self.database.save_datafile() self.popupactive = False self.del_popup_flag() return ["Message deleted"] elif request[0] == "deactivate_popup": self.popupactive = False return ["popup deactive"] elif request[0] == "showmessage": message_id = int(request[1]) return self.format_message(message_id=message_id) elif request[0] == "deletemessage": if request[1] == "all": self.database.data["messages"] = [] #self.database.data["messages"].append([time.time(), "none", "message database is empty", True]) else: message_id = int(request[1]) del (self.database.data["messages"][message_id]) self.logging.info("Deleting message: " + str(message_id), location="messages") if len(self.database.data["messages"]) == 0: self.database.data["messages"] = [] #self.database.data["messages"].append([time.time(), "none", "message database is empty", True]) self.database.save_datafile() return self.format_message_list(start=0) elif request[0] == "showmessagepage": message_id = int(request[1]) return self.format_message_list(start=message_id) elif request[0] == "toast": if "message" in data_get: self.toast_message = data_get["message"].replace( "@20", "/").replace("%3B", ":") else: self.toast_message = request[2].replace("@20", "/").replace( "%3B", ":") if "sender" in data_get: self.toast_sender = data_get["sender"].replace("@20", "/").replace( "%3B", ":") else: self.toast_sender = request[1].replace("@20", "/").replace( "%3B", ":") self.logging.debug("Received new toast message from http", location="messages") self.new_toast() return ["Toast received"] elif request[0] == "get_toast": return self.create_toast(len_max=31) def new_message(self, sender, subject, message): self.database.data["messages"].append( [time.time(), sender, subject, message, False]) self.database.save_datafile() self.del_popup_flag() ##popup flag when a popup was activated self.logging.write("Received new message from " + sender + ": " + message, level="info", location="messages") def new_toast(self): self.toast_received = time.time() self.toast_db.append( [self.toast_sender, self.toast_message, time.time(), False, 0]) self.logging.info("Received new toast message: " + self.toast_message, location="messages") def create_toast(self, len_max): toast = self.get_toast_message() data = { "text": toast[0], "from": toast[1], "len": len(toast[0]), "max": len_max } return self.page_handler.create_popup("toast", data=data, renew_screensaver=False) def get_messages(self): messages = [] for i in reversed(range(len(self.database.data["messages"]))): m = self.database.data["messages"][i] messages.append({ "id": i, "date": m[0], "from": m[1], "subject": m[2], "message": m[3] }) return messages def check_amount_unread(self): unread = 0 for message in self.database.data["messages"]: if not message[-1]: unread += 1 return unread def check_unread(self): unread = False for message in self.database.data["messages"]: if not message[-1]: unread = True return unread def get_popup_flag( self ): ##The popup flag is set when a new message has generated a popup return self.popupflag def set_popup_flag(self): self.logging.write("Setting popup flag", level="warn", location="messages") self.popupflag = True def del_popup_flag(self): ##Only a new message can delete a popup if self.popupflag: self.logging.write("Removing popup flag", level="warn", location="messages") self.popupflag = False def get_popup_active(self): if time.time( ) > self.popup_time_activated + self.setting_popup_timeout + 1: ##seconds return False else: return True def set_popup_active(self, state): self.popup_time_activated = time.time() def check_toast(self): #print("=========================, checking toast") timeout = self.setting_handler.get_setting("toast_timeout") new_toast = False last_toast_send = 0 for i in range(len(self.toast_db)): if self.toast_db[i][3]: last_toast_send = self.toast_db[i][4] if self.toast_db[i][2] < time.time() - 600: self.toast_db[i][3] = True if not self.toast_db[i][3]: new_toast = True if len(self.toast_db) > 50: del self.toast_db[0:25] if self.toast_received > time.time( ) - 600 and new_toast and last_toast_send < time.time() - timeout - 3: return True else: return False def get_toast_message(self): ##return the first unread toast message for i in range(len(self.toast_db)): if not self.toast_db[i][3]: ##toast is unread self.toast_db[i][3] = True self.toast_db[i][4] = time.time() self.logging.write("Sending toast message: " + self.toast_db[i][0] + " / " + self.toast_db[i][1], level=2, location="messages") return [self.toast_db[i][1], self.toast_db[i][0]] self.logging.write("No unread toast message, sending last one: " + self.toast_message + " / " + self.toast_sender, level="warning", location="messages") return [self.toast_message, self.toast_sender] def format_message_list(self, start=0): messages = self.get_messages() page_data = {"next_page": False, "prev_page": False, "messages": []} try: start_page = int(start) except: start_page = 0 if start_page == 0: start_message = 0 stop_message = 6 else: page_data["prev_page"] = start_page start_message = start_page * 5 + 1 stop_message = start_page * 5 + 6 n_messages = len(messages) if stop_message >= n_messages: stop_message = n_messages else: page_data["next_page"] = start_page + 1 for i in range(start_message, stop_message): messages[i]["date"] = datetime.datetime.fromtimestamp( messages[i]["date"]).strftime('%a %d-%m, %H:%M') page_data["messages"].append(messages[i]) return render_template("message_list.html", data=page_data) def format_message(self, message_id=0): messages = self.get_messages() if message_id == -1: message_id = len(messages) - 1 if len(messages) > 0: for m in messages: if m["id"] == message_id: message = m message["date"] = datetime.datetime.fromtimestamp( message["date"]).strftime('%a %d-%m, %H:%M') else: message = {"date": "", "message": "No messages", "from": ""} if len(messages) > 0 and message["subject"] == "-": message["subject"] = message["date"] return render_template("message.html", data=message) def received_mqtt_message(self, topic, payload): try: message = payload['message'] if "message" in topic.lower(): t = "message" elif "toast" in topic.lower(): t = "toast" else: try: t = payload['type'] except: t = 'message' try: sender = payload['sender'] except: sender = "unknown" if t == "message": subject = payload['subject'] self.new_message(sender, subject, message) else: self.toast_sender = sender self.toast_message = message self.new_toast() except Exception as e: raise Exception(e)
class page_handler(): def __init__(self): self.openhab = pf_openhab() self.name = "page_handler" self.database = main_database() self.setting_handler = setting_handler() self.message_handler = message_handler() self.widgets_handler = widgets_handler() self.state_handler = state_handler() self.logging = Logging() settings_c = Settings() self.host = settings_c.get_setting("main", "hostname") self.port = settings_c.get_setting("main", "port") self.enable_screen_control = settings_c.get_setting( "main", "enable_screen_control") self.openhab_host = settings_c.get_setting("main", "openhab_ip") self.openhab_port = settings_c.get_setting("main", "openhab_port") def get_page(self, request): pagelist = request["page"] dataget = request["data_get"] page = [] lowerpage = [0] if len(pagelist) > 3: lowerpage = pagelist[3:] subsubpage = pagelist[2] subpage = pagelist[1] elif len(pagelist) > 2: subsubpage = pagelist[2] subpage = pagelist[1] elif len(pagelist) > 1: subpage = pagelist[1] subsubpage = "none" else: subsubpage = "none" subpage = "none" pagename = pagelist[0] if pagename == "main": self.logging.info("Loading main page: " + subpage + "/" + subsubpage, location=self.name) if self.message_handler.get_popup_flag() and subpage != "reload": self.message_handler.del_popup_flag() self.state_handler.toggle_screen(state=True) self.state_handler.refresh_screensaver() return self.create_main_page() elif pagename == "maindiv": self.logging.info("Loading main div: " + subpage + "/" + subsubpage, location=self.name) ##turn on screen if subpage != "screensaver": self.state_handler.toggle_screen(state=True) if not "reload" in pagelist and not "screensaver" in pagelist: ##enable popup of message when there is a new message self.message_handler.del_popup_flag() self.state_handler.refresh_screensaver() if subpage not in [ "none", "popup", "", "reload", "screensaver" ]: self.state_handler.refresh_screensaver_subpage() else: self.logging.info("Not refreshing screensaver", location=self.name) if subpage in ["none", "popup", "", "reload", "screensaver"]: return self.create_main_div() elif subpage == "settings": return self.create_settings_page(subpage=subsubpage) elif subpage == "messages": return self.create_messages_page() else: if subsubpage == "reload": subsubpage = 0 if lowerpage[0] == "reload": lowerpage = [0] return self.create_subpage(subpage, subsubpage, lowerpage[0]) elif pagename == "menuwidget": self.logging.write("Loading menu widget: " + subpage + "/" + subsubpage, level=2, location=self.name) if not "reload" in pagelist and not "screensaver" in pagelist: self.state_handler.toggle_screen(state=True) self.state_handler.refresh_screensaver_subpage() try: widget, title = self.widgets_handler.create_mainpage_popup( subpage, lowerpage[0], True) except: widget = "gotomain" title = "none" page_format = {"title": title} page = render_template("subpage_widget.html", data=page_format) page = page.replace("[[WIDGET]]", widget) if (str(lowerpage) != "0" and str(lowerpage)[0:2] != "m_") and subpage not in [ "none", "items_left", "items_right" ]: d = self.openhab.get_items(subpage) pos = 0 for i in range(len(d[0])): b = d[0][i] if b["type"] == "Frame" and b["label"] == lowerpage[0]: pos = i N_items_pp, sensor_page = self._getNitemsPP(d[1], False) rb = "%s/%d" % (subpage, int(pos / N_items_pp)) else: rb = False page = self.add_bottom_bar(page, rb) if widget == "widget not in sitemap": return "widget not in sitemap" elif widget == "gotomain": return widget else: return page elif pagename == "popup": ##this is a popup widget self.logging.write("Loading popup div: " + subpage + "/" + subsubpage, level=2, location=self.name) if not "reload" in pagelist and not "screensaver" in pagelist: self.state_handler.toggle_screen(state=True) self.state_handler.refresh_screensaver_subpage() page = self.widgets_handler.create_mainpage_popup( subpage, subsubpage) if page == "generic_button_page": return self.create_subpage(subpage, 0, subsubpage, True) elif page == "widget not in sitemap": return "widget not in sitemap" else: return page elif pagename in ["clock", "black"]: cl = self.setting_handler.get_setting("clock_type") return render_template("clock.html", data={"type_clock": cl}) elif pagename == "clk_widget": return self.get_clock_page_widget() elif pagename == "photoframe": return self.create_photoframe() pagestr = "" for i in range(len(page)): pagestr = pagestr + page[i] + "\n" return pagestr def read_file(self, filename): PATH = os.path.dirname(os.path.abspath(__file__)) with open(PATH + "/../" + filename) as f: content = f.readlines() content = [x.strip() for x in content] return content def create_main_page(self): page_data = {} page_data["host"] = [self.host, self.port] settings_c = Settings() page_data["mouse"] = self.setting_handler.get_setting("mouse") page_data["event_reload"] = settings_c.get_setting( "page", "event_check_reload") page_data["page_reload"] = settings_c.get_setting( "page", "page_reload") page_data["enable_album"] = settings_c.get_setting( "main", "enable_album") if settings_c.get_setting("main", "enable_album") == "1": page_data["album_display_time"] = self.setting_handler.get_setting( "frame_display_time") return render_template("main.html", data=page_data) def get_clock_page_widget(self): ml = self.openhab.get_items("clock_page")[0] data = [] if len(ml) > 0: itemdata = ml[0] itemdata.update({"onclick": ""}) itemtype = self.widgets_handler.check_widget_type( itemdata["label"]) if itemtype[0:6] == "widget": ##special item takes 3 rows data.append(itemdata) data[-1]["group"] = itemtype[7:8] + "rows" data[-1]["label_c"] = itemdata["label"] data[-1]["label"] = self.widgets_handler.get_widget_label( itemdata["label"]).upper() if len(data) > 0: item = data[0] page = self.widgets_handler.render_widget("clock_page", item["label_c"]) return page return "" def create_main_div(self): ml = self.openhab.get_items("items_left")[0] page_data_ml = self.format_items_frontpage("items_left", ml) main_left = render_template("maindiv_half.html", data=page_data_ml) mr = self.openhab.get_items("items_right")[0] page_data_mr = self.format_items_frontpage("items_right", mr) main_right = render_template("maindiv_half.html", data=page_data_mr) page_data = {} page_data["bottom"] = self.openhab.get_pages("b_") page = render_template("maindiv.html", data=page_data) page = page.replace("[[MAINLEFT]]", main_left) page = page.replace("[[MAINRIGHT]]", main_right) for item in page_data_ml: if item["group"][1:] == "rows": page = page.replace( "[[%s]]" % item["label"].upper(), self.widgets_handler.render_widget("items_left", item["label_c"])) for item in page_data_mr: if item["group"][1:] == "rows": page = page.replace( "[[%s]]" % item["label"].upper(), self.widgets_handler.render_widget("items_right", item["label_c"])) return self.add_bottom_bar(page) def format_items_frontpage(self, name, itemdata): while len(itemdata) < 10: itemdata.append({ "label": "", "state": "", "type": "text", "id": "", "icon": "static/pictures/black.png" }) data = [] row = 1 item = 0 while row < 6: itemdata[item].update({"onclick": ""}) itemtype = self.widgets_handler.check_widget_type( itemdata[item]["label"]) if itemtype == "menu_button": ##this is a menu button itemdata[item].update({ "onclick": "reload_main_div('page/maindiv/" + name + "/0/" + itemdata[item]["label"] + "')" }) data.append(itemdata[item]) data[-1]["group"] = "menu_popup" data[-1]["label"] = self.widgets_handler.get_widget_label( itemdata[item]["label"]) if data[-1]["state"] != "": data[-1]["label"] = data[-1]["state"] item += 1 data[-1]["fontsize"] = self.determine_text_size( data[-1]["label"], max_len=13, start_font="xlargefont") elif itemtype == "widget_subpage": ##this is a menu button itemdata[item].update({ "onclick": "reload_main_div('/page/menuwidget/" + name + "/0/" + itemdata[item]["label"] + "')" }) data.append(itemdata[item]) data[-1]["group"] = "menu_popup" data[-1]["label"] = self.widgets_handler.get_widget_label( itemdata[item]["label"]) if data[-1]["state"] != "": data[-1]["label"] = data[-1]["state"] item += 1 data[-1]["fontsize"] = self.determine_text_size( data[-1]["label"], max_len=13, start_font="xlargefont") elif itemtype == "menu_popup" or itemtype == "widget_popup": ##this is a menu button itemdata[item].update({ "onclick": "frontpage_action('" + name + "', '" + itemdata[item]["label"] + "')" }) data.append(itemdata[item]) data[-1]["group"] = "menu_popup" data[-1]["label"] = self.widgets_handler.get_widget_label( itemdata[item]["label"]) if data[-1]["state"] != "": data[-1]["label"] = data[-1]["state"] item += 1 data[-1]["fontsize"] = self.determine_text_size( data[-1]["label"], max_len=13, start_font="xlargefont") elif itemtype[0:6] == "widget" and row < 6 - int( itemtype[7:8]) + 1: ##special item takes 3 rows data.append(itemdata[item]) data[-1]["group"] = itemtype[7:8] + "rows" data[-1]["label_c"] = itemdata[item]["label"] data[-1]["label"] = self.widgets_handler.get_widget_label( itemdata[item]["label"]).upper() item += 1 row += int(itemtype[7:8]) - 1 elif itemtype[0:6] == "widget": ## skip this item item += 1 row -= 1 else: col = 0 data.append({"data": [0, 0], "group": "cols"}) while col < 2: itemtype = self.widgets_handler.check_widget_type( itemdata[item]["label"]) if itemdata[item]["type"] == "Text": data[-1]["data"][col] = itemdata[item] data[-1]["data"][col]["group"] = "text" item += 1 elif itemtype in ["menu_button", "menu_popup"] or itemtype[ 0: 6] == "widget": ##two columns needed for this type data[-1]["data"][col] = { "label": "", "state": "", "type": "text" } data[-1]["data"][col]["group"] = "empty" else: itemdata[item].update({ "onclick": "item_action('" + itemdata[item]["type"] + "', '" + itemdata[item]["id"] + "', 'main')" }) data[-1]["data"][col] = itemdata[item] data[-1]["data"][col]["group"] = "popup" item += 1 col += 1 if data[-1]["data"][1]["group"] != "empty": if data[-1]["data"][1]["label"] == "" or ( data[-1]["data"][1]["label"] == "Empty" and data[-1]["data"][1]["state"] == "Empty"): d = data[-1]["data"][0] d.update({"group": "wide_text"}) data[-1] = d data[-1]["fontsize"] = self.determine_text_size( data[-1]["state"], max_len=16) else: for i in [0, 1]: data[-1]["data"][i][ "fontsize"] = self.determine_text_size( data[-1]["data"][i]["state"]) else: d = data[-1]["data"][0] d.update({"group": "wide_text"}) data[-1] = d data[-1]["fontsize"] = self.determine_text_size( data[-1]["state"], max_len=16) row += 1 return data def create_subpage(self, page, subpage=0, lowerpage=0, handle_as_popup=False): data = self.openhab.get_items(page, lowerpage) if subpage == "none": subpage = 0 else: subpage = int(subpage) items = data[0] page_data = data[1] #print(page_data[0], self.widgets_handler.get_widget_label(page_data[0])) N_items_pp, sensor_page = self._getNitemsPP(page_data, handle_as_popup) page_format = self.__get_page_data__(len(items), N_items_pp, sensor_page=sensor_page) page_format.update({ "title": self.widgets_handler.get_widget_label(page_data[0]), "returnbutton": False, "linkback": "", "linknext": "", "showbacknext": True }) if handle_as_popup: sensor_page = False page_format["showbacknext"] = False if str(lowerpage) != "0" and str(lowerpage)[0:2] != "m_": d = self.openhab.get_items(page) pos = 0 for i in range(len(d[0])): b = d[0][i] if b["type"] == "Frame" and b["label"] == lowerpage: pos = i page_format["returnbutton"] = "%s/%d" % (page, int( pos / N_items_pp)) if subpage != 0: page_format["linkback"] = str(page) + "/" + str( int(subpage) - 1) + "/" + str(lowerpage) if subpage < page_format["n_pages"] - 1: page_format["linknext"] = str(page) + "/" + str( int(subpage) + 1) + "/" + str(lowerpage) offset = subpage * N_items_pp page = render_template("subpage.html", data=page_format) n = 0 ##iterator for row in range(page_format["n_rows"]): for col in range(page_format["n_cols"]): if n + offset < len(items) and ( items[n + offset]["name"] != "Empty" and items[n + offset]["state"] != "Empty" and items[n + offset]["label"] != "Empty"): button = self.create_item_button(items[n + offset], page_format["small_icon"], sensor_page) else: button = "" page = page.replace("[[button_" + str(n) + "]]", button) n += 1 if handle_as_popup: page += render_template("popups/generic.html") return page else: return self.add_bottom_bar( page, returnbutton=page_format["returnbutton"]) def create_settings_page(self, subpage=0): settings = sorted(self.setting_handler.get_settings()) n = {'linkback': "", 'linknext': "", 'n': len(settings)} try: subpage = int(subpage) except: subpage = 0 if subpage != 0: n["linkback"] = subpage - 1 if subpage < np.ceil(len(settings) / 12) - 1: n["linknext"] = subpage + 1 if subpage != 0: settings = settings[12 * subpage:] n['n'] = len(settings) return self.add_bottom_bar( render_template("settings.html", data=settings, n=n)) def create_messages_page(self, start=0): page = render_template("messages.html") page = page.replace( "[[LIST]]", self.message_handler.format_message_list(start=start)) page = page.replace("[[MESSAGE]]", self.message_handler.format_message(message_id=-1)) return self.add_bottom_bar(page) def add_bottom_bar(self, page, returnbutton=False): pages = self.openhab.get_pages(["m_", "a_", "b_", "c_"]) for i in range(len(pages)): pages[i]["type"] = self.widgets_handler.check_widget_type( pages[i]["label"]) page_format = {"bottom": pages} page_format["returnbutton"] = returnbutton page_format["habpanel_link"] = Settings().get_setting( "main", "habpanel_link") page += "\n\n\n" page += render_template("bottombar.html", data=page_format) return page def __get_page_data__(self, n_items, n_perpage, sensor_page=False): n_page = np.ceil(n_items / n_perpage) small_icon = False page_format = { "n_pages": n_page, "n_rows": 2, "n_cols": 3, "row_height": "50", "col_width": "33", "small_icon": False } if n_perpage == 8 and not sensor_page: page_format.update({ "n_rows": 4, "n_cols": 2, "row_height": "25", "col_width": "50", "small_icon": True }) elif n_perpage == 8 and sensor_page: page_format.update({ "n_rows": 2, "n_cols": 4, "row_height": "50", "col_width": "25" }) elif n_perpage == 9: page_format.update({ "n_rows": 3, "n_cols": 3, "row_height": "33", "col_width": "33" }) elif n_perpage == 12: page_format.update({ "n_rows": 4, "n_cols": 3, "row_height": "25", "col_width": "33" }) return page_format def create_item_button(self, item_info, small_icon=False, sensor_button=False, header=True): if not sensor_button: N_items_pp = self.setting_handler.get_setting("items_per_page") button_width = int( self.__get_page_data__(1, N_items_pp, sensor_button)["col_width"]) else: N_items_pp = self.setting_handler.get_setting("sensors_per_page") button_width = int( float( self.__get_page_data__(1, N_items_pp, sensor_button)["col_width"]) * 1.2) data = { "icon": item_info["icon"], "icon_width": 90, "icon_height": 60, "action_id": item_info["id"], "header": header } if small_icon: data.update({"icon_width": 70, "icon_height": 70}) data.update({ "onclick": "item_action('" + item_info["type"] + "', '" + item_info["id"] + "')" }) itemtype = self.widgets_handler.check_widget_type(item_info["label"]) if item_info["type"] == "Frame" and ( itemtype != "widget_subpage") and ( itemtype == "widget_popup" or itemtype[0:6] == "widget"): data.update({ "onclick": "frontpage_action('" + str(item_info["page"]) + "', '" + item_info["label"] + "')" }) data["text"] = self.widgets_handler.get_widget_label( item_info["name"]) data["text_width"] = 80 elif item_info["type"] == "Frame" and (itemtype == "widget_subpage"): data.update({ "onclick": "reload_main_div('/page/menuwidget/" + str(item_info["page"]) + "/0/" + str(item_info["subpage"]) + "')" }) data["text"] = self.widgets_handler.get_widget_label( item_info["name"]) data["text_width"] = 80 elif item_info["type"] == "Frame": data.update({ "onclick": "reload_main_div('/page/maindiv/" + str(item_info["page"]) + "/0/" + str(item_info["subpage"]) + "')", "text_width": 80 }) data.update( self.format_item_string(item_info["label"], item_info["state"], button_width)) if data["state"] != '': data.update({"type": "state"}) elif item_info["type"] == "Switch": data.update({ "text": self.format_string(item_info["label"], int(20 * (button_width / 100))), "state": item_info["state"].lower(), "text_width": 60, "state_width": 20 }) data.update({"type": "switch"}) elif item_info["type"] == "Switch_single": data.update({ "text": self.format_string(item_info["label"], int(20 * (button_width / 100))), "state": item_info["state"].lower(), "text_width": 60, "state_width": 20 }) elif item_info["type"] == "Colorpicker": ##openhab item type data.update({ "text": self.format_string(item_info["label"], int(20 * (button_width / 100))), "state": item_info["state"], "text_width": 60, "state_width": 20 }) data.update({"type": "Colorpicker"}) else: data.update( self.format_item_string(item_info["label"], item_info["state"], button_width)) data.update({"type": "state"}) if sensor_button: data.update({ "text_width": 70, "state_width": 70, "icon_width": 80 }) page = render_template("buttons/sensor.html", data=data) else: page = render_template("buttons/button.html", data=data) return page def create_popup(self, type, data, renew_screensaver=True): if renew_screensaver: self.state_handler.refresh_screensaver_subpage() page = render_template("popups/" + type + ".html", data=data) return page def create_photoframe(self): td = self.setting_handler.get_setting("frame_td") info = self.setting_handler.get_setting("frame_info") page_data = { "time": "none", "date": "none", "load": "none", "album": "none" } if td == "clock" or td == "both": page_data["time"] = "" if td == "date" or td == "both": page_data["date"] = "" if info == "load" or info == "both": page_data["load"] = "" if info == "album" or info == "both": page_data["album"] = "" return render_template("album.html", data=page_data) def format_item_string(self, text, state, button_width=50): if text == "_": return { "text": self.format_string(state, width=int(54 * (button_width / 100))), "state": "", "text_width": 80, "state_width": 0 } elif state == "" and len(text) < 25: return { "text": text, "state": "", "text_width": 80, "state_width": 0 } elif state == "": return { "text": self.format_string(text, width=int(32 * (button_width / 100))), "state": "", "text_width": 80, "state_width": 0 } elif len(text) < 13 and len(state) > 7: return { "text": text, "state": self.format_string(state, width=int(26 * (button_width / 100))), "text_width": 40, "state_width": 40 } elif len(text) > 20 and len(state) > 20: return { "text": self.format_string(text, width=int(26 * (button_width / 100))), "state": self.format_string(state, width=int(26 * (button_width / 100))), "text_width": 40, "state_width": 40 } else: return { "text": self.format_string(text, width=int(38 * (button_width / 100))), "state": self.format_string(state, width=int(14 * (button_width / 100))), "text_width": 40, "state_width": 40 } def format_string(self, string, width=27): position = 0 for i in range(3): if len(string[position:]) > width: a = self.find(string[position:], " ") found = False for pos in range(len(a)): val = a[len(a) - pos - 1] if val < 27 and not found: string = string[0:position + val] + "<br>" + string[position + val + 1:] position = val + position + 4 found = True return Markup(string) def find(self, s, ch): return [i for i, ltr in enumerate(s) if ltr == ch] def determine_text_size(self, text, max_len=7, start_font="largefont"): if text == text.upper(): max_len -= 1 if start_font == "largefont": if len(text) < max_len + 1: return "largefont" else: return "smallfont" else: if len(text) < max_len + 1: return "xlargefont" else: return "smallfont" def _getNitemsPP(self, page_data, handle_as_popup): if page_data[1] != "temperature" and page_data[ 1] != "temp" and page_data[0].find("sensor") == -1: N_items_pp = self.setting_handler.get_setting("items_per_page") sensor_page = False else: N_items_pp = self.setting_handler.get_setting("sensors_per_page") if N_items_pp == 12: sensor_page = False else: sensor_page = True if handle_as_popup: N_items_pp = self.setting_handler.get_setting("items_per_page") if int(N_items_pp) < 9: N_items_pp = 6 else: N_items_pp = 9 return N_items_pp, sensor_page
class Reader(): def __init__(self): self.logger = Logging() def average(self, pixel): return 0.299 * pixel[0] + 0.587 * pixel[1] + 0.114 * pixel[2] def read_images(self, fname, sep, grayscale=None, test=None): self.d_images = [] self.c_images = [] self.file_labels = [] for root, dirnames, filenames in os.walk(fname): for filename in sorted(filenames, key=lambda x: int(x.split('.')[0])): if re.search("\.(jpg|jpeg|png|bmp|tiff)$", filename): filepath = os.path.join(root, filename) self.file_labels.append(filename.split('.')[0]) image = ndimage.imread(filepath, mode="RGB") image_resized = misc.imresize(image, (28, 28)) #check if this is from one class (dog in test) if re.search(sep, filename): #are we making this grayscale (x,784) or not if grayscale: grey = np.zeros(( image_resized.shape[0], image_resized.shape[1])) # init 2D numpy array # get row number for rownum in range(len(image_resized)): for colnum in range(len( image_resized[rownum])): grey[rownum][colnum] = self.average( image_resized[rownum][colnum]) self.d_images.append(grey.reshape(784)) #not else: self.d_images.append(image_resized) #cat in testing suite else: if grayscale: grey = np.zeros(( image_resized.shape[0], image_resized.shape[1])) # init 2D numpy array # get row number for rownum in range(len(image_resized)): for colnum in range(len( image_resized[rownum])): grey[rownum][colnum] = self.average( image_resized[rownum][colnum]) self.c_images.append(grey.reshape(784)) else: self.c_images.append(image_resized) if (len(self.d_images) + len(self.c_images)) % 1000 == 0: self.logger.info( 'read %s/%s %s/not %s images' % (len(self.d_images), len(self.c_images), sep, sep)) if test: return self.logger.info('read %s dog and %s cat images' % (len(self.d_images), len(self.c_images))) self.d_images = np.array(self.d_images) self.c_images = np.array(self.c_images) return self.d_images, self.c_images
from logger import Logging from symbol import Symbol from loader import Loader print "***** logging test *****" l = Logging() l.error("missing symbol") l.info("missing symbol") l.refresh("missing symbol") l.buy("missing symbol") l.profit("missing symbol") l.terminate("missing symbol") print "***** symbol test *****" s = Symbol('AMD') s.market_cap() print s.market_cap s.earnings_per_share() print s.eps print "***** loader test *****" load = Loader('AMD', '2016-11-01', '2016-11-21') amd = load.get_data('AMD') amd.book_value() print amd.book print load.data_to_csv('AMD')
class pf_openhab(Singleton): def __init__(self): try: if self.loadingdone: pass except: self.loadingdone = True self.logging = Logging() settings_c = Settings() self.openhab_server = settings_c.get_setting("main", "openhab_ip") self.openhab_port = settings_c.get_setting("main", "openhab_port") self.host = settings_c.get_setting("main", "hostname") self.port = settings_c.get_setting("main", "port") self.sitemap_name = settings_c.get_setting("main", "sitemap") self.sitemap_name = "main" if self.sitemap_name == None else self.sitemap_name self.resize_icons = settings_c.get_setting("main", "resize_icons") self.iconh = 64 self.iconw = 64 self.name = "pf_openhab" self.http = urllib3.PoolManager() def get_pages(self, filter): if type(filter) != list: filter = [filter] self.load_sitemap() data = [] n = 0 for i in range(len(self.sitemap["homepage"]["widgets"][0]["widgets"])): key = self.sitemap["homepage"]["widgets"][0]["widgets"][i] found = False for filt in filter: if key["label"][0:len(filt)] == filt and not found: icon_url = "/item/icon/" + key["icon"] + ".png" data.append({ "label": key["label"], "icon": icon_url, "id": n }) found = True n += 1 return data def get_page(self, name): for i in range(len(self.sitemap["homepage"]["widgets"][0]["widgets"])): key = self.sitemap["homepage"]["widgets"][0]["widgets"][i] if key["label"] == name: return key def get_items(self, pagename, subpage="none", subsubpage=0): self.load_sitemap() page = self.get_page(pagename) data = [] n_subp = 1 n = 0 page_type = [page["label"], page["icon"]] for key in page["linkedPage"]["widgets"]: n += 1 item = self.convert_item_data(key) item["id"] = item["name"] + "__" + pagename + "__" + str( subpage) + "__" + str(n) if subpage == "none" or str(subpage) == "0": if item["type"] == "Frame": item["page"] = pagename item["subpage"] = item["label"] data.append(item) elif item["type"] == "Frame" and item["label"] == subpage: page_type[0] = page_type[0] + " / " + key["label"] sub_n = 0 for k in key["widgets"]: sub_n += 1 item = self.convert_item_data(k) item["id"] = item["name"] + "__" + pagename + "__" + str( subpage) + "__" + str(sub_n) if item["type"] == "Frame": item["type"] = "Text" data.append(item) return [data, page_type] def load_sitemap(self): if self.host == None or self.openhab_server == None: #if self.openhab_server == None: data = self.load_error_sitemap(False) else: try: url = "http://" + self.openhab_server + ":" + self.openhab_port + "/rest/sitemaps/" + self.sitemap_name #print(url) content = self.http.request('GET', url) data = content.data.decode("utf-8") except: self.logging.error( "Error connecting to openHAB server, please check settings", location=self.name) data = self.load_error_sitemap(True) data = data.replace("true", "True").replace("false", "False") data = eval(data) self.sitemap = data def load_error_sitemap(self, exception): PATH = os.path.dirname(os.path.abspath(__file__)) errorfile = PATH + "/files/error_sitemap.txt" with open(errorfile, 'r') as f: data = f.read() if exception: data = data.replace("{{HOST_CONFIG_ERROR}}", "No error detected") data = data.replace("{{OPENHAB_CONFIG_ERROR}}", "Error connecting to server, check settings") else: data = data.replace("{{HOST_CONFIG_ERROR}}", "Check settings") data = data.replace("{{OPENHAB_CONFIG_ERROR}}", "Check settings") data = data.replace("{{IP}}", str(self.openhab_server)) data = data.replace("{{PORT}}", str(self.openhab_port)) data = data.replace("{{SITEMAP}}", str(self.sitemap_name)) data = data.replace("{{RESIZE}}", str(self.resize_icons)) data = data.replace("{{HOST_IP}}", str(self.host)) data = data.replace("{{HOST_PORT}}", str(self.port)) return data def get_item(self, item_name): name, pagename, subpage, n = self.split_item_name(item_name) #print(name, pagename, subpage, n) item = self.get_item_data(name, pagename, subpage, n) self.logging.debug("Item from get_item: " + str(item), location=self.name) return item def get_item_data(self, item_name, pagename, subpage, n): #search for the item self.load_sitemap() #print("Name: " + item_name) o = 1 subpage_o = 1 for i in range(len(self.sitemap["homepage"]["widgets"][0]["widgets"])): if self.sitemap["homepage"]["widgets"][0]["widgets"][i][ "label"] == pagename: for key in self.sitemap["homepage"]["widgets"][0]["widgets"][ i]["linkedPage"]["widgets"]: if key["label"].find("[") != -1: comp_label = key["label"][0:key["label"].find("[")] while comp_label[-1:] == " ": comp_label = comp_label[0:-1] else: comp_label = key["label"] try: if key["type"] == "Frame" and ( str(subpage_o) == subpage or comp_label == subpage): #print(subpage) sub_o = 0 for k in key["widgets"]: sub_o += 1 try: if k["item"][ "name"] == item_name and sub_o == n: item = self.convert_item_data(k) item["id"] = item[ "name"] + "__" + pagename + "__" + str( subpage) + "__" + str(n) item["page"] = pagename item["subpage"] = str(subpage) self.logging.debug("Item found, id: " + item["id"], location=self.name) return item except Exception as e: self.logging.warn( "Invalid item found in sitemap 2 %s" % (str(e)), location=self.name) elif "item" in key and key["item"][ "name"] == item_name and o == n: item = self.convert_item_data(key) item["id"] = item[ "name"] + "__" + pagename + "__" + str( subpage) + "__" + str(n) item["page"] = pagename item["subpage"] = str(subpage) self.logging.debug("Item found, id: " + item["id"], location=self.name) return item elif str(subpage) == "0" or subpage == "none": o += 1 elif key["type"] == "Frame": subpage_o += 1 o += 1 except Exception as e: self.logging.warn( "Invalid item found in sitemap 1: %s, %s" % (str(key), str(e)), location=self.name) def convert_item_data(self, key): #print(key) item_data = { "icon": key["icon"], "type": key["type"], "name": key["label"], "state": "" } if "item" in key: item_data.update({ "state": key["item"]["state"], "link": key["item"]["link"], "name": key["item"]["name"] }) if key["item"]["state"] != "" and key["item"]["state"].find( " ") == -1: item_data["icon"] = key["icon"] + "-" + key["item"]["state"] if "transformedState" in key["item"]: transformedState = key["item"]["transformedState"] if len(str(transformedState)) < 15: item_data.update( {"icon": key["icon"] + "-" + transformedState}) if "mappings" in key: item_data.update({"mappings": key["mappings"]}) if "label" in key: item_data.update({"label": key["label"]}) #### correct icon for state try: state = float(item_data["state"]) if state < 0.0: item_data["icon"] = key["icon"] + "-" + str(-1 * state + 100) except: if item_data["state"] == "NULL": item_data["state"] = "OFF" item_data["icon"] = key["icon"] + "-off" elif len(str(item_data["state"])) > 15: item_data["icon"] = key["icon"] #### transform state name if item_data["label"].find("[") != -1: label = item_data["label"][0:item_data["label"].find("[")] while label[-1:] == " ": label = label[0:-1] state = item_data["label"][item_data["label"].find("[") + 1:item_data["label"].find("]")] item_data.update({"state": state, "label": label}) if key["type"] == "Colorpicker": if item_data["state"].lower() != "off": item_data["state"] = self.convert_color_to_rgb( item_data["state"]) item_data["icon"] = key["icon"] + "-on" if len(item_data["state"].split(",")) > 2: if item_data["state"].split(",")[2] == "0" or item_data[ "state"].split(",")[2] == "0.0": item_data.update({ "state": "off", "icon": key["icon"] + "-off" }) elif key["type"] == "Selection": item_state = "" if len(key["mappings"]) == 1: item_data["type"] = "Switch_single" item_state = key["mappings"][0]["label"] for mapp in key["mappings"]: if mapp["command"].lower() == item_data["state"].lower(): ## mappings are like [ displayed state, actual state ] item_state = mapp["label"] elif mapp["label"].lower() == item_data["state"].lower(): item_state = mapp[ 'label'] ##sometimes a state is 0 ==> OFF, which is not mapped correctly with Off or 0 try: ##why is this????? #print(item_state) int(item_state) item_data.update({"item_state": item_data["label"]}) item_data.update({"label": "_"}) except: item_data.update({"state": item_state}) elif key["type"] == "Setpoint": try: step = round(float(key["step"]), 1) if int(step) == step: step = int(step) item_data.update({ "setpoint": [int(key["minValue"]), int(key["maxValue"]), step] }) except: pass elif key["type"] == "Slider": item_data.update({"setpoint": [0, 100, 10]}) ##update the icon to the right url: if self.resize_icons == "1": item_data["icon"] = "/item/icon/" + item_data["icon"] + ".png" else: item_data[ "icon"] = "http://" + self.openhab_server + ":" + self.openhab_port + "/icon/" + item_data[ "icon"] + ".png" return item_data def set_state(self, item_name, state): item, pagename, subpage, n = self.split_item_name(item_name) if state[0:5] == "Color": state = self.convert_color_to_hsv(state[5:]) #cmd = "curl --header \"Content-Type: text/plain\" --request POST --data \"" + state+ "\" " + self.openhab_server + ":" + self.openhab_port + "/rest/items/" + item url = "http://" + self.openhab_server + ":" + self.openhab_port + "/rest/items/" + item headers = {'Content-Type': 'text/plain'} requests.post(url, data=state, headers=headers) self.logging.info("Put state openhab: " + url + " " + str(state), location="openhab") #os.system(cmd) #print(cmd) self.load_sitemap() return self.get_item(item_name) def get_mappings(self, item_name, occurrence=1): ##self.load_sitemap() item = self.get_item(item_name) mappings = [] for mapping in item["mappings"]: mappings.append([mapping["label"], mapping["command"]]) return mappings def convert_color_to_rgb(self, color): if color == "": color = "0.0,0.0,0" color = color.split(",") color = colorsys.hsv_to_rgb( float(color[0]) / 360, float(color[1]) / 100, float(color[2]) / 100) red = hex(int(color[0] * 255))[2:] if len(red) < 2: red = "0" + red blue = hex(int(color[1] * 255))[2:] if len(blue) < 2: blue = "0" + blue green = hex(int(color[2] * 255))[2:] if len(green) < 2: green = "0" + green return "#" + red + blue + green def convert_color_to_hsv(self, color): color = colorsys.rgb_to_hsv( float(int("0x" + color[0:2], 0)) / 255.0, float(int("0x" + color[2:4], 0)) / 255.0, float(int("0x" + color[4:6], 0)) / 255.0) return str(color[0] * 360) + "," + str(color[1] * 100) + "," + str( color[2] * 100) def get_icon(self, name): URL = "http://" + self.openhab_server + ":" + self.openhab_port + "/icon/" + name response = requests.get(URL) with Image.open(BytesIO(response.content)) as image: imgByteArr = BytesIO() cover = Image.Image.resize(image, [self.iconh, self.iconw]) cover.save(imgByteArr, image.format) return imgByteArr.getvalue() def get_chart_data(self, item, period): try: p = int(period[0:len(period) - 1]) except: p = 1 if period[-1:] == "D": dt = datetime.datetime.now() - datetime.timedelta(days=p) elif period[-1:] == "H": p += 1 dt = datetime.datetime.now() - datetime.timedelta(hours=p) elif period[-1:] == "W": dt = datetime.datetime.now() - datetime.timedelta(weeks=p) elif period[-1:] == "M": dt = datetime.datetime.now() - relativedelta(months=p) start = dt.strftime("%Y-%m-%dT%H:%M:%S.000+01:00") self.logging.info("Starting date for data: " + start, location="openhab") start = start.replace("+", "%2B").replace(":", "%3A") name, pagename, subpage, n = self.split_item_name(item) URL = "http://" + self.openhab_server + ":" + self.openhab_port + "/rest/persistence/items/" + name + "?serviceId=rrd4j&starttime=" + start response = requests.get(URL) ## get item info i = self.get_item(item) if i == None: return None else: if i["icon"].lower().find("temp") != -1: typ = "temp" elif i["icon"].lower().find("humi") != -1: typ = "humi" elif i["icon"].lower().find("press") != -1: typ = "pres" elif i["icon"].lower().find("energy") != -1: typ = "watt" else: typ = "value" return {"data": response.content, "type": typ} def split_item_name(self, item_name): a = item_name.split("__") if len(a) > 1: name = a[0] pagename = a[1] subpage = a[2] n = int(a[3]) else: return item_name return name, pagename, subpage, n