Send a serial command and read the response as a sensor

Hello folks,

I am successfuly controlling my projector. I have a list of shell commands in my configuration.yaml sending HEX codes connected to buttons in lovalce/automations/services/scripts, work like a charm. Here is my appraoch.

However, I need to read some states to be sure my buttons show proper state if my wife turns projector on by remote instead by HA app. In doing so, I guess that I need to send a command to the projector that should respond. The projector has unique codes for this that does not respond with only F or P (fail/pass) but with actual code, eg. ‘OK1’ for projector being powered on.

When I send a command the same way as I control it, I expect to see some responses on the serial integration but nothing happens there. I am lost here.

Thanks for ideas!

Yeah, this is what a command line sensor would do.

You send a command, and the response is the sensor state. Use the value_template to parse the raw response to make the state be what you need it to be.

No success. I am sending commands same way as I do for controlling the projector. I tried both Command line Sensor and Serial Sensor. Then I added an entity to the lovelace and wait for data. In the developer tools, both sensors shows no data.

My config yaml is:

sensor:
  - platform: serial
    name: projector_serial
    serial_port: /dev/ttyUSB0
  - platform: command_line
    name: projector_state_on
    scan_interval: 5
    command: echo -e -n '\x7E\x30\x30\x31\x32\x34\x20\x31\x0D' > /dev/ttyUSB0

That echo command will have no response. You need some sort of command that will return a response.

What command you have on your mind?

Oh, I misread the whole thing. I don’t know anything about your projector. You would have to look at their ICD.

Given you can turn it on with a write to the USB0, maybe you can read from the serial device with a command.

Then you would add that read command to your sensor instead of the write command.

Then, combine both command line things to a template switch where the on/off uses the write command and the state uses the read command.

Given it’s a ttyUSB0, you will probably have to have some thread doing a “tail -f /dev/ttyUSB0” and processing that output as it comes in.


Or, you get a smart outlet with a power meter and use the increased power to know when the projector is on.

Or, you use a light sensor in the light path to know if the projector is on.

A few different options.

The documentation of the projector has two kinds of commands you can send to it. First column sends commands to control it and return pass or fail (P or F). The second column has commands that return fail (F) or something particular to give you desired state, in case of projector being powered on, you ask, are you powered on? It returns “OK1”. This is the reason I tried to send echo as in the case of controlling it. When I tried to control it using some app for serial communication, the app shows these returns. My question is how to read them in HA. I know the projector is responding. I cannot read it by HA

That’s good. But echo isn’t going to get a reply.

You’re going to have to figure out how to read replies.

Try opening another terminal and doing tail -f /dev/ttyUSB0. Then send that command and see if the reply comes over that other terminal.

If it does, try to see if you can do a ‘cat’ and maybe the last response will be readable.

Stop the tail -f, then send another command and do a cat /dev/ttyUSB0. If that works, you can append the cat command to the end of your power on command for the response. It’s likely this wont work…but worth a shot.

One thing you could do is have a usb reader write to a file, then use a file sensor to parse that file. As long as you only get queries for the power state, it should be straight forward as you can assume the reply is always for “are you powered on?”

I am totally new to Home Assistant and have scoured every topic I could find on this and have tried various things with no success. I have a an old (but still working perfectly and suits my needs just fine) 12 channel Sonance amp that I use for whole home audio. I have 5 zones: backyard, kitchen, living room, family room and bathroom. I have this all working in another “remote control” application but I am converting to home assistant and this is the last piece I can’t get working there.

I would like to have 4 buttons for each zone, power on, power off, volume up and volume down. I have the serial commands. I can send them with the previous app I mentioned and it works. I can send them in a putty TCP session and it works. But I cannot figure out how to get a script built to send the same.

Example commands:

zone 2 power on :Z21\x0D hex version: 3a 5a 32 31 0d
zone 2 power off :Z20\x0D hex 3a 5a 32 30 0d
zone 2 volume up: :V2++\x0D hex 3a 56 32 2b 2b 0d
zone 2 volume down :V2–\x0D hex 3a 56 32 2d 2d 0d

In Putty, it only works without the carriage return, but I’m hitting enter to trigger it.

The commands are sent to a global caceh itach ip2sl device and then via serial cable to the amp.

ip address is 192.168.1.114 and port 4999.

This topic seems about the closest to what I’m doing and is the most recent.

My vision for this is to have a Card with the media player at the top and the 4 control buttons at the bottom and to be able to short press the respective button. There are freedbacks with volume that could be used for a slider, but that’s not super important to me.

Any help or a point to a method would be very helpful

Hi,
happy to help. I haven’t figured out the problem of reading the commands. It was not super important for me and HA is simply a rabbit whole you can spent rest of your life. Thanks for @jocnnor for his idea but I still need to find some time to move on.

Regarding your question. I am doing exactly what you need. I believe that the solution I found is the most straitforward. Maybe I tuned it a bit to make it even easier.

My interface is as simple as it:


The power on uses input boolean you can create in HA/configuration. If my wife uses Siri, it keeps the state of the projector. If she uses IR remote control, I need to manually change the state but that’s detail. Dynamic Black is another input boolean. All other buttons are just simple ‘custom-button’ sending a command.

The rest is probably written in my other topic. Check it out and if it is not enough for you, come back. I will check whether I modified something since then.

1 Like

I really appreciate the response. Like you said, HA is a never ending rabbit hole. It’s frustrating in that I can send successful commands using an app that already works, the testing software provided by global cache for the itach ip2sl device, and Putty via telnet, but can’t do it (YET) with HA.

I’ve added a basic card for testing that looks like this:

type: ‘custom:button-card’
name: zone2_on
tap_action:
action: call-service
service: shell_command.zone2_on

That shows up in my dashboard and seems to be working.

in my config.yaml file I’ve added this:

shell_command:
zone2_on: ‘/bin/echo -e “:Z21” | netcat 192.168.0.49 4999’

I’ve tried about 5 different configurations of this for the above replacing what is in the double quotes with:

“:Z21\x0D”
“3a 5a 32 31 0d”
“\x3a\x5a\x32\x31\x0d”

I do have a USB to serial cable but have not tried the method you used for your projector of connecting the Pi4 directly to my amp. That requires some physical movement, relocating my pi to nearby the amp.

It’s baffling to me as a telnet session with putty sending just the plain text :Z21 to the ip/port triggers the zone 2 of the amp to come right on. I’d love to be able to replicate that with an HA button.

I dont follow what you wrote in the last two paragraphs. I have USB to serial cable directly connected between projector and RPi.

Btw, use three apostrophs when you write code in the discussion, it is really more readable. Like this. My configuration.yaml looks as follows:

shell_command:
  projector_on: echo -e -n '\x7E\x30\x30\x30\x30\x20\x31\x0D' > /dev/ttyUSB0
  projector_off: echo -e -n '\x7E\x30\x30\x30\x30\x20\x30\x0D' > /dev/ttyUSB0

I have the custom button configured the same way as you, that’s correct.

aah you use telnet. I cannot use it as my projector does not have RJ45 connector, so USB to serial was my only way

Ok. In my currently working setup I am using a 3rd party piece of hardware to tcp to serial communications. It’s from global cache, called itach ip2sl. I takes raw TCP commands and then communicates those to my amp via serial cable. So I can use a telnet to this device to send the commands on to my amp as well.

I have a usb to serial cable available so I have now moved my pi close to my amp and connected them. I see the serial info in the system hardware:

      /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0
    attributes:
      DEVLINKS: >-
        /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0
        /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0-port0
      DEVNAME: /dev/ttyUSB0
      DEVPATH: >-
        /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/ttyUSB0/tty/ttyUSB0
      ID_BUS: usb
      ID_MODEL: USB-Serial_Controller_D
      ID_MODEL_ENC: USB-Serial\x20Controller\x20D
      ID_MODEL_ID: '2303'
      ID_PATH: 'platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0'
      ID_PATH_TAG: platform-fd500000_pcie-pci-0000_01_00_0-usb-0_1_1_1_0
      ID_REVISION: '0400'
      ID_SERIAL: Prolific_Technology_Inc._USB-Serial_Controller_D
      ID_TYPE: generic
      ID_USB_DRIVER: pl2303
      ID_USB_INTERFACES: ':ff0000:'
      ID_USB_INTERFACE_NUM: '00'
      ID_VENDOR: Prolific_Technology_Inc.
      ID_VENDOR_ENC: Prolific\x20Technology\x20Inc.\x20
      ID_VENDOR_ID: 067b
      MAJOR: '188'
      MINOR: '0'
      SUBSYSTEM: tty
      USEC_INITIALIZED: '579463183924'  ```

I've updated my config.yaml with this:

``` shell_command:
   zone2_on: echo -e -n '3a 5a 32 31 0d' > /dev/ttyUSB0 ```

also tried:

``` shell_command:
   zone2_on: echo -e -n ':Z21\x0D' > /dev/ttyUSB0 ```

``` shell_command:
   zone2_on: echo -e -n ':\x3a\x5a\x32\x31\x0d' > /dev/ttyUSB0 ```

```shell_command:
   zone2_on: echo -e -n ':Z21' > /dev/ttyUSB0 ```

Ugh, sorry to anyone reading that above. I made a real mess of the text coding.

Have you been successful? When it comes to the proper syntax of the command, I was more successful in looking on general forums related to the topic rather than to forums of HA. Then, Roger, the guy who developed the software I used for testing (I am mentioning him in the other topic where I discussed the solution) was also very helpful but finally his software learnt me how to properly write the syntax

No success so far. I’m at a loss of how to trouble shoot further. Frustrating as I’m not seeing where the breakdown is. My only thinking is that the usb to serial connection requires some setup for baud rate, parity, etc. I’m not sure of a way to configure that.

I’ve continued to tinker with using telnet with netcat but will see if I can do some more tinkering with the direct connection.

I spent some hours to figure out the problem in the title of this topic: send command, read response. No success. There is definitely a way to have a sensor reading the device on the address but that should be able to read even success when I am sending commands to DLP projector when I am turning it on, which works. Sensor does not read that.

In your case. I did not set anything on the baud rate etc., I kept the defaults and it works. However, the telnet solution must be easy. What about some firewall on your router? Keep these barriers in mind as well

Hi SeldomSeen31 and for anyone else with a DAB1 - Sonance that they do not want to throw away :slight_smile:
For me, my DAB1 is using 19200 baud rate, so I just needed to set the port speed (defaults to 9600) using
stty -F /dev/ttyUSB1 19200

Then it would respond to my commands

[core-ssh ~]$ echo -e ":Z30\x0D" > /dev/ttyUSB1
[core-ssh ~]$ echo -e ":Z31\x0D" > /dev/ttyUSB1

First command is zone 3 off and second zone 3 on.

configuration.yaml

shell_command:
  zone3_off: echo -e ':Z30\x0D' > /dev/ttyUSB1
  zone3_on: echo -e ':Z31\x0D' > /dev/ttyUSB1

custom button


type: horizontal-stack
cards:
  - type: custom:button-card
    name: Study ON (zone3)
    tap_action:
      action: call-service
      service: shell_command.zone3_on
  - type: custom:button-card
    name: Study OFF (Zone3)
    tap_action:
      action: call-service
      service: shell_command.zone3_off

image

When I read your code, I don’t get where you receive the response from your device back to HA