diff --git a/packages/display/colorado/colorado-tab5.yaml b/packages/display/colorado/colorado-tab5.yaml index 0c60bdc..75addeb 100644 --- a/packages/display/colorado/colorado-tab5.yaml +++ b/packages/display/colorado/colorado-tab5.yaml @@ -650,6 +650,37 @@ sensor: unit_of_measurement: km/h/s device_class: speed update_interval: never + - platform: template + id: "odometer" + name: "Odometer" + icon: mdi:counter + state_class: "total_increasing" + unit_of_measurement: "km" + device_class: "distance" + accuracy_decimals: 0 + update_interval: never + on_value: + then: + - lvgl.label.update: + id: lbl_odometer + text: !lambda |- + if (isnan(x)) return std::string("--"); + char buf[16]; snprintf(buf, sizeof(buf), "%.0f", x); return std::string(buf); + - platform: template + id: "gear_position" + name: "Gear Position" + icon: mdi:car-shift-pattern + state_class: "measurement" + accuracy_decimals: 0 + update_interval: never + on_value: + then: + - lvgl.label.update: + id: lbl_gear + text: !lambda |- + if (isnan(x)) return std::string("-"); + int g = (int)x; + char buf[4]; snprintf(buf, sizeof(buf), "%d", g); return std::string(buf); - platform: sgp30 i2c_id: ext_bus update_interval: 1s @@ -767,7 +798,8 @@ interval: - lambda: |- static std::vector cmd_list = { "0105", "011F", "012F", "0146", - "0142", "010C", "010D", "0104" + "0142", "010C", "010D", "0104", + "22199A", "2225AE" }; if (!cmd_list.empty()) { id(script_ble_write).execute(cmd_list[id(obd_cmd_index)]); @@ -813,6 +845,22 @@ text_sensor: } else if (pid == 0x04) id(engine_load).publish_state(100 * a / 255); } + // Mode 22 (GM extended PIDs): response is "62 " + else if (x.substr(0, 2) == "62" && x.size() >= 8) { + uint16_t pid = std::stoi(x.substr(2, 4), nullptr, 16); + uint8_t a = std::stoi(x.substr(6, 2), nullptr, 16); + uint8_t b = x.size() >= 10 ? std::stoi(x.substr( 8, 2), nullptr, 16) : 0; + uint8_t c = x.size() >= 12 ? std::stoi(x.substr(10, 2), nullptr, 16) : 0; + uint8_t d = x.size() >= 14 ? std::stoi(x.substr(12, 2), nullptr, 16) : 0; + if (pid == 0x199A) { + id(gear_position).publish_state(a); + } else if (pid == 0x25AE) { + // Odometer: 4-byte unsigned, MSB-first by default. Swap if scale looks off. + uint32_t raw = ((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | d; + id(odometer).publish_state((float)raw); + } + id(script_logs).execute(("RX " + x).c_str()); + } - platform: template name: "Time" internal: True @@ -1260,6 +1308,32 @@ lvgl: clickable: false pad_all: 0 widgets: + # 기어 단수 배지 (속도 위) + - obj: + align: center + x: 0 + y: -180 + width: 76 + height: 76 + radius: 38 + bg_color: 0x141C26 + border_width: 2 + border_color: 0xF1C36C + pad_all: 0 + clickable: false + widgets: + - label: + id: lbl_gear + text: "-" + align: center + text_color: 0xF1C36C + text_font: notosans45 + - label: + text: "GEAR" + align: bottom_mid + y: -2 + text_color: 0x7F8EA3 + text_font: notosans16 # 속도 (Hero) - label: id: lbl_speed @@ -1365,6 +1439,19 @@ lvgl: - label: { text: "외기", align: left_mid, x: 68, text_color: 0x7F8EA3, text_font: notosans20 } - label: { id: lbl_ambient_air_temperature, text: "--", align: right_mid, x: -30, text_color: 0xF7FBFF, text_font: notosans45 } - label: { text: "°C", align: right_mid, x: -5, text_color: 0x7F8EA3, text_font: notosans20 } + # ── 오도미터 (작은 라벨) ── + - obj: + align: top_mid + y: 454 + width: 290 + height: 40 + bg_opa: 0% + border_width: 0 + pad_all: 0 + widgets: + - label: { text: "ODO", align: left_mid, x: 10, text_color: 0x7F8EA3, text_font: notosans20 } + - label: { id: lbl_odometer, text: "--", align: right_mid, x: -30, text_color: 0xE0E8F4, text_font: notosans25 } + - label: { text: "km", align: right_mid, x: -5, text_color: 0x7F8EA3, text_font: notosans16 } # ── 번호판 + 버전 (하단 작게) ── - obj: align: bottom_mid