コード例 #1
0
    def __process_next_sms(self):
        signal_strength_percentage = '--'
        time_before_fetch = time.time()
        try:
            sms_fetcher = SmsFetcher(self.config['gammuConfigFile'], self.config['gammuConfigSection'], self.config['logDir'] + '/sms-delete.log') 
            signal_strength_percentage = sms_fetcher.get_signal_strength_percentage()
            sms_messages = sms_fetcher.delete_get_next_sms()
        except (gammu.ERR_TIMEOUT, gammu.ERR_DEVICENOTEXIST, gammu.ERR_NOTCONNECTED):
            timeout_after_time = time.time() - time_before_fetch
            debug("Got exception after {} seconds while trying to fetch/delete next sms (signalStrength: {}%).".format(timeout_after_time, signal_strength_percentage))
            raise # re-raise exception so we get the stacktrace to stderr
        
        absolute_script_path = os.path.abspath(__file__)
        
        if not sms_messages:
            # would write a log message every minute even if no sms found 
            #debug("No sms found by {} - bye.".format(absolute_script_path))
            return TemperatureController.NO_SMS_FOUND
        
        debug("Start sms processing (found {} messages) by {}".format(len(sms_messages), absolute_script_path))
        
        sms = sms_messages[0]
        
        # set system datetime to sent/received DateTime from received sms if delta is big enough
        if self.config['systemDatetimeMaxDiffNoUpdateSeconds'] > 0:
            system_datetime = datetime.now()
            sms_datetime_naive = sms[0]['DateTime']
            delta_datetime = sms_datetime_naive - system_datetime
            delta_seconds = delta_datetime.total_seconds()
            if abs(delta_seconds) > self.config['systemDatetimeMaxDiffNoUpdateSeconds']:
                # example unix date: Thu Nov 28 23:29:53 CET 2014
                sms_datetime_unix = sms_datetime_naive.strftime("%a %b %d %H:%M:%S %Y")
                set_date_cmd = "date -s \"{0}\" > /dev/null".format(sms_datetime_unix)
                debug("Updating system datetime (delta: {} seconds) using cmd: {}".format(delta_seconds, set_date_cmd))
                os.system(set_date_cmd)
            #else:
        	#debug("system date diff ({} seconds) is not greater than configured delta ({} seconds), skipping updating.".format(delta_seconds, self.config['systemDatetimeMaxDiffNoUpdateSeconds']))
        
        now_string = datetime.now().strftime(DATETIME_FORMAT)
        
        sender_number = sms[0]['Number']
        sender_message_raw = sms[0]['Text']
        sender_message = repr(sender_message_raw)
        debug("  got sms message from {}: {}".format(sender_number, sender_message))
        
        if self.config['myNumber'] in sender_number:
            debug("  got sms from my own number - not responding in order to prevent infinite loop. Bye!")
            return TemperatureController.SMS_IGNORED
        elif self.config['blacklistSenders']: # empty strings are false in python
           for blacklist_sender in self.config['blacklistSenders'].split(","): 
                if len(blacklist_sender) > 0 and blacklist_sender in sender_number: 
                    debug("  this sender is in blacklist (matched '{}') - ignoring. Bye!".format(blacklist_sender))
                    return TemperatureController.SMS_IGNORED
        
        if len(sms_messages) > 1:
            debug("  found sms consisting of {} parts - only the first part will be considered.".format(len(sms_messages)))
        
        
        response_message = None
        
        if sender_message_raw and sender_message_raw.lower().startswith('temp'):
            temp_raw = temperaturereader.read_celsius()
            if temp_raw: 
                temp = round(temp_raw, 1)
                debug("  responding with temperature: {} Celsius.".format(temp))
                response_message = u'Hi! Current temperature here is {0} Celsius ({1}).'.format(temp, now_string)
            else:
                debug("  temperature could not be read.")
                response_message = u'Hi! Temperature sensor is offline, check log files.'
        
        elif sender_message_raw and sender_message_raw.lower().startswith('power autocontrol '):
            message_payload = sender_message_raw[len('power autocontrol '):]
            parts = message_payload.split(None, 3)
            success = False
            if len(parts) >= 2:
                try:
                    switch_on_temperature = float(parts[0].replace(',', '.'))
                    switch_off_temperature = float(parts[1].replace(',', '.'))
                except Exception as e:
                    # silently ignore, reply with help message
                    debug("  exception occurred while trying to convert supplied args to float number, ignoring")

                else:
                    pac = PowerAutocontroller(config_parser)

                    switch_on_temp_before = pac.get_switch_on_temperature()
                    switch_off_temp_before = pac.get_switch_off_temperature()
                    current_temp_raw = temperaturereader.read_celsius()

                    pac.set_switch_onoff_temperatures(CONFIG_FILEPATH, switch_on_temperature, switch_off_temperature)

                    switch_on_temp_after = pac.get_switch_on_temperature()
                    switch_off_temp_after = pac.get_switch_off_temperature()
                    
                    if current_temp_raw: 
                        current_temp = round(current_temp_raw, 1)
                        debug("  responding with updated temperature interval [{2}:{3}] (was: [{0}:{1}]), current temperature: {4} Celsius.".format(switch_on_temp_before, switch_off_temp_before, switch_on_temp_after, switch_off_temp_after, current_temp))
                        response_message = u'Hi! Successfully set temperature interval to [{0}:{1}]. Current temperature is {2}.'.format(switch_on_temp_after, switch_off_temp_after, current_temp)
                    else:
                        debug("  responding with updated temperature interval [{2}:{3}] (was: [{0}:{1}]), current temperature could not be read.".format(switch_on_temp_before, switch_off_temp_before, switch_on_temp_after, switch_off_temp_after))
                        response_message = u'Hi! Successfully set temperature interval to [{0}:{1}]. Current temperature could not be read.'.format(switch_on_temp_after, switch_off_temp_after)

                    success = True

            if not success:
                debug("  couldnt understand 'power autocontrol' message, responding with help message.")
                response_message = u'Hi! Didnt understand your message, use "power autocontrol 4 12" to enable power between 4 and 12 degrees.'

        elif sender_message_raw and sender_message_raw.lower().startswith('power'):
            gpio_channels = [int(channel) for channel in self.config['relayGpioChannels'].split(',')]
            powerswitcher = PowerSwitcher(gpio_channels=gpio_channels)
            power_status_before = powerswitcher.get_status_string()

            requested_state = ''
            if sender_message_raw.lower().startswith('power on'):
                requested_state = 'ON'
            elif sender_message_raw.lower().startswith('power off'):
                requested_state = 'OFF'

            manual_switching_allowed = not self.config['powerAutocontrolEnabled']
            if manual_switching_allowed and requested_state and requested_state == 'ON':
                powerswitcher.set_status_on()
                debug("  power has been set ON")
            elif manual_switching_allowed and requested_state and requested_state == 'OFF':
                powerswitcher.set_status_off()
                debug("  power has been set OFF")
            else: 
                debug("  power switching not requested/allowed (manual switching allowed? {})".format(manual_switching_allowed))

            power_status = powerswitcher.get_status_string()
            debug("  responding with power status: {1} (was: {0}).".format(power_status_before, power_status))
            if requested_state and not manual_switching_allowed:
                response_message = u'Hi! Power autocontrol is enabled, cannot switch power manually (currently {0}).'.format(power_status)
            elif requested_state:
                response_message = u'Hi! Power has been switched {0}, was {1} ({2}).'.format(power_status, power_status_before, now_string)
            else:
                response_message = u'Hi! Power is currently {0} ({1}).'.format(power_status, now_string)
        
        elif sender_message_raw and sender_message_raw.lower().startswith('systeminfo'):
            debug("  responding with system info:")
            up_since = systeminfo.get_last_reboot_date_time()
            kernelVersion = systeminfo.get_kernel_version()
            rpiSerialNumber = systeminfo.get_rpi_serial_number()
            localInetAddress = systeminfo.get_inet_address()
            gitRevision = systeminfo.get_git_revision()
            balance_info = self.__get_cached_balance_info(short=True)
            debug("    system datetime  : {}".format(now_string))
            debug("    up since         : {}".format(up_since))
            debug("    kernel version   : {}".format(kernelVersion))
            debug("    RPi serial       : {}".format(rpiSerialNumber))
            debug("    inet address     : {}".format(localInetAddress))
            debug("    git revision     : {}".format(gitRevision))
            debug("    Signal strength  : {}%".format(signal_strength_percentage))
            debug("    Balance          : {}".format(balance_info))
            response_message = u'Hi!\n sysTime: {0}\n uptime: {1}\n kernel: {2}\n serial: {3}\n inet: {4}\n gitRev: {5}\n signal: {6}%\n $$: {7}.'.format(now_string, up_since, kernelVersion, rpiSerialNumber, localInetAddress, gitRevision, signal_strength_percentage, balance_info)
        
        
        elif sender_message_raw and sender_message_raw.lower().startswith('checkbalance'):
            ussd = self.config['ussdCheckBalance']
            self.__update_balance_if_necessary(force=True)
            balance_info = self.__get_cached_balance_info()
            debug("  responding with USSD reply for {}:".format(ussd))
            debug("  " + balance_info.encode('ascii', 'replace'))
            response_message = u'Hi! Current balance info:\n{0}'.format(balance_info)

        else:
            debug("  not recognized, answering with help message.")
            response_message = u"Hi! 'temp' to get current temperature, 'power' (+' on'/' off') to get (change) power status. Other commands: 'systeminfo', 'checkbalance'."
        
        time_before_send = time.time()
        try:
            sms_sender = SmsSender(self.config['gammuConfigFile'], self.config['gammuConfigSection']) 
            sms_sender.send_sms(response_message, sender_number)
            return TemperatureController.SMS_PROCESSED
        except (gammu.ERR_UNKNOWN):
            timeout_after_time = time.time() - time_before_send
            debug("Got exception after {} seconds while trying to send sms.".format(timeout_after_time))
            raise # re-raise exception so we get the stacktrace to stderr
コード例 #2
0
    if uptime > uptime_threshold:  # otherwise allow reboot script to run completely to clean up etc.

        config_parser = ConfigParser.SafeConfigParser()
        config_parser.read(CONFIG_FILEPATH)

        pgrep_pattern = 'python .*' + os.path.basename(__file__) + '\\\''
        pgrep_pids = systeminfo.get_pgrep_pids(pgrep_pattern)

        if len(pgrep_pids) < 1:
            debug("pgrep pattern wrong, my own script process not found: {}".
                  format(pgrep_pattern))
        elif len(pgrep_pids) == 1 and pgrep_pids[0] == os.getpid():
            debug(
                "START no other pid found for this script (PID: {}), going ahead with running power autocontroller..."
                .format(pgrep_pids))
            power_autocontroller = PowerAutocontroller(config_parser)

            current_temp_raw = temperaturereader.read_celsius()

            power_autocontroller.run(current_temp_raw)
            debug("DONE running power autocontroller.")
        else:
            debug(
                "Found other processes already running this script (PIDs: {}), skipping this script run."
                .format(pgrep_pids))

    else:
        debug(
            "Uptime ({0} seconds) is less than {1} seconds, skipping power autocontrolling."
            .format(uptime, uptime_threshold))