diff --git a/Documentation/index.rst b/Documentation/index.rst
index a34b597553401994ed47fe20d9a20bb69a5ae06e..06aa3b7e95c0a64495ffc5b42d9659e44031f7cd 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -29,6 +29,7 @@ Last but not least, if you want to start hacking the lower-level firmware, the
    pycardium/leds
    pycardium/light-sensor
    pycardium/os
+   pycardium/personal_state
    pycardium/utime
    pycardium/vibra
 
diff --git a/Documentation/pycardium/personal_state.rst b/Documentation/pycardium/personal_state.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7bf03681840a8b407fa00cf815bdbd7127d93334
--- /dev/null
+++ b/Documentation/pycardium/personal_state.rst
@@ -0,0 +1,63 @@
+.. py:module:: personal_state
+
+``personal_state`` - Personal State
+===================================
+The :py:mod:`personal_state` module allows you to set and get the card10 users personal state from your script. The personal state is displayed on the top-left LED on the bottom of the harmonics board. While the personal state is set the LED can't be controlled by the :py:mod:`leds` module.
+
+**Example**:
+
+.. code-block:: python
+
+   import personal_state
+
+   # Enable the "camp" state only while the app is running.
+   personal_state.set(personal_state.CAMP, False)
+
+   # Enable the "chaos" state and keep it after the app exits.
+   personal_state.set(personal_state.CHAOS, True)
+
+   # Query the currently configured state and if it's persistent.
+   state, persistent = personal_state.get()
+
+   # Clear the currently configured state
+   personal_state.clear()
+
+.. py:function:: personal_state.set(state, persistent)
+
+   Set the users personal state.
+
+   :param int state: ID of the personal state to set. Must be one of :py:data:`personal_state.NO_CONTACT`, :py:data:`personal_state.CHAOS`, :py:data:`personal_state.COMMUNICATION`, :py:data:`personal_state.CAMP`.
+   :param int persistent: Controls whether the personal state is persistent. A persistent state is not reset when the pycardium application is changed or restarted. In persistent mode the personal state LED is not controllable by the pycardium application.
+
+.. py:function:: personal_state.clear()
+
+   Clears a previously set personal state.
+   
+   If no personal state was set this function does nothing. It does not matter
+   if a set state is marked as persistent or not.
+
+.. py:function:: personal_state.get()
+
+   Get the users personal state.
+   
+   :returns: A tuple containing the currently set state and a boolean indicating if it's persistent or not.
+
+.. py:data:: personal_state.NO_STATE
+
+   State ID reported when no personal state is set.
+
+.. py:data:: personal_state.NO_CONTACT
+
+   State ID for the "No Contact" personal state.
+
+.. py:data:: personal_state.CHAOS
+
+   State ID for the "Chaos" personal state.
+
+.. py:data:: personal_state.COMMUNICATION
+
+   State ID for the "Communicatoin" personal state.
+   
+.. py:data:: personal_state.CAMP
+
+   State ID for the "Camp" personal state.
diff --git a/pycardium/meson.build b/pycardium/meson.build
index 8d3b447a1750f369ff595d17271e43fc8e3d5707..40fabde700ce03eff4d117b7e5e87c024b5f35f5 100644
--- a/pycardium/meson.build
+++ b/pycardium/meson.build
@@ -9,6 +9,7 @@ modsrc = files(
   'modules/sys_leds.c',
   'modules/light_sensor.c',
   'modules/os.c',
+  'modules/personal_state.c',
   'modules/sys_display.c',
   'modules/utime.c',
   'modules/vibra.c',
diff --git a/pycardium/modules/personal_state.c b/pycardium/modules/personal_state.c
new file mode 100644
index 0000000000000000000000000000000000000000..36353534b667a3c4a48bdee9af202d5e5f05f37a
--- /dev/null
+++ b/pycardium/modules/personal_state.c
@@ -0,0 +1,67 @@
+#include "epicardium.h"
+
+#include "py/builtin.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+
+static mp_obj_t
+mp_personal_state_set(mp_obj_t state_obj, mp_obj_t persistent_obj)
+{
+	int state = mp_obj_get_int(state_obj);
+	int rc = epic_personal_state_set(state, mp_obj_is_true(persistent_obj));
+	if (rc < 0)
+		mp_raise_OSError(-rc);
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(personal_state_set, mp_personal_state_set);
+
+static mp_obj_t mp_personal_state_clear()
+{
+	int rc = epic_personal_state_set(STATE_NONE, 0);
+	if (rc < 0)
+		mp_raise_OSError(-rc);
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_0(personal_state_clear, mp_personal_state_clear);
+
+static mp_obj_t mp_personal_state_get()
+{
+	int state               = epic_personal_state_get();
+	int persistent          = epic_personal_state_is_persistent();
+	mp_obj_t persistent_obj = mp_const_false;
+	if (persistent > 0)
+		persistent_obj = mp_const_true;
+	mp_obj_t tup[] = {
+		mp_obj_new_int(state & 0xff),
+		persistent_obj,
+	};
+	return mp_obj_new_tuple(2, tup);
+}
+static MP_DEFINE_CONST_FUN_OBJ_0(personal_state_get, mp_personal_state_get);
+
+static const mp_rom_map_elem_t personal_state_module_globals_table[] = {
+	{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_personal_state) },
+	{ MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&personal_state_set) },
+	{ MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&personal_state_get) },
+	{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&personal_state_clear) },
+	{ MP_ROM_QSTR(MP_QSTR_NO_STATE), MP_OBJ_NEW_SMALL_INT(STATE_NONE) },
+	{ MP_ROM_QSTR(MP_QSTR_NO_CONTACT),
+	  MP_OBJ_NEW_SMALL_INT(STATE_NO_CONTACT) },
+	{ MP_ROM_QSTR(MP_QSTR_CHAOS), MP_OBJ_NEW_SMALL_INT(STATE_CHAOS) },
+	{ MP_ROM_QSTR(MP_QSTR_COMMUNICATION),
+	  MP_OBJ_NEW_SMALL_INT(STATE_COMMUNICATION) },
+	{ MP_ROM_QSTR(MP_QSTR_CAMP), MP_OBJ_NEW_SMALL_INT(STATE_CAMP) },
+};
+static MP_DEFINE_CONST_DICT(
+	personal_state_module_globals, personal_state_module_globals_table
+);
+
+// Define module object.
+const mp_obj_module_t personal_state_module = {
+	.base    = { &mp_type_module },
+	.globals = (mp_obj_dict_t *)&personal_state_module_globals,
+};
+
+/* Register the module to make it available in Python */
+/* clang-format off */
+MP_REGISTER_MODULE(MP_QSTR_personal_state, personal_state_module, MODULE_PERSONAL_STATE_ENABLED);
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 3300907012a50e3df7d3815458832a0c8ba0ddea..9e3f3979af79ebbfb16f821b7127424cadb563ff 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -118,3 +118,12 @@ Q(INPUT)
 Q(OUTPUT)
 Q(PULL_UP)
 Q(PULL_DOWN)
+
+/* personal_state */
+Q(personal_state)
+Q(get)
+Q(NO_STATE)
+Q(NO_CONTACT)
+Q(CHAOS)
+Q(COMMUNICATION)
+Q(CAMP)
diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h
index 0708ebe52ad745d888ac5fa0cbace2b7fc655558..309b8f7f76ba776b791288f5f9aa69d9825e4fdd 100644
--- a/pycardium/mpconfigport.h
+++ b/pycardium/mpconfigport.h
@@ -46,6 +46,7 @@
 #define MODULE_LEDS_ENABLED                 (1)
 #define MODULE_LIGHT_SENSOR_ENABLED         (1)
 #define MODULE_OS_ENABLED                   (1)
+#define MODULE_PERSONAL_STATE_ENABLED       (1)
 #define MODULE_UTIME_ENABLED                (1)
 #define MODULE_VIBRA_ENABLED                (1)