Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.97 KB | None | 0 0
  1. import socket
  2. import time
  3. import argparse
  4. import json
  5.  
  6. debugOn = False
  7.  
  8. # Define some fixed types strings
  9. class HeaterStatus():
  10. """Heater function status"""
  11. heaterOn = False
  12. fanSpeed = 0
  13. circulationFanOn = False
  14. manualMode = False
  15. autoMode = False
  16. setTemp = 0
  17. zoneA = False
  18. zoneB = False
  19. zoneC = False
  20. zoneD = False
  21.  
  22. def SetMode(self,mode):
  23. # A = Auto Mode and M = Manual Mode
  24. if mode == "A":
  25. self.autoMode = True
  26. self.manualMode = False
  27. elif mode == "M":
  28. self.autoMode = False
  29. self.manualMode = True
  30.  
  31. def SetZones(self,za,zb,zc,zd):
  32. # Y = On, N = off
  33. self.zoneA = YNtoBool(za)
  34. self.zoneB = YNtoBool(zb)
  35. self.zoneC = YNtoBool(zc)
  36. self.zoneD = YNtoBool(zd)
  37.  
  38. def CirculationFanOn(self,statusStr):
  39. # Y = On, N = Off
  40. if statusStr == "Y":
  41. self.circulationFanOn = True
  42. else:
  43. self.circulationFanOn = False
  44.  
  45. def Dump(self):
  46. """Print out the heater status in JSON format.
  47.  
  48. "Heater": {
  49. "HeaterOn":false,
  50. "FanSpeed":0,
  51. "CirculationFanOn":false,
  52. "AutoMode":false,
  53. "ManualMode":false,
  54. "SetTemp":0,
  55. "ZoneA":false,
  56. "ZoneB":false,
  57. "ZoneC":false,
  58. "ZoneD":false
  59. }
  60.  
  61. }
  62. """
  63. heaterStatusJson = "\"Heater\": { \"HeaterOn\":" + JsonBool(self.heaterOn) + "," \
  64. + "\"FanSpeed\": " + str(self.fanSpeed) + "," \
  65. + "\"CirculationFanOn\": " + JsonBool(self.circulationFanOn) + "," \
  66. + "\"AutoMode\": " + JsonBool(self.autoMode) + "," \
  67. + "\"ManualMode\": " + JsonBool(self.manualMode) + "," \
  68. + "\"SetTemp\": " + str(self.setTemp) + "," \
  69. + "\"ZoneA\": " + JsonBool(self.zoneA) + "," \
  70. + "\"ZoneB\": " + JsonBool(self.zoneB) + "," \
  71. + "\"ZoneC\": " + JsonBool(self.zoneC) + "," \
  72. + "\"ZoneD\": " + JsonBool(self.zoneD) + "}"
  73.  
  74. return heaterStatusJson
  75.  
  76. class EvapStatus():
  77. """Evap function status"""
  78. evapOn = False
  79. fanOn = False
  80. fanSpeed = 0
  81. waterPumpOn = False
  82.  
  83. def FanOn(self,statusStr):
  84. # N = On, F = Off
  85. if statusStr == "N":
  86. self.fanOn = True
  87. else:
  88. self.fanOn = False
  89.  
  90. def FanSpeed(self,speedInt):
  91. self.fanSpeed = speedInt
  92.  
  93. def WaterPumpOn(self,statusStr):
  94. # N = On, F = Off
  95. if statusStr == "N":
  96. self.waterPumpOn = True
  97. else:
  98. self.waterPumpOn = False
  99.  
  100. def Dump(self):
  101. """Print out the EVAP status in JSON format.
  102.  
  103. "Evap":{
  104. "EvapOn": false,
  105. "FanOn": false,
  106. "FanSpeed": 0,
  107. "WaterPumpOn":false
  108. }
  109. """
  110. evapStatusJson = "\"Evap\": { \"EvapOn\":" + JsonBool(self.evapOn) + "," \
  111. + "\"FanOn\": " + JsonBool(self.fanOn) + "," \
  112. + "\"FanSpeed\": " + str(self.fanSpeed) + "," \
  113. + "\"WaterPumpOn\": " + JsonBool(self.waterPumpOn) + "}"
  114.  
  115. return evapStatusJson
  116.  
  117. class BrivisStatus():
  118. """Overall Class for describing status"""
  119. evapMode = False
  120. heaterMode = False
  121. systemOn = False
  122. heaterStatus = HeaterStatus()
  123. evapStatus = EvapStatus()
  124.  
  125. def setMode(self,mode):
  126. if mode == Mode.HEATING:
  127. self.heaterMode = True
  128. self.evapMode = False
  129. elif mode == Mode.EVAP:
  130. self.heaterMode = False
  131. self.evapMode = True
  132.  
  133. def Dump(self):
  134. """Print out the overall status in JSON format.
  135. {"Status": {
  136. "System": {
  137. "EvapMode": false,
  138. "HeaterMode": false,
  139. "SystemOn": false
  140. },
  141. "Heater": {
  142. "HeaterOn":false,
  143. "FanSpeed":0,
  144. "OperatingMode":"manual",
  145. "SetTemp":0
  146. },
  147. "Evap":{
  148. "EvapOn": false,
  149. "FanOn": false,
  150. "FanSpeed": 0,
  151. "WaterPumpOn":false
  152. }
  153. }
  154. """
  155. sysStatusJson = "{\"Status\": { \"System\": { " \
  156. + "\"EvapMode\":" + JsonBool(self.evapMode) + "," \
  157. + "\"HeaterMode\":" + JsonBool(self.heaterMode) + "," \
  158. + "\"SystemOn\": " + JsonBool(self.systemOn) + " }," \
  159. + self.heaterStatus.Dump() + ","\
  160. + self.evapStatus.Dump() + "}}"
  161.  
  162. return sysStatusJson
  163.  
  164. def JsonBool(bool):
  165. """Convert python bool to JSON bool"""
  166. if bool:
  167. return "true"
  168. else:
  169. return "false"
  170.  
  171. def YNtoBool(str):
  172. """Convert Rinna YN to Bool"""
  173. if str == "Y":
  174. return True
  175. else:
  176. return False
  177.  
  178. # Ideally we could create an enum, but looks like that needs enum library - which nmight not be
  179. # available???
  180. class Mode:
  181. HEATING = 1
  182. EVAP = 2
  183. COOLING = 3
  184. RC = 4
  185. NONE = 5
  186.  
  187. # Some nice globals
  188. currentMode = Mode.NONE
  189. status = BrivisStatus()
  190.  
  191. # Command line parsing
  192. parser = argparse.ArgumentParser()
  193. parser.add_argument("hostIP", help='Rinnai Touch Host IP address')
  194.  
  195. args = parser.parse_args()
  196.  
  197.  
  198. def debugPrint(text):
  199. if (debugOn):
  200. print(text)
  201.  
  202. # Touch Box IP address
  203. touchIP = args.hostIP
  204. touchPort = 27847
  205.  
  206. def ConnectToTouch(touchIP, port):
  207. # connect the client
  208. # create an ipv4 (AF_INET) socket object using the tcp protocol (SOCK_STREAM)
  209. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  210. debugPrint("Connecting ...")
  211. client.connect((touchIP, port))
  212. return client
  213.  
  214. def GetAttribute(data, attribute, defaultValue):
  215. return data.get(attribute) or defaultValue
  216.  
  217. def HandleHeatingMode(client,j,brivisStatus):
  218. brivisStatus.setMode(Mode.HEATING)
  219.  
  220. debugPrint("We are in HEAT mode")
  221.  
  222. oop = GetAttribute(j[1].get("HGOM"),"OOP",None)
  223. if not oop:
  224. # Probably an error
  225. debugPrint("No OOP - Not happy, Jan")
  226.  
  227. else:
  228. switch = GetAttribute(oop,"ST",None)
  229. if switch == "N":
  230. debugPrint("Heater is ON")
  231. brivisStatus.systemOn = True
  232. brivisStatus.heaterStatus.heaterOn = True
  233.  
  234. # Heater is on - get attributes
  235. fanSpeed = GetAttribute(oop,"FL",None)
  236. debugPrint("Fan Speed is: {}".format(fanSpeed))
  237. brivisStatus.heaterStatus.fanSpeed = int(fanSpeed) # Should catch errors!
  238.  
  239. # Heater is on - get attributes
  240. circFan = GetAttribute(oop,"CF",None)
  241. debugPrint("Circulation Fan is: {}".format(circFan))
  242. brivisStatus.heaterStatus.CirculationFanOn(circFan)
  243.  
  244. # GSO should be there
  245. gso = GetAttribute(j[1].get("HGOM"),"GSO",None)
  246. if not gso:
  247. # Probably an error
  248. debugPrint("No GSO when heater on. Not happy, Jan")
  249. else:
  250. # Heater is on - get attributes
  251. opMode = GetAttribute(gso,"OP",None)
  252. debugPrint("Heat OpMode is: {}".format(opMode)) # A = Auto, M = Manual
  253. brivisStatus.heaterStatus.SetMode(opMode)
  254.  
  255. # Set temp?
  256. setTemp = GetAttribute(gso,"SP",None)
  257. debugPrint("Heat set temp is: {}".format(setTemp))
  258. brivisStatus.heaterStatus.setTemp = int(setTemp)
  259.  
  260. elif switch == "F":
  261. # Heater is off
  262. debugPrint("Heater is OFF")
  263. brivisStatus.systemOn = False
  264. brivisStatus.heaterStatus.heaterOn = False
  265.  
  266. za = zb = zc = zd = None
  267. z = GetAttribute(j[1].get("HGOM"),"ZAO",None)
  268. if z:
  269. za = GetAttribute(z,"UE",None)
  270. z = GetAttribute(j[1].get("HGOM"),"ZBO",None)
  271. if z:
  272. zb = GetAttribute(z,"UE",None)
  273. z = GetAttribute(j[1].get("HGOM"),"ZCO",None)
  274. if z:
  275. zc = GetAttribute(z,"UE",None)
  276. z = GetAttribute(j[1].get("HGOM"),"ZDO",None)
  277. if z:
  278. zd = GetAttribute(z,"UE",None)
  279. brivisStatus.heaterStatus.SetZones(za,zb,zc,zd)
  280.  
  281. def HandleEvapMode(client,j,brivisStatus):
  282. brivisStatus.setMode(Mode.EVAP)
  283. debugPrint("We are in EVAP mode")
  284. gso = GetAttribute(j[1].get("ECOM"),"GSO",None)
  285. if not gso:
  286. debugPrint("No GSO here")
  287. else:
  288. debugPrint("Looking at: {}".format(gso))
  289. switch = GetAttribute(gso,"SW",None)
  290. if switch == "N":
  291. # Evap is on - what is the fan speed
  292. debugPrint("EVAP is ON")
  293. brivisStatus.systemOn = True
  294. brivisStatus.evapStatus.evapOn = True
  295.  
  296. evapFan = GetAttribute(gso,"FS",None)
  297. debugPrint("Fan is: {}".format(evapFan))
  298. brivisStatus.evapStatus.FanOn(evapFan)
  299.  
  300. fanSpeed = GetAttribute(gso,"FL",None)
  301. debugPrint("Fan Speed is: {}".format(fanSpeed))
  302. brivisStatus.evapStatus.FanSpeed(int(fanSpeed))
  303.  
  304. waterPump = GetAttribute(gso,"PS",None)
  305. debugPrint("Water Pump is: {}".format(waterPump))
  306. brivisStatus.evapStatus.WaterPumpOn(waterPump)
  307.  
  308.  
  309. elif switch == "F":
  310. # Evap is off
  311. debugPrint("EVAP is OFF")
  312. brivisStatus.systemOn = False
  313. brivisStatus.evapStatus.evapOn = False
  314.  
  315. def HandleStatus(client,brivisStatus):
  316. # Make sure enough time passed to get a status message
  317. time.sleep(1)
  318. status = client.recv(4096)
  319. debugPrint(status)
  320.  
  321. jStr = status[14:]
  322. debugPrint(jStr)
  323.  
  324. j = json.loads(jStr)
  325. debugPrint(json.dumps(j, indent = 4))
  326.  
  327. if 'HGOM' in j[1]:
  328. HandleHeatingMode(client,j,brivisStatus)
  329.  
  330. elif 'ECOM' in j[1]:
  331. HandleEvapMode(client,j,brivisStatus)
  332.  
  333. else:
  334. debugPrint("Unknown mode")
  335.  
  336.  
  337. def main():
  338. client = ConnectToTouch(touchIP,touchPort)
  339. brivisStatus = BrivisStatus()
  340. HandleStatus(client,brivisStatus)
  341. statusJsonStr = brivisStatus.Dump()
  342. print(statusJsonStr)
  343. client.close()
  344.  
  345. if __name__== "__main__":
  346. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement