diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..162d5b0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM mono:latest + +COPY . /build + +RUN nuget restore /build/OmniLinkBridge.sln +RUN msbuild /build/OmniLinkBridge.sln /t:Build /p:Configuration=Release + +RUN mv /build/OmniLinkBridge/bin/Release /app +RUN rm -rf /build + +EXPOSE 8000/tcp + +VOLUME /config + +WORKDIR /app + +CMD [ "mono", "OmniLinkBridge.exe", "-i", "-c", "/config/OmniLinkBridge.ini", "-s", "/config/WebSubscriptions.json" ] \ No newline at end of file diff --git a/OmnILinkBridge.sql b/OmnILinkBridge.sql new file mode 100644 index 0000000..bc507cf --- /dev/null +++ b/OmnILinkBridge.sql @@ -0,0 +1,115 @@ +-- phpMyAdmin SQL Dump +-- version 3.5.1 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Dec 29, 2012 at 10:51 AM +-- Server version: 5.0.95 +-- PHP Version: 5.2.10 + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- Database: `hai` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `log_areas` +-- + +CREATE TABLE IF NOT EXISTS `log_areas` ( + `log_area_id` int(10) unsigned NOT NULL auto_increment, + `timestamp` datetime NOT NULL, + `id` tinyint(4) NOT NULL, + `name` varchar(12) NOT NULL, + `fire` varchar(10) NOT NULL, + `police` varchar(10) NOT NULL, + `auxiliary` varchar(10) NOT NULL, + `duress` varchar(10) NOT NULL, + `security` varchar(20) NOT NULL, + PRIMARY KEY (`log_area_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=287 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `log_messages` +-- + +CREATE TABLE IF NOT EXISTS `log_messages` ( + `log_message_id` int(10) unsigned NOT NULL auto_increment, + `timestamp` datetime NOT NULL, + `id` smallint(6) NOT NULL, + `name` varchar(12) NOT NULL, + `status` varchar(10) NOT NULL, + PRIMARY KEY (`log_message_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=139 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `log_thermostats` +-- + +CREATE TABLE IF NOT EXISTS `log_thermostats` ( + `log_tstat_id` int(10) unsigned NOT NULL auto_increment, + `timestamp` datetime NOT NULL, + `id` tinyint(4) NOT NULL, + `name` varchar(12) NOT NULL, + `status` varchar(10) NOT NULL, + `temp` smallint(6) NOT NULL, + `heat` smallint(6) NOT NULL, + `cool` smallint(6) NOT NULL, + `humidity` smallint(6) NOT NULL, + `humidify` smallint(6) NOT NULL, + `dehumidify` smallint(6) NOT NULL, + `mode` varchar(5) NOT NULL, + `fan` varchar(5) NOT NULL, + `hold` varchar(5) NOT NULL, + PRIMARY KEY (`log_tstat_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=67544 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `log_units` +-- + +CREATE TABLE IF NOT EXISTS `log_units` ( + `log_unit_id` int(10) unsigned NOT NULL auto_increment, + `timestamp` datetime NOT NULL, + `id` smallint(6) NOT NULL, + `name` varchar(12) NOT NULL, + `status` varchar(15) NOT NULL, + `statusvalue` smallint(6) NOT NULL, + `statustime` smallint(6) NOT NULL, + PRIMARY KEY (`log_unit_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1245 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `log_zones` +-- + +CREATE TABLE IF NOT EXISTS `log_zones` ( + `log_zone_id` int(10) unsigned NOT NULL auto_increment, + `timestamp` datetime NOT NULL, + `id` smallint(6) NOT NULL, + `name` varchar(16) NOT NULL, + `status` varchar(10) NOT NULL, + PRIMARY KEY (`log_zone_id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10298 ; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/OmniLinkBridge/Properties/AssemblyInfo.cs b/OmniLinkBridge/Properties/AssemblyInfo.cs index 0cfd85f..068e912 100644 --- a/OmniLinkBridge/Properties/AssemblyInfo.cs +++ b/OmniLinkBridge/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.1.1.0")] +[assembly: AssemblyFileVersion("1.1.1.0")] diff --git a/OmniLinkBridge/WebService/WebNotification.cs b/OmniLinkBridge/WebService/WebNotification.cs index 98e9483..5f90fc7 100644 --- a/OmniLinkBridge/WebService/WebNotification.cs +++ b/OmniLinkBridge/WebService/WebNotification.cs @@ -17,14 +17,20 @@ namespace OmniLinkBridge.WebAPI public static void AddSubscription(string callback) { + bool save = false; + lock (subscriptions_lock) { if (!subscriptions.Contains(callback)) { log.Debug("Adding subscription to " + callback); subscriptions.Add(callback); + save = true; } } + + if (save) + SaveSubscriptions(); } public static void Send(string type, string body) @@ -48,6 +54,7 @@ namespace OmniLinkBridge.WebAPI { log.Error("An error occurred sending notification to " + subscription, ex); subscriptions.Remove(subscription); + SaveSubscriptions(); } } } diff --git a/OmniLinkBridgeTest/Properties/AssemblyInfo.cs b/OmniLinkBridgeTest/Properties/AssemblyInfo.cs index 7ed7010..15ac401 100644 --- a/OmniLinkBridgeTest/Properties/AssemblyInfo.cs +++ b/OmniLinkBridgeTest/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; + using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/README.md b/README.md index c8370dd..b46e3af 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Provides time sync, logging, web service API, and MQTT bridge for HAI/Leviton OmniPro II controllers ## Download -You can download the [binary here](http://www.excalibur-partners.com/downloads/OmniLinkBridge_1_1_0.zip) +You can download the [binary here](http://www.excalibur-partners.com/downloads/OmniLinkBridge_1_1_1.zip) or use docker to build an image from git. ## Requirements -- .NET Framework 4.5.2 +- .NET Framework 4.5.2 (or Mono equivalent) ## Operation - Area, Messages, Units, and Zones are logged to mySQL when status changes @@ -43,6 +43,20 @@ You can download the [binary here](http://www.excalibur-partners.com/downloads/O - systemctl enable omnilinkbridge.service - systemctl start omnilinkbridge.service +## Docker +1. Clone git repo and build docker image + - git clone https://github.com/excaliburpartners/OmniLinkBridge.git + - cd OmniLinkBridge + - docker build --tag="omnilink-bridge" . +2. Configure at a minimum the controller IP and encryptions keys. The web service port must be 8000 unless the Dockerfile is changed. + - mkdir /opt/omnilink-bridge + - cp OmniLinkBridge/OmniLinkBridge.ini /opt/omnilink-bridge + - vim /opt/omnilink-bridge/OmniLinkBridge.ini +3. Start docker container + - docker run -d --name="omnilink-bridge" -v /opt/omnilink-bridge:/config --net=host --restart unless-stopped omnilink-bridge +4. Verify connectivity by looking at logs + - docker container logs omnilink-bridge + ## MySQL Setup You will want to install the MySQL Community Server, Workbench, and ODBC Connector. The Workbench software provides a graphical interface to administer the MySQL server. The OmniLink Bridge uses ODBC to communicate with the database. The MySQL ODBC Connector library is needed for Windows ODBC to communicate with MySQL. @@ -67,7 +81,7 @@ To test the API you can use your browser to view a page or PowerShell (see below - http://localhost:8000/ListUnits - http://localhost:8000/GetUnit?id=1 -- Invoke-WebRequest -Uri "http://localhost:8000/SetUnit" -Method POST -ContentType "application/json" -Body (convertto-json -InputObject @{"id"=1;"value"=100}) -UseBasicParsing +- Invoke-WebRequest -Uri "http://localhost:8000/SetUnit" -Method POST -ContentType "application/json" -Body (convertto-json -InputObject @{"id"=1;"value"=100}) -UseBasicParsing ## MQTT This module will also publish discovery topics for Home Assistant to auto configure devices. @@ -126,6 +140,10 @@ PUB omnilink/buttonX/command string ON ## Change Log +Version 1.1.1 - 2018-10-18 +- Added docker support +- Save subscriptions on change + Version 1.1.0 - 2018-10-13 - Renamed to OmniLinkBridge - Restructured code to be event based with modules diff --git a/omnilinkbridge.service b/omnilinkbridge.service new file mode 100644 index 0000000..632fa94 --- /dev/null +++ b/omnilinkbridge.service @@ -0,0 +1,12 @@ +[Unit] +Description=OmniLink Bridge +After=network.target + +[Service] +User=root +ExecStart=/usr/bin/mono-service --no-daemon /opt/OmniLinkBridge/OmniLinkBridge.exe +WorkingDirectory=/opt/OmniLinkBridge +Type=simple + +[Install] +WantedBy=multi-user.target