diff --git a/.github/workflows/release_mirror.yml b/.github/workflows/release_mirror.yml
deleted file mode 100644
index ef7eb55..0000000
--- a/.github/workflows/release_mirror.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Copy repo to release mirror
-
-on:
-  workflow_dispatch:
-  release:
-    types:
-      - published
-
-
-jobs:
-  release_mirror:
-    name: Push main to release repo
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v4
-        with:
-          ref: main
-
-      - uses: automatika-robotics/push-to-release-repo-action@v2
-        with:
-          destination-username: "${{ secrets.DESTINATION_USERNAME }}"
-          destination-access-token: ${{ secrets.DESTINATION_ACCESS_TOKEN }}
-          destination-repository: "automatika-robotics/ros-sugar-release"
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e100b28..827ad5a 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package automatika_ros_sugar
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.2.5 (2025-01-07)
+------------------
+* (fix) Gets imports and default values based on installed distro
+* (fix) Fix launch and launch_ros imports based on ros distro
+* Contributors: ahr, mkabtoul
+
 0.2.4 (2024-12-27)
 ------------------
 * (fix) Adds algorithm auto re-configuration from YAML file
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 8999ab9..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,193 +0,0 @@
-ros-rolling-automatika-ros-sugar (0.2.4-1bookworm) bookworm; urgency=high
-
-  * (fix) Adds algorithm auto re-configuration from YAML file
-  * (fix) Fixes callback got_msg property
-  * (feature) Adds topics callbacks/conversions reparsing to component
-    Supports running components from different packages in one script and each component uses its own package callbacks/conversions
-  * (fix) Updates AllowedTopics config and its validator
-  * (refactor) Removes PIL as a dependancy
-  * (fix) Fixes component state transition logging
-  * (fix) Fixes order to custom method execution in component lifecycle transition methods
-  * (refactor) Removes BaseNode class
-  * (fix) Fixes packaging workflow formatting
-  * (fix) Removes redundant methods from components
-  * (chore) Increments release action version
-  * (chore) Adds new action in debs creation workflow
-  * (refactor) Formats utils
-  * (refactor) Minor refactoring in utils
-  * (fix) Removes fix for color correction as the transformation is now applied at the time of visualization
-  * (fix) Adds color transformation when reading images of yuv encoding
-  * (chore) Changes name of release action
-  * (feature) Adds component algorithm config management to the api
-  * (fix) fixes datatypes update method for using multiple packages
-  * (chore) Cleans up cmake and packaging
-  * (refactor) Improves error message when a topic of unsupported type is created
-  * (refactor) Handles additional datatypes provided by user packages
-  * (fix) Pins release mirror workflow to run only on release publishing
-  * (fix) Adds branch name to release workflow
-  * (fix) Fixes name of action
-  * (feature) Adds release mirror action
-  * (docs) Removes autogenerated docs
-  * (docs) Adds minor modification to readme
-  * (docs) Changes package description
-  * (feature) Adds ExecuteMethod service to BaseComponent
-  * (fix) Minor fix in conversion method
-  * (refactor) Makes compressed image a realization of image
-  * (fix) Fixes ros compressed image conversion util
-  * (feature) Adds support for CompressedImage msg
-  * (feature) Adds ros_log_level option to each added package
-  * (feature) Adds additional supported types argument to BaseComponent and Topic validators
-  * (fix) Adds algorithm auto re-configuration from YAML file
-  * (fix) Fixes callback got_msg property
-  * (feature) Adds topics callbacks/conversions reparsing to component
-    Supports running components from different packages in one script and each component uses its own package callbacks/conversions
-  * (fix) Updates AllowedTopics config and its validator
-  * (refactor) Removes PIL as a dependancy
-  * (fix) Fixes component state transition logging
-  * (fix) Fixes order to custom method execution in component lifecycle transition methods
-  * (refactor) Removes BaseNode class
-  * (fix) Fixes packaging workflow formatting
-  * (fix) Removes redundant methods from components
-  * (chore) Increments release action version
-  * (chore) Adds new action in debs creation workflow
-  * (refactor) Formats utils
-  * (refactor) Minor refactoring in utils
-  * (fix) Removes fix for color correction as the transformation is now applied at the time of visualization
-  * (fix) Adds color transformation when reading images of yuv encoding
-  * (chore) Changes name of release action
-  * (feature) Adds component algorithm config management to the api
-  * (fix) fixes datatypes update method for using multiple packages
-  * (chore) Cleans up cmake and packaging
-  * (refactor) Improves error message when a topic of unsupported type is created
-  * (refactor) Handles additional datatypes provided by user packages
-  * (fix) Pins release mirror workflow to run only on release publishing
-  * (fix) Adds branch name to release workflow
-  * (fix) Fixes name of action
-  * (feature) Adds release mirror action
-  * (docs) Removes autogenerated docs
-  * (docs) Adds minor modification to readme
-  * (docs) Changes package description
-  * (feature) Adds ExecuteMethod service to BaseComponent
-  * (fix) Fixes OccupnacyGrid data publishing from numpy
-  * (fix) Minor fix in conversion method
-  * (refactor) Makes compressed image a realization of image
-  * (fix) Fixes ros compressed image conversion util
-  * (feature) Adds support for CompressedImage msg
-  * (feature) Adds ros_log_level option to each added package
-  * (feature) Adds additional supported types argument to BaseComponent and Topic validators
-  * (fix) Merge pull request #14 <https://github.com/automatika-robotics/ros-sugar/issues/14>
-  * (chore) Updates package name to automatika_ros_sugar
-  * (fix) Checks numpy array shape in OccupancyGrid converter
-  * (feature) Adds stamped header and frame_id to ros publishers/callbacks
-  * (docs) Updates install instructions
-  * Contributors: ahr, mkabtoul
-
- -- Automatika Robotics <contact@automatikarobotics.com>  Thu, 26 Dec 2024 23:00:00 -0000
-
-ros-rolling-automatika-ros-sugar (0.2.3-1bookworm) bookworm; urgency=high
-
-  * (chore) bump version 0.2.2 -> 0.2.3
-  * (chore) Adds deb packaging scripts and actions (#13 <https://github.com/automatika-robotics/ros-sugar/issues/13>)
-  * (docs) Removes notice
-  * Contributors: ahr
-
- -- Automatika Robotics <contact@automatikarobotics.com>  Tue, 12 Nov 2024 23:00:00 -0000
-
-ros-rolling-automatika-ros-sugar (0.2.2-1bookworm) bookworm; urgency=high
-
-  * (chore) bump version 0.2.1 -> 0.2.2
-  * (feature) Adds activation timeout to monitor and launcher
-  * (fix) Fixes publishing numpy data to ROS OcuupancyGrid
-  * (refactor) Updates OccupancyGrid get_output using numpy operations
-  * Contributors: mkabtoul
-
- -- Automatika Robotics <contact@automatikarobotics.com>  Sun, 03 Nov 2024 23:00:00 -0000
-
-ros-rolling-automatika-ros-sugar (0.2.1-1bookworm) bookworm; urgency=high
-
-  * (chore) bump version 0.2.0 -> 0.2.1
-  * (feature) Adds support for external tool calling in multiprocessing
-  * Contributors: ahr
-
- -- Automatika Robotics <contact@automatikarobotics.com>  Mon, 28 Oct 2024 23:00:00 -0000
-
-ros-rolling-automatika-ros-sugar (0.2.0-1bookworm) bookworm; urgency=high
-
-  * (chore) Bump version 0.1.1 -> 0.2.0
-  * Merge pull request #12 <https://github.com/automatika-robotics/ros-sugar/issues/12> from automatika-robotics/feature/external_processors
-    Adds external processor support when running components in multiprocessing
-  * (refactor) Makes msgpack a global dependancy
-  * (fix) Fixes deserialization of external processors and handling of processor result in launcher
-  * (fix) Corrects the serialization of numpy arrays within lists
-  * (feature) Changes defaults for launcher parameters when using multiprocessing
-  * (fix) Fixes handling composite type check for deserialization and input/output deserialization in components
-  * (fix) Adds node name as parameter to callbacks for init
-  * (fix) Adds alias to attrs private attribute in BaseComponentConfig
-  * (fix) Restores executable to old version
-  * Merge branch 'feature/external_processors' of github.com:automatika-robotics/ros-sugar into feature/external_processors
-  * (fix) Fixes new method name in launcher
-  * (fix) Moves callbackgroup to BaseComponentConfig and changes initialization of inputs/outputs in component
-  * (fix) Fixes serialization of callbackgroup in config
-  * (fix) Fixes type hints for compatibility
-  * (docs) Fixes ubuntu version for dependancy problems
-  * (refactor) Makes msgpack a functional dependency
-  * (refactor) Adds handling of callback group and input/output initialization to facilitate multiprocessing
-  * (feature) Adds handling of callback group for multiprocess launch
-  * (fix) Adds serialization of np arrays and tuples
-  * (fix) Adds converter for QoS profile for serialization
-  * (refactor) Changes inputs/outputs handling in executable
-  * (refactor) Changes name of enum convert utility function
-  * (fix) Fixes use of multi processors for same topic in launcher
-  * (fix) Fix package installation for documentation workflow
-  * (feature) Adds support for multiple external processors on the same topic
-  * (fix) Fixes visibility of external_processors to protected
-  * (fix) Fixes typo in attaching external preprocessors
-  * (feature) Adds unix socket based listener threads for using external processors with components being run in multiprocessing
-    - Modifies executable to add an argument for external processors
-    - Adds setting and getting for external processor json in component
-    - Adds setting up of external processors on component activation and destruction on component stop
-    - Adds setup of external processor sockets and thread pool in launcher
-  * (fix) Moves callbackgroup to BaseComponentConfig and changes initialization of inputs/outputs in component
-  * (fix) Fixes serialization of callbackgroup in config
-  * (fix) Fixes type hints for compatibility
-  * (docs) Fixes ubuntu version for dependancy problems
-  * (refactor) Makes msgpack a functional dependency
-  * (refactor) Adds handling of callback group and input/output initialization to facilitate multiprocessing
-  * (feature) Adds handling of callback group for multiprocess launch
-  * (fix) Adds serialization of np arrays and tuples
-  * (fix) Adds converter for QoS profile for serialization
-  * (refactor) Changes inputs/outputs handling in executable
-  * (refactor) Changes name of enum convert utility function
-  * (feature) Adds event processing options and supports lists in event values
-    Adds options to handle an event once or handle with a time delay
-  * (fix) Uses List from typing in type hints
-  * (feature) Adds handle_once and event_delay options to Event
-  * (feature) Adds list to supported event trigger values
-  * (fix) Handles keep_alive in component parameter update service requests
-  * (fix) Passes monitor executor to service client send_req
-  * (fix) Fixes use of multi processors for same topic in launcher
-  * (fix) Fix package installation for documentation workflow
-  * (feature) Adds support for multiple external processors on the same topic
-  * (fix) Fixes visibility of external_processors to protected
-  * (fix) Fixes typo in attaching external preprocessors
-  * (feature) Adds unix socket based listener threads for using external processors with components being run in multiprocessing
-    - Modifies executable to add an argument for external processors
-    - Adds setting and getting for external processor json in component
-    - Adds setting up of external processors on component activation and destruction on component stop
-    - Adds setup of external processor sockets and thread pool in launcher
-  * (fix) Fixes minor bugs in base component and launcher (#10 <https://github.com/automatika-robotics/ros-sugar/issues/10>)
-  * (fix) Fixes the handling of yuv422_yuy2 encoding in image reading util function
-  * (fix) Adds process id to monitor node name
-  * (fix) Fixes type check for callables in attaching post and pre processors
-  * (fix) Updates component launch arguments after parsing events_actions
-  * (docs) Updates docs url links in readme
-  * (docs) Adds github workflow for docs (#9 <https://github.com/automatika-robotics/ros-sugar/issues/9>)
-  * (fix) Adds handling image encodings with alpha channel
-  * Create LICENSE
-  * Initial release version 0.1.1 (#8 <https://github.com/automatika-robotics/ros-sugar/issues/8>)
-  * init commit
-  * Contributors: ahr, aleph-ra, mkabtoul
-
- -- Automatika Robotics <contact@automatikarobotics.com>  Thu, 24 Oct 2024 22:00:00 -0000
-
-
diff --git a/debian/changelog.em b/debian/changelog.em
new file mode 100644
index 0000000..3585909
--- /dev/null
+++ b/debian/changelog.em
@@ -0,0 +1,7 @@
+@[for change_version, change_date, changelog, main_name, main_email in changelogs]@(Package) (@(change_version)@(DebianInc)@(Distribution)) @(Distribution); urgency=high
+
+@(changelog)
+
+ -- @(main_name) <@(main_email)>  @(change_date)
+
+@[end for]
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/compat.em b/debian/compat.em
new file mode 100644
index 0000000..7a87216
--- /dev/null
+++ b/debian/compat.em
@@ -0,0 +1 @@
+@(debhelper_version)
diff --git a/debian/control b/debian/control
deleted file mode 100644
index beefb9b..0000000
--- a/debian/control
+++ /dev/null
@@ -1,12 +0,0 @@
-Source: ros-rolling-automatika-ros-sugar
-Section: misc
-Priority: optional
-Maintainer: Automatika Robotics <contact@automatikarobotics.com>
-Build-Depends: debhelper (>= 9.0.0), python3-jinja2, python3-msgpack, python3-numpy, python3-opencv, ros-rolling-ament-cmake, ros-rolling-ament-cmake-python, ros-rolling-builtin-interfaces, ros-rolling-geometry-msgs, ros-rolling-lifecycle-msgs, ros-rolling-nav-msgs, ros-rolling-rclcpp, ros-rolling-rclpy, ros-rolling-rosidl-default-generators, ros-rolling-sensor-msgs, ros-rolling-std-msgs, ros-rolling-tf2-ros, ros-rolling-ros-workspace, ros-rolling-rosidl-typesupport-fastrtps-c, ros-rolling-rosidl-typesupport-fastrtps-cpp
-Homepage: https://github.com/automatika/ros-sugar
-Standards-Version: 3.9.2
-
-Package: ros-rolling-automatika-ros-sugar
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, python3-jinja2, python3-msgpack, python3-numpy, python3-opencv, ros-rolling-builtin-interfaces, ros-rolling-geometry-msgs, ros-rolling-lifecycle-msgs, ros-rolling-nav-msgs, ros-rolling-rclcpp, ros-rolling-rclpy, ros-rolling-rosidl-default-runtime, ros-rolling-sensor-msgs, ros-rolling-std-msgs, ros-rolling-tf2-ros, ros-rolling-ros-workspace
-Description: Syntactic sugar for ROS2 nodes creation and management
diff --git a/debian/control.em b/debian/control.em
new file mode 100644
index 0000000..6d7b65c
--- /dev/null
+++ b/debian/control.em
@@ -0,0 +1,14 @@
+Source: @(Package)
+Section: misc
+Priority: optional
+Maintainer: @(Maintainer)
+Build-Depends: debhelper (>= @(debhelper_version).0.0), @(', '.join(BuildDepends))
+Homepage: @(Homepage)
+Standards-Version: 3.9.2
+
+Package: @(Package)
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, @(', '.join(Depends))
+@[if Conflicts]Conflicts: @(', '.join(Conflicts))@\n@[end if]@
+@[if Replaces]Replaces: @(', '.join(Replaces))@\n@[end if]@
+Description: @(Description)
diff --git a/debian/copyright b/debian/copyright.em
similarity index 50%
rename from debian/copyright
rename to debian/copyright.em
index af7e644..bc82fd5 100644
--- a/debian/copyright
+++ b/debian/copyright.em
@@ -1,7 +1,11 @@
 Format: Bloom subset of https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: automatika_ros_sugar
+Upstream-Name: @(Name)
+@[if BugTracker]Upstream-Contact: @(BugTracker)@\n@[end if]@
+@[if Source]Source: @(Source)@\n@[end if]@
+@[for License, Text in Licenses]@
 
 Files: See file headers in repository for details
 Copyright: See package copyright in source code for details
-License: MIT
- See repository for full license text
+License: @(License)
+ @(Text)
+@[end for]@
diff --git a/debian/gbp.conf b/debian/gbp.conf
deleted file mode 100644
index c6fecb1..0000000
--- a/debian/gbp.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-[git-buildpackage]
-upstream-tag=release/rolling/automatika_ros_sugar/0.2.4-1
-upstream-tree=tag
diff --git a/debian/gbp.conf.em b/debian/gbp.conf.em
new file mode 100644
index 0000000..ad24a16
--- /dev/null
+++ b/debian/gbp.conf.em
@@ -0,0 +1,3 @@
+[git-buildpackage]
+upstream-tag=@(release_tag)
+upstream-tree=tag
diff --git a/debian/rules b/debian/rules.em
similarity index 71%
rename from debian/rules
rename to debian/rules.em
index b1c916e..a856369 100755
--- a/debian/rules
+++ b/debian/rules.em
@@ -13,7 +13,7 @@ export DH_VERBOSE=1
 #  https://code.ros.org/trac/ros/ticket/2977
 #  https://code.ros.org/trac/ros/ticket/3842
 export LDFLAGS=
-export PKG_CONFIG_PATH=/opt/ros/rolling/lib/pkgconfig
+export PKG_CONFIG_PATH=@(InstallationPrefix)/lib/pkgconfig
 # Explicitly enable -DNDEBUG, see:
 # 	https://github.com/ros-infrastructure/bloom/issues/327
 export DEB_CXXFLAGS_MAINT_APPEND=-DNDEBUG
@@ -24,24 +24,24 @@ endif
 DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
 
 %:
-	dh $@ -v --buildsystem=cmake --builddirectory=.obj-$(DEB_HOST_GNU_TYPE)
+	dh $@@ -v --buildsystem=cmake --builddirectory=.obj-$(DEB_HOST_GNU_TYPE)
 
 override_dh_auto_configure:
 	# In case we're installing to a non-standard location, look for a setup.sh
 	# in the install tree and source it.  It will set things like
 	# CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
-	if [ -f "/opt/ros/rolling/setup.sh" ]; then . "/opt/ros/rolling/setup.sh"; fi && \
+	if [ -f "@(InstallationPrefix)/setup.sh" ]; then . "@(InstallationPrefix)/setup.sh"; fi && \
 	dh_auto_configure -- \
-		-DCMAKE_INSTALL_PREFIX="/opt/ros/rolling" \
-		-DAMENT_PREFIX_PATH="/opt/ros/rolling" \
-		-DCMAKE_PREFIX_PATH="/opt/ros/rolling" \
+		-DCMAKE_INSTALL_PREFIX="@(InstallationPrefix)" \
+		-DAMENT_PREFIX_PATH="@(InstallationPrefix)" \
+		-DCMAKE_PREFIX_PATH="@(InstallationPrefix)" \
 		$(BUILD_TESTING_ARG)
 
 override_dh_auto_build:
 	# In case we're installing to a non-standard location, look for a setup.sh
 	# in the install tree and source it.  It will set things like
 	# CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
-	if [ -f "/opt/ros/rolling/setup.sh" ]; then . "/opt/ros/rolling/setup.sh"; fi && \
+	if [ -f "@(InstallationPrefix)/setup.sh" ]; then . "@(InstallationPrefix)/setup.sh"; fi && \
 	dh_auto_build
 
 override_dh_auto_test:
@@ -49,19 +49,19 @@ override_dh_auto_test:
 	# in the install tree and source it.  It will set things like
 	# CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
 	echo -- Running tests. Even if one of them fails the build is not canceled.
-	if [ -f "/opt/ros/rolling/setup.sh" ]; then . "/opt/ros/rolling/setup.sh"; fi && \
+	if [ -f "@(InstallationPrefix)/setup.sh" ]; then . "@(InstallationPrefix)/setup.sh"; fi && \
 	dh_auto_test || true
 
 override_dh_shlibdeps:
 	# In case we're installing to a non-standard location, look for a setup.sh
 	# in the install tree and source it.  It will set things like
 	# CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
-	if [ -f "/opt/ros/rolling/setup.sh" ]; then . "/opt/ros/rolling/setup.sh"; fi && \
-	dh_shlibdeps -l$(CURDIR)/debian/ros-rolling-automatika-ros-sugar//opt/ros/rolling/lib/:$(CURDIR)/debian/ros-rolling-automatika-ros-sugar//opt/ros/rolling/opt/automatika_ros_sugar/lib/
+	if [ -f "@(InstallationPrefix)/setup.sh" ]; then . "@(InstallationPrefix)/setup.sh"; fi && \
+	dh_shlibdeps -l$(CURDIR)/debian/@(Package)/@(InstallationPrefix)/lib/:$(CURDIR)/debian/@(Package)/@(InstallationPrefix)/opt/@(Name)/lib/
 
 override_dh_auto_install:
 	# In case we're installing to a non-standard location, look for a setup.sh
 	# in the install tree and source it.  It will set things like
 	# CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, and PYTHONPATH.
-	if [ -f "/opt/ros/rolling/setup.sh" ]; then . "/opt/ros/rolling/setup.sh"; fi && \
+	if [ -f "@(InstallationPrefix)/setup.sh" ]; then . "@(InstallationPrefix)/setup.sh"; fi && \
 	dh_auto_install
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/source/format.em b/debian/source/format.em
new file mode 100644
index 0000000..9666bf4
--- /dev/null
+++ b/debian/source/format.em
@@ -0,0 +1 @@
+3.0 (@(format))
diff --git a/debian/source/options b/debian/source/options.em
similarity index 81%
rename from debian/source/options
rename to debian/source/options.em
index 8bc9182..8c4c78b 100644
--- a/debian/source/options
+++ b/debian/source/options.em
@@ -1,5 +1,6 @@
+@[if format and format == 'quilt']@
 # Automatically add upstream changes to the quilt overlay.
 # http://manpages.ubuntu.com/manpages/trusty/man1/dpkg-source.1.html
 # This supports reusing the orig.tar.gz for debian increments.
 auto-commit
-
+@[end if]
diff --git a/package.xml b/package.xml
index 24f9027..9a80492 100644
--- a/package.xml
+++ b/package.xml
@@ -2,7 +2,7 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>automatika_ros_sugar</name>
-  <version>0.2.4</version>
+  <version>0.2.5</version>
   <description>Syntactic sugar for ROS2 nodes creation and management</description>
   <maintainer email="contact@automatikarobotics.com">Automatika Robotics</maintainer>
   <url type="website">https://github.com/automatika/ros-sugar</url>
diff --git a/ros_sugar/config/base_config.py b/ros_sugar/config/base_config.py
index 02c875c..e034011 100644
--- a/ros_sugar/config/base_config.py
+++ b/ros_sugar/config/base_config.py
@@ -29,10 +29,7 @@ class QoSConfig(BaseAttrs):
     history: int = field(
         converter=_get_enum_value,
         default=qos.HistoryPolicy.KEEP_LAST,
-        validator=base_validators.in_([
-            qos.HistoryPolicy.KEEP_LAST,
-            qos.HistoryPolicy.KEEP_ALL,
-        ]),
+        validator=base_validators.in_(list(qos.HistoryPolicy)),
     )
 
     # used only if the “history” policy was set to “keep last”
@@ -45,10 +42,7 @@ class QoSConfig(BaseAttrs):
     reliability: int = field(
         converter=_get_enum_value,
         default=qos.ReliabilityPolicy.RELIABLE,
-        validator=base_validators.in_([
-            qos.ReliabilityPolicy.BEST_EFFORT,
-            qos.ReliabilityPolicy.RELIABLE,
-        ]),
+        validator=base_validators.in_(list(qos.ReliabilityPolicy)),
     )
 
     # Transient local: the publisher becomes responsible for persisting samples for “late-joining” subscriptions
@@ -56,13 +50,7 @@ class QoSConfig(BaseAttrs):
     durability: int = field(
         converter=_get_enum_value,
         default=qos.DurabilityPolicy.VOLATILE,
-        validator=base_validators.in_([
-            qos.DurabilityPolicy.TRANSIENT_LOCAL,
-            qos.DurabilityPolicy.VOLATILE,
-            # qos.DurabilityPolicy.BEST_AVAILABLE, # Only available in iron -> TODO: Get values from rclpy
-            qos.DurabilityPolicy.UNKNOWN,
-            qos.DurabilityPolicy.SYSTEM_DEFAULT,
-        ]),
+        validator=base_validators.in_(list(qos.DurabilityPolicy)),
     )
 
     # TODO: Fix default values
diff --git a/ros_sugar/core/component.py b/ros_sugar/core/component.py
index 0d33617..62fbe25 100644
--- a/ros_sugar/core/component.py
+++ b/ros_sugar/core/component.py
@@ -187,7 +187,7 @@ def _reparse_inputs_callbacks(self, inputs: Sequence[Topic]) -> Sequence[Topic]:
         :rtype: List[Topic]
         """
         for inp in inputs:
-            if not isinstance(inp.msg_type.callback, List):
+            if not inp or not isinstance(inp.msg_type.callback, List):
                 continue
             module_name = (
                 self.__module__[: self.__module__.index(".")]
@@ -217,7 +217,7 @@ def _reparse_outputs_converts(self, outputs: Sequence[Topic]) -> Sequence[Topic]
         :rtype: List[Topic]
         """
         for out in outputs:
-            if not isinstance(out.msg_type.convert, List):
+            if not out or not isinstance(out.msg_type.convert, List):
                 continue
             module_name = self.__module__
             # Get first callback by default
diff --git a/ros_sugar/core/event.py b/ros_sugar/core/event.py
index eefb68e..eea5cf3 100644
--- a/ros_sugar/core/event.py
+++ b/ros_sugar/core/event.py
@@ -12,16 +12,7 @@
 
 from ..io.topic import Topic
 from .action import Action
-
-# Get ROS distro
-__installed_distro = os.environ.get("ROS_DISTRO", "").lower()
-
-if __installed_distro == "foxy":
-    from launch.some_actions_type import SomeActionsType as SomeType
-else:
-    from launch.some_entities_type import SomeEntitiesType as SomeType
-
-SomeEntitiesType = SomeType
+from ..utils import SomeEntitiesType
 
 
 class Timer:
@@ -380,12 +371,12 @@ def __init__(
 
         # Check if given trigger is of valid type
         if trigger_value and not _check_attribute(
-            self.event_topic.msg_type._ros_type,
+            self.event_topic.msg_type.get_ros_type(),
             type(self.trigger_ref_value),
             self._attrs,
         ):
             raise TypeError(
-                f"Cannot initiate with trigger of type {type(trigger_value)} for a data of type {_get_attribute_type(self.event_topic.msg_type._ros_type, self._attrs)}"
+                f"Cannot initiate with trigger of type {type(trigger_value)} for a data of type {_get_attribute_type(self.event_topic.msg_type.get_ros_type(), self._attrs)}"
             )
 
         # Init trigger as False
diff --git a/ros_sugar/io/supported_types.py b/ros_sugar/io/supported_types.py
index 3596a61..801f2bc 100644
--- a/ros_sugar/io/supported_types.py
+++ b/ros_sugar/io/supported_types.py
@@ -103,7 +103,9 @@ def add_additional_datatypes(types: List[type]) -> None:
 
             _update_supportedtype_callback(existing_class, new_type)
 
-            if not existing_class._ros_type:
+            if hasattr(new_type, "_ros_type") and (
+                not hasattr(existing_class, "_ros_type") or not existing_class._ros_type
+            ):
                 existing_class._ros_type = new_type._ros_type
 
             _update_supportedtype_conversion(existing_class, new_type)
@@ -154,6 +156,15 @@ def convert(cls, output, **_) -> Any:
         """
         return output
 
+    @classmethod
+    def get_ros_type(cls) -> type:
+        """Getter of the ROS2 message type
+
+        :return: ROS2 type
+        :rtype: type
+        """
+        return cls._ros_type
+
 
 class String(SupportedType):
     """String."""
diff --git a/ros_sugar/io/topic.py b/ros_sugar/io/topic.py
index 4fba766..9b69f98 100644
--- a/ros_sugar/io/topic.py
+++ b/ros_sugar/io/topic.py
@@ -154,7 +154,7 @@ def _msg_type_validator(self, _, val):
                 f"Got value of 'msg_type': {val}, which is not in available datatypes. Topics can only be created with one of the following types: { {msg_t.__name__: msg_t for msg_t in msg_types} }"
             )
         # Set ros type
-        self.ros_msg_type = self.msg_type._ros_type
+        self.ros_msg_type = self.msg_type.get_ros_type()
 
 
 @define(kw_only=True)
diff --git a/ros_sugar/launch/_lifecycle_transition.py b/ros_sugar/launch/_lifecycle_transition.py
new file mode 100644
index 0000000..46bdc9c
--- /dev/null
+++ b/ros_sugar/launch/_lifecycle_transition.py
@@ -0,0 +1,249 @@
+# This Action file is copied here from OSRF to support distributions prior to Iron
+# Copyright 2022 Open Source Robotics Foundation, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import functools
+
+from typing import Iterable
+from typing import List
+from typing import Optional
+from typing import Union
+
+
+import launch
+from launch import LaunchContext, SomeSubstitutionsType
+from launch.action import Action
+from launch.actions import EmitEvent, RegisterEventHandler
+from launch.utilities import normalize_to_list_of_substitutions
+from launch.utilities import perform_substitutions
+
+from launch_ros.event_handlers import OnStateTransition
+from launch_ros.events.lifecycle import ChangeState, StateTransition
+from launch_ros.events.matchers import matches_node_name
+from lifecycle_msgs.msg import Transition
+
+
+class LifecycleTransition(Action):
+    """An action that simplifies execution of lifecycle transitions."""
+
+    transition_targets = {
+        Transition.TRANSITION_CONFIGURE: {
+            "start_state": "configuring",
+            "goal_state": "inactive",
+        },
+        Transition.TRANSITION_CLEANUP: {
+            "start_state": "cleaningup",
+            "goal_state": "unconfigured",
+        },
+        Transition.TRANSITION_ACTIVATE: {
+            "start_state": "activating",
+            "goal_state": "active",
+        },
+        Transition.TRANSITION_DEACTIVATE: {
+            "start_state": "deactivating",
+            "goal_state": "inactive",
+        },
+        Transition.TRANSITION_UNCONFIGURED_SHUTDOWN: {
+            "start_state": "shuttingdown",
+            "goal_state": "finalized",
+        },
+        Transition.TRANSITION_INACTIVE_SHUTDOWN: {
+            "start_state": "shuttingdown",
+            "goal_state": "finalized",
+        },
+        Transition.TRANSITION_ACTIVE_SHUTDOWN: {
+            "start_state": "shuttingdown",
+            "goal_state": "finalized",
+        },
+    }
+
+    def __init__(
+        self,
+        *,
+        lifecycle_node_names: Iterable[SomeSubstitutionsType],
+        transition_ids: Iterable[Union[int, SomeSubstitutionsType]],
+        **kwargs,
+    ) -> None:
+        """
+        Construct a LifecycleTransition action.
+
+        The action will execute the passed in lifecycle transition for the
+        lifecycle nodes with the indicated node names. The action will emit
+        an event that triggers the first lifecycle transition of each node
+        wait that the node reaches the transition goal and trigger the next
+        transition in the list.
+        You need to make sure, that the sequence of lifecyle transition you
+        pass in is possible.
+
+        :param lifecycle_node_names: The names of the lifecycle nodes to transition
+        :param transitions_ids: The transitions to be executed.
+        """
+        super().__init__(**kwargs)
+        if len(transition_ids) == 0:
+            raise ValueError("No transition_ids provided.")
+
+        if len(lifecycle_node_names) == 0:
+            raise ValueError("No lifecycle_node_names provided.")
+
+        self.__lifecycle_node_names = [
+            normalize_to_list_of_substitutions(name) for name in lifecycle_node_names
+        ]
+        transition_ids = [
+            str(transition_id) if isinstance(transition_id, int) else transition_id
+            for transition_id in transition_ids
+        ]
+        self.__transition_ids = [
+            normalize_to_list_of_substitutions(transition_id)
+            for transition_id in transition_ids
+        ]
+
+        self.__event_handlers = {}
+        self.__logger = launch.logging.get_logger(__name__)
+
+    def _remove_event_handlers(
+        self, context: LaunchContext, node_name: str, reason: str = None
+    ):
+        """Remove all consequent transitions if error occurs."""
+        if reason is not None:
+            self.__logger.info(
+                f"Stopping transitions for {node_name} because '{reason}'"
+            )
+
+        for event_handler in self.__event_handlers[node_name]:
+            # Unregister event handlers and ignore failures, as these are
+            # already unregistered event handlers.
+            try:
+                context.unregister_event_handler(event_handler=event_handler)
+            except ValueError:
+                pass
+
+    def execute(self, context: launch.LaunchContext) -> Optional[List[Action]]:
+        """
+        Execute the LifecycleTransition action.
+
+        :return Returns a list of actions to be executed to achieve specified transitions.
+          These are EventHandlers and EventEmitters for ChangeState and
+          StateTransition events of the nodes indicated.
+        """
+        lifecycle_node_names = [
+            perform_substitutions(context, name) for name in self.__lifecycle_node_names
+        ]
+        subs_transition_ids = [
+            perform_substitutions(context, id_) for id_ in self.__transition_ids
+        ]
+        transition_ids = []
+        for tid in subs_transition_ids:
+            try:
+                transition_ids.append(int(tid))
+            except ValueError as e:
+                raise ValueError(
+                    f"expected integer for lifecycle transition, got {tid}"
+                ) from e
+
+        emit_actions = {}
+        actions: List[Action] = []
+
+        # Create EmitEvents for ChangeStates and store
+        for name in lifecycle_node_names:
+            own_emit_actions = []
+            for tid in transition_ids:
+                change_event = ChangeState(
+                    lifecycle_node_matcher=matches_node_name(name), transition_id=tid
+                )
+                emit_action = EmitEvent(event=change_event)
+                own_emit_actions.append(emit_action)
+            emit_actions[name] = own_emit_actions
+            self.__event_handlers[name] = []
+        # Create Transition EventHandlers and Registration actions
+        i = 1
+        for tid in transition_ids:
+            # Create Transition handler for all indicated nodes
+            for node_name in lifecycle_node_names:
+                states = self.transition_targets[tid]
+                event_handler = None
+                # For all transitions except the last, emit next ChangeState Event
+                if i < len(transition_ids):
+                    event_handler = OnStateTransition(
+                        matcher=match_node_name_start_goal(
+                            node_name, states["start_state"], states["goal_state"]
+                        ),
+                        entities=[emit_actions[node_name][i]],
+                        handle_once=True,
+                    )
+                # For last transition emit Log message and remove untriggered error handlers
+                else:
+                    event_handler = OnStateTransition(
+                        matcher=match_node_name_start_goal(
+                            node_name, states["start_state"], states["goal_state"]
+                        ),
+                        entities=[
+                            launch.actions.OpaqueFunction(
+                                function=functools.partial(
+                                    self._remove_event_handlers, node_name=node_name
+                                )
+                            ),
+                        ],
+                        handle_once=True,
+                    )
+                self.__event_handlers[node_name].append(event_handler)
+                # Create register event handler action
+                register_action = RegisterEventHandler(event_handler=event_handler)
+                # Append to actions
+                actions.append(register_action)
+            # increment next ChangeState action by one
+            i += 1
+        # Create Error processing event handlers.
+        for node_name in lifecycle_node_names:
+            event_handler = launch.EventHandler(
+                matcher=match_node_name_goal(node_name, "errorprocessing"),
+                entities=[
+                    launch.actions.OpaqueFunction(
+                        function=functools.partial(
+                            self._remove_event_handlers,
+                            node_name=node_name,
+                            reason="error occured during transitions",
+                        )
+                    )
+                ],
+                handle_once=True,
+            )
+            self.__event_handlers[node_name].append(event_handler)
+            context.register_event_handler(event_handler=event_handler)
+
+        # Add first Emit actions to actions
+        for node_name in lifecycle_node_names:
+            actions.append(emit_actions[node_name][0])
+
+        return actions
+
+
+def match_node_name_start_goal(node_name: str, start_state: str, goal_state: str):
+    if not node_name.startswith("/"):
+        node_name = f"/{node_name}"
+    return lambda event: (
+        isinstance(event, StateTransition)
+        and (event.action.node_name == node_name)
+        and (event.goal_state == goal_state)
+        and (event.start_state == start_state)
+    )
+
+
+def match_node_name_goal(node_name: str, goal_state: str):
+    if not node_name.startswith("/"):
+        node_name = f"/{node_name}"
+    return lambda event: (
+        isinstance(event, StateTransition)
+        and (event.action.node_name == node_name)
+        and (event.goal_state == goal_state)
+    )
diff --git a/ros_sugar/launch/launcher.py b/ros_sugar/launch/launcher.py
index d8d324d..40b5cb7 100644
--- a/ros_sugar/launch/launcher.py
+++ b/ros_sugar/launch/launcher.py
@@ -20,7 +20,6 @@
 import msgpack
 import msgpack_numpy as m_pack
 import launch
-import launch_ros
 import rclpy
 import setproctitle
 from launch import LaunchDescription, LaunchIntrospector, LaunchService
@@ -32,7 +31,6 @@
     OpaqueFunction,
     Shutdown,
 )
-from launch.some_entities_type import SomeEntitiesType
 from launch_ros.actions import LifecycleNode as LifecycleNodeLaunchAction
 from launch_ros.actions import Node as NodeLaunchAction
 from launch_ros.actions import PushRosNamespace
@@ -48,7 +46,16 @@
 from ..core.monitor import Monitor
 from ..core.event import OnInternalEvent, Event
 from .launch_actions import ComponentLaunchAction
-from ..utils import InvalidAction, action_handler, has_decorator
+from ..utils import InvalidAction, action_handler, has_decorator, SomeEntitiesType
+
+# Get ROS distro
+__installed_distro = os.environ.get("ROS_DISTRO", "").lower()
+
+if __installed_distro in ["humble", "galactic", "foxy"]:
+    # Get local copy for older distributions
+    from ._lifecycle_transition import LifecycleTransition
+else:
+    from launch_ros.actions import LifecycleTransition
 
 # patch msgpack for numpy arrays
 m_pack.patch()
@@ -304,7 +311,7 @@ def start(self, node_name: str, **_) -> SomeEntitiesType:
         :rtype: List[SomeEntitiesType]
         """
         actions = [
-            launch_ros.actions.LifecycleTransition(
+            LifecycleTransition(
                 lifecycle_node_names=[node_name],
                 transition_ids=[
                     Transition.TRANSITION_CONFIGURE,
@@ -325,7 +332,7 @@ def stop(self, node_name: str, **_) -> SomeEntitiesType:
         :rtype: List[SomeEntitiesType]
         """
         actions = [
-            launch_ros.actions.LifecycleTransition(
+            LifecycleTransition(
                 lifecycle_node_names=[node_name],
                 transition_ids=[Transition.TRANSITION_DEACTIVATE],
             )
@@ -343,7 +350,7 @@ def restart(self, node_name: str, **_) -> SomeEntitiesType:
         :rtype: List[SomeEntitiesType]
         """
         actions = [
-            launch_ros.actions.LifecycleTransition(
+            LifecycleTransition(
                 lifecycle_node_names=[node_name],
                 transition_ids=[
                     Transition.TRANSITION_DEACTIVATE,
diff --git a/ros_sugar/utils.py b/ros_sugar/utils.py
index 73791d0..b8da96a 100644
--- a/ros_sugar/utils.py
+++ b/ros_sugar/utils.py
@@ -7,7 +7,16 @@
 from rclpy.lifecycle import Node as LifecycleNode
 from launch import LaunchContext
 from launch.actions import OpaqueFunction
-from launch.some_entities_type import SomeEntitiesType
+import os
+
+# Get ROS distro
+__installed_distro = os.environ.get("ROS_DISTRO", "").lower()
+
+if __installed_distro in ["humble", "galactic", "foxy"]:
+    # Get some_action_type for older distributions
+    from launch.some_actions_type import SomeActionsType as SomeEntitiesType
+else:
+    from launch.some_entities_type import SomeEntitiesType
 
 
 class IncompatibleSetup(Exception):