From c6673d4081ca4052668a91554c68363cb46ff635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bub=C3=ADk?= Date: Sat, 27 Feb 2021 22:28:29 +0100 Subject: [PATCH] new feature: LCD/DLP Projector Serial Control - implemented as XDRV53 - user must configure GPIO pins "DLP Rx" and "DLP Tx" for serial communication - emulates an additional RELAY by sending ON/OFF commands to Projector - continually polls the Projector's state to update virtual RELAY state - blocks RELAY1 in ON state while Projector is running (to protect the lamp) - serial codes for NEC and OPTOMA, ready for more manufacturers - tested with NEC V300W --- BUILDS.md | 1 + tasmota/language/af_AF.h | 2 + tasmota/language/bg_BG.h | 2 + tasmota/language/cs_CZ.h | 2 + tasmota/language/de_DE.h | 2 + tasmota/language/el_GR.h | 2 + tasmota/language/en_GB.h | 2 + tasmota/language/es_ES.h | 2 + tasmota/language/fr_FR.h | 2 + tasmota/language/fy_NL.h | 2 + tasmota/language/he_HE.h | 2 + tasmota/language/hu_HU.h | 2 + tasmota/language/it_IT.h | 2 + tasmota/language/ko_KO.h | 2 + tasmota/language/nl_NL.h | 2 + tasmota/language/pl_PL.h | 2 + tasmota/language/pt_BR.h | 2 + tasmota/language/pt_PT.h | 2 + tasmota/language/ro_RO.h | 2 + tasmota/language/ru_RU.h | 2 + tasmota/language/sk_SK.h | 2 + tasmota/language/sv_SE.h | 2 + tasmota/language/tr_TR.h | 2 + tasmota/language/uk_UA.h | 2 + tasmota/language/vi_VN.h | 2 + tasmota/language/zh_CN.h | 2 + tasmota/language/zh_TW.h | 2 + tasmota/my_user_config.h | 3 + tasmota/support_features.ino | 4 +- tasmota/tasmota_configurations.h | 8 + tasmota/tasmota_template.h | 6 + tasmota/xdrv_53_projector_ctrl.h | 66 +++++ tasmota/xdrv_53_projector_ctrl.ino | 455 +++++++++++++++++++++++++++++ tools/decode-status.py | 2 +- 34 files changed, 595 insertions(+), 2 deletions(-) create mode 100644 tasmota/xdrv_53_projector_ctrl.h create mode 100644 tasmota/xdrv_53_projector_ctrl.ino diff --git a/BUILDS.md b/BUILDS.md index 9e4e847d0..f510ee046 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -172,6 +172,7 @@ | USE_TASMOTA_CLIENT | - | - | - | - | - | - | - | | USE_OPENTHERM | - | - | - | - | - | - | - | | USE_MIEL_HVAC | - | - | - | - | - | - | - | +| USE_PROJECTOR_CTRL | - | - | - | - | - | - | - | | USE_AS608 | - | - | - | - | - | - | - | | USE_TCP_BRIDGE | - | - | - | - | - | - | - | zbbridge | | | | | | | | | diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 07e8a88fa..5d5c923b5 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Herstel" #define D_SENSOR_RC522_RST "RC522 Herstel" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 9f222a84c..a45e9ea27 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -768,6 +768,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 1e9382216..02eaacc0c 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index cde12947c..5f8a42d78 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 7ba39fa04..6d1ecfacf 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 16d37c32c..e1b006c62 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index f5e3e8d2a..19b9a9ecb 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 1a8eb94fe..bedcdc94b 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -765,6 +765,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index fcb977be1..0a201c9f8 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 79cc2c3b8..95636505d 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 360a4c17c..cc5ed8cb5 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 20b1957f0..066510664 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 - RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC - TX" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC - RX" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP - Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP - Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD - Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD - Reset" #define D_SENSOR_RC522_RST "RC522 - Reset" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 22f98997b..2d29d9f83 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 875f25551..0bc949743 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 825448a04..e29ae3442 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 68e4e4df1..1d78796da 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 2f26b2e64..111cefb87 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index e00935295..68c7d66a3 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index c9d8c1166..fb6e9983d 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index b752d20fe..b0360781d 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 7105f64a9..29c9ec03c 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index a23f686fe..ee6414694 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 83c78b23f..898550b21 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 329f7ebe8..6c9a7c671 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 85e7381c4..3d92dcf30 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 34ff54547..40abf06f7 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -769,6 +769,8 @@ #define D_SENSOR_IEM3000_RX "iEM3000 RX" #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" #define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" #define D_SENSOR_RC522_RST "RC522 Rst" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index b35a1c475..188d09343 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -677,6 +677,9 @@ #define USE_TASMOTA_CLIENT_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MIEL_HVAC // Add support for Mitsubishi Electric HVAC serial interface (+5k code) +//#define USE_PROJECTOR_CTRL // Add support for LCD/DLP Projector serial control interface (+1k code) +//#define USE_PROJECTOR_CTRL_NEC // Use codes for NEC +//#define USE_PROJECTOR_CTRL_OPTOMA // Use codes for OPTOMA //#define USE_AS608 // Add support for AS608 optical and R503 capacitive fingerprint sensor (+3k code) // #define USE_AS608_MESSAGES // Add verbose error messages (+0k4 code) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 45ec475fc..04acd2e07 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -718,7 +718,9 @@ void ResponseAppendFeatures(void) #if defined(USE_DISPLAY) && defined(USE_DISPLAY_TM1637) feature7 |= 0x40000000; #endif -// feature7 |= 0x80000000; +#ifdef USE_PROJECTOR_CTRL + feature7 |= 0x80000000; // xdrv_53_projector_ctrl.ino +#endif } static uint32_t feature8 = 0x00000000; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index e0bf0100e..3838c6126 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -178,6 +178,9 @@ //#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MIEL_HVAC // Add support for Mitsubishi Electric HVAC serial interface (+5k code) +//#define USE_PROJECTOR_CTRL // Add support for LCD/DLP Projector serial control interface (+1k code) +//#define USE_PROJECTOR_CTRL_NEC // Use codes for NEC +//#define USE_PROJECTOR_CTRL_OPTOMA // Use codes for OPTOMA //#define USE_AS608 // Add support for AS608 optical and R503 capacitive fingerprint sensor (+3k4 code) #define USE_ENERGY_SENSOR // Add energy sensors (-14k code) @@ -431,6 +434,8 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface + #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI @@ -560,6 +565,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface #undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_ADE7953 // Disable ADE7953 Energy monitor as used on Shelly 2.5 (I2C address 0x38) (+1k5) @@ -699,6 +705,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface //#undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_PZEM004T // Disable PZEM004T energy sensor @@ -840,6 +847,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_MIEL_HVAC // Disable support for Mitsubishi Electric HVAC serial interface (+5k code) +#undef USE_PROJECTOR_CTRL // Disable support for LCD/DLP Projector serial control interface #undef USE_AS608 // Disable support for AS608 optical and R503 capacitive fingerprint sensor (+3k4 code) #undef USE_ENERGY_SENSOR // Disable energy sensors diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 6221c833c..286ebc118 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -150,6 +150,7 @@ enum UserSelectablePins { GPIO_NEOPOOL_TX, GPIO_NEOPOOL_RX, // Sugar Valley RS485 interface GPIO_SDM72_TX, GPIO_SDM72_RX, // SDM72 Serial interface GPIO_TM1637CLK, GPIO_TM1637DIO, // TM1637 interface + GPIO_PROJECTOR_CTRL_TX, GPIO_PROJECTOR_CTRL_RX, // LCD/DLP Projector Serial Control GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -320,6 +321,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_NEOPOOL_TX "|" D_SENSOR_NEOPOOL_RX "|" D_SENSOR_SDM72_TX "|" D_SENSOR_SDM72_RX "|" D_SENSOR_TM1637_CLK "|" D_SENSOR_TM1637_DIO "|" + D_SENSOR_PROJECTOR_CTRL_TX "|" D_SENSOR_PROJECTOR_CTRL_RX "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -760,6 +762,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface #endif +#ifdef USE_PROJECTOR_CTRL + AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control +#endif /*-------------------------------------------------------------------------------------------*\ * ESP32 specifics diff --git a/tasmota/xdrv_53_projector_ctrl.h b/tasmota/xdrv_53_projector_ctrl.h new file mode 100644 index 000000000..71683b8c9 --- /dev/null +++ b/tasmota/xdrv_53_projector_ctrl.h @@ -0,0 +1,66 @@ +#ifndef _XDRV53_PROJECTOR_CTRL_H_ +#define _XDRV53_PROJECTOR_CTRL_H_ + +//define RELAY that is forced ON while projector is running +#ifndef PROJECTOR_CTRL_PWR_BY_RELAY +#define PROJECTOR_CTRL_PWR_BY_RELAY 1 +#endif //PROJECTOR_CTRL_PWR_BY_RELAY + +#define PROJECTOR_CTRL_SERIAL_TIMEOUT 10 //up to 254 seconds +#define PROJECTOR_CTRL_SERIAL_BAUDRATE 9600 + +#ifdef USE_PROJECTOR_CTRL_NEC +/* see the serial codes in + * https://www.sharpnecdisplays.eu/p/download/v/5e14a015e26cacae3ae64a422f7f8af4/cp/Products/Projectors/Shared/CommandLists/PDF-ExternalControlManual-english.pdf#page=5 + * tested with NEC V300W + * final cksum byte is appended automatically + */ +#define PROJECTOR_CTRL_LOGNAME "DLP[NEC]" +static const uint8_t projector_ctrl_msg_qry_typ[] = { 0x00, 0xBF, 0x00, 0x00, 0x01, 0x00 }; //page81 +static const uint8_t projector_ctrl_msg_qry_pwr[] = { 0x00, 0xBF, 0x00, 0x00, 0x01, 0x02 }; //page83 +static const uint8_t projector_ctrl_msg_pwr_on[] = { 0x02, 0x00, 0x00, 0x00, 0x00 }; //page15 +static const uint8_t projector_ctrl_msg_pwr_off[] = { 0x02, 0x01, 0x00, 0x00, 0x00 }; //page16 +static const struct projector_ctrl_command_info_s projector_ctrl_commands[] = { + {PROJECTOR_CTRL_S_QRY_TYPE, &projector_ctrl_msg_qry_typ[0], sizeof(projector_ctrl_msg_qry_typ), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x20, 22, 8, 4, 0xA0, 8, 5, 2}, + {PROJECTOR_CTRL_S_QRY_PWR, &projector_ctrl_msg_qry_pwr[0], sizeof(projector_ctrl_msg_qry_pwr), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x20, 22, 6, 1, 0xA0, 8, 5, 2}, + {PROJECTOR_CTRL_S_PWR_ON, &projector_ctrl_msg_pwr_on[0], sizeof(projector_ctrl_msg_pwr_on), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x22, 6, 0, 1, 0xA2, 8, 5, 2}, + {PROJECTOR_CTRL_S_PWR_OFF, &projector_ctrl_msg_pwr_off[0], sizeof(projector_ctrl_msg_pwr_off), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 0x22, 6, 0, 1, 0xA2, 8, 5, 2} +}; +#define PROJECTOR_CTRL_QRYPWR_ON 0x04 +#define PROJECTOR_CTRL_QRYPWR_COOLING 0x05 + + +#elif defined(USE_PROJECTOR_CTRL_OPTOMA) +/* see the serial codes in + * https://www.optoma.co.uk/uploads/manuals/hd36-m-en-gb.pdf#page=56 + * not really tested with OPTOMA devices + */ +#define PROJECTOR_CTRL_LOGNAME "DLP[OPTOMA]" +static const uint8_t projector_ctrl_msg_qry_typ[] = { 0x7e, 0x30, 0x30, 0x31, 0x32, 0x32, 0x20, 0x31, 0x0d }; //page59 +static const uint8_t projector_ctrl_msg_qry_pwr[] = { 0x7e, 0x30, 0x30, 0x31, 0x32, 0x34, 0x20, 0x31, 0x0d }; //page59 +static const uint8_t projector_ctrl_msg_pwr_on[] = { 0x7e, 0x30, 0x30, 0x30, 0x30, 0x20, 0x31, 0x0d }; //page56 +static const uint8_t projector_ctrl_msg_pwr_off[] = { 0x7e, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x0d }; //page56 +static const struct projector_ctrl_command_info_s projector_ctrl_commands[] = { + {PROJECTOR_CTRL_S_QRY_TYPE, &projector_ctrl_msg_qry_typ[0], sizeof(projector_ctrl_msg_qry_typ), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 'O', 6, 2, 4, 'I', 5, 4, 1}, + {PROJECTOR_CTRL_S_QRY_PWR, &projector_ctrl_msg_qry_pwr[0], sizeof(projector_ctrl_msg_qry_pwr), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 'O', 3, 2, 1, 'I', 5, 4, 1}, + {PROJECTOR_CTRL_S_PWR_ON, &projector_ctrl_msg_pwr_on[0], sizeof(projector_ctrl_msg_pwr_on), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 'P', 1, 0, 1, 'F', 1, 0, 1}, + {PROJECTOR_CTRL_S_PWR_OFF, &projector_ctrl_msg_pwr_off[0], sizeof(projector_ctrl_msg_pwr_off), + PROJECTOR_CTRL_SERIAL_TIMEOUT, 'P', 1, 0, 1, 'F', 1, 0, 1} +}; +#define PROJECTOR_CTRL_QRYPWR_ON 0x31 +#define PROJECTOR_CTRL_QRYPWR_COOLING 0x31 //placebo + + +#else +#error USE_PROJECTOR_CTRL: No projector type defined +#endif + + +#endif //_XDRV53_PROJECTOR_CTRL_H_ \ No newline at end of file diff --git a/tasmota/xdrv_53_projector_ctrl.ino b/tasmota/xdrv_53_projector_ctrl.ino new file mode 100644 index 000000000..5b3e6849a --- /dev/null +++ b/tasmota/xdrv_53_projector_ctrl.ino @@ -0,0 +1,455 @@ +/* + xdrv_53_projector_ctrl.ino - LCD/DLP Projector Serial Control support for Tasmota + + Copyright (C) 2021 Jan BubĂ­k + Written with the gifts I got from Jesus. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_PROJECTOR_CTRL +/*********************************************************************************************\ + * LCD/DLP Projector Control via serial interface + * https://www.sharpnecdisplays.eu/p/download/v/5e14a015e26cacae3ae64a422f7f8af4/cp/Products/Projectors/Shared/CommandLists/PDF-ExternalControlManual-english.pdf#page=5 + * https://www.optoma.co.uk/uploads/manuals/hd36-m-en-gb.pdf#page=56 +\*********************************************************************************************/ + +#define XDRV_53 53 + +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#define xxstr(s) xstr(s) +#define xstr(s) #s + +enum projector_ctrl_dev_state_e : uint8_t { + PROJECTOR_CTRL_DEV_UNKNOWN=0, + PROJECTOR_CTRL_DEV_PWR_OFF, + PROJECTOR_CTRL_DEV_PWR_ON +}; + +enum projector_ctrl_serial_state_e : uint8_t { + PROJECTOR_CTRL_S_UNCONNECTED=0, + PROJECTOR_CTRL_S_QRY_PWR, + PROJECTOR_CTRL_S_QRY_TYPE, + PROJECTOR_CTRL_S_IDLE, + PROJECTOR_CTRL_S_PWR_ON, + PROJECTOR_CTRL_S_PWR_OFF +}; + +enum projector_ctrl_serial_result_e : uint8_t { + PROJECTOR_CTRL_R_UNKNOWN=0, + PROJECTOR_CTRL_R_PASS, + PROJECTOR_CTRL_R_FAIL +}; + +struct projector_ctrl_command_info_s { + const enum projector_ctrl_serial_state_e command; + const uint8_t *send_codes; + const uint8_t send_len; + const uint8_t timeout_ticks; + const uint8_t pass_first_byte; + const uint8_t pass_len; + const uint8_t pass_value_offset; + const uint8_t pass_value_bytes; + const uint8_t fail_first_byte; + const uint8_t fail_len; + const uint8_t fail_value_offset; + const uint8_t fail_value_bytes; +} __packed; + +#include "xdrv_53_projector_ctrl.h" + +struct projector_ctrl_softc_s { + TasmotaSerial *sc_serial; + uint8_t sc_device; + uint8_t sc_ticks; + enum projector_ctrl_dev_state_e sc_dev_state; + enum projector_ctrl_serial_state_e sc_ser_state; + enum projector_ctrl_serial_result_e sc_ser_result; + enum projector_ctrl_serial_state_e sc_ser_next_cmd; + const struct projector_ctrl_command_info_s *sc_cmd_info; + uint8_t sc_ser_sum; + uint8_t sc_ser_len; + uint32_t sc_ser_value; +} __packed; + +static struct projector_ctrl_softc_s *projector_ctrl_sc = nullptr; + + + +static void +projector_ctrl_pre_init(void) +{ + struct projector_ctrl_softc_s *sc; + int baudrate = PROJECTOR_CTRL_SERIAL_BAUDRATE; + + if (!PinUsed(GPIO_PROJECTOR_CTRL_TX) || !PinUsed(GPIO_PROJECTOR_CTRL_RX)) + return; + + sc = (struct projector_ctrl_softc_s *)malloc(sizeof(*sc)); + if (sc == NULL) { + AddLog_P(LOG_LEVEL_ERROR, PSTR(PROJECTOR_CTRL_LOGNAME ": unable to allocate state")); + return; + } + + memset(sc, 0, sizeof(*sc)); + + sc->sc_serial = new TasmotaSerial(Pin(GPIO_PROJECTOR_CTRL_RX), + Pin(GPIO_PROJECTOR_CTRL_TX), 2); + + if (!sc->sc_serial->begin(baudrate, 2)) { + AddLog_P(LOG_LEVEL_ERROR, PSTR(PROJECTOR_CTRL_LOGNAME ": unable to begin serial " + "(baudrate %d)"), baudrate); + goto del; + } + + if (sc->sc_serial->hardwareSerial()) { + ClaimSerial(); + SetSerial(baudrate, TS_SERIAL_8N1); + } + + sc->sc_device = ++(TasmotaGlobal.devices_present); /* claim a POWER device slot */ + + AddLog_P(LOG_LEVEL_INFO, PSTR(PROJECTOR_CTRL_LOGNAME ": new RELAY%d, polling serial for Projector status"), sc->sc_device); + + projector_ctrl_sc = sc; + return; +del: + delete sc->sc_serial; +free: + free(sc); +} + + + +static void +projector_ctrl_write(struct projector_ctrl_softc_s *sc, const uint8_t *bytes, const size_t len) +{ + TasmotaSerial *serial; + uint8_t cksum; + size_t i; + + cksum = 0; + serial = sc->sc_serial; + + for (i = 0; i < len; i++) { + uint8_t b = bytes[i]; + serial->write(b); + cksum += b; + } +#ifdef USE_PROJECTOR_CTRL_NEC + serial->write(cksum); +#endif +#ifdef DEBUG_PROJECTOR_CTRL + char hex_b[(len + 1) * 2]; + AddLog_P(LOG_LEVEL_DEBUG,PSTR(PROJECTOR_CTRL_LOGNAME ": RAW bytes %s %02x"), + ToHex_P((uint8_t *)bytes, len, hex_b, sizeof(hex_b)), cksum); +#endif //DEBUG_PROJECTOR_CTRL + + serial->flush(); + return; +} + + + +static void +projector_ctrl_request(struct projector_ctrl_softc_s *sc, const uint8_t command) +{ + const struct projector_ctrl_command_info_s *e; + size_t i; + + if ((sc->sc_dev_state!=PROJECTOR_CTRL_DEV_UNKNOWN)&&(sc->sc_ser_state!=PROJECTOR_CTRL_S_IDLE)) { + if ((command!=PROJECTOR_CTRL_S_QRY_PWR)&&(command!=PROJECTOR_CTRL_S_QRY_TYPE)) { + sc->sc_ser_next_cmd=(projector_ctrl_serial_state_e)command; + AddLog_P(LOG_LEVEL_INFO, PSTR(PROJECTOR_CTRL_LOGNAME + ": Serial CMD %02x already running, enqueueing next (%02x)"), sc->sc_ser_state, command); + }; + return; + }; + + for (i = 0; i < nitems(projector_ctrl_commands); i++) { + e = &projector_ctrl_commands[i]; + if (command == e->command){ + sc->sc_cmd_info=e; + sc->sc_ser_len=0; + sc->sc_ser_result=PROJECTOR_CTRL_R_UNKNOWN; + sc->sc_ser_state=(projector_ctrl_serial_state_e)command; + sc->sc_ser_sum=0; + sc->sc_ser_next_cmd=PROJECTOR_CTRL_S_UNCONNECTED; + sc->sc_ticks=0; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Sending CMD %02x"), command); +#endif //DEBUG_PROJECTOR_CTRL + projector_ctrl_write(sc,e->send_codes,e->send_len); + return; + } + }; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Undefined serial command %02x"), command); +#endif //DEBUG_PROJECTOR_CTRL + return; +} + + + +static uint8_t +projector_ctrl_parse(struct projector_ctrl_softc_s *sc, const uint8_t byte) +{ + enum projector_ctrl_serial_state_e nstate; + const struct projector_ctrl_command_info_s *cmd; + + nstate = sc->sc_ser_state; + + switch (nstate) { + case PROJECTOR_CTRL_S_IDLE: + case PROJECTOR_CTRL_S_UNCONNECTED: +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Spurious input in state %02x, got %02x, going UNCONNECTED"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + return(PROJECTOR_CTRL_S_UNCONNECTED); + + default: + cmd=sc->sc_cmd_info; + sc->sc_ser_len++; + if (sc->sc_ser_len==1) { + if (byte==cmd->pass_first_byte){ + sc->sc_ser_result=PROJECTOR_CTRL_R_PASS; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x PASS, 1st byte %02x"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + }else if (byte==cmd->fail_first_byte){ + sc->sc_ser_result=PROJECTOR_CTRL_R_FAIL; +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x FAIL, 1st byte %02x"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + }else{ +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x UNKNOWN, 1st byte %02x, going UNCONNECTED"), nstate, byte); +#endif //DEBUG_PROJECTOR_CTRL + return(PROJECTOR_CTRL_S_UNCONNECTED); + }; + }; + if (sc->sc_ser_result==PROJECTOR_CTRL_R_PASS){ + if (sc->sc_ser_len==(cmd->pass_value_offset+1)) + sc->sc_ser_value=byte; + if ((sc->sc_ser_len>(cmd->pass_value_offset+1))&&(sc->sc_ser_len<=(cmd->pass_value_offset+cmd->pass_value_bytes))) + sc->sc_ser_value=(sc->sc_ser_value<<8)|byte; + if (sc->sc_ser_len==cmd->pass_len){ +#ifdef USE_PROJECTOR_CTRL_NEC + if(sc->sc_ser_sum!=byte){ +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Failed cksum for CMD %02x. Got %02x bytes, computed cksum: %02x, recevied cksum: %02x, going UNCONNECTED"), + nstate, sc->sc_ser_len, sc->sc_ser_sum, byte); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_UNCONNECTED; + } else +#endif //USE_PROJECTOR_CTRL_NEC + { +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x PASS, got %02x bytes, retval %02x, going IDLE"), nstate, sc->sc_ser_len, sc->sc_ser_value); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_IDLE; + }; + }; + }; + + if (sc->sc_ser_result==PROJECTOR_CTRL_R_FAIL) { + if (sc->sc_ser_len==(cmd->fail_value_offset+1)) + sc->sc_ser_value=byte; + if ((sc->sc_ser_len>(cmd->fail_value_offset+1))&&(sc->sc_ser_len<=(cmd->fail_value_offset+cmd->fail_value_bytes))) + sc->sc_ser_value=(sc->sc_ser_value<<8)|byte; + if(sc->sc_ser_len==cmd->fail_len){ +#ifdef USE_PROJECTOR_CTRL_NEC + if(sc->sc_ser_sum!=byte){ +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": Failed cksum for CMD %02x. Got %02x bytes, computed cksum: %02x, receied cksum: %02x, going UNCONNECTED"), + nstate, sc->sc_ser_len, sc->sc_ser_sum, byte); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_UNCONNECTED; + } else +#endif //USE_PROJECTOR_CTRL_NEC + { +#ifdef DEBUG_PROJECTOR_CTRL + AddLog_P(LOG_LEVEL_DEBUG, PSTR(PROJECTOR_CTRL_LOGNAME + ": CMD %02x FAIL, got %02x bytes, retval %02x, going idle"), nstate, sc->sc_ser_len, sc->sc_ser_value); +#endif //DEBUG_PROJECTOR_CTRL + nstate=PROJECTOR_CTRL_S_IDLE; + }; + }; + }; + +#ifdef USE_PROJECTOR_CTRL_NEC + sc->sc_ser_sum += byte; +#endif //USE_PROJECTOR_CTRL_NEC + + break; + } + return (nstate); +} + + + +static void +projector_ctrl_loop(struct projector_ctrl_softc_s *sc) +{ + TasmotaSerial *serial; + uint8_t oldstate; + serial = sc->sc_serial; + + while (serial->available()) { + yield(); + oldstate = sc->sc_ser_state; + switch (sc->sc_ser_state = (projector_ctrl_serial_state_e)projector_ctrl_parse(sc, serial->read())) { + case PROJECTOR_CTRL_S_UNCONNECTED: + sc->sc_dev_state=PROJECTOR_CTRL_DEV_UNKNOWN; + break; + case PROJECTOR_CTRL_S_IDLE: + if ((oldstate==PROJECTOR_CTRL_S_QRY_PWR)&&(sc->sc_ser_result==PROJECTOR_CTRL_R_PASS)){ + if(((sc->sc_ser_value==PROJECTOR_CTRL_QRYPWR_ON)||(sc->sc_ser_value==PROJECTOR_CTRL_QRYPWR_COOLING))&&(sc->sc_dev_state!=PROJECTOR_CTRL_DEV_PWR_ON)){ + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_ON; + ExecuteCommandPower(sc->sc_device, POWER_ON, SRC_IGNORE); + }; + if(((sc->sc_ser_value!=PROJECTOR_CTRL_QRYPWR_ON)&&(sc->sc_ser_value!=PROJECTOR_CTRL_QRYPWR_COOLING))&&(sc->sc_dev_state!=PROJECTOR_CTRL_DEV_PWR_OFF)){ + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_OFF; + ExecuteCommandPower(sc->sc_device, POWER_OFF, SRC_IGNORE); + }; + }; + if ((oldstate==PROJECTOR_CTRL_S_PWR_ON)&&(sc->sc_ser_result==PROJECTOR_CTRL_R_PASS)) + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_ON; + if ((oldstate==PROJECTOR_CTRL_S_PWR_OFF)&&(sc->sc_ser_result==PROJECTOR_CTRL_R_PASS)) + sc->sc_dev_state=PROJECTOR_CTRL_DEV_PWR_OFF; + if(sc->sc_ser_next_cmd!=PROJECTOR_CTRL_S_UNCONNECTED){ + oldstate=sc->sc_ser_next_cmd; + sc->sc_ser_next_cmd=PROJECTOR_CTRL_S_UNCONNECTED; + projector_ctrl_request(sc,oldstate); + }; + break; + }; + } +} + + + +static void +projector_ctrl_connect(struct projector_ctrl_softc_s *sc) +{ + projector_ctrl_request(sc,PROJECTOR_CTRL_S_QRY_PWR); +} + + + +static void +projector_ctrl_tick(struct projector_ctrl_softc_s *sc) +{ + if(sc->sc_ser_state==PROJECTOR_CTRL_S_IDLE){ + switch (TasmotaGlobal.uptime&0xf) { + case 0: + projector_ctrl_request(sc,PROJECTOR_CTRL_S_QRY_PWR); + break; + case 8: + projector_ctrl_request(sc,PROJECTOR_CTRL_S_QRY_TYPE); + break; + }; + }else if(sc->sc_ticks > sc->sc_cmd_info->timeout_ticks){ + //current CMD has ran out of time, drop connection + AddLog_P(LOG_LEVEL_INFO,PSTR(PROJECTOR_CTRL_LOGNAME ": DISCONNECTED")); + sc->sc_dev_state=PROJECTOR_CTRL_DEV_UNKNOWN; + sc->sc_ser_state=PROJECTOR_CTRL_S_UNCONNECTED; + }; +} + + + +static bool +projector_ctrl_set_power(struct projector_ctrl_softc_s *sc) +{ + if (TasmotaGlobal.active_device==PROJECTOR_CTRL_PWR_BY_RELAY){ + if ((sc->sc_dev_state == PROJECTOR_CTRL_DEV_PWR_ON) && (0==bitRead(XdrvMailbox.index, PROJECTOR_CTRL_PWR_BY_RELAY -1))) { + TasmotaGlobal.power = bitSet(TasmotaGlobal.power,PROJECTOR_CTRL_PWR_BY_RELAY -1); + AddLog_P(LOG_LEVEL_INFO,PSTR(PROJECTOR_CTRL_LOGNAME ": Keep RELAY" xxstr(PROJECTOR_CTRL_PWR_BY_RELAY) " ON")); + } else { + return(false); + }; + } else if (TasmotaGlobal.active_device==sc->sc_device){ + if (bitRead(XdrvMailbox.index, sc->sc_device -1)) { + switch (sc->sc_dev_state) { + case PROJECTOR_CTRL_DEV_UNKNOWN: + TasmotaGlobal.power = bitClear(TasmotaGlobal.power,sc->sc_device -1); + break; + case PROJECTOR_CTRL_DEV_PWR_OFF: + projector_ctrl_request(sc,PROJECTOR_CTRL_S_PWR_ON); + break; + }; + }else{ + if (sc->sc_dev_state == PROJECTOR_CTRL_DEV_PWR_ON) + projector_ctrl_request(sc,PROJECTOR_CTRL_S_PWR_OFF); + }; + } else { + return(false); + }; + return (true); +} + + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv53(uint8_t function) { + bool result; + struct projector_ctrl_softc_s *sc; + + result = false; + sc = projector_ctrl_sc; + + switch (function) { + case FUNC_PRE_INIT: + projector_ctrl_pre_init(); + return (false); + } + + if (sc == NULL) + return (false); + + switch (function) { + case FUNC_LOOP: + projector_ctrl_loop(sc); + break; + + case FUNC_EVERY_SECOND: + sc->sc_ticks++; + if (sc->sc_dev_state!=PROJECTOR_CTRL_DEV_UNKNOWN) + projector_ctrl_tick(sc); + else if ((TasmotaGlobal.uptime&0x7)==0) //each 8 seconds + projector_ctrl_connect(sc); + break; + + case FUNC_SET_DEVICE_POWER: + result = projector_ctrl_set_power(sc); + break; + + } + + return (result); +} + +#endif // USE_PROJECTOR_CTRL \ No newline at end of file diff --git a/tools/decode-status.py b/tools/decode-status.py index bd1f959a8..4e12be5d5 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -247,7 +247,7 @@ a_features = [[ "USE_DISPLAY_ILI9488","USE_DISPLAY_SSD1351","USE_DISPLAY_RA8876","USE_DISPLAY_ST7789", "USE_DISPLAY_SSD1331","USE_UFILESYS","USE_TIMEPROP","USE_PID", "USE_BS814A2","USE_SEESAW_SOIL","USE_WIEGAND","USE_NEOPOOL", - "USE_TOF10120","USE_SDM72","USE_DISPLAY_TM1637","" + "USE_TOF10120","USE_SDM72","USE_DISPLAY_TM1637","USE_PROJECTOR_CTRL" ],[ "","","","", "","","","",