import machine, time, gc, network, micropython, json, esp
from machine import Pin, Timer, I2C, RTC
from ht16k33segment import HT16K33Segment
from ds_read_temp import *
from simple import MQTTClient
micropython.alloc_emergency_exception_buf(100)
# Global variables
global client, con_cb_connected, mqtt_broker, callback_error
global pub_no, wlan, d_error, screen2, mqtt_connected
red_pin = 2
ds_pin_nr = 33
scr_onoff_pin = 32
i2c = I2C(scl=Pin(22), sda=Pin(21))
red_led = Pin(red_pin, Pin.OUT)
red_led(0)
scr_onoff = Pin(scr_onoff_pin, Pin.IN, Pin.PULL_DOWN)
d_error = False
ds_pin = machine.Pin(ds_pin_nr)
readings ={}
pub_no = 0
#s1 = '0xd6k301d607db6628'
#s2 = '0xa73c01d6072bb828'
s1 = "0xdc3c01d607225028"
s2 = "0xb50300a279846428"
s3 = "0x463c01d607ac8128"
s4 = "0xad3c01d6073b6e28"
m_broker = '192.168.127.246'
d_name = 'ESP32-Bryggeriskap'
timer = Timer(0)
restart = Timer(1)
screen2 = 0.0
con_cb_connected = False
mqtt_broker = False
callback_error = ''
try:
display1 = HT16K33Segment(i2c, i2c_address=0x74)
display1.set_brightness(15)
except OSError:
print('Display 1 med adresse: 0x74 finnes ikke')
d_error = True
try:
display2 = HT16K33Segment(i2c, i2c_address=0x70)
display2.set_brightness(15)
except OSError:
print('Display 2 med adresse: 0x70 finnes ikke')
d_error = True
try:
display3 = HT16K33Segment(i2c, i2c_address=0x72)
display3.set_brightness(15)
except OSError:
print('Display 3 med adresse: 0x72 finnes ikke')
d_error = True
try:
display4 = HT16K33Segment(i2c, i2c_address=0x71)
display4.set_brightness(15)
except OSError:
print('Display 4 med adresse: 0x71 finnes ikke')
d_error = True
def restart_command():
machine.reset()
def safe_float_conversion(value):
"""
Safely convert a value to float.
Parameters:
- value: The input value to be converted.
Returns:
- The float representation of the value or None if conversion fails.
"""
try:
return float(value)
except ValueError:
print("Error: Unable to convert to float.")
red_led(1)
time.sleep(0.2)
red_led(0)
time.sleep(0.2)
red_led(1)
time.sleep(2)
red_led(0)
time.sleep(0.2)
return None
def do_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
essid='Bryggeriet'
pwd = 'hersbrucker'
wlan.connect(essid,pwd)
t = time.ticks_ms()
while not wlan.isconnected():
if time.ticks_diff(time.ticks_ms(), t) > 15000:
wlan.disconnect()
print("Timeout. Could not connect.")
ssid = 'MicroPython-AP'
password = '123456789'
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=ssid, password=password)
while ap.active() == False:
pass
wlan = False
return wlan,ap
print("Successfully connected to " + essid)
print('network config:', wlan.ifconfig())
ap=False
return wlan, ap
else:
print("Already connected")
ap = False
return wlan, ap
# Assuming all necessary imports are made, and global variables and functions are defined elsewhere
# Helper functions
def handle_one_wire_error():
try:
client.publish('tele/bryggeriskap', '{"Error":"OneWireError"}')
print('Publishing: OneWireError')
for _ in range(100):
red_led(1)
time.sleep_ms(100)
red_led(0)
time.sleep_ms(100)
except Exception as e:
print(e)
finally:
restart_command()
def publish_readings(readings):
try:
json_data = json.dumps(readings)
client.publish('tele/bryggeriskap', json_data)
print('Publishing: ' + json_data)
global pub_no
pub_no = 0 if pub_no >= 100000 else pub_no + 1
setup_restart_timer()
red_led(0 if len(readings) == 3 else 1)
except Exception as e:
print(e)
def setup_restart_timer():
restart.deinit()
restart.init(period=600000, mode=Timer.PERIODIC, callback=lambda t:restart_command())
def show_sensor_values(display, sensor_id, readings):
try:
show_values(display, str(int(readings[sensor_id]*10)))
except KeyError:
print('Cannot find ' + sensor_id)
show_values(display, '000')
global d_error
d_error = True
except NameError:
print('Display not found')
d_error = True
def update_values(readings, ds_pin):
print(f'client: {client}, mqtt_broker: {mqtt_broker}, con_cb_connected: {con_cb_connected}, callback_error: {callback_error}')
client.check_msg()
readings = {}
try:
readings = read_ds_temp(readings, ds_pin)
except onewire.OneWireError:
handle_one_wire_error()
return readings
if mqtt_connected:
publish_readings(readings)
else:
for _ in range(5):
red_led(1)
time.sleep(0.1)
red_led(0)
time.sleep(0.1)
red_led(1)
time.sleep(2)
red_led(0)
# Update displays
for i in range(1, 5):
display = globals().get(f'display{i}')
sensor_id = globals().get(f's{i}')
show_sensor_values(display, sensor_id, readings)
return readings
""" def update_values(readings, ds_pin):
global client, con_cb_connected, mqtt_broker, callback_error
print('client:', client, 'mqtt_broker: ', mqtt_broker, 'con_cb_connected: ', con_cb_connected, 'callbackerror: ', callback_error)
client.check_msg()
readings = {}
global pub_no
global wlan
global d_error
global screen2
global mqtt_connected
try:
r = read_ds_temp(readings, ds_pin)
except onewire.OneWireError:
oe = 0
try:
client.publish('tele/bryggeriskap', '{"Error":"OneWireError"}')
print('Publiserer: '+ 'OneWireError')
except Exception as e:
print(e)
r={}
while oe <= 100:
oe += 1
red_led(1)
time.sleep_ms(100)
red_led(0)
time.sleep_ms(100)
restart_command()
# if len(r) != 3 or d_error or wlan == False:
# red_led(1)
# else:
# red_led(0)
# print(r)
if mqtt_connected:
try:
try:
json_data = json.dumps(r)
except TypeError as e:
print("JSON serialization error:")
try:
client.publish('tele/bryggeriskap', json_data)
except Exception as e:
pass
print('Publiserer: '+ json.dumps(r))
if pub_no <= 100000:
pub_no += 1
else:
pub_no = 0
restart.deinit()
restart.init(period=600000, mode=Timer.PERIODIC, callback=lambda t:restart_command())
if len(r) == 3: #change
red_led(0)
else:
red_led(1)
except Exception as e:
print(e)
else:
red_led(1)
time.sleep(0.1)
red_led(0)
time.sleep(0.1)
red_led(1)
time.sleep(0.1)
red_led(0)
time.sleep(0.1)
red_led(1)
time.sleep(2)
red_led(0)
try:
show_values(display1, str(int(r[s1]*10)))
except KeyError:
print('Finner ikke '+s1)
show_values(display1, '000')
d_error = True
except NameError:
print('Finner ikke display 1')
d_error = True
try:
print('screen2: ', screen2)
show_values(display2, str(int(screen2*10)))
except KeyError:
print('Finner ikke '+s2)
show_values(display2, '000')
d_error = True
except NameError:
print('Finner ikke display 2')
d_error = True
try:
show_values(display3, str(int(r[s3]*10)))
except KeyError:
print('Finner ikke '+s3)
show_values(display2, '000')
d_error = True
except NameError:
print('Finner ikke display 3')
d_error = True
try:
show_values(display4, str(int(r[s4]*10)))
except KeyError:
print('Finner ikke '+s4)
show_values(display4, '000')
d_error = True
except NameError:
print('Finner ikke display 4')
d_error = True
return r """
def show_values(d, d_txt):
d.clear()
time.sleep_ms(100)
if scr_onoff() == 0:
d.power_on()
#print(d_txt)
#print(len(d_txt))
if len(d_txt) == 4:
for i in range(len(d_txt)):
dot = True if i == 2 else False
d.set_number(int(d_txt[i]), i, dot)
elif len(d_txt) == 3:
for i in range(len(d_txt)):
dot = True if i == 1 else False
d.set_number(int(d_txt[i]), i+1, dot)
elif len(d_txt) == 2:
for i in range(len(d_txt)):
dot = True if i == 0 else False
d.set_number(int(d_txt[i]), i+2, dot)
elif len(d_txt) == 1:
d.set_number(int(d_txt),3,False)
d.set_number(0,2,True)
d.draw()
else:
d.power_off()
def connect_to_mqtt_broker(client, max_retries=5):
global mqtt_broker
"""
Attempt to connect to the MQTT broker.
Parameters:
- client: The MQTT client instance.
- max_retries: The maximum number of connection attempts.
Returns:
- True if connected, False otherwise.
"""
attempt = 0
while attempt < max_retries:
try:
mqtt_conn = client.connect(False)
if mqtt_conn:
mqtt_broker = True
return True # Successful connection.
else:
print("Failed to connect to MQTT broker. Retrying...")
attempt += 1
time.sleep(1) # Wait for 1 second before retrying.
except Exception as e:
print("Exception during MQTT connection:")
attempt += 1
time.sleep(1) # Wait for 1 second before retrying.
print("Failed to connect to MQTT broker after multiple attempts.")
return False
def con_cb(connected):
global con_cb_connected
if connected:
con_cb_connected = True
client.subscribe(b'cmnd/bryggeriskap', qos=1)
print('abbonerer på cmnd/bryggeriskap')
client.subscribe(b'tele/labu/mesk', qos=1)
print('abbonerer på tele/labu/mesk')
def msg_cb(topic, pay):
global screen2
print('Received')
if isinstance(topic, bytes):
msg_topic = topic.decode("utf-8")
else:
msg_topic = topic
print('topic: ', topic)
if isinstance(pay, bytes):
msg_pay = pay.decode("utf-8")
else:
msg_pay = pay
print('pay: ', pay)
if msg_topic == 'cmnd/bryggeriskap':
if msg_pay == 'reset':
restart_command()
elif msg_topic == 'tele/labu/mesk':
screen2 = safe_float_conversion(msg_pay)
if screen2 is not None:
print("Converted value: ", screen2)
else:
# Handle the error (e.g., log it, raise an exception, etc.)
screen2 = 0.0
pass
else:
pass
wlan, ap = do_connect()
if not wlan:
we = 0
while we <= 50:
we += 1
red_led(1)
time.sleep_ms(900)
red_led(0)
time.sleep_ms(100)
restart_command()
client = MQTTClient(d_name, m_broker, 1883)
client.set_callback(msg_cb)
# Now, use the above function to connect
if connect_to_mqtt_broker(client):
mqtt_connected = True
try:
con_cb(True) # If connected, invoke the connection callback.
except Exception as e:
print("Error setting MQTT callback:")
red_led(1)
time.sleep(0.2)
red_led(0)
time.sleep(0.2)
red_led(1)
time.sleep(0.2)
red_led(0)
time.sleep(0.2)
callback_error = e
else:
# Handle the case where the MQTT broker connection failed.
# Maybe restart the system or alert the user.
pass
gc.collect()
try:
init_read = read_ds_temp(readings, ds_pin)
except onewire.OneWireError:
oe = 0
while oe <= 1000:
oe += 1
red_led(1)
time.sleep_ms(100)
red_led(0)
time.sleep_ms(100)
restart_command()
for i in range(len(init_read)):
red_led(1)
time.sleep_ms(200)
red_led(0)
time.sleep_ms(200)
time.sleep(5)
for i in range(len(init_read)):
red_led(1)
time.sleep_ms(200)
red_led(0)
time.sleep_ms(200)
time.sleep(5)
readings = update_values(readings, ds_pin)
with open('json_data.json', 'w') as outfile:
json.dump(readings, outfile)
timer.init(period=8000, mode=Timer.PERIODIC, callback=lambda t:update_values(readings, ds_pin))
restart.init(period=600000, mode=Timer.PERIODIC, callback=lambda t:restart_command())