diff --git a/Photon/IoTlib/build.sh b/Photon/IoTlib/build.sh index 7614d6c1..94d65125 100755 --- a/Photon/IoTlib/build.sh +++ b/Photon/IoTlib/build.sh @@ -4,6 +4,8 @@ example=everything if [ $# -gt 0 ]; then example=$1 +else + example="starter" fi echo "particle compile photon examples/$example" particle compile photon examples/$example diff --git a/Photon/IoTlib/library.properties b/Photon/IoTlib/library.properties index 370565d8..d0f12e64 100644 --- a/Photon/IoTlib/library.properties +++ b/Photon/IoTlib/library.properties @@ -1,5 +1,5 @@ name=IoT -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Control your Photon projects using events from other Photons, Alexa and iOS devices diff --git a/Photon/IoTlib/publish.sh b/Photon/IoTlib/publish.sh new file mode 100755 index 00000000..0f4ca402 --- /dev/null +++ b/Photon/IoTlib/publish.sh @@ -0,0 +1,3 @@ +# Publish previously uploaded IoT library +particle library publish IoT + diff --git a/Photon/IoTlib/src/IoT.cpp b/Photon/IoTlib/src/IoT.cpp index d1762a16..b24c80c5 100644 --- a/Photon/IoTlib/src/IoT.cpp +++ b/Photon/IoTlib/src/IoT.cpp @@ -16,6 +16,7 @@ BSD license, check LICENSE for more information. All text above must be included in any redistribution. Changelog: +2018-01-17: Add functions for device state and type 2017-10-22: Convert to scene-like behavior 2017-10-12: Add control using device names 2017-05-15: Make devices generic @@ -126,7 +127,11 @@ void IoT::begin() _devices = new Devices(); _deviceNames = new DeviceNames(); + // Subscribe to events. There is a 1/second limit for events. Particle.subscribe(publishNameVariable, globalSubscribeHandler, MY_DEVICES); + + // Register cloud variables. Up to 20 may be registered. Name length max 12. + // There does not appear to be any time limit/throttle on variable reads. if(!Particle.variable(kSupportedActivitiesVariableName, supportedActivitiesVariable)) { log("Unable to expose "+String(kSupportedActivitiesVariableName)+" variable"); @@ -137,8 +142,25 @@ void IoT::begin() log("Unable to expose publishName variable"); return; } + + // Register cloud functions. Up to 15 may be registered. Name length max 12. + // Allows 1 string argument up to 63 chars long. + // There does not appear to be any time limit/throttle on function calls. + if(!Particle.function("program", &IoT::programHandler, this)) + { + log("Unable to register program handler"); + } + if(!Particle.function("value", &IoT::valueHandler, this)) + { + log("Unable to register value handler"); + } + if(!Particle.function("type", &IoT::typeHandler, this)) + { + log("Unable to register type handler"); + } } + /** * Loop method must be called periodically, * typically from the sketch loop() method. @@ -231,3 +253,85 @@ void IoT::subscribeHandler(const char *eventName, const char *rawData) log(" performing activity " + name + " = " + String(value)); _behaviors->performActivity(name, value); } + + +/** + * Program Handler + * Called by particle.io to update behaviors. + * It will define a new behavior for an activity for the specified device, + * and return an int indicating if the activity is new or changed. + * + * @param command "device:activity:compare:value:level" + * @returns int response indicating if activity already existed (1) or error (-1) + */ +int IoT::programHandler(String command) { + log("programHandler called with command: " + command); + String components[5]; + + int lastColonPosition = -1; + for(int i = 0; i < 4; i++) + { + int colonPosition = command.indexOf(':', lastColonPosition+1); + if(colonPosition == -1) + { + return -1 - i; + } + components[i] = command.substring(lastColonPosition+1, colonPosition); + lastColonPosition = colonPosition; + } + components[4] = command.substring(lastColonPosition+1); + + // Parse out each item into the correct type + Device *device = _devices->getDeviceWithName(components[0]); + String activity = components[1]; + char compare = components[2].charAt(0); + int value = components[3].toInt(); + int level = components[4].toInt(); + + //TODO: see if behavior already exists. If so, then change it. + // Is there already a behavior for the same device and activity? + + + //TODO: Otherwise just add a new behavior. + log("programHandler: new behavior("+components[0]+", "+components[1]+", "+components[2]+", "+components[3]+", "+components[4]+")"); + addBehavior(new Behavior(device, activity, compare, value, level)); + addBehavior(new Behavior(device, activity, '=', 0, 0)); // Add 'Off' state also + return 0; +} + +/** + * Value Handler + * Called by particle.io to read device current value. + * It will return an int indicating the current value of the specified device. + * + * @param deviceName String name of device + * @returns int response indicating value (0-100) or -1 if invalid device or error. + */ +int IoT::valueHandler(String deviceName) { + log("valueHandler called with device name: " + deviceName); + + Device *device = _devices->getDeviceWithName(deviceName); + if(device==NULL) { + return -1; + } + return device->getPercent(); +} + +/** + * Type Handler + * Called by particle.io to read device type (enum). + * It will return a string indicating the type of the specified device. + * A string is used to allow flexibility and simple future expansion. + * + * @param deviceName String name of device + * @returns int indicating DeviceType of device + */ +int IoT::typeHandler(String deviceName) { + log("typeHandler called with device name: " + deviceName); + + Device *device = _devices->getDeviceWithName(deviceName); + if(device==NULL) { + return -1; + } + return static_cast(device->type()); +} diff --git a/Photon/IoTlib/src/IoT.h b/Photon/IoTlib/src/IoT.h index d31c2142..985407d2 100644 --- a/Photon/IoTlib/src/IoT.h +++ b/Photon/IoTlib/src/IoT.h @@ -16,6 +16,7 @@ BSD license, check LICENSE for more information. All text above must be included in any redistribution. Changelog: +2018-01-17: Add functions for device state and type 2017-10-22: Convert to scene-like behavior 2017-05-15: Make devices generic 2017-03-24: Rename Patriot @@ -104,4 +105,7 @@ class IoT { void buildSupportedActivitiesVariable(); void performActivities(); //TODO: To be deprecated + int programHandler(String command); + int valueHandler(String deviceName); + int typeHandler(String deviceName); }; diff --git a/Photon/IoTlib/src/behaviors.cpp b/Photon/IoTlib/src/behaviors.cpp index 9291f5b8..f3c55f5a 100644 --- a/Photon/IoTlib/src/behaviors.cpp +++ b/Photon/IoTlib/src/behaviors.cpp @@ -6,11 +6,6 @@ A Behavior object describes the response of a device to received "activity notifications". Activities are received via Particle.io Pub/Sub. -TODO: -1. persist behaviors to EEPROM - - Photon has 2k EEPROM (actually, flash working like EEPROM) - - So can hold 128 x 16 byte activity structures per device - http://www.github.com/rlisle/Patriot Written by Ron Lisle @@ -48,7 +43,6 @@ int Behaviors::addBehavior(Behavior *behavior) IoT::log("Max # behaviors exceeded"); return -1; } - //TODO: Write out all behaviors to EEPROM return _numBehaviors - 1; } @@ -56,8 +50,6 @@ int Behaviors::addBehavior(Behavior *behavior) void Behaviors::performActivity(String name, int value) { - Serial.println("Behaviors performing activity "+name+" = "+String(value)); - for (int i = 0; i < _numBehaviors; i++) { Behavior *behavior = _behaviors[i]; diff --git a/Photon/IoTlib/src/device.h b/Photon/IoTlib/src/device.h index 01ecb516..17a8bf14 100644 --- a/Photon/IoTlib/src/device.h +++ b/Photon/IoTlib/src/device.h @@ -12,6 +12,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-17: Add function for device type 2017-10-27: V2.0.0 2017-05-20: Provide default implementations for everything, so this class is not abstract anymore. @@ -23,17 +24,32 @@ All text above must be included in any redistribution. ******************************************************************/ #pragma once +enum class DeviceType { + Unknown, + Fan, + Light, + Motor, + NCD8Relay, + Presence, + Relay, + Switch, + TempHumidity, + Ultrasonic +}; + class Device { protected: - String _name; - int _percent; + String _name; + DeviceType _type; + int _percent; public: // Note: refer to http://www.learncpp.com/cpp-tutorial/114-constructors-and-initialization-of-derived-classes/ // for an explanation of how derived constructor member initialization works. - Device(String name = "") : _name(name) { }; + Device(String name = "", DeviceType type = DeviceType::Unknown) : _name(name), _type(type) { } virtual String name() { return _name; }; + virtual DeviceType type() { return _type; }; // This method can either read the device directly, or use a value // set in the loop() if continuous or asynchronous polling is used. diff --git a/Photon/IoTlib/upload.sh b/Photon/IoTlib/upload.sh new file mode 100755 index 00000000..35246f0c --- /dev/null +++ b/Photon/IoTlib/upload.sh @@ -0,0 +1,3 @@ +# Upload IoT library +# Be sure to increment version number befor uploading +particle library upload diff --git a/Photon/Plugins/DHT/library.properties b/Photon/Plugins/DHT/library.properties index 44bd8acf..1c5677ea 100644 --- a/Photon/Plugins/DHT/library.properties +++ b/Photon/Plugins/DHT/library.properties @@ -1,5 +1,5 @@ name=PatriotDHT -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support DHT11 / DHT22 sensors. diff --git a/Photon/Plugins/DHT/src/PatriotDHT.cpp b/Photon/Plugins/DHT/src/PatriotDHT.cpp index c2a0db59..4fbcc953 100644 --- a/Photon/Plugins/DHT/src/PatriotDHT.cpp +++ b/Photon/Plugins/DHT/src/PatriotDHT.cpp @@ -16,6 +16,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add name and type properties 2017-05-20: Convert to plugin 2017-03-24: Rename Patriot 2017-03-05: Convert to v2 particle library @@ -40,7 +41,8 @@ extern String publishNameVariable; /** * Constructor. */ -DHT::DHT(int pin, int type) +DHT::DHT(int pin, String name, int type) + : Device(name, DeviceType::TempHumidity) { lastLoopTime = 0; interval = kDefaultInterval; diff --git a/Photon/Plugins/Fan/library.properties b/Photon/Plugins/Fan/library.properties index 299cba71..f4fc09d1 100644 --- a/Photon/Plugins/Fan/library.properties +++ b/Photon/Plugins/Fan/library.properties @@ -1,5 +1,5 @@ name=PatriotFan -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support fans. diff --git a/Photon/Plugins/Fan/src/PatriotFan.cpp b/Photon/Plugins/Fan/src/PatriotFan.cpp index 7daec7ff..befe2fc9 100644 --- a/Photon/Plugins/Fan/src/PatriotFan.cpp +++ b/Photon/Plugins/Fan/src/PatriotFan.cpp @@ -16,6 +16,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add type property 2017-10-28: Convert to v2. 2017-05-20: Convert to Patriot plugin library 2017-03-24: Rename Patriot @@ -32,7 +33,7 @@ All text above must be included in any redistribution. * @param name String name used to address the fan. */ Fan::Fan(int pinNum, String name) - : Device(name) + : Device(name, DeviceType::Fan) { _pinNum = pinNum; _percent = 0; diff --git a/Photon/Plugins/Light/library.properties b/Photon/Plugins/Light/library.properties index 2eeee3ef..e6c749ae 100644 --- a/Photon/Plugins/Light/library.properties +++ b/Photon/Plugins/Light/library.properties @@ -1,5 +1,5 @@ name=PatriotLight -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support lights. diff --git a/Photon/Plugins/Light/src/PatriotLight.cpp b/Photon/Plugins/Light/src/PatriotLight.cpp index 54eab557..1e712d49 100644 --- a/Photon/Plugins/Light/src/PatriotLight.cpp +++ b/Photon/Plugins/Light/src/PatriotLight.cpp @@ -33,7 +33,7 @@ * @param forceDigital True if output On/Off only (even if pin supports PWM) */ Light::Light(int pinNum, String name, bool isInverted, bool forceDigital) - : Device(name), + : Device(name, DeviceType::Light), _pin(pinNum), _isInverted(isInverted), _forceDigital(forceDigital) @@ -49,7 +49,6 @@ Light::Light(int pinNum, String name, bool isInverted, bool forceDigital) outputPWM(); // Set initial off state } - /** * Set percent * @param percent Int 0 to 100 diff --git a/Photon/Plugins/Motorized/library.properties b/Photon/Plugins/Motorized/library.properties index a6f63005..9e336614 100644 --- a/Photon/Plugins/Motorized/library.properties +++ b/Photon/Plugins/Motorized/library.properties @@ -1,5 +1,5 @@ name=PatriotMotorized -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support motorized devices. diff --git a/Photon/Plugins/Motorized/src/PatriotMotorized.cpp b/Photon/Plugins/Motorized/src/PatriotMotorized.cpp index 0a96990d..20eb27f6 100644 --- a/Photon/Plugins/Motorized/src/PatriotMotorized.cpp +++ b/Photon/Plugins/Motorized/src/PatriotMotorized.cpp @@ -23,6 +23,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add type property 2017-10-28: Convert to v2. 2017-10-08: Add pulse mode 2017-09-17: Initial version based on fan plugin. @@ -38,7 +39,7 @@ All text above must be included in any redistribution. * @param name String name used to address this device. */ Motorized::Motorized(int8_t openPinNum, int8_t closePinNum, int8_t duration, String name) - : Device(name) + : Device(name, DeviceType::Motor) { _openPinNum = openPinNum; _closePinNum = closePinNum; diff --git a/Photon/Plugins/NCD8Relay/library.properties b/Photon/Plugins/NCD8Relay/library.properties index 6f5d2ede..d02a8899 100644 --- a/Photon/Plugins/NCD8Relay/library.properties +++ b/Photon/Plugins/NCD8Relay/library.properties @@ -1,5 +1,5 @@ name=PatriotNCD8Relay -version=2.0.2 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support NCD 8 Relay board diff --git a/Photon/Plugins/NCD8Relay/src/PatriotNCD8Relay.cpp b/Photon/Plugins/NCD8Relay/src/PatriotNCD8Relay.cpp index dfffb050..1ec58b4f 100644 --- a/Photon/Plugins/NCD8Relay/src/PatriotNCD8Relay.cpp +++ b/Photon/Plugins/NCD8Relay/src/PatriotNCD8Relay.cpp @@ -19,6 +19,7 @@ Datasheets: Changelog: + 2018-01-18: Add type property 2017-12-03: Add retry. 2017-10-03: Initial creation ******************************************************************/ @@ -40,7 +41,7 @@ int8_t NCD8Relay::_addresses[8]; // Addresses of up to 8 boards * @param duration Optional seconds value to automatically turn off relay. 0 = no automatic turn off. */ NCD8Relay::NCD8Relay(int8_t address, int8_t numRelays, int8_t relayNum, String name, int8_t duration) - : Device(name) + : Device(name, DeviceType::NCD8Relay) { _relayNum = relayNum; _percent = 0; diff --git a/Photon/Plugins/Relay/library.properties b/Photon/Plugins/Relay/library.properties index 89b797f7..1156c629 100644 --- a/Photon/Plugins/Relay/library.properties +++ b/Photon/Plugins/Relay/library.properties @@ -1,5 +1,5 @@ name=PatriotRelay -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support a relay connected to a GPIO. diff --git a/Photon/Plugins/Relay/src/PatriotRelay.cpp b/Photon/Plugins/Relay/src/PatriotRelay.cpp index 20e66257..1b9ba631 100644 --- a/Photon/Plugins/Relay/src/PatriotRelay.cpp +++ b/Photon/Plugins/Relay/src/PatriotRelay.cpp @@ -13,6 +13,7 @@ All text above must be included in any redistribution. Changelog: + 2018-01-18: Add type property 2017-10-31: Initial creation ******************************************************************/ @@ -27,7 +28,7 @@ * @param duration is an optional automatic turn off duration in seconds. */ Relay::Relay(int8_t pinNum, String name, int8_t duration) - : Device(name) + : Device(name, DeviceType::Relay) { _pinNum = pinNum; _duration = duration; diff --git a/Photon/Plugins/Switch/library.properties b/Photon/Plugins/Switch/library.properties index 7997037b..261ad22d 100644 --- a/Photon/Plugins/Switch/library.properties +++ b/Photon/Plugins/Switch/library.properties @@ -1,5 +1,5 @@ name=PatriotSwitch -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support switches. diff --git a/Photon/Plugins/Switch/src/PatriotSwitch.cpp b/Photon/Plugins/Switch/src/PatriotSwitch.cpp index 2b3298d9..44f9f8ce 100644 --- a/Photon/Plugins/Switch/src/PatriotSwitch.cpp +++ b/Photon/Plugins/Switch/src/PatriotSwitch.cpp @@ -12,6 +12,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add type property 2017-10-27: v2.0.0. Change name to command. 2017-05-17: Move to separate library 2017-05-15: Make devices generic @@ -34,9 +35,10 @@ extern String publishNameVariable; * @param pinNum int pin number that is connected to the switch * @param name String name of the event to send when switch changes */ -Switch::Switch(int pinNum, String command) - : _pin(pinNum), - _command(command) +Switch::Switch(int pinNum, String name, String command) + : Device(name, DeviceType::Switch), + _pin(pinNum), + _command(command) { _percent = 0; pinMode(pinNum, INPUT_PULLUP); diff --git a/Photon/Plugins/Ultrasonic/library.properties b/Photon/Plugins/Ultrasonic/library.properties index 49264fa4..252056db 100644 --- a/Photon/Plugins/Ultrasonic/library.properties +++ b/Photon/Plugins/Ultrasonic/library.properties @@ -1,5 +1,5 @@ name=PatriotUltrasonic -version=2.0.0 +version=2.1.0 author=Ron Lisle license=BSD sentence=Extend Patriot IoT to support ultrasonic proximity detectors. diff --git a/Photon/Plugins/Ultrasonic/src/PatriotUltrasonic.cpp b/Photon/Plugins/Ultrasonic/src/PatriotUltrasonic.cpp index 4ad21fd0..609d4e4a 100644 --- a/Photon/Plugins/Ultrasonic/src/PatriotUltrasonic.cpp +++ b/Photon/Plugins/Ultrasonic/src/PatriotUltrasonic.cpp @@ -12,6 +12,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add type property 2017-05-17: Move to separate library 2017-05-15: Make devices generic 2017-03-24: Rename Patriot @@ -27,7 +28,7 @@ All text above must be included in any redistribution. extern String publishNameVariable; Ultrasonic::Ultrasonic(int triggerPin, int echoPin, String name) - : Device(name) + : Device(name, DeviceType::Ultrasonic) { _triggerPin = triggerPin; _echoPin = echoPin; diff --git a/Photon/Plugins/presence.cpp b/Photon/Plugins/presence.cpp index 5b3449ca..f4a4cbb1 100644 --- a/Photon/Plugins/presence.cpp +++ b/Photon/Plugins/presence.cpp @@ -11,6 +11,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add name and type properties 2017-03-24: Rename Patriot 2017-03-05: Convert to v2 particle library 2017-02-04: Convert from on/off to percent @@ -19,17 +20,19 @@ All text above must be included in any redistribution. #include "application.h" #include "presence.h" #include "proximity.h" +#include "../IoTlib/src/device.h" #define kDefaultShutOffDelay 5000 // 5 seconds -Presence::Presence(int min, int max, String event, long interval) +Presence::Presence(String name, int min, int max, String event, long interval) + : Device(name, DeviceType::Presence), + _minInches(min), + _maxInches(max), + _event(event), + _interval(interval) { _isPresent = false; _lastPingTime = 0; - _minInches = min; - _maxInches = max; - _event = event; - _interval = interval; _shutOffDelay = kDefaultShutOffDelay; _lastPresentTime = 0; } diff --git a/Photon/Plugins/presence.h b/Photon/Plugins/presence.h index 17c0a062..27aee1ac 100644 --- a/Photon/Plugins/presence.h +++ b/Photon/Plugins/presence.h @@ -12,6 +12,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add name and type properties 2017-03-24: Rename Patriot 2017-03-05: Convert to v2 particle library 2016-11-25: Initial version @@ -36,7 +37,7 @@ class Presence void publishPresenceDetected(bool present); public: - Presence(int minInches, int maxInches, String event, long interval); + Presence(String name, int minInches, int maxInches, String event, long interval); bool loop(Proximity *proximity); }; diff --git a/Photon/Plugins/template/library.properties b/Photon/Plugins/template/library.properties index e01fa005..4db593f5 100644 --- a/Photon/Plugins/template/library.properties +++ b/Photon/Plugins/template/library.properties @@ -1,5 +1,5 @@ name=Patriot -version=2.0.0 +version=2.1.0 author= license= sentence=Extend Patriot IoT to support . diff --git a/Photon/Plugins/template/src/PatriotMyDevice.cpp b/Photon/Plugins/template/src/PatriotMyDevice.cpp index aa45e098..f7fc2abc 100644 --- a/Photon/Plugins/template/src/PatriotMyDevice.cpp +++ b/Photon/Plugins/template/src/PatriotMyDevice.cpp @@ -12,6 +12,7 @@ BSD license, check license.txt for more information. All text above must be included in any redistribution. Changelog: +2018-01-18: Add type property 2017-05-17: Move to separate library 2017-05-15: Make devices generic 2017-03-24: Rename Patriot @@ -34,7 +35,7 @@ extern String publishNameVariable; * @param name String name of the event to send when switch changes */ Switch::Switch(int pinNum, String name) - : Device(name), + : Device(name, DeviceType::YourDeviceType), _pin(pinNum) { pinMode(pinNum, INPUT_PULLUP);