def remove_subscription(ip, port, alarm_name): # TODO: This is global and should probably not be global subscriptions, alarm_queue # Does the alarm exist if alarm_name not in alarm_queue.names: return Commands.create_command_string(('FN', alarm_name)) # Try to delete the subscription client_obj = Client.Client(ip, port) if alarm_name in alarm_queue.names: if alarm_name in subscriptions: if any(c for c in subscriptions[alarm_name] if c == client_obj): try: index = subscriptions[alarm_name].index(client_obj) del subscriptions[alarm_name][index] except ValueError: # Not subscribed return Commands.create_command_string(('FB', alarm_name)) # Not subscribed else: return Commands.create_command_string(('FB', alarm_name)) else: # Not subscribed return Commands.create_command_string(('FB', alarm_name)) # Tell the client they've been removed from the list return Commands.create_command_string(('S', alarm_name))
def subscribe_to_alarms(alarms, settings): # Did we subscribe to even one alarm? success = False # Connect to the server t = socket.socket(socket.AF_INET, socket.SOCK_STREAM) t.settimeout(RESPONSE_TIMEOUT) t.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) t.bind((settings['address'], settings['port'])) t.connect((settings['server_address'], settings['server_port'])) # Ask the server to subscribe us for each alarm for alarm in alarms: command_string = Commands.create_command_string(('B', alarm)) t.send(command_string) Log.debug('Subscription request for alarm "%s" sent.' % alarm) # Receive data command_string = t.recv(BUFFER_SIZE) # Print the command Log.debug('Got response "%s"' % command_string) # Parse the command command = Commands.parse_command(command_string) if command[0] == 'FB': Log.debug('Already subscribed to alarm "%s".' % alarm) success = True elif command[0] == 'S': Log.debug('Successfully subscribed to alarm "%s".' % alarm) success = True elif command[0] == 'FN': Log.error('Server says alarm "%s" does not exist.' % alarm) else: Log.error('Unable to parse response from server.') t.close() return success
def add_subscription(ip, port, alarm_name): # TODO: This is global and should probably not be global subscriptions, alarm_queue # Does the alarm exist if alarm_name not in alarm_queue.names: return Commands.create_command_string(('FN', alarm_name)) # Try to add the subscription client_obj = Client.Client(ip, port) if alarm_name in alarm_queue.names: if alarm_name in subscriptions: # Already subscribed if any(c for c in subscriptions[alarm_name] if c == client_obj): return Commands.create_command_string(('FB', alarm_name)) else: subscriptions[alarm_name].append(client_obj) else: subscriptions[alarm_name] = [client_obj] # Tell the client they've been added to the list return Commands.create_command_string(('S', alarm_name))
def listen(settings): # Create a socket and listen for packets sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((settings['address'], settings['port'])) sock.listen(1) Log.debug('Listening on port %i' % settings['port']) # This is our main listening thread while True: # Accept incoming connection connection, address = sock.accept() server = address[0] + ':' + str(address[1]) Log.debug('Connection from %s' % server) # Receive data command_string = connection.recv(BUFFER_SIZE) # Print the command Log.debug('Received command %s from %s.' % (command_string, server)) # Parse the command command = Commands.parse_command(command_string) response = 'E general' if command: response = Commands.create_command_string(('F', command[1])) # Handle the alarm if command[0] == 'A': Log.debug('Alarm %s triggered.', command[1]) result = dispatch_alarm(command[1]) # Success if result: response = Commands.create_command_string(('S', command[1])) # Invalid command else: Log.error('Invalid command "%s" from server.', command[0]) # Invalid command else: Log.error('Invalid command from server.') connection.send(response) # Close the connection from the server connection.close() # Close the socket sock.close()
# See how long we'll have to wait now if len(alarm_queue) > 0: alarm = alarm_queue.peek() wait = alarm.wait_time() Log.debug('Next alarm in %i seconds. Sleeping until then.' % wait) # If two alarms occur at the same time, wait will be zero or negative. # No point in sleeping if that's the case. if wait > 0: time.sleep(wait) # Remove the alarm from the queue alarm = alarm_queue.pop() # If anybody cares about this alarm, alert them if alarm.name in subscriptions: clients = subscriptions[alarm.name] Log.debug('Alerting %i clients about alarm "%s"' % (len(clients), alarm.name)) # Notify all subscribed clients for client in clients: # Spin off a thread to talk to the client #t_handle = thread.start_new_thread(alert_client, (client, alarm)) c = Client.OutgoingClient(client.ip, client.port, handle_alarm_response) c.send_command(Commands.create_command_string(('A', alarm.name))) else: Log.debug('No subscriptions to alarm "%s"' % alarm.name) # Sleep for 1 second to prevent the alarm from firing again time.sleep(1) # Stick the alarm back in the queue if it repeats if not alarm.once: alarm_queue.enqueue(alarm)