Python serial.serialutil.SerialException() Examples

The following are 30 code examples of serial.serialutil.SerialException(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module serial.serialutil , or try the search function .
Example #1
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def _is_in_atcmd_mode(self):
        """
        Returns whether the command mode is active or not.

        Returns:
            Boolean: ``True`` if the AT command mode is active, ``False`` otherwise.
        """
        _log.debug("Checking AT command mode...")
        try:
            self._serial_port.write(str.encode(_COMMAND_AT, encoding='utf-8'))
            answer = self._read_data(timeout=_GUARD_TIME)

            return answer is not None and _COMMAND_MODE_ANSWER_OK in answer
        except SerialException as e:
            _log.exception(e)
            return False 
Example #2
Source File: protocol_loop.py    From ddt4all with GNU General Public License v3.0 6 votes vote down vote up
def from_url(self, url):
        """extract host and port from an URL string"""
        parts = urlparse.urlsplit(url)
        if parts.scheme != "loop":
            raise SerialException(
                'expected a string in the form '
                '"loop://[?logging={debug|info|warning|error}]": not starting '
                'with loop:// ({!r})'.format(parts.scheme))
        try:
            # process options now, directly altering self
            for option, values in urlparse.parse_qs(parts.query, True).items():
                if option == 'logging':
                    logging.basicConfig()   # XXX is that good to call it here?
                    self.logger = logging.getLogger('pySerial.loop')
                    self.logger.setLevel(LOGGER_LEVELS[values[0]])
                    self.logger.debug('enabled logging')
                else:
                    raise ValueError('unknown option: {!r}'.format(option))
        except ValueError as e:
            raise SerialException(
                'expected a string in the form '
                '"loop://[?logging={debug|info|warning|error}]": {}'.format(e))

    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
Example #3
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def _supports_filesystem(self):
        """
        Returns whether the device supports file system or not.

        Returns:
             Boolean: ``True`` if the device supports file system, ``False`` otherwise.
        """
        _log.debug("Checking if device supports file system...")
        if not self._check_atcmd_mode():
            return False

        try:
            self._serial_port.write(str.encode(_COMMAND_FILE_SYSTEM, encoding='utf-8'))
            answer = self._read_data()
            if answer and _ANSWER_ATFS in answer.upper():
                self._parse_filesystem_functions(answer.replace("\r", ""))
                return True

            return False
        except SerialException as e:
            _log.exception(e)
            return False 
Example #4
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def disconnect(self):
        """
        Disconnects the file system manager and restores the device connection.

        Raises:
            XBeeException: if there is any error restoring the XBee device connection.
        """
        if not self._is_connected:
            return

        # Exit AT command mode.
        self._exit_atcmd_mode()

        # Restore serial port timeout.
        try:
            self._serial_port.set_read_timeout(self._old_read_timeout)
        except SerialException:
            pass
        self._serial_port.close()
        self._is_connected = False
        if self._device_was_connected:
            time.sleep(0.3)
            self._xbee_device.open() 
Example #5
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def _xmodem_read_cb(self, size, timeout=_READ_DATA_TIMEOUT):
        """
        Callback function used to read data from the serial port when requested from the XModem transfer.

        Args:
            size (Integer): the size of the data to read.
            timeout (Integer, optional): the maximum time to wait to read the requested data (seconds).

        Returns:
            Bytearray: the read data, ``None`` if data could not be read.
        """
        deadline = _get_milliseconds() + (timeout * 1000)
        data = bytearray()
        try:
            while len(data) < size and _get_milliseconds() < deadline:
                read_bytes = self._serial_port.read(size - len(data))
                if len(read_bytes) > 0:
                    data.extend(read_bytes)
            return data
        except SerialException as e:
            _log.exception(e)

        return None 
Example #6
Source File: uart.py    From fluxclient with GNU Affero General Public License v3.0 6 votes vote down vote up
def connect(self):
        try:
            if is_windows():
                self.s = Serial(port=self.port, baudrate=self.baudrate,
                                timeout=0.1)
            else:
                self.s = Serial(port=self.port, baudrate=self.baudrate,
                                timeout=0)
        except SerialException as e:
            raise ManagerException(*e.args, err_symbol=("DEVICE_ERROR", ))

        self.s.write(b"\x00" * 16)
        if is_windows():
            try:
                self.s.readall()  # Normally returns with empty string
            except SerialTimeoutException:
                logger.error("Serial timeout")
        else:
            while True:
                rl = select((self.s, ), (), (), 0.1)[0]
                if rl:
                    self.s.readall()
                else:
                    break
        self._discover() 
Example #7
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def _xmodem_write_cb(self, data):
        """
        Callback function used to write data to the serial port when requested from the XModem transfer.

        Args:
            data (Bytearray): the data to write to serial port from the XModem transfer.

        Returns:
            Boolean: ``True`` if the data was successfully written, ``False`` otherwise.
        """
        try:
            self._serial_port.purge_port()
            self._serial_port.write(data)
            self._serial_port.flush()
            return True
        except SerialException as e:
            _log.exception(e)

        return False 
Example #8
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def format_filesystem(self):
        """
        Formats the device file system.

        Raises:
            FileSystemException: if there is any error formatting the file system.
        """
        command = _COMMAND_ATFS % _FilesystemFunction.FORMAT.command
        _log.info("Formatting file system...")
        self._execute_command(_FilesystemFunction.FORMAT, wait_for_answer=False)
        try:
            deadline = _get_milliseconds() + (_FORMAT_TIMEOUT * 1000)
            ok_received = False
            while not ok_received and _get_milliseconds() < deadline:
                answer = self._read_data()
                self._check_function_error(answer, command)
                if _COMMAND_MODE_ANSWER_OK in answer:
                    ok_received = True
            if not ok_received:
                raise FileSystemException(_ERROR_TIMEOUT)
        except SerialException as e:
            raise FileSystemException(_ERROR_EXECUTE_COMMAND % (command.replace("\r", ""), str(e))) 
Example #9
Source File: protocol_loop.py    From android_universal with MIT License 6 votes vote down vote up
def from_url(self, url):
        """extract host and port from an URL string"""
        parts = urlparse.urlsplit(url)
        if parts.scheme != "loop":
            raise SerialException(
                'expected a string in the form '
                '"loop://[?logging={debug|info|warning|error}]": not starting '
                'with loop:// ({!r})'.format(parts.scheme))
        try:
            # process options now, directly altering self
            for option, values in urlparse.parse_qs(parts.query, True).items():
                if option == 'logging':
                    logging.basicConfig()   # XXX is that good to call it here?
                    self.logger = logging.getLogger('pySerial.loop')
                    self.logger.setLevel(LOGGER_LEVELS[values[0]])
                    self.logger.debug('enabled logging')
                else:
                    raise ValueError('unknown option: {!r}'.format(option))
        except ValueError as e:
            raise SerialException(
                'expected a string in the form '
                '"loop://[?logging={debug|info|warning|error}]": {}'.format(e))

    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
Example #10
Source File: recovery.py    From xbee-python with Mozilla Public License 2.0 6 votes vote down vote up
def _restore_target_connection(self):
        """
        Leaves the firmware update target connection (XBee device or serial port) in its original state.

        Raises:
            SerialException: if there is any error restoring the serial port connection.
            XBeeException: if there is any error restoring the device connection.
        """
        if self._xbee_device is not None:
            if self._xbee_serial_port is not None:
                if self._xbee_serial_port.isOpen():
                    self._xbee_serial_port.close()
            if self._device_was_connected and not self._xbee_device.is_open():
                self._xbee_device.open()
            elif not self._device_was_connected and self._xbee_device.is_open():
                self._xbee_device.close()
        elif self._xbee_serial_port is not None and self._xbee_serial_port.isOpen():
            self._xbee_serial_port.close()
        _log.debug("Restored target connection") 
Example #11
Source File: Plugwise-2.py    From Plugwise-2-py with GNU General Public License v3.0 6 votes vote down vote up
def get_status_json(self, mac):
        try:
            c = self.circles[self.bymac[mac]]
            control = self.controls[self.controlsbymac[mac]]
        except:
            info("get_status_json: mac not found in circles or controls")
            return ""
        try:
            status = c.get_status()
            status["monitor"] = (control['monitor'].lower() == 'yes')
            status["savelog"] = (control['savelog'].lower() == 'yes')
            #json.encoder.FLOAT_REPR = lambda f: ("%.2f" % f)
            #msg = json.dumps(status, default = jsondefault)
            msg = json.dumps(status)
        except (ValueError, TimeoutException, SerialException) as reason:
            error("Error in get_status_json: %s" % (reason,))
            msg = ""
        return str(msg) 
Example #12
Source File: Join-2.py    From Plugwise-2-py with GNU General Public License v3.0 6 votes vote down vote up
def test_offline(self):
        """
        When an unrecoverable communication failure with a circle occurs, the circle
        is set online = False. This function will test on this condition and if offline,
        it test whether it is available again, and if so, it will recover
        control settings and switching schedule if needed.
        In case the circle was offline during initialization, a reinit is performed.
        """
        for c in self.circles:
            if not c.online:
                try:
                    c.ping()
                    if c.online:
                        #back online. Make sure switch and schedule is ok
                        if not c.initialized:
                            c.reinit()
                            self.set_interval_production(c)
                        idx=self.controlsbymac[c.mac]
                        self.apply_control_to_circle(self.controls[idx], c.mac)
                except ValueError:
                    continue
                except (TimeoutException, SerialException) as reason:
                    debug("Error in test_offline(): %s" % (reason,))
                    continue 
Example #13
Source File: protocol_socket.py    From android3dblendermouse with Apache License 2.0 6 votes vote down vote up
def from_url(self, url):
        """extract host and port from an URL string"""
        parts = urlparse.urlsplit(url)
        if parts.scheme != "socket":
            raise SerialException('expected a string in the form "socket://<host>:<port>[?logging={debug|info|warning|error}]": not starting with socket:// (%r)' % (parts.scheme,))
        try:
            # process options now, directly altering self
            for option, values in urlparse.parse_qs(parts.query, True).items():
                if option == 'logging':
                    logging.basicConfig()   # XXX is that good to call it here?
                    self.logger = logging.getLogger('pySerial.socket')
                    self.logger.setLevel(LOGGER_LEVELS[values[0]])
                    self.logger.debug('enabled logging')
                else:
                    raise ValueError('unknown option: %r' % (option,))
            # get host and port
            host, port = parts.hostname, parts.port
            if not 0 <= port < 65536:
                raise ValueError("port not in range 0...65535")
        except ValueError as e:
            raise SerialException('expected a string in the form "socket://<host>:<port>[?logging={debug|info|warning|error}]": %s' % e)
        return (host, port)

    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
Example #14
Source File: Join-2.py    From Plugwise-2-py with GNU General Public License v3.0 6 votes vote down vote up
def sync_time(self):
        for c in self.circles:
            if not c.online:
                continue
            try:
                info("sync_time: circle %s time is %s" % (c.attr['name'], c.get_clock().isoformat()))
                if c.type()=='circle+':
                    #now = datetime.now()            
                    #local time not following DST (always non-DST)
                    locnow = datetime.utcnow()-timedelta(seconds=time.timezone)
                    now = locnow
                    c.set_circleplus_datetime(now)
                #now = datetime.now()            
                #local time not following DST (always non-DST)
                locnow = datetime.utcnow()-timedelta(seconds=time.timezone)
                now = locnow
                c.set_clock(now)
            except (ValueError, TimeoutException, SerialException) as reason:
                error("Error in sync_time: %s" % (reason,)) 
Example #15
Source File: Join-2.py    From Plugwise-2-py with GNU General Public License v3.0 6 votes vote down vote up
def get_status_json(self, mac):
        try:
            c = self.circles[self.bymac[mac]]
            control = self.controls[self.controlsbymac[mac]]
        except:
            info("get_status_json: mac not found in circles or controls")
            return ""
        try:
            status = c.get_status()
            status["monitor"] = (control['monitor'].lower() == 'yes')
            status["savelog"] = (control['savelog'].lower() == 'yes')
            #json.encoder.FLOAT_REPR = lambda f: ("%.2f" % f)
            #msg = json.dumps(status, default = jsondefault)
            msg = json.dumps(status)
        except (ValueError, TimeoutException, SerialException) as reason:
            error("Error in get_status_json: %s" % (reason,))
            msg = ""
        return str(msg) 
Example #16
Source File: serialwin32.py    From android3dblendermouse with Apache License 2.0 6 votes vote down vote up
def write(self, data):
        """Output the given byte string over the serial port."""
        if not self._port_handle:
            raise portNotOpenError
        #~ if not isinstance(data, (bytes, bytearray)):
            #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))
        # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview
        data = to_bytes(data)
        if data:
            #~ win32event.ResetEvent(self._overlapped_write.hEvent)
            n = win32.DWORD()
            err = win32.WriteFile(self._port_handle, data, len(data), ctypes.byref(n), self._overlapped_write)
            if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:
                raise SerialException("WriteFile failed (%r)" % ctypes.WinError())
            if self._write_timeout != 0:  # if blocking (None) or w/ write timeout (>0)
                # Wait for the write to complete.
                #~ win32.WaitForSingleObject(self._overlapped_write.hEvent, win32.INFINITE)
                err = win32.GetOverlappedResult(self._port_handle, self._overlapped_write, ctypes.byref(n), True)
                if n.value != len(data):
                    raise writeTimeoutError
            return n.value
        else:
            return 0 
Example #17
Source File: api.py    From Plugwise-2-py with GNU General Public License v3.0 6 votes vote down vote up
def send_msg(self, cmd):
        #log communication done in serialize function of message object. Could be too early!
        debug("SEND %4d %s" % (len(cmd), repr(cmd)))
        try:
            self.write(cmd)
        except SerialException as e:
            print e
            info("SerialException during write - recovering. msg %s" % str(e))
            self.reconnect()
        while 1:
            resp = self.expect_response(PlugwiseAckResponse)
            #test on sequence number, to be refined for wrap around
            if (self.last_counter - int(resp.command_counter, 16) >= 0):
                debug("Seqnr already used in send_msg")
            #in case a timeout on previous send occurs, then ignore here.
            if resp.status.value == 0xE1:
                debug("Ignoring 0xE1 status in send_msg")
                continue
            success = False
            if resp.status.value == 0xC1:
                success = True
            self.last_counter = int(resp.command_counter, 16)
            break
        return (success, resp.command_counter) 
Example #18
Source File: usb.py    From dizzy-legacy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def run(self):
        try:
            self.d.run()            
        except SerialException:
            pass
        except select.error:
            pass
        except OSError:
            pass
        except TypeError:
            pass
        except IndexError:
            pass
        except Exception as e:
            if DEBUG:
                traceback.print_exc()
            print(e)
        self.opened = False 
Example #19
Source File: usb.py    From dizzy-legacy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def close(self):
        if not self.open:
            return
        if not self.d is None:
            try:
                self.d.disconnect()
            except IndexError:
                pass
            except SerialException:
                pass
            except ValueError:
                pass
            except Exception as e:
                if DEBUG:
                    traceback.print_exc()
                print(e)
        if not self.sp is None:
            self.sp.close()
        self.open = False 
Example #20
Source File: filesystem.py    From xbee-python with Mozilla Public License 2.0 5 votes vote down vote up
def _read_data(self, timeout=_READ_DATA_TIMEOUT, empty_retries=_READ_EMPTY_DATA_RETRIES_DEFAULT):
        """
        Reads data from the serial port waiting for the provided timeout.

        Args:
            timeout (Integer, optional): the maximum time to wait for data (seconds). Defaults to 1 second.
            empty_retries (Integer, optional): the number of consecutive zero-bytes read before considering no more
                                               data is available.

        Returns:
            String: the read data as string.

        Raises:
            SerialException: if there is any problem reading data from the serial port.
        """
        answer_string = ""
        empty_attempts = 0
        deadline = _get_milliseconds() + (timeout * 1000)
        read_bytes = self._serial_port.read(_READ_BUFFER)
        while (len(answer_string) == 0 or empty_attempts < empty_retries) and _get_milliseconds() < deadline:
            read_string = _filter_non_printable(read_bytes)
            answer_string += read_string
            # Continue reading, maybe there is more data.
            read_bytes = self._serial_port.read(_READ_BUFFER)
            if len(read_string) == 0:
                empty_attempts += 1
            else:
                empty_attempts = 0

        return answer_string 
Example #21
Source File: uart.py    From fluxclient with GNU Affero General Public License v3.0 5 votes vote down vote up
def _make_request(self, code, buf=b"", timeout=6.0):
        try:
            header = struct.pack("<3sHH", b'\x97\xae\x02', code, len(buf))
            payload = header + buf
            self.s.write(payload)

            ttl = time() + timeout
            resp = b""
            while time() < ttl:
                rl = False
                if is_windows():
                    # In windows, the timeout=0.1 works like select
                    rl = True
                else:
                    rl = select((self.s, ), (), (), max(time() - ttl, 0))[0]
                if rl:
                    resp += self.s.readall()
                    if self._try_parse_response(code, resp):
                        status = struct.unpack("<b", resp[7:8])[0]
                        if status == 1:
                            return resp[8:]
                        else:
                            m = resp[8:].decode("ascii", "ignore")
                            raise ManagerError("Operation error",
                                               "status: %i" % status,
                                               err_symbol=m.split(" "))

            raise TimeoutError()
        except SerialException as e:
            logger.exception("UART device error")
            raise ManagerException(*e.args, err_symbol="DEVICE_ERROR") 
Example #22
Source File: Join-2.py    From Plugwise-2-py with GNU General Public License v3.0 5 votes vote down vote up
def get_relays(self):
        """
        Update the relay state for circles with schedules enabled.
        """
        for c in self.circles:
            if c.online and c.schedule_state == 'on':
                try:
                    c.get_info()
                except (TimeoutException, SerialException, ValueError) as reason:
                    debug("Error in get_relays(): %s" % (reason,))
                    continue
                #publish relay_state for schedule-operated circles.
                #could also be done unconditionally every 15 minutes in main loop.
                self.publish_circle_state(c.mac) 
Example #23
Source File: util.py    From Plugwise-2-py with GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, port="/dev/ttyUSB0", baud=115200, bits=8, stop=1, parity='N', timeout=5):
        self.connected = False
        self.port = port
        self.baud = baud
        self.bits = bits
        self.stop = stop
        self.parity = parity
        self.timeout = timeout
        self.open()
        # try:
            # self._fd = serial.Serial(port, baudrate=baud, bytesize=bits, stopbits=stop, parity=parity, timeout=timeout)
            # self.connected = True
        # except SerialException as e:
            # self.connected = False 
Example #24
Source File: api.py    From Plugwise-2-py with GNU General Public License v3.0 5 votes vote down vote up
def reinit(self):
        #self.get_info()  called by _get_interval
        try:
            self._get_interval()
            self.online = True
            self.online_changed = True
            self.initialized = True
        except (ValueError, TimeoutException, SerialException, AttributeError) as reason:
            self.online = False
            self.online_changed = True
            self.initialized = False
            error("OFFLINE Circle '%s' during initialization Error: %s" % (self.attr['name'], str(reason)))       
        self.pong = False 
Example #25
Source File: api.py    From Plugwise-2-py with GNU General Public License v3.0 5 votes vote down vote up
def find_circleplus(self):
        req = PlugwiseQueryCirclePlusRequest(self.mac)
        _, seqnr  = self.send_msg(req.serialize())
        #Receive the circle+ response, but possibly, only an end-protocol response is seen.
        success = False
        circleplusmac = None
        try:
            resp = self.expect_response(PlugwiseQueryCirclePlusResponse)
            success=True
            circleplusmac = resp.new_node_mac_id.value
        except (TimeoutException, SerialException) as reason:
            error("Error: %s, %s" % (datetime.datetime.now().isoformat(), str(reason),))        
        return success,circleplusmac 
Example #26
Source File: serial_connection.py    From thonny with MIT License 5 votes vote down vote up
def __init__(self, port, baudrate, skip_reader=False):
        import serial
        from serial.serialutil import SerialException

        super().__init__()

        try:
            self._serial = serial.Serial(port, baudrate=baudrate, timeout=None)
        except SerialException as error:
            err_str = str(error)
            if "FileNotFoundError" in err_str:
                err_str = "port not found"
            message = "Unable to connect to " + port + ": " + err_str

            # TODO: check if these error codes also apply to Linux and Mac
            if error.errno == 13 and platform.system() == "Linux":
                # TODO: check if user already has this group
                message += "\n\n" + dedent(
                    """\
                Try adding yourself to the 'dialout' group:
                > sudo usermod -a -G dialout <username>
                (NB! This needs to be followed by reboot or logging out and logging in again!)"""
                )

            elif "PermissionError" in message:
                message += "\n\n" + dedent(
                    """\
                If you have serial connection to the device from another program,
                then disconnect it there."""
                )

            elif error.errno == 16:
                message += "\n\n" + "Try restarting the device."

            raise ConnectionFailedException(message)

        if skip_reader:
            self._reading_thread = None
        else:
            self._reading_thread = threading.Thread(target=self._listen_serial, daemon=True)
            self._reading_thread.start() 
Example #27
Source File: gps.py    From RF-Monitor with GNU General Public License v2.0 5 votes vote down vote up
def run(self):
        try:
            self.__open()
            self.__read()
        except SerialException as error:
            event = Event(Events.GPS_ERROR, msg=error.message)
            post_event(self._eventHandler, event)
        except OSError as error:
            event = Event(Events.GPS_ERROR, msg=error)
            post_event(self._eventHandler, event)
        except ValueError as error:
            event = Event(Events.GPS_ERROR, msg=error)
            post_event(self._eventHandler, event)

        self.__close() 
Example #28
Source File: protocol_loop.py    From android_universal with MIT License 5 votes vote down vote up
def open(self):
        """\
        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        """
        if self.is_open:
            raise SerialException("Port is already open.")
        self.logger = None
        self.queue = queue.Queue(self.buffer_size)

        if self._port is None:
            raise SerialException("Port must be configured before it can be used.")
        # not that there is anything to open, but the function applies the
        # options found in the URL
        self.from_url(self.port)

        # not that there anything to configure...
        self._reconfigure_port()
        # all things set up get, now a clean start
        self.is_open = True
        if not self._dsrdtr:
            self._update_dtr_state()
        if not self._rtscts:
            self._update_rts_state()
        self.reset_input_buffer()
        self.reset_output_buffer() 
Example #29
Source File: pymata_express.py    From pymata-express with GNU Affero General Public License v3.0 5 votes vote down vote up
def shutdown(self):
        """
        This method attempts an orderly shutdown
        If any exceptions are thrown, they are ignored.

        """

        self.shutdown_flag = True

        # stop all reporting - both analog and digital
        for pin in range(len(self.analog_pins)):
            await self.disable_analog_reporting(pin)

        for pin in range(len(self.digital_pins)):
            await self.disable_digital_reporting(pin)

        try:
            if self.close_loop_on_shutdown:
                self.loop.stop()
            await self.send_reset()
            await self.serial_port.reset_input_buffer()
            await self.serial_port.close()
            if self.close_loop_on_shutdown:
                self.loop.close()
        except (RuntimeError, SerialException):
            pass 
Example #30
Source File: Join-2.py    From Plugwise-2-py with GNU General Public License v3.0 5 votes vote down vote up
def apply_schedule_changes(self):
        """ in case off a failure to upload schedule,
            c.online is set to False by api, so reload handled through
            self.test_offline() and self.apply_<func>_to_circle
        """

        debug("apply_schedule_changes()")
        for c in self.circles:
            if not c.online:
                continue
            if c.schedule != None:
                if c.schedule.name in self.schedulebyname:
                    sched = self.schedules[self.schedulebyname[c.schedule.name]]
                    if sched != c.schedule._watt:
                        info("apply_schedule_changes: schedule changed. Update in circle %s - %s" % (c.attr['name'], c.schedule.name))
                        #schedule changed so upload to this circle
                        c.define_schedule(c.schedule.name, sched, time.localtime().tm_isdst)
                        try:
                            sched_state = c.schedule_state
                            c.schedule_off()
                            c.load_schedule(time.localtime().tm_isdst)
                            #update scheduleCRC
                            c.get_clock()
                            if sched_state == 'on':
                                c.schedule_on()
                        except (ValueError, TimeoutException, SerialException) as reason:
                            #failure to upload schedule.
                            c.undefine_schedule() #clear schedule forces a retry at next call
                            error("Error during uploading schedule: %s" % (reason,))
                        self.publish_circle_state(c.mac)
                else:
                    error("Error during uploading schedule. Schedule %s not found." % (c.schedule.name,))