#
# Python script to send MODBUS RTU to XY-MD01 to read Temperature and humidity
#
# This has examples of converting the bytes received.
# py_dhr_serial_XY_MD01.py reads temperature and humidity
# and outputs to gbFat.js
# graphPiT.htm includes gbFat.js and plots it
#
#It is run every 15 minutes by the cron 
#crontab -e
#run python script
#Add:-
#0,15,30,45 * * * *  /usr/bin/python /home/pi/py_dhr_serial_XY_MD01_pi.py

from datetime import datetime
import time
import sys

#I needed to run: sudo apt install python3-serial
import serial

# on windows port="comX"
# use mode to list know com ports

# on RaspberryPi:
# port="/dev/ttyUSB0"
# to find out
# ls /dev to find out 
#
# 

# set up serial port
# when using Request/ respond, 
# send a message and await a response. 
# It might wait up to timeout seconds
# or 
# it returns with any available bytes
# so send command , pause, and read
#
ser = serial.Serial(
	#uncomment 
	#port="com4",
	#port="com15",
	#port="/dev/ttyUSB0",	# RS-485 dongle using CH340 or FTDI chip
	port="/dev/ttyACM0",	# RS-485 dongle in clear box

	baudrate=9600,
	parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE,
	bytesize=serial.EIGHTBITS, xonxoff=False,
#	rtscts=True, dsrdtr=True, timeout=3,	
	rtscts=False, dsrdtr=False, timeout=2 )

print(ser.name)

#sys.stdin.read(1)

# the XY-MD01 RTU command is these and the CRC needs to be correct.

print( "temperature:" )
# Temperature
cmd = b'\x01\x04\x00\x01\x00\x01\x60\x0A' # temperature
ser.write( cmd )
time.sleep(0.1)
data = ser.read( ser.in_waiting )
# print received bytes as list
print( list( data ) )
print( list( data[3:5])  )
# 
print( int.from_bytes( data[3:5], "big" )/10.0 , "C") 
temperature =  int.from_bytes( data[3:5], "big" )/10.0 

# Humidity
print( "Humidity:" )

cmd = b'\x01\x04\x00\x02\x00\x01\x90\x0A' # humidity
ser.write( cmd )
time.sleep(0.1)
data = ser.read( ser.in_waiting )

# print received bytes as list
print( list( data ) )
print( int.from_bytes( data[3:5], "big" )/10.0 , "%") 

humidity = int.from_bytes( data[3:5], "big" )/10.0 


# Create a datetime object
current_time = datetime.now()

# Convert to ISO 8601 format YYYY-MM-DDTHH:mm

iso_formatted_time = current_time.isoformat()
print(iso_formatted_time)

#gbFa( "2025-03-15 05:00 t=16750" )

opStr = "gbFa( \""

#opStr += iso_formatted_time + " "
#we want
opStr += iso_formatted_time[0:10] + " " + iso_formatted_time[11:16] + " "
opStr += " t="
opStr += str( temperature )

opStr += " h="
opStr += str( humidity )
opStr += " \" ) \n"

#
#Append the readings to a file that can be read by the Web page
#
with open("/home/pi/www/gb/gbFat.js", "a") as f:
  f.write( opStr )
  f.close()

print( "\r\n" ) # CR LF \r in carrage return, \n in Line feed

# =======================================
# The XY-M01 also responds to these commands
#

#convert the string to byte array by using the b' prefix
# AUTO causes module to stream temperature and humidity 
# 
print( " The XY-M01 responds to AUTO and streams data " )

ser.write( b'AUTO' )
#
print( "buffering readings...")
time.sleep(3)
data = ser.read( ser.in_waiting )

# print received bytes 
print( str( data ) )

#
# send STOP to turn off streaming
ser.write( b'STOP' )
time.sleep(0.2)
data = ser.read( ser.in_waiting )

# print received bytes
print( str( data ) )
print( data.hex( "_" ) )


ser.write( b'PARAM' )
time.sleep(0.2)
data = ser.read( ser.in_waiting )
# print received bytes as list
print( str( data ) )

ser.close()
