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
示例#3
0
    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
示例#4
0
    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
示例#5
0
    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)
示例#7
0
    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()
示例#8
0
    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)
示例#9
0
    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
示例#10
0
    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
示例#11
0
    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
示例#12
0
    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