S&B Volcano vaporizer remote control with Pi Pico W
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

state_wait_temp.py 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #!/usr/bin/env python
  2. import uasyncio as asyncio
  3. from poll import set_target_temp, get_current_temp
  4. import math
  5. # https://github.com/pimoroni/pimoroni-pico
  6. def from_hsv(h, s, v):
  7. i = math.floor(h * 6.0)
  8. f = h * 6.0 - i
  9. v *= 255.0
  10. p = v * (1.0 - s)
  11. q = v * (1.0 - f * s)
  12. t = v * (1.0 - (1.0 - f) * s)
  13. i = int(i) % 6
  14. if i == 0:
  15. return int(v), int(t), int(p)
  16. if i == 1:
  17. return int(q), int(v), int(p)
  18. if i == 2:
  19. return int(p), int(v), int(t)
  20. if i == 3:
  21. return int(p), int(q), int(v)
  22. if i == 4:
  23. return int(t), int(p), int(v)
  24. if i == 5:
  25. return int(v), int(p), int(q)
  26. # https://stackoverflow.com/a/1969274
  27. def translate(value, leftMin, leftMax, rightMin, rightMax):
  28. leftSpan = leftMax - leftMin
  29. rightSpan = rightMax - rightMin
  30. valueScaled = float(value - leftMin) / float(leftSpan)
  31. return rightMin + (valueScaled * rightSpan)
  32. def draw_graph(lcd, min, val, max):
  33. if max == min:
  34. lcd.textC("{} -> {} -> {}".format(min, val, max), int(self.lcd.width / 2), int(lcd.height / 2), lcd.white)
  35. return
  36. hue = translate(val, min, max, 0.0, 0.333)
  37. r, g, b = from_hsv(hue, 1.0, 1.0)
  38. c = lcd.color(r, g, b)
  39. ratio = (val - min) / (max - min)
  40. lcd.pie(lcd.width / 2, lcd.height / 2, lcd.width - 42, lcd.white, c, ratio)
  41. lcd.textC("{} / {}".format(val, max), int(lcd.width / 2), int(lcd.height / 2), lcd.white, lcd.black)
  42. class StateWaitTemp:
  43. def __init__(self, lcd):
  44. self.lcd = lcd
  45. self.lock = asyncio.Lock()
  46. def enter(self, val = None):
  47. self.value = val
  48. self.temp = 0.0
  49. self.min = 0.0
  50. self.max = 100.0
  51. self.poller = asyncio.create_task(self.poll())
  52. def exit(self):
  53. self.poller.cancel()
  54. if self.lock.locked():
  55. self.lock.release()
  56. return (self.value[0], self.value[1], self.value[2])
  57. async def poll(self):
  58. device, workflow, index = self.value
  59. async with self.lock:
  60. self.temp = 0.0
  61. self.min = 0.0
  62. self.max = workflow["steps"][index][0]
  63. temp = await get_current_temp(device)
  64. async with self.lock:
  65. self.temp = temp
  66. self.min = temp
  67. await set_target_temp(device, self.max)
  68. while temp < self.max:
  69. temp = await get_current_temp(device)
  70. async with self.lock:
  71. self.temp = temp
  72. async def draw(self):
  73. device, workflow, index = self.value
  74. self.lcd.text("Running Workflow - Heat {}".format(workflow["steps"][index][0]), 0, 10, self.lcd.red)
  75. keys = self.lcd.buttons()
  76. if keys.once("y"):
  77. return 4
  78. async with self.lock:
  79. if self.temp == 0.0:
  80. self.lcd.textC("Setting temperature...", int(self.lcd.width / 2), int(self.lcd.height / 2), self.lcd.white)
  81. else:
  82. draw_graph(self.lcd, self.min, self.temp, self.max)
  83. if self.temp >= self.max:
  84. return 7
  85. return -1