mlodedrwale 2025-06-29 13:38:04 -07:00 zatwierdzone przez GitHub
commit 5353d726d5
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
6 zmienionych plików z 103 dodań i 50 usunięć

2
.gitignore vendored
Wyświetl plik

@ -6,7 +6,7 @@
.DStore/
thumbs.db
#storage/profiles
#config.py
config.py
.idea/*
state.json
venv/*

Wyświetl plik

@ -68,6 +68,7 @@ Download [Raspberry PI OS](https://www.raspberrypi.org/software/). Use Rasberry
$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install python3-dev
$ git clone https://github.com/jbruce12000/kiln-controller
$ cd kiln-controller
$ python3 -m venv venv
@ -86,6 +87,10 @@ If you're done playing around with simulations and want to deploy the code on a
## Configuration
Before you begin, make sure to copy the default settings:
$cp config-default.py config.py
All parameters are defined in config.py. You need to read through config.py carefully to understand each setting. Here are some of the most important settings:
| Variable | Default | Description |

40
config.py → config-default.py 100644 → 100755
Wyświetl plik

@ -20,8 +20,8 @@ listening_port = 8081
# This is used to calculate a cost estimate before a run. It's also used
# to produce the actual cost during a run. My kiln has three
# elements that when my switches are set to high, consume 9460 watts.
kwh_rate = 0.1319 # cost per kilowatt hour per currency_type to calculate cost to run job
kw_elements = 9.460 # if the kiln elements are on, the wattage in kilowatts
kwh_rate = 1 # cost per kilowatt hour per currency_type to calculate cost to run job
kw_elements = 6.9 # if the kiln elements are on, the wattage in kilowatts
currency_type = "$" # Currency Symbol to show when calculating cost to run job
########################################################################
@ -84,11 +84,11 @@ currency_type = "$" # Currency Symbol to show when calculating cost to run j
try:
import board
spi_sclk = board.D17 #spi clock
spi_miso = board.D27 #spi Microcomputer In Serial Out
spi_cs = board.D22 #spi Chip Select
spi_sclk = board.D11 #spi clock
spi_miso = board.D9 #spi Microcomputer In Serial Out
spi_cs = board.D8 #spi Chip Select
spi_mosi = board.D10 #spi Microcomputer Out Serial In (not connected)
gpio_heat = board.D23 #output that controls relay
gpio_heat = board.D25 #output that controls relay
gpio_heat_invert = False #invert the output state
except (NotImplementedError,AttributeError):
print("not running on blinka recognized board, probably a simulation")
@ -102,8 +102,8 @@ except (NotImplementedError,AttributeError):
max31855 = 1
max31856 = 0
# uncomment these two lines if using MAX-31856
import adafruit_max31856
thermocouple_type = adafruit_max31856.ThermocoupleType.K
# import adafruit_max31856
# thermocouple_type = adafruit_max31856.ThermocoupleType.S
# here are the possible max-31856 thermocouple types
# ThermocoupleType.B
@ -140,9 +140,9 @@ sensor_time_wait = 2
# well with the simulated oven. You must tune them to work well with
# your specific kiln. Note that the integral pid_ki is
# inverted so that a smaller number means more integral action.
pid_kp = 10 # Proportional 25,200,200
pid_ki = 80 # Integral
pid_kd = 220.83497910261562 # Derivative
pid_kp = 25 # Proportional 25,200,200
pid_ki = 200 # Integral
pid_kd = 200 # Derivative
########################################################################
#
@ -176,7 +176,7 @@ sim_speedup_factor = 1
#
# If you change the temp_scale, all settings in this file are assumed to
# be in that scale.
temp_scale = "f" # c = Celsius | f = Fahrenheit - Unit to display
temp_scale = "c" # c = Celsius | f = Fahrenheit - Unit to display
time_scale_slope = "h" # s = Seconds | m = Minutes | h = Hours - Slope displayed in temp_scale per time_scale_slope
time_scale_profile = "m" # s = Seconds | m = Minutes | h = Hours - Enter and view target time in time_scale_profile
@ -214,7 +214,7 @@ thermocouple_offset=0
temperature_average_samples = 10
# Thermocouple AC frequency filtering - set to True if in a 50Hz locale, else leave at False for 60Hz locale
ac_freq_50hz = False
ac_freq_50hz = True
########################################################################
# Emergencies - or maybe not
@ -238,12 +238,12 @@ ignore_tc_cold_junction_temp_low = False
ignore_tc_temp_high = False
ignore_tc_temp_low = False
ignore_tc_voltage_error = False
ignore_tc_short_errors = False
ignore_tc_short_errors = True
ignore_tc_unknown_error = False
# This overrides all possible thermocouple errors and prevents the
# process from exiting.
ignore_tc_too_many_errors = False
ignore_tc_too_many_errors = True
########################################################################
# automatic restarts - if you have a power brown-out and the raspberry pi
@ -277,3 +277,13 @@ kiln_profiles_directory = os.path.abspath(os.path.join(os.path.dirname( __file__
# To prevent throttling, set throttle_percent to 100.
throttle_below_temp = 300
throttle_percent = 20
#mqtt config
mqtt_enable = True
mqtt_host = 'example.com'
mqtt_port = 1883
mqtt_user = 'my_user'
mqtt_pass = 'my_passwd'
mqtt_topic = 'kiln/sensor'
mqtt_kiln_name = 'My Kiln'

Wyświetl plik

@ -1,7 +1,28 @@
import threading,logging,json,time,datetime
import config
import paho.mqtt.client as mqtt
import json
from oven import Oven
log = logging.getLogger(__name__)
# Callback when the client successfully connects to the broker
def on_connect(client, userdata, flags, rc):
if rc == 0:
log.info("Connected to MQTT broker")
else:
log.warning(f"MQTT connection failed, return code: {rc}")
# Callback when the client disconnects from the broker
def on_disconnect(client, userdata, rc):
log.warning(f"Disconnected from MQTT broker (code: {rc}), retrying in 5s...")
time.sleep(5)
try:
client.reconnect()
except Exception as e:
log.error(f"Reconnection attempt failed: {e}")
class OvenWatcher(threading.Thread):
def __init__(self,oven):
self.last_profile = None
@ -12,6 +33,8 @@ class OvenWatcher(threading.Thread):
threading.Thread.__init__(self)
self.daemon = True
self.oven = oven
if config.mqtt_enabled:
self._setup_mqtt()
self.start()
# FIXME - need to save runs of schedules in near-real-time
@ -22,18 +45,46 @@ class OvenWatcher(threading.Thread):
# out more than N minutes, don't restart
# FIXME - this should not be done in the Watcher, but in the Oven class
def _setup_mqtt(self):
self.client = mqtt.Client()
self.client.username_pw_set(config.mqtt_user, config.mqtt_pass)
#self.client.on_connect = on_connect
#self.client.on_disconnect = on_disconnect
self.client.connect(config.mqtt_host, config.mqtt_port)
self.client.loop_start()
def run(self):
# Main loop: each iteration handles exceptions internally to stay alive
while True:
oven_state = self.oven.get_state()
# record state for any new clients that join
if oven_state.get("state") == "RUNNING":
self.last_log.append(oven_state)
else:
self.recording = False
self.notify_all(oven_state)
try:
oven_state = self.oven.get_state()
# Save state for new observers if the oven is running
if oven_state.get("state") == "RUNNING":
self.last_log.append(oven_state)
else:
self.recording = False
# Notify all connected observers via WebSocket
self.notify_all(oven_state)
# Publish temperature to MQTT topic
if config.mqtt_enabled:
oven_state["name"] = config.mqtt_kiln_name
payload = json.dumps(oven_state)
result = self.client.publish(config.mqtt_topic, payload)
if result.rc != mqtt.MQTT_ERR_SUCCESS:
log.error(f"Publish failed, code: {result.rc}")
except Exception as exc:
log.exception(f"Exception in OvenWatcher iteration: {exc}")
# Sleep for configured time_step, even after exception
time.sleep(self.oven.time_step)
def lastlog_subset(self,maxpts=50):
'''send about maxpts from lastlog by skipping unwanted data'''
totalpts = len(self.last_log)

Wyświetl plik

@ -1,25 +1,10 @@
setuptools
greenlet
bottle
gevent
gevent-websocket
websocket-client
requests
# for folks running raspberry pis
# we have no proof of anyone using another board yet, but when that
# happens, you might want to comment this out.
RPi.GPIO
# List of all supported adafruit modules for thermocouples
adafruit-circuitpython-max31855
adafruit-circuitpython-max31856
# for folks using sw spi (bit banging)
adafruit-circuitpython-bitbangio
# untested - for PT100 platinum thermocouples
#adafruit-circuitpython-max31865
# untested - for mcp9600 and mcp9601
#adafruit-circuitpython-mcp9600
adafruit_blinka==8.58.1
adafruit_circuitpython_bitbangio==1.3.18
adafruit_circuitpython_max31855==3.2.24
adafruit_circuitpython_max31856==0.12.3
bottle==0.13.3
gevent==25.5.1
gevent_websocket==0.10.1
paho_mqtt==2.1.0
Requests==2.32.4
websocket_client==1.8.0

Wyświetl plik

@ -1,3 +1,5 @@
#!/bin/bash
sudo cp /home/pi/kiln-controller/lib/init/kiln-controller.service /etc/systemd/system/
path=$PWD
sed -i "/ExecStart=/c\ExecStart\=$path/venv/bin/python $path/kiln-controller.py" lib/init/kiln-controller.service
sudo cp $path/lib/init/kiln-controller.service /etc/systemd/system/
sudo systemctl enable kiln-controller