2021-07-01 19:14:36 +00:00
import paho . mqtt . client as mqtt
import time
import board
import busio
from adafruit_ht16k33 import segments
2021-07-03 19:14:56 +00:00
from enum import Enum
2021-07-01 19:14:36 +00:00
__TOPIC_BRIGHTNESS__ = " brightness "
2021-07-03 19:14:56 +00:00
__TOPIC_SCROLL_INTERVAL__ = " scrollinterval "
__TOPIC_TEXT_STATIC__ = " textstatic "
__TOPIC_TEXT_ONCE__ = " textonce "
__TOPIC_TEXT_SCROLL__ = " textscroll "
__TOPIC_TEXT_SCROLL_REPEAT__ = " textscrollrepeat "
__TOPIC_TEXT_SCROLL_LR__ = " textscrolllr "
NUMDIGITS = 8
class Mode ( Enum ) :
STATIC = 1 #show text constantly. may cut digits
ONCE = 3 #show once for some time
SCROLL = 2 #scroll thorugh once
SCROLL_LR = 4 #scroll back and forth
SCROLL_REPEAT = 5
2021-07-01 19:14:36 +00:00
class Controller :
2021-07-01 19:50:35 +00:00
connected = False
2021-07-03 19:14:56 +00:00
displayL = None
displayR = None
2021-07-01 20:06:18 +00:00
last_scrollupdate = 0
2021-07-03 19:14:56 +00:00
mode = Mode . STATIC
2021-07-01 19:50:35 +00:00
def __init__ ( self , base_topic , mqtt_host , mqtt_port = 1883 ) :
self . scroll_interval = 0.25
2021-07-01 20:06:18 +00:00
self . text = " "
2021-07-01 19:50:35 +00:00
self . poscount = 0
# Create the I2C interface.
self . i2c = busio . I2C ( board . SCL , board . SDA )
# Create the LED segment class.
# This creates a 14 segment 4 character display:
2021-07-03 19:14:56 +00:00
self . displayL = segments . Seg14x4 ( self . i2c , address = 0x70 ) # find address with "sudo i2cdetect -y 1" . you need to install: sudo apt-get install -y python-smbus i2c-tools
self . displayR = segments . Seg14x4 ( self . i2c , address = 0x71 )
2021-07-01 19:50:35 +00:00
# Clear the display.
2021-07-03 19:14:56 +00:00
self . displayL . fill ( 0 )
self . displayR . fill ( 0 )
2021-07-01 19:50:35 +00:00
# set brightness, range 0-1.0, 1.0 max brightness
2021-07-03 19:14:56 +00:00
self . displayL . brightness = 1.0
self . displayR . brightness = 1.0
2021-07-01 19:50:35 +00:00
self . mqtt = mqtt . Client ( )
self . mqtt . on_connect = self . on_connect
self . mqtt . on_message = self . on_message
self . mqtt . on_disconnect = self . on_disconnect
self . mqtt . connect ( mqtt_host , mqtt_port )
self . topic = base_topic
2021-07-03 19:14:56 +00:00
self . displayL . print ( " LEFT " )
self . displayR . print ( " RIGH " )
2021-07-01 19:50:35 +00:00
def on_disconnect ( self , client , userdata , rc ) :
print ( " MQTT disconnected " )
self . connected = False
def on_message ( self , client , userdata , message ) :
msg = str ( message . payload . decode ( " utf-8 " ) )
print ( " msg = " + msg )
if message . topic . endswith ( __TOPIC_BRIGHTNESS__ + " /set " ) :
val = float ( msg )
if val > = 0.0 and val < = 1.0 :
2021-07-03 19:14:56 +00:00
self . displayL . brightness = val
self . displayR . brightness = val
print ( " changed brightness to " , self . displayL . brightness )
self . mqtt . publish ( self . topic + " / " + __TOPIC_BRIGHTNESS__ , self . displayL . brightness , 1 )
2021-07-01 19:50:35 +00:00
else :
print ( " invalid brightness " , val )
if message . topic . endswith ( __TOPIC_SCROLL_INTERVAL__ + " /set " ) :
val = float ( msg )
if val > 0.0 :
self . scroll_interval = val
print ( " changed scroll_interval to " , self . scroll_interval )
self . mqtt . publish ( self . topic + " / " + __TOPIC_SCROLL_INTERVAL__ , self . scroll_interval , 1 )
else :
print ( " error not >0.0: " , val )
2021-07-03 19:14:56 +00:00
if message . topic . endswith ( __TOPIC_TEXT_SCROLL_REPEAT__ + " /set " ) :
self . mode = Mode . SCROLL_REPEAT
2021-07-01 20:06:18 +00:00
self . poscount = 0 #start at beginning of new text
2021-07-01 19:50:35 +00:00
self . text = msg
2021-07-01 20:06:18 +00:00
if len ( self . text ) == 0 :
self . text = " "
2021-07-01 19:50:35 +00:00
print ( " changed text to " , self . text )
2021-07-03 19:14:56 +00:00
self . mqtt . publish ( self . topic + " / " + __TOPIC_TEXT_SCROLL_REPEAT__ , self . text , 1 )
if message . topic . endswith ( __TOPIC_TEXT_SCROLL_LR__ + " /set " ) :
self . mode = Mode . SCROLL_LR
self . poscount = 0 #start at beginning of new text
self . text = msg
if len ( self . text ) == 0 :
self . text = " "
print ( " changed text to " , self . text )
self . mqtt . publish ( self . topic + " / " + __TOPIC_TEXT_SCROLL_LR__ , self . text , 1 )
2021-07-01 19:50:35 +00:00
def on_connect ( self , client , userdata , flags , rc ) :
print ( " Connected to MQTT Broker " )
self . mqtt . subscribe ( self . topic + " /# " )
self . connected = True
2021-07-03 19:14:56 +00:00
def displayTextOffset ( self , _text , _offset = 0 , _wrap = True ) :
while len ( _text ) < NUMDIGITS :
_text + = " "
if _wrap :
self . displayL [ 0 ] = _text [ ( ( _offset + 0 ) % len ( _text ) ) ]
self . displayL [ 1 ] = _text [ ( ( _offset + 1 ) % len ( _text ) ) ]
self . displayL [ 2 ] = _text [ ( ( _offset + 2 ) % len ( _text ) ) ]
self . displayL [ 3 ] = _text [ ( ( _offset + 3 ) % len ( _text ) ) ]
self . displayR [ 0 ] = _text [ ( ( _offset + 4 ) % len ( _text ) ) ]
self . displayR [ 1 ] = _text [ ( ( _offset + 5 ) % len ( _text ) ) ]
self . displayR [ 2 ] = _text [ ( ( _offset + 6 ) % len ( _text ) ) ]
self . displayR [ 3 ] = _text [ ( ( _offset + 7 ) % len ( _text ) ) ]
else :
if _offset + 0 > = 0 and _offset + 0 < len ( _text ) :
self . displayL [ 0 ] = _text [ ( ( _offset + 0 ) ) ]
if _offset + 1 > = 0 and _offset + 1 < len ( _text ) :
self . displayL [ 1 ] = _text [ ( ( _offset + 1 ) ) ]
if _offset + 2 > = 0 and _offset + 2 < len ( _text ) :
self . displayL [ 2 ] = _text [ ( ( _offset + 2 ) ) ]
if _offset + 3 > = 0 and _offset + 3 < len ( _text ) :
self . displayL [ 3 ] = _text [ ( ( _offset + 3 ) ) ]
if _offset + 4 > = 0 and _offset + 4 < len ( _text ) :
self . displayR [ 0 ] = _text [ ( ( _offset + 4 ) ) ]
if _offset + 5 > = 0 and _offset + 5 < len ( _text ) :
self . displayR [ 1 ] = _text [ ( ( _offset + 5 ) ) ]
if _offset + 6 > = 0 and _offset + 6 < len ( _text ) :
self . displayR [ 2 ] = _text [ ( ( _offset + 6 ) ) ]
if _offset + 7 > = 0 and _offset + 7 < len ( _text ) :
self . displayR [ 3 ] = _text [ ( ( _offset + 7 ) ) ]
2021-07-01 19:50:35 +00:00
def loop_forever ( self ) :
run = True
while run :
2021-07-01 20:06:18 +00:00
self . mqtt . loop ( 0.1 ) #with block timeout
2021-07-01 19:50:35 +00:00
2021-07-03 19:14:56 +00:00
if self . displayL is not None and self . displayR is not None : #displays initialized
if self . mode == Mode . SCROLL_REPEAT :
if time . time ( ) > self . last_scrollupdate + self . scroll_interval : #time to update animation
self . displayTextOffset ( self . text , self . poscount , True )
self . poscount + = 1
self . poscount % = len ( self . text )
self . last_scrollupdate = time . time ( )
if self . mode == Mode . SCROLL_LR :
if time . time ( ) > self . last_scrollupdate + self . scroll_interval : #time to update animation
print ( " pos= " , self . poscount )
scrolloffset = self . poscount
if scrolloffset > = ( len ( self . text ) - NUMDIGITS ) :
scrolloffset = ( len ( self . text ) - NUMDIGITS ) - ( scrolloffset - ( len ( self . text ) - NUMDIGITS ) ) #reverse
scrolloffset = max ( 0 , scrolloffset ) #cap at zero
print ( " scrolloffset= " , scrolloffset )
self . displayTextOffset ( self . text , scrolloffset , False )
self . poscount + = 1
self . poscount % = ( len ( self . text ) - NUMDIGITS ) * 2 #if poscount over scrollable width means scroll backwards
self . last_scrollupdate = time . time ( )