Advice on command line sensor, while moving to new format

Hi folks, so I have a substantial number of comand line sensors.

And I now have to move them all to the new format. So I thought, there might could be a more easy / elegant way of doing that…

Right now I have set up 6 sensors per machine. Each is defined by its self. Quite some copy paste work, with lots of errors to debug in the beginning, but working fine since monthes now.

“MY” coding looks like this… crude:

- platform: command_line
  name: S19-31-Inlet-Temp-Board-1
  command: "python3 /config/shell/S19-31.py"
  unit_of_measurement: "°C"
  value_template: '{{ value_json["STATS"][1].temp1 }}'

- platform: command_line
  name: S19-31-Outlet-Temp-Board-1
  command: "python3 /config/shell/S19-31.py"
  unit_of_measurement: "°C"
  value_template: '{{ value_json["STATS"][1].temp2_1 }}'

- platform: command_line
  name: S19-31-Inlet-Temp-Board-2
  command: "python3 /config/shell/S19-31.py"
  unit_of_measurement: "°C"
  value_template: '{{ value_json["STATS"][1].temp2 }}'

- platform: command_line
  name: S19-31-Outlet-Temp-Board-2
  command: "python3 /config/shell/S19-31.py"
  unit_of_measurement: "°C"
  value_template: '{{ value_json["STATS"][1].temp2_2 }}'

- platform: command_line
  name: S19-31-Inlet-Temp-Board-3
  command: "python3 /config/shell/S19-31.py"
  unit_of_measurement: "°C"
  value_template: '{{ value_json["STATS"][1].temp3 }}'

- platform: command_line
  name: S19-31-Outlet-Temp-Board-3
  command: "python3 /config/shell/S19-31.py"
  unit_of_measurement: "°C"
  value_template: '{{ value_json["STATS"][1].temp2_3 }}'

as you can see, its exactly the same asside from

  • inlet/ outlet and Bord number in the nameing, and
  • temp1 (inlet) / temp2_1 (outlet)

for each board (3 of them in each machine…

on the python side it looks like this

#!/usr/bin/env python3
# https://community.home-assistant.io/t/read-antminer-api-and-show-details/123795/4

import socket
import json

HOST = 'IP.of.machine'  
PORT = 'port'        

m = {"command": "stats"}
jdata = json.dumps(m)


try:            
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
      s.connect((HOST, PORT))
      s.sendall(bytes(jdata,encoding="utf-8"))
      data = ''
      while 1:
          chunk = s.recv(4026)
          if chunk:
              data += chunk.decode("utf-8") 
          else:
              break
      datajs = json.loads(data[:-1])
finally:
    s.close


print (json.dumps(datajs))

I have a copy of this script for each machine…

the only change is the last numbers of the ip address.

how could i get that more elegant ? like just one script and send the ip with the command line sensor or what ever, give it a range, to poll say IP .180 to .196 or what ever, like hand over a list of IPs to querry?

nobody any ideas? realy?

yeah, had some vague ideas, but having a look at the complete json might be useful

awsome,
how would I get that json snippet from my HA?

Run the python from any other PC?

erm…is this usefull?
Create one sensor, and set attributes fro json?

Something like this (but hard to say for me without the exact json data, I am not completely sure how to deal with the multiple stats[1], but I hope you get the idea

command_line:
  - sensor:
    name: S19-31
    json_attributes:
      - status
    command: '/python3 /config/shell/S19-31.py'
    command_timeout: 30
    value_template: '{{ value_json.status.total }}'  

Then you should have the data available in the sensor attributes

state_attr('sensor.S19-31', 'status').temp1
state_attr('sensor.S19-31', 'status').temp2

this is the cli output from one of my linux macines… stupid me, ive been down this rabbit hole a bunch of times

echo -n "stats" | nc IP 4028

STATUS=S,When=1695756252,Code=70,Msg=CGMiner stats,Description=cgminer 1.0.0|BMMiner=1.0.0,Miner=uart_trans.1.3,CompileTime=Wed Apr 27 15:19:27 CST 2022,Type=Antminer S19|,STATS=0,ID=BTM_SOC0,Elapsed=39516,Calls=0,Wait=0,Max=0,Min=99999999,GHS 5s=94096.21,GHS av=91613.80,rate_30m=91568.55,Mode=2,miner_count=3,frequency=675,fan_num=4,fan1=6000,fan2=6000,fan3=6000,fan4=6000,temp_num=3,temp1=69,temp2_1=74,temp2=68,temp2_2=73,temp3=68,temp2_3=73,temp_pcb1=55-53-69-69,temp_pcb2=57-53-68-67,temp_pcb3=57-53-68-67,temp_pcb4=0-0-0-0,temp_chip1=60-58-74-74,temp_chip2=62-58-73-72,temp_chip3=62-58-73-72,temp_chip4=0-0-0-0,temp_pic1=45-43-59-59,temp_pic2=47-43-58-57,temp_pic3=47-43-58-57,temp_pic4=0-0-0-0,total_rateideal=90000.00,rate_unit=GH,total_freqavg=675,total_acn=264,total rate=91613.80,temp_max=0,no_matching_work=0,chain_acn1=88,chain_acn2=88,chain_acn3=88,chain_acn4=0,chain_acs1= oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo,chain_acs2= oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo,chain_acs3= oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo,chain_acs4=,chain_hw1=0,chain_hw2=0,chain_hw3=0,chain_hw4=0,chain_rate1=30522.44,chain_rate2=32259.67,chain_rate3=31314.09,chain_rate4=,freq1=675,freq2=675,freq3=675,freq4=0,miner_version=uart_trans.1.3,miner_id=no miner id now|

so thats the json

in this post, I have already listed all available data fileds in this json in a nice fashion.

Can you just post the json?

STATUS=S,When=1695756939,Code=70,Msg=CGMiner stats,Description=cgminer 1.0.0|BMMiner=1.0.0,Miner=uart_trans.1.3,CompileTime=Wed Apr 27 15:19:27 CST 2022,Type=Antminer S19|,STATS=0,ID=BTM_SOC0,Elapsed=40202,Calls=0,Wait=0,Max=0,Min=99999999,GHS 5s=91919.17,GHS av=91621.90,rate_30m=91850.45,Mode=2,miner_count=3,frequency=675,fan_num=4,fan1=6000,fan2=6000,fan3=6000,fan4=6000,temp_num=3,temp1=69,temp2_1=74,temp2=67,temp2_2=72,temp3=68,temp2_3=73,temp_pcb1=55-53-69-69,temp_pcb2=57-52-67-66,temp_pcb3=57-53-68-67,temp_pcb4=0-0-0-0,temp_chip1=60-58-74-74,temp_chip2=62-57-72-71,temp_chip3=62-58-73-72,temp_chip4=0-0-0-0,temp_pic1=45-43-59-59,temp_pic2=47-42-57-56,temp_pic3=47-43-58-57,temp_pic4=0-0-0-0,total_rateideal=90000.00,rate_unit=GH,total_freqavg=675,total_acn=264,total rate=91621.90,temp_max=0,no_matching_work=0,chain_acn1=88,chain_acn2=88,chain_acn3=88,chain_acn4=0,chain_acs1= oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo,chain_acs2= oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo,chain_acs3= oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo,chain_acs4=,chain_hw1=0,chain_hw2=0,chain_hw3=0,chain_hw4=0,chain_rate1=30544.43,chain_rate2=30522.44,chain_rate3=30852.30,chain_rate4=,freq1=675,freq2=675,freq3=675,freq4=0,miner_version=uart_trans.1.3,miner_id=no miner id now|

u mean like so?

that’s not json. Json looks like
{"X":1,"Y":2}
or

{
  "X": 1,
  "Y": 2
}

dont know how i would get that json, i only can get the output via netcat, thats all ive ever done in regard to json… sorry, i would need a hint here to continue.

… the output of your python file is json.

Yeah @petro, i figured the same:

…shouldn’t be too complicated, but this confuses me…

["STATS"][1]

dont know how to make that script run on my HA.

in the netcat output is a pipe seperator “|”

So stats 1 is the first section after the intro, stats 2 would be after the second | seperator

btw, i did put your example code into my commandline_sensor.yaml. syntax wise it looked fine to me, but I do not get a result from that sensor.

working:

- sensor:
    name: S19-30-Inlet-Temp-Board-1
    command: "python3 /config/shell/S19-30.py"
    unit_of_measurement: "°C"
    value_template: '{{ value_json["STATS"][1].temp1 }}'

and non working

- sensor:
    name: S19-30-test
    json_attributes:
        - status
    command: '/python3 /config/shell/S19-30.py'
    command_timeout: 30
    value_template: '{{ value_json.status.total }}'

That makes sense…as I don’t know exactly how the json structure looks like :thinking:
I suspect it has multiple elements ?

If you can run netcat, why can’t you just execute the python script??

python S19-31.py

cause I run netcat from the cli of my host.

the HA is in a VM, never got into it via ssh and the UI does not have a built in CLI

I could put a terminal addon onto HA, well, that put me onto an idea, wait on, Ill try that.

talking about cant see the woods for the trees :roll_eyes: :angry:

well, the py output looks basically exactly the same like the netcat output

v

sorry, no copy paste from the terminal add on

edit 1: well i forgot about linux basics “> text.file” will fix that problem… here is the output

{"STATUS": [{"STATUS": "S", "When": 1695794937, "Code": 70, "Msg": "CGMiner stats", "Description": "cgminer 1.0.0"}], "STATS": [{"BMMiner": "1.0.0", "Miner": "uart_trans.1.3", "CompileTime": "Wed Apr 27 15:19:27 CST 2022", "Type": "Antminer S19"}, {"STATS": 0, "ID": "BTM_SOC0", "Elapsed": 78201, "Calls": 0, "Wait": 0, "Max": 0, "Min": 99999999, "GHS 5s": 91721.26, "GHS av": 91628.16, "rate_30m": 91933.53, "Mode": 2, "miner_count": 3, "frequency": 675, "fan_num": 4, "fan1": 5940, "fan2": 6000, "fan3": 6000, "fan4": 6000, "temp_num": 3, "temp1": 66, "temp2_1": 71, "temp2": 64, "temp2_2": 69, "temp3": 65, "temp2_3": 70, "temp_pcb1": "52-50-66-66", "temp_pcb2": "54-50-64-64", "temp_pcb3": "54-50-65-64", "temp_pcb4": "0-0-0-0", "temp_chip1": "57-55-71-71", "temp_chip2": "59-55-69-69", "temp_chip3": "59-55-70-69", "temp_chip4": "0-0-0-0", "temp_pic1": "42-40-56-56", "temp_pic2": "44-40-54-54", "temp_pic3": "44-40-55-54", "temp_pic4": "0-0-0-0", "total_rateideal": 90000.0, "rate_unit": "GH", "total_freqavg": 675, "total_acn": 264, "total rate": 91628.16, "temp_max": 0, "no_matching_work": 4, "chain_acn1": 88, "chain_acn2": 88, "chain_acn3": 88, "chain_acn4": 0, "chain_acs1": " oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo", "chain_acs2": " oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo", "chain_acs3": " oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo", "chain_acs4": "", "chain_hw1": 0, "chain_hw2": 1, "chain_hw3": 3, "chain_hw4": 0, "chain_rate1": "30874.29", "chain_rate2": "30830.31", "chain_rate3": "30016.67", "chain_rate4": "", "freq1": 675, "freq2": 675, "freq3": 675, "freq4": 0, "miner_version": "uart_trans.1.3", "miner_id": "no miner id now"}], "id": 1}

so we got a staus and in that status, we have status and stats

  • status (the overview)
  • stats (with some basic facts and then the sub stats with the details)
  1. Sub stats:0
  2. … and so on