From 8fc2a739d58406cbb5157279093a7016e19a200e Mon Sep 17 00:00:00 2001 From: Felix Kunsmann Date: Tue, 14 Mar 2017 10:25:53 +0000 Subject: [PATCH] Initial commit: Display Startup message on LCD screen --- octoprint_hd44780/__init__.py | 106 ++++++++++++++++++++++++++++++++++ requirements.txt | 3 + setup.py | 67 +++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 octoprint_hd44780/__init__.py create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/octoprint_hd44780/__init__.py b/octoprint_hd44780/__init__.py new file mode 100644 index 0000000..707a23c --- /dev/null +++ b/octoprint_hd44780/__init__.py @@ -0,0 +1,106 @@ +# coding=utf-8 + +import future + +__author__ = "Felix Kunsmann " +__license__ = "GNU Affero General Public License http://www.gnu.org/licenses/agpl.html" +__copyright__ = "Copyright (C) 2017 Felix Kunsmann - Released under terms of the AGPLv3 License" + +import octoprint.plugin + +import RPi.GPIO as GPIO + +from RPLCD import CharLCD +from RPLCD import CursorMode +from RPLCD import cursor + +class LCD_HD44780(octoprint.plugin.StartupPlugin, + octoprint.plugin.SettingsPlugin): + def __init__(self): + self._pin_to_gpio_rev1 = [-1, -1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17, 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + self._pin_to_gpio_rev2 = [-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + self._pin_to_gpio_rev3 = [-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 26, 20, -1, 21 ] + self._configuredGPIOPins = [] + + self.pin_rs = 15 + self.pin_rw = None + self.pin_e = 16 + self.pin_d4 = 21 + self.pin_d5 = 22 + self.pin_d6 = 23 + self.pin_d7 = 24 + + self.cols = 20 + self.rows = 4 + + self._lcd = None + + def on_settings_initialized(self): + self._initialize_lcd() + + def _gpio_board_to_bcm(self, pin): + if GPIO.RPI_REVISION == 1: + pin_to_gpio = self._pin_to_gpio_rev1 + elif GPIO.RPI_REVISION == 2: + pin_to_gpio = self._pin_to_gpio_rev2 + else: + pin_to_gpio = self._pin_to_gpio_rev3 + + return pin_to_gpio[pin] + + def _gpio_get_pin(self, pin): + if GPIO.getmode() == GPIO.BOARD: + return pin + elif GPIO.getmode() == GPIO.BCM: + return self._gpio_board_to_bcm(pin) + else: + return 0 + + def _initialize_lcd(self): + self._logger.info("Running RPi.GPIO version %s" % GPIO.VERSION) + if GPIO.VERSION < "0.6": + self._logger.error("RPi.GPIO version 0.6.0 or greater required.") + + GPIO.setwarnings(False) + + for pin in self._configuredGPIOPins: + self._logger.debug("Cleaning up pin %s" % pin) + try: + GPIO.cleanup(self._gpio_get_pin(pin)) + except (RuntimeError, ValueError) as e: + self._logger.error(e) + self._configuredGPIOPins = [] + + if GPIO.getmode() is None: + GPIO.setmode(GPIO.BOARD) + + pin_rs = self._gpio_get_pin(self.pin_rs) + + if self.pin_rw is not None: + pin_rw = self._gpio_get_pin(self.pin_rw) + else: + pin_rw = None + + pin_e = self._gpio_get_pin(self.pin_e) + pin_d4 = self._gpio_get_pin(self.pin_d4) + pin_d5 = self._gpio_get_pin(self.pin_d5) + pin_d6 = self._gpio_get_pin(self.pin_d6) + pin_d7 = self._gpio_get_pin(self.pin_d7) + + self._lcd = CharLCD(pin_rs=pin_rs, pin_rw=pin_rw, pin_e=pin_e, pins_data=[pin_d4, pin_d5, pin_d6, pin_d7], + numbering_mode=GPIO.getmode(), cols=self.cols, rows=self.rows) + + self._lcd.cursor_mode = CursorMode.hide + self._lcd.clear() + self._lcd.write_string('Octoprint-LCD-HD44780\n\rVersion: 0.1') + +__plugin_name__ = "LCD: HD44780-compatible" + +def __plugin_load__(): + global __plugin_implementation__ + __plugin_implementation__ = LCD_HD44780() + + global __plugin_hooks__ + __plugin_hooks__ = { +# "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information + } diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c3c82c1 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +OctoPrint +RPi.GPIO>=0.6.3 +RPLCD diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..a86cdfc --- /dev/null +++ b/setup.py @@ -0,0 +1,67 @@ +# coding=utf-8 +import setuptools + +######################################################################################################################## + +plugin_identifier = "hd44780" +plugin_package = "octoprint_%s" % plugin_identifier +plugin_name = "OctoPrint-LCD-HD44780" +plugin_version = "0.1" +plugin_description = "Display useful information on a connected HD44780 compatible display." +plugin_author = "Felix Kunsmann" +plugin_author_email = "felix@kunsmann.eu" +plugin_url = "https://github.com/Kunsi/Octoprint-LCD-HD44780" +plugin_license = "AGPLv3" +plugin_additional_data = [] + +######################################################################################################################## + +def package_data_dirs(source, sub_folders): + import os + dirs = [] + + for d in sub_folders: + folder = os.path.join(source, d) + if not os.path.exists(folder): + continue + + for dirname, _, files in os.walk(folder): + dirname = os.path.relpath(dirname, source) + for f in files: + dirs.append(os.path.join(dirname, f)) + + return dirs + +def params(): + # Our metadata, as defined above + name = plugin_name + version = plugin_version + description = plugin_description + author = plugin_author + author_email = plugin_author_email + url = plugin_url + license = plugin_license + + # we only have our plugin package to install + packages = [plugin_package] + + # we might have additional data files in sub folders that need to be installed too + #package_data = {plugin_package: package_data_dirs(plugin_package, ['static', 'templates', 'translations'] + plugin_additional_data)} + #include_package_data = True + + # If you have any package data that needs to be accessible on the file system, such as templates or static assets + # this plugin is not zip_safe. + zip_safe = False + + # Read the requirements from our requirements.txt file + install_requires = open("requirements.txt").read().split("\n") + + # Hook the plugin into the "octoprint.plugin" entry point, mapping the plugin_identifier to the plugin_package. + # That way OctoPrint will be able to find the plugin and load it. + entry_points = { + "octoprint.plugin": ["%s = %s" % (plugin_identifier, plugin_package)] + } + + return locals() + +setuptools.setup(**params())