『瀚思彼岸』» 智能家居技术论坛

标题: 升降桌改造方案的设想,望大佬指点 [打印本页]

作者: hcfong2020    时间: 2024-5-23 07:53
标题: 升降桌改造方案的设想,望大佬指点
本帖最后由 hcfong2020 于 2024-6-2 16:29 编辑

[attach]59520[/attach]

杂牌升降桌,下面是手控器和控制器的图片。通过协议分析,使用的应该也是uart协议。
这个手控器的网线头是10芯的,用了6芯,其中数据主要是通过R,T,和P口传输,R和T穿数据,大概是5位,使用16进制表示的话是 0xa5 0x00,0x02,0x01,0x03
平时的时候P口是低电平,当手控器一下上升会发送一段16进制的码,同时P口发送高电平,发送的16进制码是没隔11ms发送,知道离开按钮,发送结束。恢复到正常的每隔11ms发送特定的16进制码。
同时在R口也会收到反馈,反馈信息也是一组16进制的码。


现在改造的设想是在中间增加一个d1mini,通过接收RT口的数据,转发到控制器,实现对控制器的操作。
问题一:比如pin1和pin3用于接收手控器的发送和接收,D5和D6接收控制器的发送和接收,把两个接收打通后,使得d1mini相当于导线,需要网络控制的时候,通过发送特定的信号,模式手控器动作,这种方案是否可行?
问题二:直接从网线的中间破线,不破坏原先的线路,通过d1 mini,直接模拟手控器的操作,从而操作控制器。这样是否可以行,中间破线,会不会影响信号的传输,发送信号的时候会不会出现问题。

望指点。
主要参考
https://community.home-assistant.io/t/desky-standing-desk-esphome-works-with-desky-uplift-jiecang-assmann-others/383790/34
跟我这个桌子最接近的无线控制的改造网页地址,是同一个厂家的,不过线序和颜色以及控制方式还是有一定的区别的,目前根据这个网页中一名叫veli提供的代码,通过一定的修改后可以看到桌子的高度,也可以控制桌子升降,不过在控制升降的时候,会返回一些报错信息。还需要好好研究一下代码。
https://community.home-assistant ... mart-desk/530732/13
[attach]59862[/attach]
控制器电源
[attach]59863[/attach]
手控器,通过网线和控制器电源连接
[attach]59865[/attach]
手控器的线接口,P,R,T,5V电源,G,接地



作者: crazymouse    时间: 2024-5-23 10:17
一个升降桌,为啥需要远程控制?我实在搞不懂

作者: 萌萌之家    时间: 2024-5-23 10:50
一个升降桌,你发三个帖子?我实在搞不懂
作者: shenmirenQUQ    时间: 2024-5-23 13:05
crazymouse 发表于 2024-5-23 10:17
一个升降桌,为啥需要远程控制?我实在搞不懂

我也想改,我的想法是家里没人自动扫地的时候把桌子升高,扫地机器人不会卷到线
作者: shenmirenQUQ    时间: 2024-5-23 13:07
我之前看过别人用esp32改的,不过我动手能力不行就放弃了~
作者: csl0524    时间: 2024-5-23 14:21
楼主就想着有电的都给接入,不可控的设备看着难受   
作者: wzx123    时间: 2024-5-23 14:25
想法有很多的 不能打击楼主的兴趣对吧
作者: kjjuhfv    时间: 2024-5-23 15:09
既然知道p口高电平时上升  
那你直接在p口输入高电平看会不会上升
如果会上升那就不需要发射16进制代码了
作者: crazymouse    时间: 2024-5-23 18:33
shenmirenQUQ 发表于 2024-5-23 13:05
我也想改,我的想法是家里没人自动扫地的时候把桌子升高,扫地机器人不会卷到线 ...

额,搞个桌子下的集线器是不是就解决问题了啊,我就是用的宜家的
作者: leung    时间: 2024-5-23 19:50
crazymouse 发表于 2024-5-23 18:33
额,搞个桌子下的集线器是不是就解决问题了啊,我就是用的宜家的

物理暴击
作者: hcfong2020    时间: 2024-5-23 20:31
crazymouse 发表于 2024-5-23 10:17
一个升降桌,为啥需要远程控制?我实在搞不懂

应用场景是,这个桌子是放在幕布前的,平时使用的时候是75厘米高度,当幕布下降的时候,自动下降到50,只为了这个功能。懒人一个,比如说启动娱乐模式,先降下幕布,打开电视,降下升降桌,关闭灯光。
作者: hcfong2020    时间: 2024-5-23 20:32
kjjuhfv 发表于 2024-5-23 15:09
既然知道p口高电平时上升  
那你直接在p口输入高电平看会不会上升
如果会上升那就不需要发射16进制代码了 ...

下降的时候P口也是高电平。平时无动作的时候是低电平。
作者: crazymouse    时间: 2024-5-24 11:28
hcfong2020 发表于 2024-5-23 20:31
应用场景是,这个桌子是放在幕布前的,平时使用的时候是75厘米高度,当幕布下降的时候,自动下降到50,只 ...

哈哈,我懂,和我最初玩物联网的时候一样,希望一切都自动化,然后最后发现,一个人住还好,一家人的话,大家的习惯不一样,很难
作者: crazymouse    时间: 2024-5-24 11:34
leung 发表于 2024-5-23 19:50
物理暴击

就是所谓的你是为了鱼呢,还是为了钓鱼
作者: JGhost    时间: 2024-5-25 22:27
坐等实现学习,我想做一个自动投影抽屉
作者: hcfong2020    时间: 2024-6-2 16:12
本帖最后由 hcfong2020 于 2024-6-2 16:15 编辑
  1. substitutions:
  2.   friendly_name: 'Seisuk'
  3.   device_name: 'seisuk'
  4.   node_name: 'seisuk'
  5.   device_description: 'Seisuk AOKE WP-H01 WP-CB01-001 Desktronic/JSDRIVE DCU_G-PRT5G'
  6.   project_base: 'AOKE' # https://aoke-europe.com/troubleshooting
  7.   project_name: 'WP-H01' # panel
  8.   project_version: 'WP-CB01-001' # control box # https://aoke-europe.com/mwdownloads/download/link/id/88/

  9.     # https://profeqprofessional.nl/media/productattach//e/r/error_codes_wp-cb01-001_2.pdf
  10.     # https://motionwise-products.com/wp-content/uploads/2018/11/MotionWise_sf_Manual_081318_E_Rev-USB.pdf
  11.     # https://profeqprofessional.nl/media/productattach//e/r/error_codes_wp-cb01-001_2.pdf

  12.   min_height: "50.0" # real 65  # Min height + 0.5
  13.   max_height: "100.0" # real 130  # Max height - 0.5
  14.   initial_value: "70"

  15. globals:
  16.   - id: height
  17.     type: float
  18.     restore_value: yes
  19.     initial_value: '70.0'

  20.   - id: min_height
  21.     type: float
  22.     restore_value: yes
  23.     initial_value: '50.0'

  24.   - id: max_height
  25.     type: float
  26.     restore_value: yes
  27.     initial_value: '100.0'

  28. esphome:
  29.   name: ${device_name}
  30.   friendly_name: ${friendly_name}
  31.   name_add_mac_suffix: false
  32.   comment: ${device_description}
  33.   project:
  34.     name: ${project_base}.${project_name}
  35.     version: $project_version
  36.   on_boot:
  37.     - priority: 600.0
  38.       then:
  39.         - button.press: stop
  40.     - priority: -200.0
  41.       then:
  42.         - lambda: |-
  43.             id(uart_height).publish_state( id(height) );

  44. api:
  45. web_server:
  46.   port: 80
  47. wifi:
  48.   ssid: "XXXXXXXX"
  49.   password: "XXXXXXXX"



  50.   # Enable fallback hotspot (captive portal) in case wifi connection fails
  51.   ap:
  52.     ssid: "P1Test Fallback Hotspot"
  53.     password: "12345678"

  54. esp8266:
  55.   board: nodemcu
  56.   early_pin_init: false
  57.   restore_from_flash: true

  58. # packages:
  59. #   device_base: !include common/device.base.yaml

  60. ota:
  61.   on_begin:
  62.     then:
  63.       - button.press: stop

  64. logger:
  65.   esp8266_store_log_strings_in_flash: false  
  66.   level: DEBUG
  67.   baud_rate: 0

  68. uart:
  69.   - id: remote_bus
  70.     tx_pin: 1 # WHITE (2nd pin)
  71.     rx_pin: 3 # N/A (3rd pin)
  72.     baud_rate: 9600

  73.   - id: desk_bus
  74.     tx_pin: 4 # N/A (D2)
  75.     rx_pin: 5 # BLACK (D1)
  76.     baud_rate: 9600
  77.     rx_buffer_size: 256

  78. external_components:
  79.   - source: veli
  80.     components: [ desktronic ]  

  81. desktronic:
  82.   id: seisuk
  83.   desk_uart: desk_bus
  84.   remote_uart: remote_bus
  85.   height:
  86.     name: Wnotworkign desktronic Height
  87.     id: desk_height_sensor
  88.     icon: mdi:human-male-height
  89.     device_class: distance
  90.     unit_of_measurement: cm
  91.     accuracy_decimals: 1   
  92.     internal: true
  93.   move_pin:
  94.     number: 14 # (D5)

  95. binary_sensor:
  96.   - id: moving
  97.     name: Moving
  98.     platform: template
  99.     device_class: moving
  100.     icon: mdi:hand-back-right-off
  101.     lambda: return id(seisuk).current_operation != desktronic::DESKTRONIC_OPERATION_IDLE;
  102.     on_state:
  103.       - while:
  104.           condition:
  105.             binary_sensor.is_on: moving
  106.           then:
  107.             - script.execute: get_debug_height
  108.             - delay: 50ms

  109.   - id: going_up
  110.     name: Moving up
  111.     platform: template
  112.     device_class: moving
  113.     icon: mdi:transfer-up
  114.     entity_category: diagnostic
  115.     lambda: return (id(seisuk).current_operation == desktronic::DESKTRONIC_OPERATION_RAISING) || (id(seisuk).current_operation == desktronic::DESKTRONIC_OPERATION_UP);

  116.   - id: going_down
  117.     name: Moving down
  118.     platform: template
  119.     device_class: moving
  120.     icon: mdi:transfer-down
  121.     entity_category: diagnostic
  122.     lambda: return (id(seisuk).current_operation == desktronic::DESKTRONIC_OPERATION_LOWERING) || (id(seisuk).current_operation == desktronic::DESKTRONIC_OPERATION_DOWN);

  123. sensor:
  124.   - id: uart_height
  125.     platform: template
  126.     name: Height
  127.     icon: mdi:human-male-height
  128.     device_class: distance
  129.     unit_of_measurement: cm
  130.     accuracy_decimals: 1
  131.     update_interval: never
  132.     lambda: |-
  133.       float current = id(height);
  134.       return current;

  135. number:
  136.   - platform: template
  137.     id: desk_height
  138.     name: Height
  139.     icon: mdi:human-male-height-variant
  140.     min_value: $min_height
  141.     max_value: $max_height
  142.     lambda: |-
  143.       return id(height);
  144.     device_class: distance
  145.     unit_of_measurement: cm
  146.     update_interval: never
  147.     mode: box
  148.     step: 0.1
  149.     set_action:
  150.       then:
  151.         - while:
  152.             condition:
  153.               - lambda: |-
  154.                   float to = std::round(x * 10) / 10;
  155.                   float from = std::round(id(height) * 10) / 10;
  156.                   if ( to != from ) {
  157.                     return true;
  158.                   }
  159.                   else{
  160.                     return false;
  161.                   }
  162.             then:
  163.               - script.execute:
  164.                   id: move_it
  165.                   to: !lambda 'return x;'
  166.               - delay: 150ms

  167. cover:
  168.   - platform: template
  169.     name: None
  170.     optimistic: true
  171.     device_class: damper
  172.     icon: mdi:desk
  173.     assumed_state: true
  174.     has_position: true   
  175.     lambda: |-
  176.       auto value = (int)id(height);
  177.       float percentage = (float)(value - id(min_height)) / (id(max_height) - id(min_height));
  178.       return percentage;
  179.     open_action:
  180.       - number.set:
  181.           id: desk_height
  182.           value: $max_height
  183.     close_action:
  184.       - number.set:
  185.           id: desk_height
  186.           value: $min_height
  187.     stop_action:
  188.       - button.press: stop
  189.     position_action:
  190.       - number.set:
  191.           id: desk_height
  192.           value: !lambda |-
  193.             int value = id(min_height) + (int)( ( pos ) * (id(max_height) - id(min_height)) );
  194.             return value;

  195. button:
  196.   - platform: template
  197.     name: Stop
  198.     icon: mdi:stop
  199.     entity_category: config
  200.     id: stop
  201.     on_press:
  202.       then:
  203.         - switch.turn_off: takeover
  204.         - script.stop: move_it
  205.         - switch.turn_off: switch_up
  206.         - switch.turn_off: switch_down
  207.         - lambda: |-
  208.             id(seisuk).stop();
  209.         - number.set:
  210.             id: desk_height
  211.             value: !lambda |-
  212.               float x = id(height);
  213.               return x;
  214.         - component.update: desk_height

  215. switch:
  216. - platform: gpio
  217.    name: Takeover
  218.    icon: mdi:gesture-tap
  219.    id: takeover
  220.    pin:
  221.      number: 2 # (D4)
  222.      mode: OUTPUT
  223.    restore_mode:  ALWAYS_OFF   
  224.    entity_category: diagnostic
  225.    disabled_by_default: true
  226.    on_turn_on:
  227.     then:
  228.       - delay: 50ms
  229.       - switch.turn_off: takeover

  230. - platform: template
  231.    optimistic: true
  232.    name: Move Up
  233.    entity_category: config
  234.    restore_mode: ALWAYS_OFF
  235.    icon: mdi:arrow-up-bold-box
  236.    id: switch_up
  237.    on_turn_on:
  238.      then:
  239.        - switch.turn_on: takeover
  240.        - switch.turn_off: switch_down
  241.        - lambda: |-
  242.            id(seisuk).move_up();
  243.    on_turn_off:
  244.      then:
  245.        button.press: stop

  246. - platform: template
  247.    name: Move Down
  248.    entity_category: config
  249.    restore_mode: ALWAYS_OFF
  250.    optimistic: true
  251.    icon: mdi:arrow-down-bold-box
  252.    id: switch_down
  253.    on_turn_on:
  254.      then:
  255.        - switch.turn_on: takeover
  256.        - switch.turn_off: switch_up #  interlock: [up]
  257.        - lambda: |-
  258.            id(seisuk).move_down();
  259.    on_turn_off:
  260.      then:
  261.        button.press: stop

  262. script:
  263.   - id: move_it
  264.     parameters:
  265.       to: float
  266.     mode: restart
  267.     then:
  268.       - if:
  269.           condition:
  270.               - binary_sensor.is_off: moving
  271.           then:
  272.             - lambda: |-
  273.                 float target = std::round(to * 10) / 10;
  274.                 float from = std::round(id(height) * 10) / 10;
  275.       
  276.                 ESP_LOGI("seisuk", "target %.1f from %.1f", target, from);
  277.       
  278.                 if ( target != from ) {  
  279.                   if ( target < from ) {
  280.                     id(switch_down).turn_on();
  281.                   }
  282.                   else if ( target > from ) {
  283.                     id(switch_up).turn_on();
  284.                   }
  285.                   else if ( target == from ) {
  286.                     id(stop).press();
  287.                     ESP_LOGI("seisuk", "target == from");
  288.                   }         
  289.                   else {
  290.                     id(stop).press();
  291.                     ESP_LOGI("seisuk", "else height same");
  292.                   }
  293.                 }
  294.                 else{
  295.                   id(stop).press();
  296.                   ESP_LOGI("seisuk", "height not not same");
  297.                 }
  298.           else:
  299.           - if:
  300.               condition:
  301.                   - binary_sensor.is_on: going_up
  302.               then:
  303.               - lambda: |-
  304.                   float target = std::round(to * 10) / 10;
  305.                   float from = std::round(id(uart_height).state * 10) / 10;

  306.                   ESP_LOGI("seisuk", "moving to %.1f from %.1f", target, from);

  307.                   if ( target <= from ) {
  308.                     id(stop).press();
  309.                     ESP_LOGE("seisuk", "height more");

  310.                     auto call = id(desk_height).make_call();
  311.                     call.set_value(id(uart_height).state);
  312.                     call.perform();                  
  313.                   }
  314.           - if:
  315.               condition:
  316.                   - binary_sensor.is_on: going_down
  317.               then:
  318.               - lambda: |-
  319.                   float target = std::round(to * 10) / 10;
  320.                   float from = std::round(id(uart_height).state * 10) / 10;

  321.                   ESP_LOGI("seisuk", "moving to %.1f from %.1f", target, from);

  322.                   if ( target >= from ) {
  323.                     id(stop).press();
  324.                     ESP_LOGE("seisuk", "height less");

  325.                     auto call = id(desk_height).make_call();
  326.                     call.set_value(id(uart_height).state);
  327.                     call.perform();                  
  328.                   }
  329.       - delay: 100ms

  330.   - id: get_debug_height
  331.     mode: single
  332.     then:
  333.       - lambda: |-

  334.           // before continuing tell its not really moving

  335.           // id(moving).publish_state(false);
  336.           // id(going_up).publish_state(false);
  337.           // id(going_down).publish_state(false);

  338.           uint8_t data[5];
  339.           while (id(desk_bus).available() >= 5) {

  340.             id(desk_bus).read_array(data, 5);
  341.             if (data[0] != 0x5A) {
  342.               break;
  343.             }
  344.             if ((data[1] | data[2] | data[3]) == 0x00) {
  345.               break;
  346.             }

  347.             enum Segment : uint8_t
  348.             {
  349.                 SEGMENT_INVALID = 0x00,
  350.                 SEGMENT_0 = 0x3f,
  351.                 SEGMENT_1 = 0x06,
  352.                 SEGMENT_2 = 0x5b,
  353.                 SEGMENT_3 = 0x4f,
  354.                 SEGMENT_4 = 0x67,
  355.                 SEGMENT_5 = 0x6d,
  356.                 SEGMENT_6 = 0x7d,
  357.                 SEGMENT_7 = 0x07,
  358.                 SEGMENT_8 = 0x7f,
  359.                 SEGMENT_9 = 0x6f,
  360.             };
  361.          
  362.             auto segment_to_number = [](const uint8_t segment) {
  363.                 switch (segment & 0x7f)
  364.                 {
  365.                 case SEGMENT_0:
  366.                     return 0;
  367.                 case SEGMENT_1:
  368.                     return 1;
  369.                 case SEGMENT_2:
  370.                     return 2;
  371.                 case SEGMENT_3:
  372.                     return 3;
  373.                 case SEGMENT_4:
  374.                     return 4;
  375.                 case SEGMENT_5:
  376.                     return 5;
  377.                 case SEGMENT_6:
  378.                     return 6;
  379.                 case SEGMENT_7:
  380.                     return 7;
  381.                 case SEGMENT_8:
  382.                     return 8;
  383.                 case SEGMENT_9:
  384.                     return 9;
  385.                 default:
  386.                     ESP_LOGD("desktronic", "idk");
  387.                 }
  388.                 return -1;
  389.             };            

  390.             int data0 = segment_to_number(data[1]);
  391.             int data1 = segment_to_number(data[2]);
  392.             int data2 = segment_to_number(data[3]);

  393.             float got_height = 0.0;

  394.             if (data0 < 0x00 || data1 < 0x00 || data2 < 0x00) {
  395.               break;
  396.             }

  397.             got_height = data0 * 100 + data1 * 10 + data2; // + decimal * 0.1;

  398.             // flip height for below 100
  399.             if (data[2] & 0x80 ) {
  400.               got_height /= 10.0;
  401.             }
  402.             
  403.             // If all correct, publish values
  404.             if (got_height <= id(max_height) - 0.5 && got_height >= id(min_height) + 0.5 ){
  405.               id(height) = got_height;
  406.               id(uart_height).publish_state(got_height);              
  407.             }

  408.             if (got_height >= id(max_height) || got_height <= id(min_height) ){
  409.               // id(stop).press();
  410.               ESP_LOGE("seisuk","stopped, out of bounds");
  411.             }

  412.             // now its moving
  413.             // id(moving).publish_state(true);
  414.             // id(going_up).publish_state(true);
  415.             // id(going_down).publish_state(true);            

  416.           }
  417.       - delay: 50ms
复制代码

[attach]59861[/attach]

用这个代码现在能够控制升降,不过还是有很多问题。
作者: hcfong2020    时间: 2024-6-2 16:30
萌萌之家 发表于 2024-5-23 10:50
一个升降桌,你发三个帖子?我实在搞不懂

不是发三个帖子,是因为上传图片的时候,提示错误,又重新编辑了。所以帖子变多了。也不知道怎么删除。




欢迎光临 『瀚思彼岸』» 智能家居技术论坛 (https://bbs.hassbian.com/) Powered by Discuz! X3.5