diff --git a/aiopulse/__init__.py b/aiopulse/__init__.py
index 8876b3b..9cb5982 100644
--- a/aiopulse/__init__.py
+++ b/aiopulse/__init__.py
@@ -26,7 +26,7 @@ __all__ = [
     "InvalidResponseException",
     "UpdateType",
 ]
-__version__ = "0.4.6"
+__version__ = "0.5.0"
 __author__ = "Alan Murray"
 
 _LOGGER = logging.getLogger(__name__)
diff --git a/aiopulse/py.typed b/aiopulse/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/pyproject.toml b/pyproject.toml
index 80dfd3a..6c025d4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
 
 [project]
 name = "aiopulse"
-version = "0.4.7"
+version = "0.5.0"
 authors = [
   { name="Alan Murray", email="pypi@atmurray.net" },
 ]
@@ -13,22 +13,51 @@ Asynchronous library to control Rollease Acmeda Automate roller blinds via a ver
 """
 readme = "README.md"
 license = {file = 'LICENSE'}
-requires-python = ">=3.4"
+requires-python = ">=3.10"
 classifiers = [
     "Development Status :: 4 - Beta",
     "Intended Audience :: Developers",
     "Topic :: Software Development :: Libraries :: Python Modules",
     "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
     "License :: OSI Approved :: Apache Software License",
     "Operating System :: OS Independent",
 ]
 
+[project.optional-dependencies]
+dev = [
+    "pytest>=7.0",
+    "pytest-asyncio>=0.21",
+    "pytest-cov>=4.0",
+    "mypy>=1.0",
+    "ruff>=0.4",
+    "black>=24.0",
+    "build>=1.0",
+]
+
 [project.urls]
 Homepage = "https://github.com/atmurray/aiopulse"
 Issues = "https://github.com/atmurray/aiopulse/issues"
 
+[tool.pytest.ini_options]
+asyncio_mode = "auto"
+testpaths = ["tests"]
+
+[tool.mypy]
+python_version = "3.10"
+warn_return_any = true
+warn_unused_configs = true
+disallow_untyped_defs = true
+
+[tool.ruff]
+target-version = "py310"
+line-length = 88
+select = ["E", "F", "I", "N", "W", "UP"]
+
 [tool.bumpver]
-current_version = "0.4.7"
+current_version = "0.5.0"
 version_pattern = "MAJOR.MINOR.PATCH"
 commit_message  = "Bump version {old_version} -> {new_version}"
 commit          = true
diff --git a/setup.py b/setup.py
index 570a820..b1d3514 100644
--- a/setup.py
+++ b/setup.py
@@ -1,11 +1,11 @@
 """Pip setup file for aiopulse library."""
 
-from distutils.core import setup
+from setuptools import setup
 
 setup(
     name="aiopulse",
     packages=["aiopulse"],
-    version="0.4.7",
+    version="0.5.0",
     license="apache-2.0",
     description="Python module for Rollease Acmeda Automate integration.",
     long_description=open("README.md").read(),
@@ -13,12 +13,12 @@ setup(
     author="Alan Murray",
     author_email="pypi@atmurray.net",
     url="https://github.com/atmurray/aiopulse",
-    download_url="https://github.com/atmurray/aiopulse/archive/v0.4.7.tar.gz",
+    download_url="https://github.com/atmurray/aiopulse/archive/v0.5.0.tar.gz",
     keywords=["automation"],
-    python_requires=">=3.4",
+    python_requires=">=3.10",
     install_requires=["async_timeout"],
     classifiers=[
-        "Development Status :: 3 - Alpha",
+        "Development Status :: 4 - Beta",
         "Intended Audience :: Developers",
         "Operating System :: OS Independent",
         "Topic :: Software Development :: Libraries :: Python Modules",
