S&B Volcano vaporizer remote control with Pi Pico W
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

state_wait_temp.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #!/usr/bin/env python3
  2. # ----------------------------------------------------------------------------
  3. # Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # See <http://www.gnu.org/licenses/>.
  16. # ----------------------------------------------------------------------------
  17. import uasyncio as asyncio
  18. from poll import set_target_temp, get_current_temp
  19. import math
  20. # https://github.com/pimoroni/pimoroni-pico
  21. def from_hsv(h, s, v):
  22. i = math.floor(h * 6.0)
  23. f = h * 6.0 - i
  24. v *= 255.0
  25. p = v * (1.0 - s)
  26. q = v * (1.0 - f * s)
  27. t = v * (1.0 - (1.0 - f) * s)
  28. i = int(i) % 6
  29. if i == 0:
  30. return int(v), int(t), int(p)
  31. if i == 1:
  32. return int(q), int(v), int(p)
  33. if i == 2:
  34. return int(p), int(v), int(t)
  35. if i == 3:
  36. return int(p), int(q), int(v)
  37. if i == 4:
  38. return int(t), int(p), int(v)
  39. if i == 5:
  40. return int(v), int(p), int(q)
  41. # https://stackoverflow.com/a/1969274
  42. def translate(value, leftMin, leftMax, rightMin, rightMax):
  43. leftSpan = leftMax - leftMin
  44. rightSpan = rightMax - rightMin
  45. valueScaled = float(value - leftMin) / float(leftSpan)
  46. return rightMin + (valueScaled * rightSpan)
  47. def draw_graph(lcd, min, val, max):
  48. if max == min:
  49. lcd.textC("{} -> {} -> {}".format(min, val, max), int(self.lcd.width / 2), int(lcd.height / 2), lcd.white)
  50. return
  51. hue = translate(val, min, max, 0.0, 0.333)
  52. r, g, b = from_hsv(hue, 1.0, 1.0)
  53. c = lcd.color(r, g, b)
  54. ratio = (val - min) / (max - min)
  55. lcd.pie(lcd.width / 2, lcd.height / 2, lcd.width - 42, lcd.white, c, ratio)
  56. lcd.textC("{} / {}".format(val, max), int(lcd.width / 2), int(lcd.height / 2), lcd.white, lcd.black)
  57. class StateWaitTemp:
  58. def __init__(self, lcd):
  59. self.lcd = lcd
  60. self.lock = asyncio.Lock()
  61. def enter(self, val = None):
  62. self.value = val
  63. self.temp = 0.0
  64. self.min = 0.0
  65. self.max = 100.0
  66. self.poller = asyncio.create_task(self.poll())
  67. def exit(self):
  68. self.poller.cancel()
  69. if self.lock.locked():
  70. self.lock.release()
  71. return (self.value[0], self.value[1], self.value[2])
  72. async def poll(self):
  73. device, workflow, index = self.value
  74. async with self.lock:
  75. self.temp = 0.0
  76. self.min = 0.0
  77. self.max = workflow["steps"][index][0]
  78. temp = await get_current_temp(device)
  79. async with self.lock:
  80. self.temp = temp
  81. self.min = temp
  82. await set_target_temp(device, self.max)
  83. while temp < self.max:
  84. temp = await get_current_temp(device)
  85. async with self.lock:
  86. self.temp = temp
  87. async def draw(self):
  88. device, workflow, index = self.value
  89. self.lcd.text("Running Workflow - Heat {}".format(workflow["steps"][index][0]), 0, 10, self.lcd.red)
  90. keys = self.lcd.buttons()
  91. if keys.once("y"):
  92. return 4
  93. async with self.lock:
  94. if self.temp == 0.0:
  95. self.lcd.textC("Setting temperature...", int(self.lcd.width / 2), int(self.lcd.height / 2), self.lcd.white)
  96. else:
  97. draw_graph(self.lcd, self.min, self.temp, self.max)
  98. if self.temp >= self.max:
  99. return 7
  100. return -1