Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions pkg/oled/espresso_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

132 changes: 132 additions & 0 deletions pkg/oled/espresso_pb2_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

import espresso_pb2 as espresso__pb2


class EspressoStub(object):
"""Missing associated documentation comment in .proto file."""

def __init__(self, channel):
"""Constructor.

Args:
channel: A grpc.Channel.
"""
self.BoilerTemperature = channel.unary_stream(
'/espressopb.Espresso/BoilerTemperature',
request_serializer=espresso__pb2.TemperatureStreamRequest.SerializeToString,
response_deserializer=espresso__pb2.TemperatureStreamResponse.FromString,
)
self.GetConfiguration = channel.unary_unary(
'/espressopb.Espresso/GetConfiguration',
request_serializer=espresso__pb2.GetConfigurationRequest.SerializeToString,
response_deserializer=espresso__pb2.Configuration.FromString,
)
self.SetConfiguration = channel.unary_unary(
'/espressopb.Espresso/SetConfiguration',
request_serializer=espresso__pb2.Configuration.SerializeToString,
response_deserializer=espresso__pb2.Configuration.FromString,
)


class EspressoServicer(object):
"""Missing associated documentation comment in .proto file."""

def BoilerTemperature(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def GetConfiguration(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def SetConfiguration(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')


def add_EspressoServicer_to_server(servicer, server):
rpc_method_handlers = {
'BoilerTemperature': grpc.unary_stream_rpc_method_handler(
servicer.BoilerTemperature,
request_deserializer=espresso__pb2.TemperatureStreamRequest.FromString,
response_serializer=espresso__pb2.TemperatureStreamResponse.SerializeToString,
),
'GetConfiguration': grpc.unary_unary_rpc_method_handler(
servicer.GetConfiguration,
request_deserializer=espresso__pb2.GetConfigurationRequest.FromString,
response_serializer=espresso__pb2.Configuration.SerializeToString,
),
'SetConfiguration': grpc.unary_unary_rpc_method_handler(
servicer.SetConfiguration,
request_deserializer=espresso__pb2.Configuration.FromString,
response_serializer=espresso__pb2.Configuration.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'espressopb.Espresso', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))


# This class is part of an EXPERIMENTAL API.
class Espresso(object):
"""Missing associated documentation comment in .proto file."""

@staticmethod
def BoilerTemperature(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/espressopb.Espresso/BoilerTemperature',
espresso__pb2.TemperatureStreamRequest.SerializeToString,
espresso__pb2.TemperatureStreamResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def GetConfiguration(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/espressopb.Espresso/GetConfiguration',
espresso__pb2.GetConfigurationRequest.SerializeToString,
espresso__pb2.Configuration.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def SetConfiguration(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/espressopb.Espresso/SetConfiguration',
espresso__pb2.Configuration.SerializeToString,
espresso__pb2.Configuration.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
69 changes: 69 additions & 0 deletions pkg/oled/grpc_client_micro_oled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python3
"""
We are using Sparkfun micro OLED breakout (Qwiic), article LCD-14532

Prereqs:
* all packages need to be installed including luma
* I2C is enabled on port 1
"""
import datetime
import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
import grpc
import espresso_pb2
import espresso_pb2_grpc
import requests
import os
import subprocess
import sys, time

# Use for I2C.
serial = i2c(port=1, address=0x3D)
device = ssd1306(serial, width=64, height=48, rotate=2)
font = ImageFont.truetype("LiberationSerif-Bold.ttf", size=15)
aux_font = ImageFont.truetype("LiberationSerif-Bold.ttf", size=10)

def print_to_oled( temp,error ):
t_now = datetime.datetime.now(datetime.timezone.utc).strftime("%d-%m/%H:%M:%S")
(tfont_width, tfont_height) = font.getsize(t_now)
(font_width, font_height) = font.getsize(str(temp))
error_str = "Delta T="+str(error)+"°C"
(error_font_width, error_font_height) = font.getsize(error_str)
with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline="white", fill="black")
draw.text((device.width // 2 - font_width // 2,
device.height // 2 - font_height // 2),
temp,
font=font,
fill="white",
)
draw.text((device.width // 2 - tfont_width // 3.1,
device.height // 10 - tfont_height // 10),
t_now,
font=aux_font,
fill="green",
)
draw.text((device.width // 2 - error_font_width // 3.1,
device.height // 2 - error_font_height // -1.4),
error_str,
font=aux_font,
fill="white",)

def run():
with grpc.insecure_channel('localhost:8080') as channel:
stub = espresso_pb2_grpc.EspressoStub(channel)
#TODO: Initialize the PID values once here to P=1, I=4, D=8

response_iter_temp = stub.BoilerTemperature(espresso_pb2.TemperatureStreamRequest())
for response in response_iter_temp:
print(response.sample.value)
response_setT = stub.GetConfiguration(espresso_pb2.GetConfigurationRequest())
print(str(response_setT.temperature))
error = response_setT.temperature - response.sample.value
print_to_oled(str(float(f'{response.sample.value:.1f}'))+"°C",error)
#TODO: display an image of steaming cup if error is < 5°C
run()
12 changes: 12 additions & 0 deletions systemd/espresso.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Espresso PID service
After=multi-user.target

[Service]
Restart=on-failure
RestartSec=5s
User=pi
ExecStart=/bin/bash --login -c "/usr/bin/espresso --boiler-therm-clk-pin 23 --boiler-therm-cs-pin 27 --boiler-therm-miso-pin 22 --verbose"
[Install]
WantedBy=multi-user.target

13 changes: 13 additions & 0 deletions systemd/micro_oled.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Sparkfun micro oled service
After=multi-user.target espresso.service

[Service]
Restart=on-failure
RestartSec=5s
User=pi
ExecStart=/usr/bin/python3 /home/pi/espresso-controller/pkg/espressopb/grpc_client_micro_oled.py

[Install]
WantedBy=multi-user.target

6 changes: 6 additions & 0 deletions systemd/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copy the .service files to your /lib/systemd/system/
## type into terminal
### `sudo systemctl daemon-reload`
### `sudo systemctl enable espresso.service`
### `sudo systemctl enable micro_oled.servic`
# Reboot