Skip to content

Commit e17f472

Browse files
committed
Initial support for RP2040 (Raspberry Pi Pico W)
Currently working with ESPHome 2024.12.4. Modified a number of things to allow for selective inclusion of components depending on platform.
1 parent 277ae0e commit e17f472

29 files changed

+1682
-96
lines changed

firmware/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/.esphome/
22
/secrets.yaml
33
esphome_env/*
4+
.gdb_history
5+
.DS_Store
46

57
*.pyc

firmware/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ clean:
1717
esphome clean lolin_s2_mini.yaml
1818
esphome clean lolin_s3_mini.yaml
1919
esphome clean esp32-s3-devkitc-1.yaml
20+
esphome clean esp32_s3_super_mini.yaml
21+
esphome clean rpipicow.yaml
2022
rm -rf .esphome/idedata/*
2123
rm -rf ~/.platformio/penv
2224
# build-esp32s2-mini:
@@ -69,6 +71,12 @@ lolin_s2_mini:
6971
lolin_s3_mini:
7072
esphome \
7173
run lolin_s3_mini.yaml --device $(USB_ADDRESS)
74+
rpipicow:
75+
esphome \
76+
run rpipicow.yaml --device $(USB_ADDRESS)
7277
devkit:
7378
esphome \
74-
run esp32-s3-devkitc-1.yaml --device $(USB_ADDRESS)
79+
run esp32-s3-devkitc-1.yaml --device $(USB_ADDRESS)
80+
s3_super_mini:
81+
esphome \
82+
run esp32_s3_super_mini.yaml --device $(USB_ADDRESS)

firmware/common.yaml

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
---
22
substitutions:
33
name: openspool
4+
5+
globals:
6+
- id: global_lan_access_code
7+
type: std::string
8+
restore_value: yes
9+
- id: global_bambu_ip
10+
type: std::string
11+
restore_value: yes
12+
- id: global_bambu_serial
13+
type: std::string
14+
restore_value: yes
15+
416
esphome:
517
name: ${name}
618
name_add_mac_suffix: true
@@ -13,6 +25,7 @@ esphome:
1325
build_flags:
1426
- -std=gnu++14
1527
- -DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"
28+
# - -DDISABLE_WATCHDOG=1
1629
on_boot:
1730
then:
1831
#TODO: breahting blue studders a little bit
@@ -36,15 +49,27 @@ esphome:
3649
id: neopixel_light
3750
effect: none
3851
brightness: 50%
39-
# - delay: 100ms
40-
# - light.addressable_set:
41-
# id: neopixel_light
42-
# color_brightness: 50%
43-
# range_from: 0
44-
# range_to: ${led_count}
45-
# red: 50%
46-
# green: 50%
47-
# blue: 50%
52+
# # - delay: 100ms
53+
# - light.addressable_set:
54+
# id: neopixel_light
55+
# color_brightness: 50%
56+
# range_from: 0
57+
# range_to: ${led_count}
58+
# red: 50%
59+
# green: 50%
60+
# blue: 50%
61+
- text.set:
62+
id: bambu_lan_access_code
63+
value: !lambda |-
64+
return id(global_lan_access_code);
65+
- text.set:
66+
id: bambu_ip_address
67+
value: !lambda |-
68+
return id(global_bambu_ip);
69+
- text.set:
70+
id: bambu_serial_number
71+
value: !lambda |-
72+
return id(global_bambu_serial);
4873
- if:
4974
condition:
5075
lambda: |-
@@ -55,13 +80,13 @@ esphome:
5580
- logger.log:
5681
level: info
5782
format: "Connecting to Bambu printer"
58-
- mqtt.enable:
83+
- ${mqtt}.enable:
5984
id: bambu_mqtt
6085
else:
6186
- logger.log:
6287
level: info
6388
format: "Missing Bambu Credentials, skipping mqtt connect"
64-
- mqtt.disable:
89+
- ${mqtt}.disable:
6590
id: bambu_mqtt
6691
# - script.execute: set_all_leds_white
6792
# - lambda: |-
@@ -75,14 +100,16 @@ esphome:
75100
on_shutdown:
76101
then:
77102
- script.execute: set_led_off
78-
esp32:
79-
framework:
80-
type: esp-idf
81-
version: 5.3.1
82-
platform_version: 6.9.0 # https://github.com/platformio/platform-espressif32/releases/
83-
sdkconfig_options:
84-
CONFIG_MBEDTLS_HKDF_C: y # Needed for bambu KDF
85-
CONFIG_MBEDTLS_MD_C: y # Needed for bambu KDF
103+
104+
105+
# esp32:
106+
# framework:
107+
# type: esp-idf
108+
# version: 5.3.1
109+
# platform_version: 6.9.0 # https://github.com/platformio/platform-espressif32/releases/
110+
# sdkconfig_options:
111+
# CONFIG_MBEDTLS_HKDF_C: y # Needed for bambu KDF
112+
# CONFIG_MBEDTLS_MD_C: y # Needed for bambu KDF
86113
# version: recommended
87114
# sdkconfig_options:
88115
# MBEDTLS_CERTIFICATE_BUNDLE: y
@@ -107,7 +134,6 @@ packages:
107134
bambu_printer: !include conf.d/bambu_printer.yaml
108135
pn532_rfid-solo: !include conf.d/pn532_rfid-solo.yaml
109136
automation: !include conf.d/automation.yaml
110-
led-external: !include conf.d/led-external.yaml
111137
ota: !include conf.d/ota.yaml
112138
#update: !include conf.d/update.yaml
113139
api: !include conf.d/api.yaml
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Copyright (C) 2025 Drew Green (@agreenbhm)
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
import esphome.codegen as cg
17+
import esphome.config_validation as cv
18+
from esphome.automation import Condition
19+
from esphome.const import CONF_ID
20+
from esphome.core import CORE, coroutine_with_priority
21+
from esphome import automation
22+
from esphome.const import (
23+
CONF_TOPIC,
24+
CONF_PAYLOAD,
25+
CONF_QOS,
26+
CONF_RETAIN
27+
)
28+
29+
rp2040_mqtt_ns = cg.esphome_ns.namespace("rp2040_mqtt")
30+
RP2040MQTTComponent = rp2040_mqtt_ns.class_("RP2040MQTT", cg.Component)
31+
RP2040MQTTConnectedCondition = rp2040_mqtt_ns.class_("RP2040MQTTConnectedCondition", Condition)
32+
RP2040MQTTEnableAction = rp2040_mqtt_ns.class_("RP2040MQTTEnableAction", automation.Action)
33+
RP2040MQTTDisableAction = rp2040_mqtt_ns.class_("RP2040MQTTDisableAction", automation.Action)
34+
RP2040MQTTPublishAction = rp2040_mqtt_ns.class_("RP2040MQTTPublishAction", automation.Action)
35+
36+
MULTI_CONF = True
37+
38+
CONF_SECURE = "secure"
39+
CONF_MQTT_HOST = "mqtt_host"
40+
CONF_MQTT_PORT = "mqtt_port"
41+
CONF_AUTH = "auth"
42+
CONF_MQTT_USER = "mqtt_user"
43+
CONF_MQTT_PASS = "mqtt_pass"
44+
45+
46+
CONFIG_SCHEMA = (
47+
cv.Schema(
48+
{
49+
cv.GenerateID(): cv.declare_id(RP2040MQTTComponent),
50+
cv.Optional(CONF_MQTT_HOST): cv.string,
51+
cv.Optional(CONF_MQTT_PORT): cv.port,
52+
cv.Optional(CONF_SECURE): cv.boolean,
53+
cv.Optional(CONF_AUTH): cv.boolean,
54+
cv.Optional(CONF_MQTT_USER): cv.string,
55+
cv.Optional(CONF_MQTT_PASS): cv.string
56+
57+
}
58+
)
59+
.extend(cv.COMPONENT_SCHEMA)
60+
)
61+
62+
@automation.register_action(
63+
"rp2040_mqtt.enable",
64+
RP2040MQTTEnableAction,
65+
cv.Schema(
66+
{
67+
cv.GenerateID(): cv.use_id(RP2040MQTTComponent),
68+
}
69+
),
70+
)
71+
72+
async def rp2040_mqtt_enable_to_code(config, action_id, template_arg, args):
73+
paren = await cg.get_variable(config[CONF_ID])
74+
return cg.new_Pvariable(action_id, template_arg, paren)
75+
76+
@automation.register_action(
77+
"rp2040_mqtt.disable",
78+
RP2040MQTTDisableAction,
79+
cv.Schema(
80+
{
81+
cv.GenerateID(): cv.use_id(RP2040MQTTComponent),
82+
}
83+
),
84+
)
85+
86+
async def rp2040_mqtt_disable_to_code(config, action_id, template_arg, args):
87+
paren = await cg.get_variable(config[CONF_ID])
88+
return cg.new_Pvariable(action_id, template_arg, paren)
89+
90+
MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema(
91+
{
92+
cv.GenerateID(): cv.use_id(RP2040MQTTComponent),
93+
cv.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
94+
cv.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
95+
cv.Optional(CONF_QOS, default=0): cv.templatable(cv.mqtt_qos),
96+
cv.Optional(CONF_RETAIN, default=False): cv.templatable(cv.boolean),
97+
}
98+
)
99+
100+
101+
@automation.register_action(
102+
"rp2040_mqtt.publish", RP2040MQTTPublishAction, MQTT_PUBLISH_ACTION_SCHEMA
103+
)
104+
async def rp2040_mqtt_publish_action_to_code(config, action_id, template_arg, args):
105+
paren = await cg.get_variable(config[CONF_ID])
106+
var = cg.new_Pvariable(action_id, template_arg, paren)
107+
template_ = await cg.templatable(config[CONF_TOPIC], args, cg.std_string)
108+
cg.add(var.set_topic(template_))
109+
110+
template_ = await cg.templatable(config[CONF_PAYLOAD], args, cg.std_string)
111+
cg.add(var.set_payload(template_))
112+
template_ = await cg.templatable(config[CONF_QOS], args, cg.uint8)
113+
cg.add(var.set_qos(template_))
114+
template_ = await cg.templatable(config[CONF_RETAIN], args, bool)
115+
cg.add(var.set_retain(template_))
116+
return var
117+
118+
119+
120+
@automation.register_condition(
121+
"rp2040_mqtt.connected",
122+
RP2040MQTTConnectedCondition,
123+
cv.Schema(
124+
{
125+
cv.GenerateID(): cv.use_id(RP2040MQTTComponent),
126+
}
127+
),
128+
)
129+
async def rp2040_mqtt_connected_to_code(config, condition_id, template_arg, args):
130+
paren = await cg.get_variable(config[CONF_ID])
131+
return cg.new_Pvariable(condition_id, template_arg, paren)
132+
133+
def to_code(config):
134+
var = cg.new_Pvariable(config[CONF_ID])
135+
if CONF_MQTT_HOST in config:
136+
cg.add(var.set_mqtt_host(config[CONF_MQTT_HOST]))
137+
if CONF_MQTT_PORT in config:
138+
cg.add(var.set_mqtt_port(config[CONF_MQTT_PORT]))
139+
if CONF_SECURE in config:
140+
cg.add(var.set_secure(config[CONF_SECURE]))
141+
if CONF_AUTH in config:
142+
cg.add(var.set_authenticate(config[CONF_AUTH]))
143+
if CONF_MQTT_USER in config:
144+
cg.add(var.set_mqtt_user(config[CONF_MQTT_USER]))
145+
if CONF_MQTT_PASS in config:
146+
cg.add(var.set_mqtt_password(config[CONF_MQTT_PASS]))
147+
# if CORE.is_rp2040:
148+
# cg.add_library("mobizt/ESP_SSLClient", None)
149+
cg.add_library("mobizt/ESP_SSLClient", None)
150+
cg.add_library("arduino-libraries/ArduinoMqttClient", None)
151+
152+
153+
yield cg.register_component(var, config)

0 commit comments

Comments
 (0)