Mcclellan
Mcclellan | |
---|---|
![]() | |
Name | mcclellan |
Zone | Infrastructure
|
Owner | i3Detroit |
Make Model | Debian VM |
Part Number | |
Date Acquired | 2015-08-09 |
Storage Location | hardac.i3detroit.local |
Authorization Required | Yes |
Status | Running |
Value | 0 |
IP Address | 10.13.0.26 |
MAC Address | 08:00:27:7e:08:1e |
Hostname | mcclellan |
Documentation | OpenHAB |
Other References | Supersedes: |
Contents
Intro
This VM serves space automation functions. Currently, discussion is about two applications:
- Smarter thermal control, with furnaces, AC, and fans controlled synchronously
- Better power reporting from the Power Meter
Rules
Instructions
Maintenance Info
FAQ
ToDo
- IoT Subnet
* Wifi IoT network connected to IoT DHCP
Authorized Users and Trainers
Trainer Name | Certified Date |
---|---|
Amelia Meyer | 2016-11-25 |
Evan Allen | 2016-11-25 |
Leonard Kinnaird-Heether | 2016-11-25 |
Mark Furland | 2016-11-27 |
User Name | Authorized By | Date of Most Recent Training |
---|---|---|
Amelia Meyer | Amelia Meyer | 2016-11-25 |
Evan Allen | Amelia Meyer | 2016-11-25 |
Leonard Kinnaird-Heether | Evan Allen | 2016-11-25 |
Mark Furland | Amelia Meyer | 2016-11-27 |
Services
OpenHAB2 runtime
Port 8080
To make config changes, there *might* be a openahb console command, but it didn't work. Restart the daemon.
To restart the daemon: `sudo service openhab2 restart`
To connect to the openhab 2 console: `ssh openhab@localhost -p 8101` password `habopen`. Those are the defaults. Not accessible from non-localhost.
Mosquitto MQTT broker
- Port 1883
Listen to all: `mosquitto_sub -v -h localhost -p 1883 -t '#'`
Services that have yet to be reinstalled
Slack integration
Modified slackhab.py to work with new Slack RTM API
from __future__ import print_function from __future__ import unicode_literals import requests import time import xml.etree.ElementTree as xml from rtmbot.core import Plugin crontable = [] outputs = [] debug = True openhab_url = 'http://127.0.0.1:8080' slackhab_user_id = "<<<elided>>>" headers = { 'Content-Type': 'text/plain' } class SlackHab(Plugin): def process_message(self,data): self.print_debug(str(data)) # check we have sufficient details if 'channel' not in data or 'user' not in data or 'text' not in data: return channel = data['channel'] user = data['user'] text = data['text'] # first check if we are interested in this command command_text = self.get_command_text(channel, user, text) if command_text is None: self.print_debug('Boring message') return tokens = command_text.split() if len(tokens) == 0: self.print_debug('No tokens') return command = tokens[0].lower() if command == "send" and len(tokens) >= 3: item = tokens[1] value = " ".join(tokens[2:]) url = openhab_url + '/rest/items/' + item r = requests.post(url, headers=headers, data=value) if self.check_response(r, channel): self.outputs.append([ channel, "```Sent %s command to %s```" % (value, item) ]) elif command == "update" and len(tokens) >= 3: item = tokens[1] value = " ".join(tokens[2:]) url = openhab_url + '/rest/items/' + item + '/state' r = requests.put(url, headers=headers, data=value) if self.check_response(r, channel): self.outputs.append([ channel, "```Sent %s update to %s```" % (value, item) ]) elif command == "status" and len(tokens) >= 2: item = tokens[1] url = openhab_url + '/rest/items/' + item + '/state' r = requests.get(url, headers=headers) if self.check_response(r, channel): self.outputs.append([ channel, "```%s is %s```" % (item, r.text) ]) elif command == "items": filter = None if len(tokens) > 1: filter = tokens[1].lower() url = openhab_url + '/rest/items' r = requests.get(url, headers=headers) if self.check_response(r, channel): items = [] output = "" maxtypelen = 0 maxnamelen = 0 for item in xml.fromstring(r.content).findall('item'): name = item.find('name').text type = item.find('type').text if filter is None or filter in name.lower(): items.append(item) if len(type) > maxtypelen: maxtypelen = len(type) if len(name) > maxnamelen: maxnamelen = len(name) for item in items: name = item.find('name').text state = item.find('state').text type = item.find('type').text output = output + "%s%s%s\n" % (type.ljust(maxtypelen+5), name.ljust(maxnamelen+5), state) if len(output) >= 8000: output = output + "... (too much output, please specify a filter)" break if len(items) == 0: if filter is None: self.outputs.append([ channel, "```No items found```" ]) else: self.outputs.append([ channel, "```No items found matching '%s'```" % (filter) ]) else: self.outputs.append([ channel, "```%s```" % (output) ]) def get_command_text(self,channel, user, text): if channel == "" or channel is None: self.print_debug('No channel') return None if user == "" or user is None: self.print_debug('No user') return None if text == "" or text is None: self.print_debug('No text') return None # check for a message directed at our bot user_tag = "<@%s>" % (slackhab_user_id) self.print_debug('Calculated user tag as %s'%user_tag) if text.startswith(user_tag): self.print_debug('Returning text from command in channel') return text[len(user_tag):] # check for a DM to our bot if channel.startswith("D"): self.print_debug('Returning text from command in DM') return text self.print_debug('No DM or channel command') return None def check_response(self,r, channel): # check our rest api call was successful if r.status_code == 200: return True if r.status_code == 201: return True # log the response code/reason back to our slack channel self.outputs.append([ channel, "```%d: %s```" % (r.status_code, r.reason) ]) return False def print_debug(self,message): if debug: print(message)
rtmbot.conf
DEBUG: False SLACK_TOKEN: "<<<elided>>>" BASE_PATH: "/var/lib/openhab/rtmbot" ACTIVE_PLUGINS: - plugins.slackhab.SlackHab
Systemd service
[Unit] Description=OpenHAB Slack Bot After=syslog.target network.target Requires=openhab.service [Service] Type=simple User=openhab Group=openhab WorkingDirectory=/var/lib/openhab/rtmbot ExecStart=/usr/local/bin/rtmbot -c /var/lib/openhab/rtmbot/rtmbot.conf [Install] WantedBy=multi-user.target