def add_system_log(self, myLog: SystemLog): """Function gets a SystemLog object and writes it to the database :arg myLog: The SystemLog to write to the database :type myLog: SystemLog :return log_rowid: rowid if log was written successfully or None if not :rtype log_rowid: Union[int, None] """ log_rowid = None # type: int query_str = [ "INSERT INTO system_logs", "(card_id, time_stamp, message, message_type, severity)", "VALUES('{0}', '{1}', '{2}', '{3}', '{4}');" ] self.c.execute( str.join(" ", query_str).format(str(myLog.get_card()), time.mktime(myLog.get_time_stamp()), str(myLog.get_message()), myLog.get_message_type().name, myLog.get_severity())) log_rowid = self.c.lastrowid # print(log_rowid) self.conn.commit() return False
def get_system_log_by_id(self, logID: int): """Function gets a SystemLog ID and returns a SystemLog object or None if no such object :arg logID: SystemLog ID :type logID: int :return ret_log: The requested log or None :rtype ret_log: Union[SystemLog, None] """ ret_log = None # type: SystemLog query_str = [ "SELECT", "rowid, card_id, time_stamp, message, message_type, severity", "FROM system_logs", "WHERE rowid = {0};" ] self.c.execute(str.join(" ", query_str).format(logID)) data = self.c.fetchone() if len(data) == 0: return ret_log rowid = data[0] # type: int card_id = data[1] # type: str time_stamp = int(data[2]) # type: int msg = data[3] # type: str msg_type = MessageTypes[data[4]] # type: MessageTypes severity = data[5] # type: int ret_log = SystemLog(message=msg, rowid=rowid, card=card_id, time_stamp=time_stamp, message_type=msg_type, severity=severity) return ret_log
def stop_network_discovery(self): logstr = "Stopping network discovery." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) print(logstr) self.__browser.zc.close() return None
def start_network_discovery(self): logstr = "Starting network discovery." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) print(logstr) zeroconf = Zeroconf() self.__browser = ServiceBrowser( zeroconf, "_FatCatBB._tcp.local.", handlers=[self.on_service_state_change]) return None
def purge_logs(self): cn = FoodBoxDB() # type: FoodBoxDB cn.purge_logs() self.__last_purge = time.time() del cn self.__set_system_setting(SystemSettings.Last_Purge, self.__last_purge) logstr = "Logs purged." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev, card=None) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) return True
def get_all_system_logs(self, logs_since: time.struct_time = None): """Returns a tuple of all system logs since logs_since, or all of them :arg logs_since: Limit logs to a date, if it's None then no limit on date. :type logs_since: Union[None, time.struct_time] :return systemlog_tuple: A tuple of SystemLogs :rtype systemlog_tuple: Tuple[SystemLog] """ log_list = [] # type: List[SystemLog] if logs_since is None: query_str = [ "SELECT", "rowid, card_id, time_stamp, message, message_type, severity", "FROM system_logs;" ] self.c.execute(str.join(" ", query_str)) else: query_str = [ "SELECT", "rowid, card_id, time_stamp, message, message_type, severity", "FROM system_logs", "WHERE time_stamp >= '{0}';" ] self.c.execute( str.join(" ", query_str).format(time.mktime(logs_since))) logs_data = self.c.fetchall() for row in logs_data: rowid = row[0] # type: int card_id = row[1] # type: str time_stamp = int(row[2]) # type: int msg = row[3] # type: str msg_type = MessageTypes[row[4]] # type: MessageTypes severity = row[5] # type: int log_list.append( SystemLog(message=msg, rowid=rowid, card=card_id, time_stamp=time_stamp, message_type=msg_type, severity=severity)) return tuple(log_list)
def admin_refill(self, start_weight: float, end_weight: float, card_uid: str): logstr = "ADMIN refilled the box from: {0} to {1}.".format( start_weight, end_weight) logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev, card=card_uid) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__last_weight = end_weight self.__set_system_setting(SystemSettings.Last_Weight, end_weight) sync_success = self.sync_foodbox_with_brainbox() if sync_success: sync_uid, sync_success = self.sync_with_brainbox() if sync_success: self.sync_cards_from_brainbox()
def on_service_state_change(self, zeroconf: Zeroconf, service_type: ZeroconfServiceTypes, name: str, state_change: ServiceStateChange): logstr = "service_state_change" logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) info = zeroconf.get_service_info(service_type, name) if info: if state_change is ServiceStateChange.Added: print("IP: {0} - PORT: {1}".format( socket.inet_ntoa(info.address), info.port)) if time.time() - time.mktime( self.__sync_last) >= self.__sync_interval: self.__sync_last = time.localtime(time.time() - self.__sync_interval + 20) self.__brainbox_ip_address = info.address self.__brainbox_port_number = info.port self.__set_system_setting(setting=SystemSettings.BrainBox_IP, value=socket.inet_ntoa(info.address)) self.__set_system_setting(setting=SystemSettings.BrainBox_Port, value=info.port) logstr = "BrainBox_IP and BrainBox_Port updates - {0}:{1}".format( socket.inet_ntoa(info.address), info.port) logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) # if not self.__said_hi_to_brainbox: # self.sync_foodbox_with_brainbox() elif state_change is ServiceStateChange.Removed: # We never get inside here, because it always goes to else print( "BrainBox_IP and BrainBox_Port removed. - This is the 'We never get inside her' part." ) # Debug message. self.__brainbox_ip_address = None self.__brainbox_port_number = None self.__set_system_setting(setting=SystemSettings.BrainBox_IP, value=None) self.__set_system_setting(setting=SystemSettings.BrainBox_Port, value=None) logstr = "BrainBox_IP and BrainBox_Port removed." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) else: print("BrainBox_IP and BrainBox_Port removed.") # Debug message self.__brainbox_ip_address = None self.__brainbox_port_number = None self.__set_system_setting(setting=SystemSettings.BrainBox_IP, value=None) self.__set_system_setting(setting=SystemSettings.BrainBox_Port, value=None) logstr = "BrainBox_IP and BrainBox_Port removed." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog)
def start_mainloop(self): """The main loop of reading card, checking access and writing logs. :rtype: bool """ while True: if time.time() - time.mktime( self.__sync_last) >= self.__sync_interval: sync_success = self.sync_foodbox_with_brainbox() if sync_success: sync_uid, sync_success = self.sync_with_brainbox() if sync_success: self.sync_cards_from_brainbox() if time.time() - self.__last_purge >= 1440: self.purge_logs() carduid = self.__rfid_scanner.get_uid() if carduid is None: time.sleep(0.1) continue cn = FoodBoxDB() # type: FoodBoxDB card = cn.get_card_byID(carduid) # type: RFIDCard del cn if card is None or not card.get_active(): logstr = "Invalid card tried to open box." logtype = MessageTypes.Information logsev = 1 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev, card=carduid) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) old_carduid = carduid while self.__rfid_scanner.get_uid() == old_carduid: time.sleep(0.1) continue logstr = "Opened lid for card." admin_card = False if card.get_name() == "ADMIN": logstr = "ADMIN card opened the box." admin_card = True logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev, card=carduid) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) open_time = time.localtime() start_weight = self.__scale.get_units_2() print("Starting weight is: ", start_weight) self.open_lid() time.sleep(5) if card.get_name() == "ADMIN": while self.__rfid_scanner.get_uid() == carduid: time.sleep(5) long_flag = False while self.__proximity.is_blocked(): time.sleep(0.1) if not long_flag and (time.time() - time.mktime(open_time) >= self.__max_open_time): long_flag = True logstr = "Lid was opened for too long." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev, card=carduid) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) # TODO - Beep at the cat self.close_lid() close_time = time.localtime() end_weight = self.__scale.get_units_2() print("End weight is: ", end_weight) if admin_card: self.admin_refill(start_weight=start_weight, end_weight=end_weight, card_uid=carduid) continue feedinglog = FeedingLog(card=card, open_time=open_time, close_time=close_time, start_weight=start_weight, end_weight=end_weight, feeding_id=uuid.uuid4().hex) print("feedinglog: {}".format(feedinglog)) # Debug message self.write_feeding_log(feedinglog) self.__last_weight = end_weight self.__set_system_setting(SystemSettings.Last_Weight, end_weight) del feedinglog if self.__sync_on_change: sync_success = self.sync_foodbox_with_brainbox() if sync_success: sync_uid, sync_success = self.sync_with_brainbox() if sync_success: self.sync_cards_from_brainbox() if False: # Ignore me. break return False
def sync_foodbox_with_brainbox(self): if self.__brainbox_ip_address is None or self.__brainbox_port_number is None: return False url = "http://{0}:{1}/bbox/pullfoodbox/{2}".format( socket.inet_ntoa(self.__brainbox_ip_address), self.__brainbox_port_number, self.__foodbox_id) print("url: {}".format(url)) # Debug message payload = {"current_weight": self.__last_weight} print("payload: {}\n\n".format(payload)) # Debug message try: brainbox_response = requests.get(url=url, params=payload, headers={"connection": "close"}) if brainbox_response.status_code != 200: success = False logstr = "Sync FoodBox with brainbox failed - status_code = {}.".format( brainbox_response.status_code) logtype = MessageTypes.Error logsev = 1 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return success response_obj = json.loads(brainbox_response.text) response_box_name = response_obj["foodbox_name"] print("response_box_name: {}\n\n".format( response_box_name)) # Debug message if "brainbox_response" in vars(): brainbox_response.close() except (ValueError, AttributeError, requests.exceptions.RequestException) as e: success = False logstr = "Sync FoodBox with brainbox failed - exception = {}.".format( "TODO") # fixme (#74) logtype = MessageTypes.Error logsev = 2 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return success self.__foodbox_name = response_box_name self.__set_system_setting(SystemSettings.FoodBox_Name, self.__foodbox_name) success = True logstr = "Sync FoodBox with brainbox succeeded." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if not self.__said_hi_to_brainbox: self.__said_hi_to_brainbox = True if "brainbox_response" in vars(): brainbox_response.close() return success
def sync_cards_from_brainbox(self): """Pull new cards from brainbox. :return synced_cards: A Tuple[str] of card_ids that were received from the server. :return success: Did it sync successfully or not. :rtype synced_cards: Tuple[str] :rtype success: bool """ synced_cards = [] if self.__brainbox_ip_address is None or self.__brainbox_port_number is None: success = False logstr = "Sync cards with BrainBox failed - BrainBox not recognized." logtype = MessageTypes.Error logsev = 1 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() return tuple(synced_cards), success url = "http://{0}:{1}/bbox/pullcards/{2}".format( socket.inet_ntoa(self.__brainbox_ip_address), self.__brainbox_port_number, self.__foodbox_id) try: brainbox_response = requests.get(url=url, headers={"connection": "close"}) if brainbox_response.status_code != 200: success = False logstr = "Sync cards with brainbox failed - status_code = {}.".format( brainbox_response.status_code) logtype = MessageTypes.Error logsev = 1 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return tuple(synced_cards), success response_obj = json.loads(brainbox_response.text) admin_cards = tuple(response_obj["admin_cards"]) modified_cards = tuple(response_obj["modified_cards"]) new_cards = tuple(response_obj["new_cards"]) print("admin cards: {}\n\n".format(admin_cards)) # Debug message print("modified cards: {}\n\n".format( modified_cards)) # Debug message print("new cards: {}\n\n".format(new_cards)) # Debug message cn = FoodBoxDB() # type: FoodBoxDB for admin_card in admin_cards: tmp_id = admin_card["card_id"] tmp_active = admin_card["active"] cn.set_state(cardID=tmp_id, newState=tmp_active) cn.set_card_name(cardID=tmp_id, new_name="ADMIN") synced_cards.append(tmp_id) for modified_card in modified_cards: tmp_id = modified_card["card_id"] tmp_active = modified_card["active"] tmp_name = modified_card["card_name"] cn.set_state(cardID=tmp_id, newState=tmp_active) cn.set_card_name(cardID=tmp_id, new_name=tmp_name) synced_cards.append(tmp_id) for new_card in new_cards: tmp_id = new_card["card_id"] tmp_active = new_card["active"] tmp_name = new_card["card_name"] cn.set_state(cardID=tmp_id, newState=tmp_active) cn.set_card_name(cardID=tmp_id, new_name=tmp_name) synced_cards.append(tmp_id) del cn success = True if "brainbox_response" in vars(): brainbox_response.close() except (ValueError, AttributeError, requests.exceptions.RequestException) as e: success = False logstr = "Sync cards with brainbox failed - exception = {}.".format( "TODO") # fixme (#74) logtype = MessageTypes.Error logsev = 2 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return tuple(synced_cards), success logstr = "Sync cards with brainbox succeeded." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return tuple(synced_cards), success
def sync_with_brainbox(self): """Sync unsynced FeedingLogs with the brainbox. :return synced_uid: A Tuple[str] of uids that were synced, or failed to sync. :return success: Did it sync successfully or not. :rtype sync_uid: Tuple[str] :rtype success: bool """ cn = FoodBoxDB() # type: FoodBoxDB logs_to_sync = cn.get_not_synced_feeding_logs( ) # type: list[FeedingLog] del cn sync_uid = tuple([log.get_id() for log in logs_to_sync]) # type: tuple[str] # success = False # type: bool if not logs_to_sync: success = True logstr = "Sync with BrainBox succeeded - Nothing to sync." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() return sync_uid, success if self.__brainbox_ip_address is None or self.__brainbox_port_number is None: success = False logstr = "Sync with BrainBox failed - BrainBox not recognized." logtype = MessageTypes.Error logsev = 1 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() return sync_uid, success logs_list = [] for log in logs_to_sync: tmp_open_time = log.get_open_time() # type: time.struct_time tmp_open_datetime = datetime.datetime.fromtimestamp( time.mktime(tmp_open_time), pytz.timezone("Asia/Jerusalem")) tmp_close_time = log.get_close_time() # type: time.struct_time tmp_close_datetime = datetime.datetime.fromtimestamp( time.mktime(tmp_close_time), pytz.timezone("Asia/Jerusalem")) tmp_log_dict = { "feeding_id": log.get_id(), "card_id": log.get_card().get_uid(), "open_time": str(tmp_open_datetime), "close_time": str(tmp_close_datetime), "start_weight": log.get_start_weight(), "end_weight": log.get_end_weight() } logs_list.append(tmp_log_dict) payload = {"box_id": self.__foodbox_id, "feeding_logs": logs_list} url = "http://{0}:{1}/bbox/pushlogs/".format( socket.inet_ntoa(self.__brainbox_ip_address), self.__brainbox_port_number) print("url: {}".format(url)) # Debug message print("payload: {}\n\n".format(payload)) # Debug message try: brainbox_response = requests.post(url=url, json=payload, headers={"connection": "close"}) if brainbox_response.status_code != 200: success = False logstr = "Sync with brainbox failed - status_code = {}.".format( brainbox_response.status_code) logtype = MessageTypes.Error logsev = 1 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return sync_uid, success response_obj = json.loads(brainbox_response.text) confirmed_ids = tuple( response_obj["confirm_ids"]) # TODO - Compare against sync_uid print( "confirmed ids: {}\n\n".format(confirmed_ids)) # Debug message if "brainbox_response" in vars(): brainbox_response.close() self.mark_feeding_logs_synced(confirmed_ids) except (ValueError, AttributeError, requests.exceptions.RequestException) as e: success = False logstr = "Sync with brainbox failed - exception = {}.".format( "TODO") # fixme (#74) logtype = MessageTypes.Error logsev = 2 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return sync_uid, success success = True logstr = "Sync with brainbox succeeded." logtype = MessageTypes.Information logsev = 0 syslog = SystemLog(message=logstr, message_type=logtype, time_stamp=time.localtime(), severity=logsev) print("syslog: {}".format(syslog)) # Debug message self.write_system_log(syslog) self.__sync_last = time.localtime() if "brainbox_response" in vars(): brainbox_response.close() return sync_uid, success