def handle_read(self): try : if self.bytes_available() == 0: # Socket is closing self.recv(0) else: self.read_packet() except Exception as e : logger.log_exception(e)
def handle_read_stdout(self): result = [] self.stdout_buffer = self.handle_read_channel(self.stdout_buffer, self.stdout, result) for code in result: try: packet = eval(code) if type(packet) == tuple : packet = packet[1] self.event_loop.process(self, packet) except Exception as e: logger.log("Unable to evaluate the process answer: '{}'".format(code)) logger.log_exception(e)
def status_update(self): _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) ret = None for name, data in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, data["mac"]) from btlewrap import BluetoothBackendException try: yield self.update_device_state(name, data["poller"]) self.fail_count = 0 except BluetoothBackendException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, data["mac"], type(e).__name__, suppress=True, ) self.fail_count = self.fail_count + 1 except DeviceTimeoutError as e: logger.log_exception( _LOGGER, "Time out during update of %s device '%s' (%s)", repr(self), name, data["mac"], suppress=True, ) self.fail_count = self.fail_count + 1 finally: if self.fail_count > self.max_fail_count: ret.append( MqttMessage( self.format_topic(name, "availability"), payload="offline", retain=True ) ) return ret
def status_update(self): from bluepy import btle _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) for name, device in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, device.mac) try: yield self.update_device_state(name, device) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, device.mac, type(e).__name__, suppress=True, )
def on_command(self, topic, value): from bluepy import btle topic_without_prefix = topic.replace('{}/'.format(self.topic_prefix), '') device_name, method, _ = topic_without_prefix.split('/') data = self.devices[device_name] value = value.decode('utf-8') if method == STATE_AWAY: method = "mode" value = self.ModesMapper.on_off_to_mode(value) # It needs to be on separate if because first if can change method if method == "mode": value = self._modes_mapper.get_reverse_mapping(value) elif method == "target_temperature": value = float(value) _LOGGER.info("Setting %s to %s on %s device '%s' (%s)", method, value, repr(self), device_name, data["mac"]) try: setattr(data["thermostat"], method, value) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error setting %s to %s on %s device '%s' (%s): %s", method, value, repr(self), device_name, data["mac"], type(e).__name__) return [] try: return self.update_device_state(device_name, data["thermostat"]) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), device_name, data["mac"], type(e).__name__, suppress=True) return []
def status_update(self): _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) ret = [] for name, data in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, data["mac"]) from btlewrap import BluetoothBackendException try: ret += self.update_device_state(name, data["poller"]) except BluetoothBackendException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, data["mac"], type(e).__name__, suppress=True) return ret
def get_state(self): if isinstance(self.handler_state, statemachine.State): return self.handler_state else : if self.ctor_parameters is not None: try : logger.log('Next state : {}{}'.format(self.handler_state.__name__, self.ctor_parameters)) return self.handler_state(*self.ctor_parameters) except Exception as e : logger.dbg("Exception while calling constructor for {} with parameters".format(self.handler_state, self.ctor_parameters)) logger.log_exception(e) raise else: try : logger.log('Next state : {}()'.format(self.handler_state.__name__)) return self.handler_state() except Exception as e : logger.dbg("Exception while calling constructor for {}".format(self.handler_state)) logger.log_exception(e) raise
def crawl_over_prices(storage, lastmod): ids_of_products_with_stale_prices = storage.get_ids_of_products_with_stale_prices( ) batch_size = 50 for i in range( 0, math.ceil(len(ids_of_products_with_stale_prices) / batch_size)): try: batch_with_product_ids = ids_of_products_with_stale_prices[ i * batch_size:(i + 1) * batch_size] stockprice_objs = get_stockprice_obj(batch_with_product_ids) if not stockprice_objs: continue asos_prices = [ AsosPrice.from_stockprice_obj(lastmod, so) for so in stockprice_objs ] storage.stage_prices(asos_prices) time.sleep(0.25) except requests.ConnectionError: log_exception()
def status_update(self): from bluepy import btle ret = [] _LOGGER.debug("Updating %d %s devices", len(self.devices), repr(self)) for name, bot in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, bot["mac"]) try: ret += self.update_device_state(name, bot["state"]) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, bot["mac"], type(e).__name__, suppress=True, ) return ret
def status_update(self): from bluepy import btle _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) for name, data in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, data["mac"]) thermostat = data["thermostat"] try: thermostat.update() except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, data["mac"], type(e).__name__, suppress=True, ) else: yield self.present_device_state(name, thermostat)
def main_loop(self): while True: if not self.website.in_stock(self.driver, self.timeout, self.id): logger.log(f"{self.website.name} is out of stock. Retrying.", self.id) time.sleep(self.sleep_time) try: self.driver.get(self.website.url) except TimeoutException: logger.log(f"Reloading webpage timed out...", self.id) except Exception as e: logger.log(f"Unexpected error loading page... Continuing.", self.id) logger.log_exception(e, self.id) continue logger.log(f"{self.website.name} is in stock!", self.id) try: self.website.add_to_cart(self.driver, self.timeout, self.id) except Exception as e: logger.log("Exception occured while adding to cart...", self.id) logger.log_exception(e, self.id) continue try: purchase_result = self.website.checkout(self.driver, self.timeout, self.id) except Exception as e: logger.log(f"Exception occured while checking out...", self.id) logger.log_exception(e, self.id) continue if purchase_result: logger.log(f"Purchase successful from {self.website.url}", self.id) break
def send_eacq_init() -> tuple: """Sends Init and handles possible answers and exceptions. Can be used as example of realization only. """ order_id = gen_order_id() try: answer_code, init_response = eacq.init(order_id, two_step=True) payment_url = init_response["PaymentURL"] eacq.set_internal_payment_status(init_response["Status"]) payment_id = init_response["PaymentId"] webbrowser.open_new(payment_url) time.sleep(20) get_state_response = eacq.get_state(payment_id) eacq.set_internal_payment_status(get_state_response[1]["Status"]) return payment_id, get_state_response except ConnectionError: logger.log_into_file('send_eacq_init', 'Error', message='Connection error') logger.log_exception(ConnectionError, exc_info=True) except MAPI_EACQ.RequestError: logger.log_into_file('send_eacq_init', 'Error', message='Request was not successful') logger.log_exception(MAPI_EACQ.RequestError, exc_info=True) except MAPI_EACQ.PaymentStatusError: logger.log_into_file('send_eacq_init', 'Error', message='Connection error') logger.log_exception(MAPI_EACQ.PaymentStatusError, exc_info=True)
def send_eacq_confirm(payment_id: str) -> dict: """ Sends Confirm and handles possible answers and exceptions. Can be used as example of realization only. :param payment_id: str :return: payment gateway response dictionary """ try: answer_code, confirm_response = eacq.confirm(payment_id) eacq.set_internal_payment_status(confirm_response["Status"]) return confirm_response except ConnectionError: logger.log_into_file('send_eacq_confirm', 'Error', message='Connection error') logger.log_exception("Exception occurred", exc_info=True) except MAPI_EACQ.RequestError: logger.log_into_file('send_eacq_init', 'Error', message='Request was not successful') logger.log_exception(MAPI_EACQ.RequestError, exc_info=True) except MAPI_EACQ.PaymentStatusError: logger.log_into_file('send_eacq_init', 'Error', message='Connection error') logger.log_exception(MAPI_EACQ.PaymentStatusError, exc_info=True)
def _get_height(self): from bluepy import btle with timeout( self.SCAN_TIMEOUT, exception=DeviceTimeoutError( "Retrieving the height from {} device {} timed out after {} seconds" .format(repr(self), self.mac, self.SCAN_TIMEOUT)), ): try: self.desk.read_dpg_data() return self.desk.current_height_with_offset.cm + self.desk_offset_cm except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of linak desk '%s' (%s): %s", repr(self), self.mac, type(e).__name__, suppress=True, ) raise DeviceTimeoutError
def status_update(self): _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) for name, data in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, data["mac"]) from btlewrap import BluetoothBackendException try: with timeout(self.per_device_timeout, exception=DeviceTimeoutError): yield retry(self.update_device_state, retries=self.update_retries, exception_type=BluetoothBackendException)( name, data["poller"]) except BluetoothBackendException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, data["mac"], type(e).__name__, suppress=True, ) self.avail_offline() except DeviceTimeoutError: logger.log_exception( _LOGGER, "Time out during update of %s device '%s' (%s)", repr(self), name, data["mac"], suppress=True, ) self.avail_offline()
def status_update(self): from bluepy import btle _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) if self.passive: scanner = btle.Scanner() results = scanner.scan( self.scan_timeout if hasattr(self, 'scan_timeout') else 20.0, passive=True) for res in results: device = self.find_device(res.addr) if device: for (adtype, desc, value) in res.getScanData(): if ("1a18" in value): _LOGGER.debug("%s - received scan data %s", res.addr, value) device.processScanValue(value) for name, device in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, device.mac) # from btlewrap import BluetoothBackendException try: with timeout(self.command_timeout, exception=DeviceTimeoutError): yield self.update_device_state(name, device) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, device.mac, type(e).__name__, suppress=True, ) except TypeError: logger.log_exception( _LOGGER, "Data error during update of %s device '%s' (%s)", repr(self), name, device.mac, suppress=True, ) except DeviceTimeoutError: logger.log_exception( _LOGGER, "Time out during update of %s device '%s' (%s)", repr(self), name, device.mac, suppress=True, )
def status_update(self): from bluepy import btle _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) ret = [] try: devices = self.scanner.scan(float(self.scan_timeout), passive=booleanize(self.scan_passive)) mac_addresses = {device.addr: device for device in devices} for status in self.last_status: device = mac_addresses.get(status.mac, None) status.set_status(device is not None) ret += status.generate_messages(device) ret += self.parse_payload(device, status.name) uniqueId = status.mac.replace(':', '', 5) autoconf_data = self.get_autoconf_data(uniqueId, status.name) if autoconf_data != False: _LOGGER.info("Autoconfiguring %s %s", uniqueId, status.name) ret += autoconf_data except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update (%s)", repr(self), type(e).__name__, suppress=True, ) return ret
def single_device_status_update(self, device_name, data): import Zemismart _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), device_name, data["mac"]) shade = Zemismart.Zemismart(data["mac"], data["pin"], max_connect_time=self.per_device_timeout, withMutex=True) try: with shade: ret = [] device_state = self.get_device_state(device_name, data, shade) ret += self.create_mqtt_messages(device_name, device_state) if not device_state['positionState'].endswith( 'ing' ) and self.default_update_interval != self.update_interval: ret.append( MqttMessage(topic=self.format_topic('update_interval'), payload=self.default_update_interval)) return ret except AttributeError as e: # This type of error can be thrown from time to time if the underlying # zemismart library doesn't connect correctly logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), device_name, data["mac"], type(e).__name__, suppress=True, )
def read_packet(self): while True: if self.packet is None: try: b = self.bytes_available() if b == 0: return received_data = self.recv(1) if len(received_data) == 0: return self.buffer += received_data try: self.packet = packets.create_packet(self.buffer) except packets.PacketNotFoundException as e: logger.error("Packet not found (type={})".format( e.packet_type)) logger.error("Last good packet : {} size={}".format( self.last_good_packet, self.last_good_packet.get_size())) except socket.error as err: if err.errno in [errno.EAGAIN, errno.EINTR]: return logger.log_exception(err) return else: try: packet_size = self.packet.get_size() try: if self.bytes_available() < packet_size - 1: return received_data = self.recv(packet_size - len(self.buffer)) if len(received_data) == 0: return self.buffer += received_data except socket.error as err: if err.errno in [errno.EAGAIN, errno.EINTR]: return logger.log_exception(err) return if len(self.buffer) == packet_size: # A complete packet has been received, notify the state machine self.packet.deserialize(self.buffer) self.last_good_packet = self.packet self.event_loop.process(self, self.packet) self.buffer = bytes() self.packet = None except Exception as e: self.packet = None self.buffer = bytes() logger.log_exception(e)
def get_file_list(file_path: str): try: file_entries = get_file_entries(file_path) return render_template("file_list.html", current_path=PathInfo(file_path), file_entries=file_entries) except FileNotFoundError: log_exception() return "Directory not found.", 404 except NotADirectoryError: log_exception() return "Path is not a directory.", 406 except Exception as ex: log_exception(repr(ex)) return f"Error occurred when viewing the directory. ({ex})", 500
def status_update(self): _LOGGER.info("Updating %d %s devices", len(self.devices), repr(self)) # Trigger update of sensors self.poller.update_ble() for name, data in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, data) from btlewrap import BluetoothBackendException try: with timeout(self.per_device_timeout, exception=DeviceTimeoutError): yield self.update_device_state(name, data, self.poller) except BluetoothBackendException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, data, type(e).__name__, suppress=True, ) except DeviceTimeoutError: logger.log_exception( _LOGGER, "Time out during update of %s device '%s' (%s)", repr(self), name, data, suppress=True, ) except RuntimeError as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, data, type(e).__name__, suppress=True, )
def read_packet(self): while True: if self.packet is None: try: b = self.bytes_available() if b == 0: return received_data = self.recv(1) if len(received_data) == 0: return self.buffer += received_data self.packet = packets.create_packet(self.buffer) except socket.error as err: if err.errno in [errno.EAGAIN, errno.EINTR]: return logger.log_exception(err) return else: try: try: if self.bytes_available() < self.packet.MAX_SIZE - 1: return received_data = self.recv(self.packet.MAX_SIZE - len(self.buffer)) if len(received_data) == 0: return self.buffer += received_data except socket.error as err: if err.errno in [errno.EAGAIN, errno.EINTR]: return logger.log_exception(err) return if len(self.buffer) == self.packet.MAX_SIZE: # A complete packet has been received, notify the state machine self.packet.deserialize(self.buffer) self.event_loop.process(self, self.packet) self.buffer = bytes() self.packet = None except Exception as e: self.packet = None self.buffer = bytes() logger.log_exception(e)
def read_packet(self): while True : if self.packet is None: try: b = self.bytes_available() if b == 0: return received_data = self.recv(1) if len(received_data) == 0: return self.buffer += received_data self.packet = packets.create_packet(self.buffer) except socket.error as err: if err.errno in [errno.EAGAIN, errno.EINTR]: return logger.log_exception(err) return else: try: try: if self.bytes_available() < self.packet.MAX_SIZE - 1: return received_data = self.recv(self.packet.MAX_SIZE - len(self.buffer)) if len(received_data) == 0: return self.buffer += received_data except socket.error as err: if err.errno in [errno.EAGAIN, errno.EINTR]: return logger.log_exception(err) return if len(self.buffer) == self.packet.MAX_SIZE: # A complete packet has been received, notify the state machine self.packet.deserialize(self.buffer) self.event_loop.process(self, self.packet) self.buffer = bytes() self.packet = None except Exception as e: self.packet = None self.buffer = bytes() logger.log_exception(e)
def crawl(storage): start_dtm = dt.datetime.now().astimezone(dt.timezone.utc) last_process_status = storage.get_last_process_status() if last_process_status and last_process_status.is_running(): msg = 'Process with ID {} is still running. Finishing...'.format( last_process_status.process_id) log_message(msg) return if last_process_status and last_process_status.is_success( ) or not last_process_status: last_run_failed = False stg_product_ids = set() process_status = storage.log_new_process(start_dtm=start_dtm) storage.truncate_stage() storage.populate_stale_prices() if last_process_status and last_process_status.is_error(): last_run_failed = True stg_product_ids = storage.get_stg_product_ids() process_status = last_process_status.copy() process_status.set_running() storage.update_process_status(process_status) msg = 'Process {} has started at {}. Last process status: *{}*'.format( process_status.process_id, start_dtm, last_process_status.status if last_process_status else 'NOT EXISTED') log_message(msg) try: if storage.need_to_update_web_categories(): crawl_over_web_categories(storage, start_dtm) crawl_over_prices(storage, start_dtm) products_lastmod = storage.get_products_lastmod() sitemap_urls = parse_root_sitemap(ROOT_SITEMAP_URL) for sitemap_url in sitemap_urls: for url, product_id, lastmod in get_product_urls_from_sitemap( sitemap_url, products_lastmod): try: if last_run_failed and product_id in stg_product_ids: continue product_obj = get_product_obj(product_id) asos_product = AsosProduct(url, lastmod, product_obj) storage.stage_product(asos_product) process_status.cnt += 1 time.sleep(0.25) except requests.ConnectionError as e: log_exception() #remove this when all img_urls are filled for url, product_id, lastmod in storage.db.execute( 'select url, id, lastmod from products where img_url is null and id in (select product_id from prices_stg) limit 300' ).fetchall(): try: if last_run_failed and product_id in stg_product_ids: continue product_obj = get_product_obj(product_id) asos_product = AsosProduct(url, lastmod, product_obj) storage.db.execute(storage.sql_stage_product, asos_product.get_product_stg_json()) process_status.cnt += 1 time.sleep(0.25) except requests.ConnectionError as e: log_exception() storage.db.commit() #block finish storage.load_stage_into_storage() process_status.end_dtm = dt.datetime.now().astimezone(dt.timezone.utc) process_status.set_succeeded() except Exception as e: log_exception() process_status.set_error() finally: storage.update_process_status(process_status) storage.close() msg = 'Process {} finished with status *{}* on {}. Updated products: {}'.format( process_status.process_id, process_status.status, dt.datetime.now().astimezone(dt.timezone.utc), process_status.cnt) log_message(msg)
def on_command(self, topic, value): _LOGGER.info("On command called with %s %s", topic, value) import Zemismart topic_without_prefix = topic.replace("{}/".format(self.topic_prefix), "") device_name, field, action = topic_without_prefix.split("/") ret = [] if device_name in self.devices: data = self.devices[device_name] _LOGGER.debug("On command got device %s %s", device_name, data) else: logger.log_exception( _LOGGER, "Ignore command because device %s is unknown", device_name) return ret value = value.decode("utf-8") if field == "positionState" and action == "set": shade = Zemismart.Zemismart( data["mac"], data["pin"], max_connect_time=self.per_device_timeout, withMutex=True) try: with shade: device_state = self.get_device_state( device_name, data, shade) device_position = self.correct_value( data, device_state["currentPosition"]) if value == 'STOP': shade.stop() device_state = { "currentPosition": device_position, "targetPosition": device_position, "battery": shade.battery, "positionState": 'stopped' } self.last_target_position = device_position if self.default_update_interval: ret.append( MqttMessage( topic=self.format_topic('update_interval'), payload=self.default_update_interval)) ret += self.create_mqtt_messages( device_name, device_state) elif value == 'OPEN' and device_position > self.target_range_scale: # Yes, for open command we need to call close(), because "closed blinds" in AM43 # means that they're hidden, and the window is full open shade.close() device_state = { "currentPosition": device_position, "targetPosition": 0, "battery": shade.battery, "positionState": 'opening' } self.last_target_position = 0 if self.default_update_interval: self.update_interval = 3 ret.append( MqttMessage( topic=self.format_topic('update_interval'), payload=3)) ret += self.create_mqtt_messages( device_name, device_state) elif value == 'CLOSE' and device_position < 100 - self.target_range_scale: # Same as above for 'OPEN': we need to call open() when want to close() the window shade.open() device_state = { "currentPosition": device_position, "targetPosition": 100, "battery": shade.battery, "positionState": 'closing' } self.last_target_position = 100 ret += self.create_mqtt_messages( device_name, device_state) if self.default_update_interval: self.update_interval = 3 ret.append( MqttMessage( topic=self.format_topic('update_interval'), payload=3)) except AttributeError as e: # This type of error can be thrown from time to time if the underlying # zemismart library doesn't connect correctly logger.log_exception( _LOGGER, "Error setting %s to %s on %s device '%s' (%s): %s", field, value, repr(self), device_name, data["mac"], type(e).__name__, ) elif field == "targetPosition" and action == "set": # internal state of the target position should align with the scale used by the # device if self.target_range_scale <= int( value) <= 100 - self.target_range_scale: value = int((int(value) - self.target_range_scale) * (100 / (100 - self.target_range_scale * 2))) target_position = self.correct_value(data, int(value)) self.last_target_position = target_position shade = Zemismart.Zemismart( data["mac"], data["pin"], max_connect_time=self.per_device_timeout, withMutex=True) try: with shade: # get the current state so we can work out direction for update messages # after getting this, convert so we are using the device scale for # values device_state = self.get_device_state( device_name, data, shade) device_position = self.correct_value( data, device_state["currentPosition"]) if device_position == target_position: # no update required, not moved _LOGGER.debug( "Position for device '%s' (%s) matches, %s %s", device_name, data["mac"], device_position, value) return [] else: # work out the direction # this compares the values using the caller scale instead # of the internal scale. if device_state["currentPosition"] < int(value): state = "closing" else: state = "opening" # send the new position shade.set_position(target_position) device_state = { "currentPosition": device_position, "targetPosition": target_position, "battery": shade.battery, "positionState": state } ret += self.create_mqtt_messages( device_name, device_state) if self.default_update_interval: self.update_interval = 3 ret.append( MqttMessage( topic=self.format_topic('update_interval'), payload=3)) except AttributeError as e: # This type of error can be thrown from time to time if the underlying # zemismart library doesn't connect correctly logger.log_exception( _LOGGER, "Error setting %s to %s on %s device '%s' (%s): %s", field, value, repr(self), device_name, data["mac"], type(e).__name__, ) elif field == "get" or action == "get": ret += self.single_device_status_update(device_name, data) return ret
def on_command(self, topic, value): from bluepy import btle from bluepy.btle import Peripheral _, _, device_name, _ = topic.split("/") bot = self.devices[device_name] value = value.decode("utf-8") # It needs to be on separate if because first if can change method _LOGGER.debug( "Setting %s on %s device '%s' (%s)", value, repr(self), device_name, bot["mac"], ) try: bot["bot"] = Peripheral(bot["mac"], "random") hand_service = bot["bot"].getServiceByUUID( "cba20d00-224d-11e6-9fb8-0002a5d5c51b" ) hand = hand_service.getCharacteristics( "cba20002-224d-11e6-9fb8-0002a5d5c51b" )[0] if bot["pw"]: cmd = b'\x57\x11' + bot["pw"] else: cmd = b'\x57\x01' if value == STATE_ON: cmd += b'\x01' hand.write(cmd) elif value == STATE_OFF: cmd += b'\x02' hand.write(cmd) elif value == "PRESS": hand.write(cmd) bot["bot"].disconnect() except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error setting %s on %s device '%s' (%s): %s", value, repr(self), device_name, bot["mac"], type(e).__name__, ) return [] try: return self.update_device_state(device_name, value) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), device_name, bot["mac"], type(e).__name__, suppress=True, ) return []
try: arg_parser = argparse.ArgumentParser( description='Live baseball scoreboard emulator.') arg_parser.add_argument('--team', action='store', default="Red Sox", type=str, help='') arg_parser.add_argument("-v", "--virtual", help="Run scoreboard in virtual mode.", action="store_true") arg_parser.add_argument("-d", "--debug", help="Run scoreboard in debug mode.", action="store_true") arg_parser.add_argument("-r", "--record", help="Record game events to json file.", action="store_true") args = arg_parser.parse_args() scoreboard = VirtualScoreboard( ) if args.virtual else PhysicalScoreboard() scoreboard.run(vars(args)) except Exception as ex: paul_bunyan.log_exception(ex) print("Exit from exception: ", ex) # end __main__
def on_command(self, topic, value): _LOGGER.info("On command called with %s %s", topic, value) import Zemismart topic_without_prefix = topic.replace("{}/".format(self.topic_prefix), "") device_name, field, action = topic_without_prefix.split("/") if device_name in self.devices: data = self.devices[device_name] _LOGGER.debug("On command got device %s %s", device_name, data) else: logger.log_exception( _LOGGER, "Ignore command because device %s is unknown", device_name) return [] value = value.decode("utf-8") if field == "targetPosition" and action == "set": # internal state of the target position should align with the scale used by the # device target_position = self.correct_value(data, int(value)) self.last_target_position = target_position shade = Zemismart.Zemismart( data["mac"], data["pin"], max_connect_time=self.per_device_timeout, withMutex=True) try: with shade: # get the current state so we can work out direction for update messages # after getting this, convert so we are using the device scale for # values device_state = self.get_device_state( device_name, data, shade) device_position = self.correct_value( data, device_state["currentPosition"]) if device_position == target_position: # no update required, not moved _LOGGER.debug( "Position for device '%s' (%s) matches, %s %s", device_name, data["mac"], device_position, value) return [] else: # work out the direction # this compares the values using the caller scale instead # of the internal scale. if device_state["currentPosition"] < int(value): direction = "DECREASING" else: direction = "INCREASING" # send the new position shade.set_position(target_position) # Until we reach a point where the position stops moving, send # updated state messages # Setting this initially to a large invalid value so we get at least one update device_position = 255 while not ( target_position - self.target_range_scale ) <= device_position <= ( target_position + self.target_range_scale ) or self.last_target_position != target_position: _LOGGER.debug( "Moving %s device '%s' (%s), %s %s %s %s", repr(self), device_name, data["mac"], direction, device_position, shade.position, target_position) shade.update() if device_position != shade.position: # Initially thought this would send state updates as it goes, # sends them all in bulk at the end! # device_state = { # "currentPosition": self.correct_value(data, shade.position), # "targetPosition": int(value), # "battery": shade.battery, # "positionState": direction # } # yield self.create_mqtt_messages(device_name, device_state) device_position = shade.position # SLEEP 1s, if shade is moving it's position will # have changed when we loop back around time.sleep(1) _LOGGER.debug( "%s Exited loop for device '%s' (%s), %s %s %s %s %s", repr(self), device_name, data["mac"], direction, device_position, shade.position, self.last_target_position, target_position) # Device has finished updating, return one last message saying we stopped # Also set the last target position, we won't always stop bang # on where we targeted. self.last_target_position = device_position device_state = { "currentPosition": self.correct_value(data, device_position), "targetPosition": self.correct_value(data, device_position), "battery": shade.battery, "positionState": "STOPPED" } return self.create_mqtt_messages( device_name, device_state) except AttributeError as e: # This type of error can be thrown from time to time if the underlying # zemismart library doesn't connect correctly logger.log_exception( _LOGGER, "Error setting %s to %s on %s device '%s' (%s): %s", field, value, repr(self), device_name, data["mac"], type(e).__name__, ) return [] elif field == "get" or action == "get": return self.single_device_status_update(device_name, data) else: return []
def on_command(self, topic, value): from bluepy import btle from eq3bt import Mode default_fallback_mode = Mode.Auto topic_without_prefix = topic.replace("{}/".format(self.topic_prefix), "") device_name, method, _ = topic_without_prefix.split("/") if device_name in self.devices: data = self.devices[device_name] thermostat = data["thermostat"] else: logger.log_exception(_LOGGER, "Ignore command because device %s is unknown", device_name) return [] value = value.decode("utf-8") if method == "mode": state_mapping = { STATE_HEAT: Mode.Manual, STATE_AUTO: Mode.Auto, STATE_OFF: Mode.Closed, } if value in state_mapping: value = state_mapping[value] else: logger.log_exception(_LOGGER, "Invalid mode setting %s", value) return [] elif method == "hold": if value == HOLD_BOOST: method = "mode" value = Mode.Boost elif value in (HOLD_COMFORT, HOLD_ECO): method = "preset" elif value == "off": method = "mode" value = default_fallback_mode else: logger.log_exception(_LOGGER, "Invalid hold setting %s", value) return [] elif method == "away": method = "mode" if value == 'OFF': value = default_fallback_mode else: value = Mode.Away elif method == "target_temperature": value = float(value) _LOGGER.info( "Setting %s to %s on %s device '%s' (%s)", method, value, repr(self), device_name, data["mac"], ) try: if method == "preset": if value == HOLD_COMFORT: thermostat.activate_comfort() else: thermostat.activate_eco() else: setattr(thermostat, method, value) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error setting %s to %s on %s device '%s' (%s): %s", method, value, repr(self), device_name, data["mac"], type(e).__name__, ) return [] return self.present_device_state(device_name, thermostat)
def read_payload_cmd_start(self, device_name, payload, topic): try: cmd_start = {} cmd_start = json.loads(payload) _LOGGER.info( "MelsecplcWorker --> read_payload_cmd_start: payload = " + payload) _LOGGER.info( "MelsecplcWorker --> read_payload_cmd_start: cmd_start = " + str(cmd_start)) _LOGGER.info( "MelsecplcWorker --> read_payload_cmd_start: cmd_start['Device_Info] = " + str(cmd_start['Device_Info'])) sendout_topic = topic + "/Ack" if cmd_start['Cmd_Type'] == "Start": connect_status = 'OK' self.devices.update({device_name: cmd_start['Device_Info']}) # 連線設定完成 if not self.start_to_collect: self.create_devices() for status in self.last_status: if status.p_device == None: connect_status = 'NG' ret_json = {} ret_json.update({'Cmd_Result': connect_status}) ret_json.update({'Trace_ID': cmd_start['Trace_ID']}) json_msg = json.dumps(ret_json) self.Job_queue.put( [MqttMessage(topic=sendout_topic, payload=json_msg)]) if connect_status == 'NG': self.Status = "Down" self.report_alarm('1001', 'ERROR', 'Connected PLC Faild') else: self.Status = "Ready" self.report_alarm('0001', 'INFO', 'Connected PLC successed') else: ret_json = {} ret_json.update({'Cmd_Result': "NG"}) ret_json.update({'Trace_ID': cmd_start['Trace_ID']}) json_msg = json.dumps(ret_json) self.Job_queue.put( [MqttMessage(topic=sendout_topic, payload=json_msg)]) # 補送Alarm to MQTT self.report_alarm('1002', 'ERROR', 'Cmd_Type not Start') except Exception as ee: logger.log_exception(_LOGGER, 'Cmd Start Exception Error Msg : %s', str(ee)) self.Status = "Down" ret_json = {} ret_json.update({'Cmd_Result': "NG"}) ret_json.update({'Trace_ID': cmd_start['Trace_ID']}) json_msg = json.dumps(ret_json) self.Job_queue.put( [MqttMessage(topic=sendout_topic, payload=json_msg)]) # 補送Alarm to MQTT self.report_alarm( '1003', 'ERROR', 'Cmd_Type Start happened exception error :' + str(ee))
def test_log_exception(caplog): """Test correct exception message is logged""" msg = 'Test exception' logger.log_exception(msg) assert msg in caplog.text assert 'ERROR' in caplog.text
_LOGGER.info('Starting') global_topic_prefix = settings['mqtt'].get('topic_prefix') mqtt = MqttClient(settings['mqtt']) manager = WorkersManager(settings['manager']) manager.register_workers(global_topic_prefix).start(mqtt) running = True while running: try: mqtt.publish(_WORKERS_QUEUE.get(timeout=10).execute()) except queue.Empty: # Allow for SIGINT processing pass except TimeoutError as e: logger.log_exception( _LOGGER, str(e) if str(e) else 'Timeout while executing worker command', suppress=True) except (KeyboardInterrupt, SystemExit): running = False _LOGGER.info( 'Finish current jobs and shut down. If you need force exit use kill' ) except Exception as e: logger.log_exception(_LOGGER, "Fatal error while executing worker command: %s", type(e).__name__) raise e
def on_command(self, topic, value): from bluepy import btle import binascii from bluepy.btle import Peripheral _, _, device_name, _ = topic.split("/") lightstring = self.devices[device_name] value = value.decode("utf-8") # It needs to be on separate if because first if can change method _LOGGER.debug( "Setting %s on %s device '%s' (%s)", value, repr(self), device_name, lightstring["mac"], ) success = False while not success: try: lightstring["lightstring"] = Peripheral(lightstring["mac"]) if value == STATE_ON: lightstring["lightstring"].writeCharacteristic( HAND, binascii.a2b_hex(HEX_STATE_ON)) elif value == STATE_OFF: lightstring["lightstring"].writeCharacteristic( HAND, binascii.a2b_hex(HEX_STATE_OFF)) else: lightstring["lightstring"].writeCharacteristic( HAND, binascii.a2b_hex(HEX_CONF_PREFIX) + bytes([int(value)])) lightstring["lightstring"].disconnect() success = True except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error setting %s on %s device '%s' (%s): %s", value, repr(self), device_name, lightstring["mac"], type(e).__name__, ) success = True try: if value in (STATE_ON, STATE_OFF): return self.update_device_state(device_name, value) else: return self.update_device_conf(device_name, value) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), device_name, lightstring["mac"], type(e).__name__, suppress=True, ) return []
def status_update(self): from bluepy import btle import binascii from bluepy.btle import Peripheral class MyDelegate(btle.DefaultDelegate): def __init__(self): self.state = '' btle.DefaultDelegate.__init__(self) def handleNotification(self, cHandle, data): try: if data[3] in (0, 3): self.state = "OFF" else: self.state = "ON" except: self.state = -1 class ConfDelegate(btle.DefaultDelegate): def __init__(self): self.conf = 0 btle.DefaultDelegate.__init__(self) def handleNotification(self, cHandle, data): try: self.conf = int(data[17]) except: self.conf = -1 delegate = MyDelegate() cdelegate = ConfDelegate() ret = [] _LOGGER.debug("Updating %d %s devices", len(self.devices), repr(self)) for name, lightstring in self.devices.items(): _LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, lightstring["mac"]) try: lightstring["lightstring"] = Peripheral(lightstring["mac"]) lightstring["lightstring"].setDelegate(delegate) lightstring["lightstring"].writeCharacteristic( HAND, binascii.a2b_hex(HEX_ENUM_STATE)) lightstring["lightstring"].waitForNotifications(1.0) lightstring["lightstring"].disconnect() lightstring["lightstring"].connect(lightstring["mac"]) lightstring["lightstring"].setDelegate(cdelegate) lightstring["lightstring"].writeCharacteristic( HAND, binascii.a2b_hex(HEX_ENUM_CONF)) lightstring["lightstring"].waitForNotifications(1.0) lightstring["lightstring"].disconnect() if delegate.state != -1: lightstring["state"] = delegate.state ret += self.update_device_state(name, lightstring["state"]) if cdelegate.conf != -1: lightstring["conf"] = cdelegate.conf ret += self.update_device_conf(name, lightstring["conf"]) except btle.BTLEException as e: logger.log_exception( _LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, lightstring["mac"], type(e).__name__, suppress=True, ) return ret