diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..17c7c71
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,78 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/python
+{
+	"name": "Python 3",
+	// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
+	"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bookworm",
+
+	// Features to add to the dev container. More info: https://containers.dev/features.
+	// "features": {},
+	"features": {
+		"ghcr.io/devcontainers-contrib/features/apt-get-packages:1": {
+			"packages": "usbutils,libusb-1.0,texinfo,libftdi1,libtinfo5,gdb-arm-none-eabi,gcc-arm-none-eabi,cmake"
+		}
+	},
+
+	// Use 'forwardPorts' to make a list of ports inside the container available locally.
+	// "forwardPorts": [],
+	
+	"runArgs": [
+		"-v", "/dev/bus/usb:/dev/bus/usb", 
+		"-v", "/usr/lib/udev/hwdb.bin:/usr/lib/udev/hwdb.bin:ro", 
+		"-v", "/lib/udev/hwdb.bin:/lib/udev/hwdb.bin:ro", 
+		"-v", "/usr/share/hwdata/usb.ids:/usr/share/hwdata/usb.ids:ro", 
+		"-v", "/run/udev:/run/udev", 
+		"-v", "/sys:/sys:ro",
+		"--privileged",
+		"--device-cgroup-rule", "c 188:* rmw",
+		"--device-cgroup-rule", "c 166:* rmw"
+	],
+
+	"mounts": [
+		{
+			"source": "${localWorkspaceFolder}/../esphome",
+			"target": "${containerWorkspaceFolder}/../esphome",
+			"type": "bind"
+		},
+		{
+			"source": "${localEnv:HOME}/.platformio",
+			"target": "/home/vscode/.platformio",
+			"type": "bind"
+		},
+		{
+			"source": "${localWorkspaceFolder}/../rp2040",
+			"target": "${containerWorkspaceFolder}/../rp2040",
+			"type": "bind"
+		},
+		{
+			"source": "/opt/openocd-rp2040",
+			"target": "/opt/openocd-rp2040",
+			"type": "bind"
+		}
+	],
+
+	// Use 'postCreateCommand' to run commands after the container is created.
+	"postCreateCommand": "pip3 install -r requirements.txt",
+
+	// Configure tool-specific properties.
+	"customizations": {
+		"vscode": {
+			"extensions": [
+				"ms-vscode.cpptools-extension-pack",
+				"jbenden.c-cpp-flylint",
+				"ESPHome.esphome-vscode",
+				"ms-python.vscode-pylance",
+				"marus25.cortex-debug",
+				"ms-vscode.cpptools",
+				"ms-vscode.cmake-tools",
+				"mikestead.dotenv",
+				"ZixuanWang.linkerscript",
+				"alefragnani.Bookmarks",
+				"ciprianelies.arm-assembly-syntax"
+			]
+		}
+	},
+
+	// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
+	// "remoteUser": "root"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b639a65
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+# Gitignore settings for ESPHome
+# This is an example and may include too much for your use-case.
+# You can modify this file to suit your needs.
+/.esphome/
+/secrets.yaml
+*.py[ocd]
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..5239be6
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,17 @@
+{
+    "configurations": [
+        {
+            "name": "Linux",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/../esphome/"
+            ],
+            "defines": ["USE_RP2040"],
+            "compilerPath": "/usr/bin/gcc",
+            "cStandard": "c11",
+            "cppStandard": "gnu++14",
+            "intelliSenseMode": "linux-gcc-x64"
+        }
+    ],
+    "version": 4
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..7a62736
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,41 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Pico Debug (Cortex-Debug)",
+            "cwd": "${workspaceRoot}",
+            "executable": "${workspaceRoot}/.esphome/build/enviro-weather/.pioenvs/enviro-weather/firmware.elf",
+            "request": "launch",
+            "type": "cortex-debug",
+            "servertype": "openocd",
+            "device": "RP2040",
+            "runToEntryPoint": "main",
+            "configFiles": [
+                "interface/cmsis-dap.cfg",
+                "target/rp2040.cfg"
+            ],
+            "openOCDLaunchCommands": [
+                "adapter speed 5000"
+            ],
+            "searchDir": ["/opt/openocd-rp2040/share/openocd/scripts"],
+            "svdFile": "/workspaces/rp2040/pico-sdk/src/rp2040/hardware_regs/rp2040.svd",
+            "gdbPath": "gdb-multiarch"
+        },
+        {
+            "name": "Pico Debug (Cortex-Debug with external OpenOCD)",
+            "cwd": "${workspaceRoot}",
+            "executable": "${workspaceRoot}/.esphome/build/enviro-weather/.pioenvs/enviro-weather/firmware.elf",
+            "request": "launch",
+            "type": "cortex-debug",
+            "servertype": "external",
+            "gdbTarget": "localhost:3333",
+            "device": "RP2040",
+            "runToEntryPoint": "main",
+            "svdFile": "/workspaces/rp2040/pico-sdk/src/rp2040/hardware_regs/rp2040.svd",
+            "showDevDebugOutput": "raw"
+        },
+    ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..a3b08b1
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,8 @@
+{
+    "search.exclude": {
+        "**/node_modules": true,
+        "**/bower_components": true,
+        "**/*.code-search": true,
+        ".esphome": true,
+    },
+}
\ No newline at end of file
diff --git a/openshell-components.code-workspace b/openshell-components.code-workspace
new file mode 100644
index 0000000..808e0f9
--- /dev/null
+++ b/openshell-components.code-workspace
@@ -0,0 +1,27 @@
+{
+	"folders": [
+		{
+			"path": "."
+		},
+		{
+			"path": "../rp2040"
+		},
+		{
+			"path": "../esphome"
+		}
+	],
+	"settings": {
+		"c-cpp-flylint.flexelint.enable": false,
+		"c-cpp-flylint.lizard.enable": false,
+		"c-cpp-flylint.flawfinder.enable": false,
+		"files.associations": {
+			"*.tmpl": "jinja",
+			"*.txt": "plaintext",
+			"memory": "cpp",
+			"istream": "cpp",
+			"ostream": "cpp"
+		},
+		"cortex-debug.openocdPath": "/opt/openocd-rp2040/bin/openocd",
+		//"cortex-debug.gdbPath": "/workspaces/rp2040/system/arm-none-eabi/bin/arm-none-eabi-gdb",
+	}
+}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..c8d0acb
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+-e ../esphome
\ No newline at end of file