import json


def build_message(status, message=None, state=None):
    """
    Build message string to send to connected clients.

    :param status: HTTP status code of the message, int
    :param message: Optional free-form message to display to the client, can be string or dictionary.
        Either this or state should be set.
    :param state: Optional state to pass to the client. This can be the full state by passing in config.data() or a
        subset that you define yourself. Should be a dictionary. Either this or message should be set.
    :return: JSON string
    """
    # The server needs to send either a message or state to inform other clients what's going on.
    # The client sending a command will know that its action was successful and can update its UI, but the other
    # clients would only know that something was successful, not what.
    if message is None and state is None:
        raise ValueError('Either  message or state should be set')
    msg = {'status': status, 'message': message, 'state': state}
    return json.dumps(msg)