Compare commits
No commits in common. "BUILD-18" and "master" have entirely different histories.
910 changed files with 128788 additions and 35253 deletions
17
.classpath
17
.classpath
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/dom4j-1.6.1.jar" sourcepath="C:/Users/Ziver/Documents/Programmering/Java/libs/dom4j-1.6.1/src"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/javassist.jar" sourcepath="C:/Users/Ziver/Documents/Programmering/Java/libs/javassist-3.12.GA"/>
|
||||
<classpathentry kind="lib" path="libs/junit-benchmarks-0.7.0.jar"/>
|
||||
<classpathentry kind="lib" path="libs/mysql-connector-java-5.1.36-bin.jar"/>
|
||||
<classpathentry kind="lib" path="libs/servlet-api.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/commons-fileupload-1.2.1.jar" sourcepath="C:/Users/Ziver/Documents/Programmering/Java/libs/commons/commons-fileupload-1.2.1-sources.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/commons-io-1.4.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v7.0"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="libs/sqlite-jdbc-3.7.2.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Github language stats file
|
||||
external/* linguist-vendored
|
||||
lib/* linguist-vendored
|
||||
*.css linguist-vendored
|
||||
*.js linguist-vendored
|
||||
16
.gitignore
vendored
Executable file → Normal file
16
.gitignore
vendored
Executable file → Normal file
|
|
@ -1,2 +1,14 @@
|
|||
Zutil.jar
|
||||
/build/
|
||||
# Configuration and dependencies
|
||||
/hal.conf
|
||||
/hal.db*
|
||||
/lib/zutil-*
|
||||
/recordings/
|
||||
|
||||
# Runtime files
|
||||
/screenlog.0*
|
||||
/OZW_Log.txt
|
||||
|
||||
# Build and Ide files
|
||||
build
|
||||
.gradle
|
||||
.idea
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "arduino/lib/NexaControl"]
|
||||
path = arduino/lib/NexaControl
|
||||
url = https://github.com/dcollin/NexaControl.git
|
||||
31
.project
31
.project
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ZUtil</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.jem.beaninfo.BeanInfoNature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
35
Jenkinsfile
vendored
Normal file
35
Jenkinsfile
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Jenkinsfile (Pipeline Script)
|
||||
node {
|
||||
// Configure environment
|
||||
env.JAVA_HOME = tool name: 'jdk-11'
|
||||
env.REPO_URL = "repo.koc.se/hal.git" //scm.getUserRemoteConfigs()[0].getUrl()
|
||||
env.BUILD_NAME = "BUILD-${env.BUILD_ID}"
|
||||
|
||||
|
||||
checkout scm
|
||||
|
||||
stage('Build') {
|
||||
sh './gradlew clean'
|
||||
sh './gradlew build'
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
try {
|
||||
sh './gradlew test'
|
||||
} finally {
|
||||
junit testResults: '**/build/test-results/test/*.xml'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Package') {
|
||||
sh './gradlew distZip'
|
||||
archiveArtifacts artifacts: 'build/distributions/Hal.zip', fingerprint: true
|
||||
|
||||
// Tag artifact
|
||||
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'f8e5f6c6-4adb-4ab2-bb5d-1c8535dff491',
|
||||
usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
|
||||
sh "git tag ${env.BUILD_NAME}"
|
||||
sh "git push 'https://${USERNAME}:${PASSWORD}@${env.REPO_URL}' ${env.BUILD_NAME}"
|
||||
}
|
||||
}
|
||||
}
|
||||
42
LICENSE.txt
42
LICENSE.txt
|
|
@ -1,21 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Ziver Koc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2025 Daniel Collin, Ziver Koc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
|||
104
README.md
Normal file
104
README.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# Hal
|
||||
|
||||
Hal is a home automation hub with sensor statistics with the functionality to
|
||||
share that data between friends. It has been developed to be very extensible so future
|
||||
Sensors and other input devices can be supported.
|
||||
|
||||
Features:
|
||||
- **Map**, Set up a house map with sensors and events mapped on a floorplan
|
||||
- **Triggers and Actions**, IFTTT type functionality
|
||||
- **Power;Challenge**, Sync power or sensor usage between friends to challenge each other to lower the power usage
|
||||
- **[Google Assistant Integration](plugins/hal-assistant-google/READNME.md)**
|
||||
|
||||
Currently supported devices:
|
||||
- **Network Scanner**, IP scanner to detect devices on local network
|
||||
- **NUT**, Linux UPS daemon
|
||||
- **Tellstick**, Supported devices:
|
||||
- NexaSelfLearning
|
||||
- Oregon0x1A2D
|
||||
- **Raspberry Pi**, GPIO connected sensors
|
||||
- **[Zigbee](plugins/hal-zigbee/README.md)**
|
||||
- Temperature Sensors
|
||||
- Humidity Sensors
|
||||
- Pressure Sensors
|
||||
- OnnOff Devices
|
||||
- **Google Assistant**
|
||||
- **MQTT Devices**
|
||||
|
||||
Under development (Not ready to be used yet)
|
||||
- **Z-Wave**
|
||||
|
||||
|
||||
The project is currently in alpha state, and as such things will change and break continuously.
|
||||
|
||||
### Screenshots
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Installing
|
||||
|
||||
To run the Hal server you first need to clone the git repository and then run the
|
||||
gradle command to build and run the server:
|
||||
|
||||
```
|
||||
./gradlew run
|
||||
```
|
||||
|
||||
Check `hal.conf.example` for available configuration options.
|
||||
By default, HAL server will be listening to http://localhost:8080.
|
||||
|
||||
## Running the tests
|
||||
|
||||
The current test coverage is greatly lacking, but to run the available JUnit
|
||||
test-cases run:
|
||||
|
||||
```
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
HalAbstractControlerManager
|
||||
|
|
||||
| HalAbstractController
|
||||
| |
|
||||
| | HalAbstractDevice
|
||||
| | |
|
||||
.-----------. .------------. .--------.
|
||||
| | | | | |
|
||||
| | | | ----> | Device |
|
||||
| | | | | |
|
||||
| | ----> | Controller | '--------'
|
||||
| | | | .--------.
|
||||
| | | | | |
|
||||
| Manager | | | ----> | Device |
|
||||
| | | | | |
|
||||
| | '------------' '--------'
|
||||
| | .------------. .--------.
|
||||
| | | | | |
|
||||
| | ----> | Controller | ----> | Device |
|
||||
| | | | | |
|
||||
'-----------' '------------' '--------'
|
||||
|
||||
```
|
||||
|
||||
## Authors
|
||||
|
||||
* **Daniel Collin**
|
||||
* **Ziver Koc**
|
||||
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the
|
||||
[LICENSE.txt](LICENSE.txt) file for details
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
* Tellstick, for open-sourcing their code
|
||||
35
Zutil.iml
35
Zutil.iml
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module-library" scope="TEST">
|
||||
<library name="JUnit4">
|
||||
<CLASSES>
|
||||
<root url="jar://$APPLICATION_HOME_DIR$/lib/junit-4.12.jar!/" />
|
||||
<root url="jar://$APPLICATION_HOME_DIR$/lib/hamcrest-core-1.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library name="lib">
|
||||
<CLASSES>
|
||||
<root url="file://$MODULE_DIR$/lib" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$MODULE_DIR$/lib" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
|
||||
<jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" type="SOURCES" />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
72
arduino/ArduinoTellstickDuo/ArduinoTellstickDuo.ino
Normal file
72
arduino/ArduinoTellstickDuo/ArduinoTellstickDuo.ino
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include "usart.h"
|
||||
#include "rf.h"
|
||||
#include "buffer.h"
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Timer2 interrupt in 16kHz. Samples the RF Rx data pin
|
||||
*/
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
|
||||
if ( !IS_RADIO_RECIEVER_ON() ) { //if no Radio Rx should be performed
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t bit = RX_PIN_READ();
|
||||
|
||||
//will store "lows" on even buffer addresses and "highs" on odd buffer addresses
|
||||
if ( ( ((uintptr_t)bufferWriteP) & 0x1 ) != bit ) { //compare the bit and the buffer pointer address. true if one is odd and one is even.
|
||||
//step the buffer pointer
|
||||
if ( bufferWriteP+1 > RF_rxBufferEndP ) {
|
||||
*RF_rxBufferStartP = 1; //reset the next data point before going there
|
||||
bufferWriteP = RF_rxBufferStartP;
|
||||
} else {
|
||||
*(bufferWriteP+1) = 1; //reset the next data point before going there
|
||||
++bufferWriteP;
|
||||
}
|
||||
} else {
|
||||
if ( *bufferWriteP < 255 ) { //Do not step the value if it already is 255 (max value)
|
||||
++(*bufferWriteP); //step the buffer value
|
||||
}
|
||||
}
|
||||
|
||||
};//end timer2 interrupt
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
setupPins();
|
||||
|
||||
//setup timer2 interrupt at 16kHz for RF sampling
|
||||
cli(); //stop interrupts
|
||||
TCCR2A = 0; // set entire TCCR2A register to 0
|
||||
TCCR2B = 0; // same for TCCR2B
|
||||
TCNT2 = 0; //initialize counter value to 0
|
||||
OCR2A = 124; // = ( (16000000Hz) / (16000Hz*8prescaler) ) - 1 (must be <256)
|
||||
TCCR2A |= (1 << WGM21); // turn on CTC mode
|
||||
TCCR2B |= (1 << CS21); // Set CS21 bit for 8 prescaler
|
||||
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt
|
||||
sei(); //allow interrupts
|
||||
|
||||
//reset buffer just to be sure
|
||||
for (uint8_t* p = RF_rxBufferStartP; p <= RF_rxBufferEndP; ++p) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
Serial.println(F("+V2"));
|
||||
|
||||
ACTIVATE_RADIO_RECEIVER();
|
||||
|
||||
};//end setup
|
||||
|
||||
void loop() {
|
||||
|
||||
//Receive and execute command over serial
|
||||
parseSerialForCommand();
|
||||
|
||||
//Receive signal over air and send it over serial
|
||||
parseRadioRXBuffer();
|
||||
|
||||
};//end loop
|
||||
115
arduino/ArduinoTellstickDuo/archtech.cpp
Normal file
115
arduino/ArduinoTellstickDuo/archtech.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include "archtech.h"
|
||||
#include "buffer.h"
|
||||
|
||||
/*******************************************************************************
|
||||
--ARCHTECH PROTOCOL SPECIFICATION--
|
||||
|
||||
----SIGNAL----
|
||||
A signal consists of a PREAMBLE, DATA and an POSTAMBLE.
|
||||
Each signal is sent 4 times in a row to increase the delivery success rate.
|
||||
|
||||
----PREAMBLE----
|
||||
send high for 250 microseconds
|
||||
send low for 2,500 microseconds
|
||||
|
||||
----DATA----
|
||||
26 bits of transmitter id
|
||||
1 bit indicating if the on/off bit is targeting a group
|
||||
1 bit indicating "on" or "off"
|
||||
4 bits indicating the targeted unit/channel/device
|
||||
4 bits indicating a absolute dim level (optional)
|
||||
|
||||
Total: 32 or 36 bits depending if absolute dimming is used
|
||||
|
||||
Each real bit in the data field is sent over air as a pair of two inverted bits.
|
||||
real bit bits over air
|
||||
1 = "10"
|
||||
0 = "01"
|
||||
|
||||
Over air a "1"(one) is sent as:
|
||||
send high for 250 microseconds
|
||||
send low for 1,250 microseconds
|
||||
|
||||
Over air a "0"(zero) is sent as:
|
||||
send high for 250 microseconds
|
||||
send low for 250 microseconds
|
||||
|
||||
----POSTAMBLE----
|
||||
send high for 250 microseconds
|
||||
send low for 10,000 microseconds
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#define ARCHTECH_SHORT_MIN 2
|
||||
#define ARCHTECH_SHORT_MAX 7
|
||||
#define ARCHTECH_LONG_MIN 17
|
||||
#define ARCHTECH_LONG_MAX 27
|
||||
#define ARCHTECH_PREAMP_MIN 40
|
||||
#define ARCHTECH_PREAMP_MAX 48
|
||||
|
||||
#define IS_SHORT(b) ( ARCHTECH_SHORT_MIN <= b && b <= ARCHTECH_SHORT_MAX )
|
||||
#define IS_LONG(b) ( ARCHTECH_LONG_MIN <= b && b <= ARCHTECH_LONG_MAX )
|
||||
#define IS_PREAMP_LONG(b) ( ARCHTECH_PREAMP_MIN <= b && b <= ARCHTECH_PREAMP_MAX )
|
||||
|
||||
#define IS_ONE(b1,b2,b3,b4) ( IS_SHORT(b1) && IS_LONG(b2) && IS_SHORT(b3) && IS_SHORT(b4) )
|
||||
#define IS_ZERO(b1,b2,b3,b4) ( IS_SHORT(b1) && IS_SHORT(b2) && IS_SHORT(b3) && IS_LONG(b4) )
|
||||
#define IS_PREAMP(b1,b2) ( IS_SHORT(b1) && IS_PREAMP_LONG(b2) )
|
||||
|
||||
bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP) { //start points to a "high" buffer byte, end points to a "low" buffer byte
|
||||
uint64_t data = 0;
|
||||
bool dimValuePresent;
|
||||
uint8_t b1,b2,b3,b4;
|
||||
|
||||
//parse preamp
|
||||
|
||||
b1 = *bufStartP;
|
||||
stepBufferPointer(&bufStartP);
|
||||
b2 = *bufStartP;
|
||||
stepBufferPointer(&bufStartP);
|
||||
if (!IS_PREAMP(b1, b2)){
|
||||
return false;
|
||||
}
|
||||
|
||||
//parse data
|
||||
|
||||
uint16_t dataBitsInBuffer = (calculateBufferPointerDistance(bufStartP, bufEndP)-2) / 4; //each bit is representd by 4 high/low
|
||||
if (dataBitsInBuffer == 32) {
|
||||
dimValuePresent = false;
|
||||
} else if (dataBitsInBuffer == 36){
|
||||
dimValuePresent = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < dataBitsInBuffer; ++i) {
|
||||
b1 = *bufStartP; //no of high
|
||||
stepBufferPointer(&bufStartP);
|
||||
b2 = *bufStartP; //no of low
|
||||
stepBufferPointer(&bufStartP);
|
||||
b3 = *bufStartP; //no of high
|
||||
stepBufferPointer(&bufStartP);
|
||||
b4 = *bufStartP; //no of low
|
||||
stepBufferPointer(&bufStartP);
|
||||
|
||||
if (IS_ONE(b1,b2,b3,b4)) { //"one" is sent over air
|
||||
data <<= 1; //shift in a zero
|
||||
data |= 0x1; //add one
|
||||
} else if (IS_ZERO(b1,b2,b3,b4)) { //"zero" is sent over air
|
||||
data <<= 1; //shift in a zero
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//data parsed - send event over serial
|
||||
|
||||
Serial.print(F("+Wclass:command;protocol:arctech;model:selflearning;data:0x"));
|
||||
uint8_t hexToSend = (dimValuePresent ? 9 : 8);
|
||||
for (int8_t i = hexToSend - 1; i >= 0; --i) {
|
||||
Serial.print( (byte)((data >> (4 * i)) & 0x0F), HEX);
|
||||
}
|
||||
Serial.println(F(";"));
|
||||
|
||||
return true;
|
||||
}; //end parseArctechSelfLearning
|
||||
8
arduino/ArduinoTellstickDuo/archtech.h
Normal file
8
arduino/ArduinoTellstickDuo/archtech.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef ARCHTECH_H
|
||||
#define ARCHTECH_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP);
|
||||
|
||||
#endif //ARCHTECH_H
|
||||
6
arduino/ArduinoTellstickDuo/buffer.cpp
Normal file
6
arduino/ArduinoTellstickDuo/buffer.cpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "buffer.h"
|
||||
|
||||
uint8_t RF_rxBuffer[512]; //must have and even number of elements
|
||||
uint8_t* RF_rxBufferStartP = &RF_rxBuffer[0];
|
||||
uint8_t* RF_rxBufferEndP = &RF_rxBuffer[511];
|
||||
volatile uint8_t* bufferWriteP = RF_rxBufferStartP;
|
||||
31
arduino/ArduinoTellstickDuo/buffer.h
Normal file
31
arduino/ArduinoTellstickDuo/buffer.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
extern uint8_t RF_rxBuffer[512]; //must have and even number of elements
|
||||
extern uint8_t* RF_rxBufferStartP;
|
||||
extern uint8_t* RF_rxBufferEndP;
|
||||
extern volatile uint8_t* bufferWriteP;
|
||||
|
||||
inline uint16_t calculateBufferPointerDistance(uint8_t* bufStartP, uint8_t* bufEndP) {
|
||||
if (bufStartP <= bufEndP) {
|
||||
return bufEndP - bufStartP + 1;
|
||||
} else {
|
||||
return (RF_rxBufferEndP - bufStartP) + (bufEndP - RF_rxBufferStartP) + 2;
|
||||
}
|
||||
}; //end calculateBufferPointerDistance
|
||||
|
||||
inline uint8_t* getNextBufferPointer(uint8_t* p) {
|
||||
if ( p + 1 > RF_rxBufferEndP) {
|
||||
return RF_rxBufferStartP;
|
||||
} else {
|
||||
return p + 1;
|
||||
}
|
||||
}; //end getNextBufferPointer
|
||||
|
||||
inline void stepBufferPointer(uint8_t** p) {
|
||||
*p = getNextBufferPointer(*p);
|
||||
}; //end stepBufferPointer
|
||||
|
||||
#endif //BUFFER_H
|
||||
25
arduino/ArduinoTellstickDuo/config.h
Normal file
25
arduino/ArduinoTellstickDuo/config.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
/*
|
||||
* RX PIN = 7
|
||||
* TX PIN = 8
|
||||
*/
|
||||
inline void setupPins(){
|
||||
pinMode(7, INPUT);
|
||||
pinMode(8, OUTPUT);
|
||||
};
|
||||
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
|
||||
//pin7 = PD7 = port D, bit 8
|
||||
#define RX_PIN_READ() ( digitalRead(7) ) // optimized "digitalRead(7)"
|
||||
//pin8 = PB0 = port B, bit 1
|
||||
#define TX_PIN_LOW() ( PORTB &= 0b01111111 ) // optimized "digitalWrite(8, LOW)"
|
||||
#define TX_PIN_HIGH() ( PORTB |= 0b10000000 ) // optimized "digitalWrite(8, HIGH)"
|
||||
#else
|
||||
#unsupported architecture
|
||||
#endif
|
||||
|
||||
#endif //CONFIG_H
|
||||
210
arduino/ArduinoTellstickDuo/oregonV2.1.cpp
Normal file
210
arduino/ArduinoTellstickDuo/oregonV2.1.cpp
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
#include "oregonV2.1.h"
|
||||
#include "buffer.h"
|
||||
|
||||
/*******************************************************************************
|
||||
--OREGON v2.1 PROTOCOL SPECIFICATION--
|
||||
|
||||
----SIGNAL----
|
||||
A signal consists of a PREAMBLE, DATA and an POSTAMBLE.
|
||||
Each signal is sent 2 times in a row to increase the delivery success rate.
|
||||
Between the two times there is a "low" pause of 8192us.
|
||||
|
||||
----PREAMBLE----
|
||||
send 16 "1"(ones) over the air
|
||||
|
||||
----DATA----
|
||||
16 bits of sensor type
|
||||
XX bits of data (where XX <= 64)
|
||||
|
||||
The length XX depends on the sensor type. I.e. 0x1A2D => XX=56
|
||||
|
||||
Over air a "1"(one) is sent as:
|
||||
send high for 512 microseconds
|
||||
send low for 1024 microseconds
|
||||
send high for 512 microseconds
|
||||
|
||||
Over air a "0"(zero) is sent as:
|
||||
send low for 512 microseconds
|
||||
send high for 1024 microseconds
|
||||
send low for 512 microseconds
|
||||
|
||||
----POSTAMBLE----
|
||||
send 8 "0"(zeros) over the air
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#define SMALL_PULSE(x) ( 4<=x && x<=13 )
|
||||
#define BIG_PULSE(x) ( 12<=x && x<=22 )
|
||||
#define MORE_DATA_NEEDED -1
|
||||
#define INVALID_DATA -2
|
||||
|
||||
enum {
|
||||
PARSE_PREAMP = 0,
|
||||
PARSE_ID,
|
||||
PARSE_DATA
|
||||
} static state = PARSE_PREAMP;
|
||||
|
||||
static uint8_t byteCnt = 0;
|
||||
static uint8_t bitCnt = 0;
|
||||
static uint8_t totByteCnt = 0;
|
||||
int8_t byteLength = -1;
|
||||
|
||||
void reset() {
|
||||
byteCnt = 0;
|
||||
bitCnt = 0;
|
||||
totByteCnt = 0;
|
||||
state = PARSE_PREAMP;
|
||||
byteLength = -1;
|
||||
}; //end reset
|
||||
|
||||
void parseOregonStream(bool level, uint8_t count) {
|
||||
static uint8_t cnt = 0; //used for counting stuff independent in every state
|
||||
static uint16_t sensorType = 0;
|
||||
static int8_t byte;
|
||||
static uint8_t bytesToParse = 0; //the number of bytes left in the data part to parse
|
||||
static uint8_t buffer[8];
|
||||
|
||||
if (level) {
|
||||
count+=3;
|
||||
} else {
|
||||
count-=3;
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
case PARSE_PREAMP: //look for 25 big pulses followed by one short in a row
|
||||
if (BIG_PULSE(count)) {
|
||||
++cnt;
|
||||
break;
|
||||
}
|
||||
if (SMALL_PULSE(count)) {
|
||||
if (cnt > 25) {
|
||||
state=PARSE_ID;
|
||||
sensorType = 0;
|
||||
}
|
||||
cnt = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case PARSE_ID: //get the two first Bytes
|
||||
byte = getByte(level, count);
|
||||
if (byte == INVALID_DATA) {
|
||||
reset();
|
||||
cnt = 0;
|
||||
break;
|
||||
} else if (byte == MORE_DATA_NEEDED) {
|
||||
break;
|
||||
} else {
|
||||
if (sensorType == 0) {
|
||||
sensorType = byte << 8;
|
||||
} else {
|
||||
sensorType |= byte;
|
||||
switch (sensorType) {
|
||||
case 0xEA4C:
|
||||
bytesToParse = 5;
|
||||
byteLength = 63;
|
||||
break;
|
||||
case 0x0A4D:
|
||||
case 0x1A2D: //sensor THGR2228N (channel + sensor_id + battery_level + temp + humidity + checksum)
|
||||
bytesToParse = 7;
|
||||
byteLength = 79;
|
||||
break;
|
||||
default:
|
||||
reset();
|
||||
cnt = 0;
|
||||
return;
|
||||
}
|
||||
state = PARSE_DATA;
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PARSE_DATA: //get the remaining data
|
||||
byte = getByte(level, count);
|
||||
if (byte == INVALID_DATA) {
|
||||
reset();
|
||||
cnt = 0;
|
||||
break;
|
||||
} else if (byte == MORE_DATA_NEEDED) {
|
||||
break;
|
||||
}
|
||||
buffer[cnt] = byte;
|
||||
++cnt;
|
||||
if (bytesToParse == 0) {
|
||||
Serial.print(F("+Wclass:sensor;protocol:oregon;model:0x"));
|
||||
Serial.print(sensorType, HEX);
|
||||
Serial.print(F(";data:0x"));
|
||||
for (int8_t i = 0; i < cnt; ++i) {
|
||||
Serial.print(buffer[i], HEX);
|
||||
}
|
||||
Serial.println(F(";"));
|
||||
reset();
|
||||
cnt = 0;
|
||||
}
|
||||
--bytesToParse;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}; //end parseOregonStream
|
||||
|
||||
int8_t getByte(bool level, uint8_t count) {
|
||||
int8_t bit = getBit(level, count);
|
||||
static uint8_t byte = 0;
|
||||
|
||||
if (bit == INVALID_DATA) {
|
||||
return INVALID_DATA;
|
||||
} else if (bit == MORE_DATA_NEEDED) {
|
||||
return MORE_DATA_NEEDED;
|
||||
}
|
||||
byte >>= 1;
|
||||
if (bit) {
|
||||
byte |= (1<<7);
|
||||
}
|
||||
++totByteCnt;
|
||||
++byteCnt;
|
||||
if (byteCnt < 8) {
|
||||
return MORE_DATA_NEEDED;
|
||||
}
|
||||
byteCnt=0;
|
||||
return byte;
|
||||
}; //end getByte
|
||||
|
||||
int8_t getBit(bool level, uint8_t count) {
|
||||
static bool bit = 0;
|
||||
|
||||
if (bitCnt == 0) {
|
||||
//First pulse must be small
|
||||
if (!SMALL_PULSE(count)) {
|
||||
return INVALID_DATA;
|
||||
}
|
||||
bitCnt = 1;
|
||||
|
||||
} else if (bitCnt == 1) {
|
||||
//Second pulse must be long
|
||||
if (!BIG_PULSE(count) && totByteCnt!=byteLength){ //special check - last byte might have strange values
|
||||
bitCnt = 0;
|
||||
return INVALID_DATA;
|
||||
}
|
||||
|
||||
bit = level;
|
||||
bitCnt = 2;
|
||||
return bit;
|
||||
|
||||
} else if (bitCnt == 2) {
|
||||
//Prepare for next bit
|
||||
if (level && SMALL_PULSE(count)) {
|
||||
//Clean start
|
||||
bitCnt = 0;
|
||||
} else if (BIG_PULSE(count)) {
|
||||
//Combined bit
|
||||
bitCnt = 1;
|
||||
} else if (SMALL_PULSE(count)) {
|
||||
//Clean start
|
||||
bitCnt = 0;
|
||||
}
|
||||
return MORE_DATA_NEEDED;
|
||||
}
|
||||
|
||||
return MORE_DATA_NEEDED;
|
||||
}; //end getBit
|
||||
11
arduino/ArduinoTellstickDuo/oregonV2.1.h
Normal file
11
arduino/ArduinoTellstickDuo/oregonV2.1.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef OREGONV21_H
|
||||
#define OREGONV21_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
void reset();
|
||||
void parseOregonStream(bool level, uint8_t sampleCount);
|
||||
int8_t getByte(bool level, uint8_t count);
|
||||
int8_t getBit(bool level, uint8_t count);
|
||||
|
||||
#endif //OREGONV21_H
|
||||
127
arduino/ArduinoTellstickDuo/rf.cpp
Normal file
127
arduino/ArduinoTellstickDuo/rf.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#include "rf.h"
|
||||
#include "buffer.h"
|
||||
#include "archtech.h"
|
||||
#include "config.h"
|
||||
#include "oregonV2.1.h"
|
||||
|
||||
#define SILENCE_LENGTH 100 //the number of samples with "low" that represents a silent period between two signals
|
||||
|
||||
volatile bool RFRX = false;
|
||||
|
||||
void parseRadioRXBuffer() {
|
||||
static uint8_t* bufferReadP = RF_rxBufferStartP;
|
||||
static uint8_t* startDataP = 0; //will always point to a "high" buffer address
|
||||
static uint8_t* endDataP = 0; //will always point to a "low" buffer address
|
||||
static uint8_t prevValue = 0; //contains the value of the previous buffer index read
|
||||
|
||||
bool parse = false;
|
||||
while (bufferReadP != bufferWriteP) { //stop if the read pointer is pointing to where the writing is currently performed
|
||||
uint8_t sampleCount = *bufferReadP;
|
||||
|
||||
if ( (((uintptr_t)bufferReadP) & 0x1) == 1 ) { //buffer pointer is odd (stores highs)
|
||||
//Serial.print("high:"); Serial.println(sampleCount);
|
||||
if (prevValue >= SILENCE_LENGTH) {
|
||||
startDataP = bufferReadP; //some new data must start here since this is the first "high" after a silent period
|
||||
}
|
||||
|
||||
//stream data to stream parsers
|
||||
parseOregonStream(HIGH, sampleCount);
|
||||
|
||||
} else { //buffer pointer is even (stores lows)
|
||||
//Serial.print("low:"); Serial.println(sampleCount);
|
||||
if (sampleCount >= SILENCE_LENGTH) { //evaluate if it is time to parse the curernt data
|
||||
endDataP = bufferReadP; //this is a silient period and must be the end of a data
|
||||
if (startDataP != 0){
|
||||
parse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//stream data to stream parsers
|
||||
parseOregonStream(LOW, sampleCount);
|
||||
|
||||
}
|
||||
|
||||
//step the read pointer one step
|
||||
uint8_t* nextBufferReadP = getNextBufferPointer(bufferReadP);
|
||||
if (nextBufferReadP == startDataP) { //next pointer will point to startDataP. Data will overflow. Reset the data pointers.
|
||||
startDataP = 0;
|
||||
endDataP = 0;
|
||||
prevValue = 0;
|
||||
}
|
||||
|
||||
//advance buffer pointer one step
|
||||
bufferReadP = nextBufferReadP;
|
||||
|
||||
prevValue = sampleCount; //update previous value
|
||||
}
|
||||
|
||||
if (!parse) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (startDataP == 0 || endDataP == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point the startDataP will point to the first high after a silent period
|
||||
* and the endDataP will point at the first (low) silent period after the data data start.
|
||||
*/
|
||||
|
||||
//Serial.print((uintptr_t)startDataP); Serial.print(" - "); Serial.println((uintptr_t)endDataP);
|
||||
|
||||
//Let all available parsers parse the data set now.
|
||||
parseArctechSelfLearning(startDataP, endDataP);
|
||||
//TODO: add more parsers here
|
||||
|
||||
//reset the data pointers since the data have been parsed at this point
|
||||
startDataP = 0;
|
||||
endDataP = 0;
|
||||
|
||||
}; //end radioTask
|
||||
|
||||
void sendTCodedData(uint8_t* data, uint8_t T_long, uint8_t* timings, uint8_t repeat, uint8_t pause) {
|
||||
ACTIVATE_RADIO_TRANSMITTER();
|
||||
for (uint8_t rep = 0; rep < repeat; ++rep) {
|
||||
bool nextPinState = HIGH;
|
||||
for (int i = 0; i < T_long; ++i) {
|
||||
uint8_t timeIndex = (data[i / 4] >> (6 - (2 * (i % 4)))) & 0x03;
|
||||
if (timings[timeIndex] > 0 || i == T_long - 1) {
|
||||
if (nextPinState){
|
||||
TX_PIN_HIGH();
|
||||
}else{
|
||||
TX_PIN_LOW();
|
||||
}
|
||||
delayMicroseconds(10 * timings[timeIndex]);
|
||||
}
|
||||
nextPinState = !nextPinState;
|
||||
}
|
||||
TX_PIN_LOW();
|
||||
if (rep < repeat - 1) {
|
||||
delay(pause);
|
||||
}
|
||||
}
|
||||
ACTIVATE_RADIO_RECEIVER();
|
||||
};
|
||||
|
||||
void sendSCodedData(uint8_t* data, uint8_t pulseCount, uint8_t repeat, uint8_t pause) {
|
||||
ACTIVATE_RADIO_TRANSMITTER();
|
||||
for (uint8_t rep = 0; rep < repeat; ++rep) {
|
||||
bool nextPinState = HIGH;
|
||||
for (int i = 0; i < pulseCount; ++i) {
|
||||
if (data[i] > 0 || i == pulseCount - 1) {
|
||||
if (nextPinState){
|
||||
TX_PIN_HIGH();
|
||||
}else{
|
||||
TX_PIN_LOW();
|
||||
}
|
||||
delayMicroseconds(data[i] * 10);
|
||||
}
|
||||
nextPinState = !nextPinState;
|
||||
}
|
||||
delay(pause);
|
||||
}
|
||||
TX_PIN_LOW();
|
||||
ACTIVATE_RADIO_RECEIVER();
|
||||
};
|
||||
17
arduino/ArduinoTellstickDuo/rf.h
Normal file
17
arduino/ArduinoTellstickDuo/rf.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef RF_H
|
||||
#define RF_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define ACTIVATE_RADIO_RECEIVER() (RFRX = true)
|
||||
#define ACTIVATE_RADIO_TRANSMITTER() (RFRX = false)
|
||||
#define IS_RADIO_RECIEVER_ON() (RFRX)
|
||||
#define IS_RADIO_TRANSMITTER_ON() (!RFRX)
|
||||
|
||||
extern volatile bool RFRX;
|
||||
|
||||
void parseRadioRXBuffer();
|
||||
void sendTCodedData(uint8_t* data, uint8_t T_long, uint8_t* timings, uint8_t repeat, uint8_t pause);
|
||||
void sendSCodedData(uint8_t* data, uint8_t pulseCount, uint8_t repeat, uint8_t pause);
|
||||
|
||||
#endif //RF_H
|
||||
106
arduino/ArduinoTellstickDuo/usart.cpp
Normal file
106
arduino/ArduinoTellstickDuo/usart.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include "usart.h"
|
||||
#include "rf.h"
|
||||
|
||||
uint8_t Serial_rxBuffer[79];
|
||||
|
||||
void parseSerialForCommand() {
|
||||
if (Serial.available() > 0) {
|
||||
uint8_t rxDataSize = Serial.readBytesUntil('+', &Serial_rxBuffer[0], 79);
|
||||
if (rxDataSize > 0) {
|
||||
parseRxBuffer(&Serial_rxBuffer[0], 0, rxDataSize, false, 3, 0);
|
||||
}
|
||||
}
|
||||
}; //end serialTask
|
||||
|
||||
bool parseRxBuffer(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause) {
|
||||
if (startIndex > endIndex) {
|
||||
return false;
|
||||
}
|
||||
char c = buffer[startIndex];
|
||||
//Serial.print("DEBUG: char:"); Serial.println(c, DEC);
|
||||
switch (c) {
|
||||
case 'S':
|
||||
return handleSCommand(buffer, startIndex + 1, endIndex, debug, repeat, pause);
|
||||
case 'T':
|
||||
return handleTCommand(buffer, startIndex + 1, endIndex, debug, repeat, pause);
|
||||
case 'V':
|
||||
Serial.println(F("+V2"));
|
||||
return parseRxBuffer(buffer, startIndex + 1, endIndex, debug, repeat, pause);
|
||||
case 'D':
|
||||
return parseRxBuffer(buffer, startIndex + 1, endIndex, !debug, repeat, pause);
|
||||
case 'P':
|
||||
if (endIndex - startIndex + 1 < 3) {
|
||||
return false;
|
||||
} //at least {'P',[p-value],'+'} must be left in the buffer
|
||||
return parseRxBuffer(buffer, startIndex + 2, endIndex, debug, repeat, buffer[startIndex + 1]);
|
||||
case 'R':
|
||||
if (endIndex - startIndex + 1 < 3) {
|
||||
return false;
|
||||
} //at least {'R',[r-value],'+'} must be left in the buffer
|
||||
return parseRxBuffer(buffer, startIndex + 2, endIndex, debug, buffer[startIndex + 1], pause);
|
||||
case '+':
|
||||
return true;
|
||||
default:
|
||||
//Serial.print("DEBUG: unknown char: '"); Serial.print(c, BIN); Serial.println("'");
|
||||
return false;
|
||||
}
|
||||
}; //end parseRxBuffer
|
||||
|
||||
bool handleSCommand(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause) {
|
||||
//Parse message received from serial
|
||||
uint8_t S_data[78]; //78 pulses
|
||||
uint8_t pulseCount = 0;
|
||||
for (uint8_t i = startIndex; i <= endIndex; ++i) {
|
||||
if (buffer[i] == '+') {
|
||||
break;
|
||||
} else if (i == endIndex) {
|
||||
return false;
|
||||
} else {
|
||||
S_data[pulseCount++] = buffer[i];
|
||||
}
|
||||
}
|
||||
//Send message
|
||||
sendSCodedData(&S_data[0], pulseCount, repeat, pause);
|
||||
|
||||
//send confirmation over serial
|
||||
Serial.println(F("+S"));
|
||||
return true;
|
||||
}; //end handleS
|
||||
|
||||
bool handleTCommand(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause) {
|
||||
//Parse message received from serial
|
||||
uint8_t T_data[72]; //0-188 pulses
|
||||
if (endIndex - startIndex < 5) {
|
||||
//Serial.println("DEBUG: wrong size!");
|
||||
return false;
|
||||
}
|
||||
uint8_t buff_p = startIndex;
|
||||
uint8_t T_times[4] = {buffer[buff_p++], buffer[buff_p++], buffer[buff_p++], buffer[buff_p++]};
|
||||
uint8_t T_long = buffer[buff_p++];
|
||||
uint8_t T_bytes = 0;
|
||||
if ( (T_long / 4.0) > (float)(T_long / 4) ) {
|
||||
T_bytes = T_long / 4 + 1;
|
||||
} else {
|
||||
T_bytes = T_long / 4;
|
||||
}
|
||||
uint8_t j = 0;
|
||||
while (j < T_bytes) {
|
||||
if (buffer[buff_p] == '+') {
|
||||
break;
|
||||
} else if (buff_p >= endIndex) {
|
||||
return false;
|
||||
} else {
|
||||
T_data[j++] = buffer[buff_p++];
|
||||
}
|
||||
}
|
||||
if ( j != T_bytes ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Send message
|
||||
sendTCodedData(&T_data[0], T_long, &T_times[0], repeat, pause);
|
||||
|
||||
//send confirmation over serial
|
||||
Serial.println(F("+T"));
|
||||
return parseRxBuffer(buffer, buff_p, endIndex, debug, repeat, pause);
|
||||
}; //end handleT
|
||||
13
arduino/ArduinoTellstickDuo/usart.h
Normal file
13
arduino/ArduinoTellstickDuo/usart.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef USART_H
|
||||
#define USART_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
void parseSerialForCommand();
|
||||
bool parseRxBuffer(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause);
|
||||
bool handleSCommand(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause);
|
||||
bool handleTCommand(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause);
|
||||
|
||||
extern uint8_t Serial_rxBuffer[79];
|
||||
|
||||
#endif //USART_H
|
||||
31
arduino/HalMultiSensor/HalConfiguration.h
Normal file
31
arduino/HalMultiSensor/HalConfiguration.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef HALCONFIGURATION_H
|
||||
#define HALCONFIGURATION_H
|
||||
|
||||
//#define ENABLE_DEBUG // comment out to disable debug
|
||||
|
||||
|
||||
#define TIMER_MILLISECOND 60000 // poling in minutes
|
||||
#define INDICATOR_PIN 13 // diode
|
||||
#define TX_PIN 11
|
||||
#define DEVICE_BASE_ID 99
|
||||
|
||||
// POWER CONSUMPTION SENSOR
|
||||
//#define POWERCON_ENABLED // comment out to disable sensor
|
||||
#define POWERCON_SENSOR SensorPhotocell()
|
||||
#define POWERCON_PROTOCOL ProtocolOregon(TX_PIN, DEVICE_BASE_ID + 0)
|
||||
#define POWER_TIMER_MULTIPLIER 1
|
||||
|
||||
// TEMPERATURE SENSOR
|
||||
#define TEMPERATURE_ENABLED // comment out to disable sensor
|
||||
#define TEMPERATURE_SENSOR SensorDHT(DHT11, 10)
|
||||
#define TEMPERATURE_PROTOCOL ProtocolOregon(TX_PIN, DEVICE_BASE_ID + 1)
|
||||
#define TEMPERATURE_TIMER_MULTIPLIER 10
|
||||
|
||||
// LIGHT SENSOR
|
||||
//#define LIGHT_ENABLED // comment out to disable sensor
|
||||
#define LIGHT_SENSOR SensorBH1750()
|
||||
#define LIGHT_PROTOCOL ProtocolOregon(TX_PIN, DEVICE_BASE_ID + 2)
|
||||
#define LIGHT_TIMER_MULTIPLIER 10
|
||||
|
||||
|
||||
#endif // HALCONFIGURATION_H
|
||||
14
arduino/HalMultiSensor/HalInclude.h
Normal file
14
arduino/HalMultiSensor/HalInclude.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef HALDEFINITIONS_H
|
||||
#define HALDEFINITIONS_H
|
||||
|
||||
/////// SENSORS
|
||||
#include "SensorBH1750.h"
|
||||
#include "SensorDHT.h"
|
||||
#include "SensorPhotocell.h"
|
||||
|
||||
//////// PROTOCOLS
|
||||
#include "ProtocolNexa.h"
|
||||
#include "ProtocolOregon.h"
|
||||
|
||||
|
||||
#endif // HALDEFINITIONS_H
|
||||
101
arduino/HalMultiSensor/HalInterfaces.h
Normal file
101
arduino/HalMultiSensor/HalInterfaces.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef HALINTERFACES_H
|
||||
#define HALINTERFACES_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "HalConfiguration.h"
|
||||
|
||||
// Utility functions
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
#define DEBUG(msg) \
|
||||
Serial.println(msg); \
|
||||
Serial.flush();
|
||||
#define DEBUGF(msg, ...) \
|
||||
static char buffer[80];\
|
||||
snprintf(buffer, sizeof(buffer), msg, __VA_ARGS__);\
|
||||
Serial.println(buffer);\
|
||||
Serial.flush();
|
||||
#else
|
||||
#define DEBUG(msg)
|
||||
#define DEBUGF(msg, ...)
|
||||
#endif
|
||||
|
||||
|
||||
inline void pulse(short pin, short count)
|
||||
{
|
||||
while (--count >= 0)
|
||||
{
|
||||
digitalWrite(INDICATOR_PIN, HIGH);
|
||||
delay(150);
|
||||
digitalWrite(INDICATOR_PIN, LOW);
|
||||
if (count != 0) delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// INTERFACES
|
||||
|
||||
class Sensor
|
||||
{
|
||||
public:
|
||||
virtual void setup() = 0;
|
||||
};
|
||||
class Protocol
|
||||
{
|
||||
public:
|
||||
virtual void setup() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PowerData
|
||||
{
|
||||
unsigned int consumption;
|
||||
};
|
||||
class SensorPowerConsumption : public Sensor
|
||||
{
|
||||
public:
|
||||
// returns number of pulses from power meter
|
||||
virtual void read(PowerData& data) = 0;
|
||||
};
|
||||
class ProtocolPowerConsumption : public Protocol
|
||||
{
|
||||
public:
|
||||
virtual void send(const PowerData& data) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct TemperatureData
|
||||
{
|
||||
float temperature;
|
||||
float humidity;
|
||||
};
|
||||
class SensorTemperature : public Sensor
|
||||
{
|
||||
public:
|
||||
virtual void read(TemperatureData& data) = 0;
|
||||
};
|
||||
class ProtocolTemperature : public Protocol
|
||||
{
|
||||
public:
|
||||
virtual void send(const TemperatureData& data) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct LightData
|
||||
{
|
||||
unsigned int lumen;
|
||||
};
|
||||
class SensorLight : public Sensor
|
||||
{
|
||||
public:
|
||||
virtual void read(LightData& data) = 0;
|
||||
};
|
||||
class ProtocolLight : public Protocol
|
||||
{
|
||||
public:
|
||||
virtual void send(const LightData& data) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // HALINTERFACES_H
|
||||
132
arduino/HalMultiSensor/HalMultiSensor.ino
Normal file
132
arduino/HalMultiSensor/HalMultiSensor.ino
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
A interrupt based sensor device that reads multiple sensors and transmits
|
||||
the data to a central location.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "HalConfiguration.h"
|
||||
#include "HalInterfaces.h"
|
||||
#include "HalInclude.h"
|
||||
#include "Interrupt.h"
|
||||
|
||||
|
||||
#ifndef POWERCON_ENABLED
|
||||
#define POWER_TIMER_MULTIPLIER 1
|
||||
#endif
|
||||
#ifndef TEMPERATURE_ENABLED
|
||||
#define TEMPERATURE_TIMER_MULTIPLIER 1
|
||||
#endif
|
||||
#ifndef LIGHT_ENABLED
|
||||
#define LIGHT_TIMER_MULTIPLIER 1
|
||||
#endif
|
||||
#define TIMER_MULTIPLIER_MAX \
|
||||
POWER_TIMER_MULTIPLIER * TEMPERATURE_TIMER_MULTIPLIER * LIGHT_TIMER_MULTIPLIER
|
||||
unsigned int timerMultiplier = 0;
|
||||
|
||||
// Sensors
|
||||
SensorPowerConsumption* powerSensor;
|
||||
SensorTemperature* tempSensor;
|
||||
SensorLight* lightSensor;
|
||||
|
||||
// Protocols
|
||||
ProtocolPowerConsumption* powerProtocol;
|
||||
ProtocolTemperature* tempProtocol;
|
||||
ProtocolLight* lightProtocol;
|
||||
|
||||
|
||||
|
||||
void timerInterruptFunc();
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef ENABLE_DEBUG
|
||||
Serial.begin(9600);
|
||||
#endif
|
||||
pinMode(INDICATOR_PIN, OUTPUT);
|
||||
|
||||
// Setup Sensors and protocols
|
||||
#ifdef POWERCON_ENABLED
|
||||
DEBUG("Setup POWERCON_SENSOR");
|
||||
powerSensor = new POWERCON_SENSOR;
|
||||
powerSensor->setup();
|
||||
powerProtocol = new POWERCON_PROTOCOL;
|
||||
powerProtocol->setup();
|
||||
#endif
|
||||
|
||||
#ifdef TEMPERATURE_ENABLED
|
||||
DEBUG("Setup TEMPERATURE_SENSOR");
|
||||
tempSensor = new TEMPERATURE_SENSOR;
|
||||
tempSensor->setup();
|
||||
tempProtocol = new TEMPERATURE_PROTOCOL;
|
||||
tempProtocol->setup();
|
||||
#endif
|
||||
|
||||
#ifdef LIGHT_ENABLED
|
||||
DEBUG("Setup LIGHT_SENSOR");
|
||||
lightSensor = new LIGHT_SENSOR;
|
||||
lightSensor->setup();
|
||||
lightProtocol = new LIGHT_PROTOCOL;
|
||||
lightProtocol->setup();
|
||||
#endif
|
||||
|
||||
DEBUG("Setup SLEEP_INTERRUPT");
|
||||
Interrupt::setWatchDogCallback(timerInterruptFunc);
|
||||
Interrupt::setupWatchDogInterrupt(TIMER_MILLISECOND); // one minute scheduled interrupt
|
||||
|
||||
|
||||
pulse(INDICATOR_PIN, 3);
|
||||
DEBUG("Ready");
|
||||
}
|
||||
|
||||
|
||||
void timerInterruptFunc()
|
||||
{
|
||||
++timerMultiplier;
|
||||
if (timerMultiplier > TIMER_MULTIPLIER_MAX)
|
||||
timerMultiplier = 1;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
digitalWrite(INDICATOR_PIN, HIGH);
|
||||
|
||||
// Send power consumption
|
||||
#ifdef POWERCON_ENABLED
|
||||
if (timerMultiplier % POWER_TIMER_MULTIPLIER == 0)
|
||||
{
|
||||
static PowerData powerData;
|
||||
powerSensor->read(powerData); // not needed, only here for future use
|
||||
DEBUGF("Read POWERCON_SENSOR= consumption:%d", powerData.consumption);
|
||||
powerProtocol->send(powerData);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle temperature sensor
|
||||
#ifdef TEMPERATURE_ENABLED
|
||||
if (timerMultiplier % TEMPERATURE_TIMER_MULTIPLIER == 0)
|
||||
{
|
||||
static TemperatureData tempData;
|
||||
tempSensor->read(tempData);
|
||||
DEBUGF("Read TEMPERATURE_SENSOR= temperature:%d, humidity:%d", (int)tempData.temperature, (int)tempData.humidity);
|
||||
tempProtocol->send(tempData);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle light sensor
|
||||
#ifdef LIGHT_ENABLED
|
||||
if (timerMultiplier % LIGHT_TIMER_MULTIPLIER == 0)
|
||||
{
|
||||
static LightData lightData;
|
||||
lightSensor->read(lightData);
|
||||
DEBUGF("Read LIGHT_SENSOR= lumen:%d", lightData.lumen);
|
||||
lightProtocol->send(lightData);
|
||||
}
|
||||
#endif
|
||||
|
||||
digitalWrite(INDICATOR_PIN, LOW);
|
||||
|
||||
DEBUG("Sleeping");
|
||||
Interrupt::sleep();
|
||||
DEBUG("Wakeup");
|
||||
}
|
||||
|
||||
BIN
arduino/HalMultiSensor/HalMultiSensorEnclosure.FCStd
Normal file
BIN
arduino/HalMultiSensor/HalMultiSensorEnclosure.FCStd
Normal file
Binary file not shown.
BIN
arduino/HalMultiSensor/HalMultiSensorEnclosure_bottom.stl
Normal file
BIN
arduino/HalMultiSensor/HalMultiSensorEnclosure_bottom.stl
Normal file
Binary file not shown.
BIN
arduino/HalMultiSensor/HalMultiSensorEnclosure_top.stl
Normal file
BIN
arduino/HalMultiSensor/HalMultiSensorEnclosure_top.stl
Normal file
Binary file not shown.
234
arduino/HalMultiSensor/Interrupt.cpp
Normal file
234
arduino/HalMultiSensor/Interrupt.cpp
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
#include "Interrupt.h"
|
||||
#include <avr/power.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/wdt.h>
|
||||
#include "HalInterfaces.h"
|
||||
|
||||
void emptyFunc(){}
|
||||
bool Interrupt::wakeUpNow = false;
|
||||
InterruptFunction Interrupt::pinCallback = emptyFunc;
|
||||
InterruptFunction Interrupt::wdtCallback = emptyFunc;
|
||||
|
||||
|
||||
void Interrupt::handlePinInterrupt() // the interrupt is handled here after wakeup
|
||||
{
|
||||
(*Interrupt::pinCallback) ();
|
||||
//Interrupt::wakeUp();
|
||||
}
|
||||
|
||||
void Interrupt::sleep()
|
||||
{
|
||||
/*
|
||||
* The 5 different modes are:
|
||||
* SLEEP_MODE_IDLE -the least power savings
|
||||
* SLEEP_MODE_ADC
|
||||
* SLEEP_MODE_PWR_SAVE
|
||||
* SLEEP_MODE_STANDBY
|
||||
* SLEEP_MODE_PWR_DOWN -the most power savings
|
||||
*
|
||||
* For now, we want as much power savings as possible, so we
|
||||
* choose the according
|
||||
* sleep mode: SLEEP_MODE_PWR_DOWN
|
||||
*/
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
|
||||
wakeUpNow = false;
|
||||
|
||||
sleep_enable(); // enables the sleep bit in the mcucr register
|
||||
// so sleep is possible. just a safety pin
|
||||
|
||||
//power_adc_disable();
|
||||
//power_spi_disable();
|
||||
//power_usart0_disable();
|
||||
//power_timer0_disable();
|
||||
//power_timer1_disable();
|
||||
//power_timer2_disable();
|
||||
//power_twi_disable();
|
||||
//power_all_disable();
|
||||
|
||||
while( ! Interrupt::wakeUpNow)
|
||||
{
|
||||
sleep_mode(); // here the device is actually put to sleep!!
|
||||
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
|
||||
}
|
||||
sleep_disable(); // first thing after waking from sleep:
|
||||
// disable sleep...
|
||||
|
||||
//power_adc_enable();
|
||||
//power_spi_enable();
|
||||
//power_usart0_enable();
|
||||
//power_timer0_enable();
|
||||
//power_timer1_enable();
|
||||
//power_timer2_enable();
|
||||
//power_twi_enable();
|
||||
//power_all_enable(); // during normal running time.
|
||||
}
|
||||
|
||||
void Interrupt::setupPinInterrupt(int pin)
|
||||
{
|
||||
noInterrupts(); // disable all interrupts
|
||||
|
||||
/* Now it is time to enable an interrupt.
|
||||
* In the function call attachInterrupt(A, B, C)
|
||||
* A can be either 0 or 1 for interrupts on pin 2 or 3.
|
||||
* B Name of a function you want to execute at interrupt for A.
|
||||
* C Trigger mode of the interrupt pin. can be:
|
||||
* LOW a low level triggers
|
||||
* CHANGE a change in level triggers
|
||||
* RISING a rising edge of a level triggers
|
||||
* FALLING a falling edge of a level triggers
|
||||
*
|
||||
* In all but the IDLE sleep modes only LOW can be used.
|
||||
*/
|
||||
attachInterrupt((pin == PIND2 ? 0 : 1), Interrupt::handlePinInterrupt, RISING);
|
||||
|
||||
//detachInterrupt(0); // disables interrupt 0 on pin 2 so the
|
||||
// wakeUpNow code will not be executed
|
||||
|
||||
interrupts(); // enable all interrupts
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Watchdog timer
|
||||
uint16_t wdtTime;
|
||||
int32_t wdtTimeLeft;
|
||||
|
||||
|
||||
void Interrupt::handleWatchDogInterrupt()
|
||||
{
|
||||
wdt_disable();
|
||||
if (wdtTime <= 0)
|
||||
return;
|
||||
DEBUGF("WDT interrupt, time=%u, timeLeft=%ld", wdtTime, wdtTimeLeft);
|
||||
|
||||
if (wdtTimeLeft <= 0)
|
||||
{
|
||||
Interrupt::wakeUp();
|
||||
(*Interrupt::wdtCallback) ();
|
||||
wdtTimeLeft = wdtTime;
|
||||
}
|
||||
|
||||
setupWatchDogInterrupt();
|
||||
}
|
||||
|
||||
ISR(WDT_vect)
|
||||
{
|
||||
Interrupt::handleWatchDogInterrupt();
|
||||
}
|
||||
|
||||
void Interrupt::setupWatchDogInterrupt(int32_t milliseconds)
|
||||
{
|
||||
wdtTimeLeft = wdtTime = milliseconds;
|
||||
setupWatchDogInterrupt();
|
||||
}
|
||||
|
||||
void Interrupt::setupWatchDogInterrupt()
|
||||
{
|
||||
if (wdtTime <= 0){
|
||||
wdt_disable();
|
||||
return;
|
||||
}
|
||||
|
||||
noInterrupts();
|
||||
|
||||
unsigned short duration;
|
||||
|
||||
if (8000 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 8000;
|
||||
duration = (1 << WDP3) | (1 << WDP0);
|
||||
} else if (4000 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 4000;
|
||||
duration = (1 << WDP3);
|
||||
} else if (2000 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 2000;
|
||||
duration = (1 << WDP2) | (1 << WDP1) | (1 << WDP0);
|
||||
} else if (1000 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 1000;
|
||||
duration = (1 << WDP2) | (1 << WDP1);
|
||||
} else if (500 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 500;
|
||||
duration = (1 << WDP2) | (1 << WDP0);
|
||||
} else if (256 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 256;
|
||||
duration = (1 << WDP2);
|
||||
} else if (128 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 128;
|
||||
duration = (1 << WDP1) | (1 << WDP0);
|
||||
} else if (64 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 64;
|
||||
duration = (1 << WDP1);
|
||||
} else if (32 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 32;
|
||||
duration = (1 << WDP0);
|
||||
} else { //(16 <= wdtTimeLeft){
|
||||
wdtTimeLeft -= 16;
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
wdt_reset();
|
||||
MCUSR &= ~(1 << WDRF); // reset status flag
|
||||
|
||||
/* WDCE = Watchdog Change Enable
|
||||
*
|
||||
* WDTON(1) WDE WDIE Mode
|
||||
* 1 0 0 Stopped
|
||||
* 1 0 1 Interrupt
|
||||
* 1 1 0 Reset
|
||||
* 1 1 1 Interrupt first, reset on second trigger
|
||||
* 0 x x Reset
|
||||
*/
|
||||
WDTCSR = (1 << WDCE) | (1<<WDE); // enable configuration
|
||||
/* WDP3 WDP2 WDP1 WDP0 Number of cycles Typical Time-out time (VCC = 5.0V)
|
||||
* 0 0 0 0 2K (2048) 16 ms
|
||||
* 0 0 0 1 4K (4096) 32 ms
|
||||
* 0 0 1 0 8K (8192) 64 ms
|
||||
* 0 0 1 1 16K (16384) 0.125 s
|
||||
* 0 1 0 0 32K (32768) 0.25 s
|
||||
* 0 1 0 1 64K (65536) 0.5 s
|
||||
* 0 1 1 0 128K (131072) 1.0 s
|
||||
* 0 1 1 1 256K (262144) 2.0 s
|
||||
* 1 0 0 0 512K (524288) 4.0 s
|
||||
* 1 0 0 1 1024K (1048576) 8.0 s
|
||||
*/
|
||||
WDTCSR = (1 << WDIE) | duration;
|
||||
//WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0);
|
||||
|
||||
interrupts();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Timer 1
|
||||
/*
|
||||
ISR(Timer1_COMPA_vect) // timer compare interrupt service routine
|
||||
{
|
||||
//DEBUG("Timer1e Interrupt");
|
||||
__pinInterruptHandler__();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void Interrupt::setupTimerInterrupt(unsigned int milliseconds)
|
||||
{
|
||||
noInterrupts(); // disable all interrupts
|
||||
|
||||
// initialize Timer1
|
||||
TCCR1A = 0;
|
||||
TCCR1B = 0;
|
||||
|
||||
/* Clock Select Bit Description
|
||||
* CS12 CS11 CS10 Description
|
||||
* 0 0 0 No clock source (Stop timer)
|
||||
* 0 0 1 clk/1 (No prescaling)
|
||||
* 0 1 0 clk/8
|
||||
* 0 1 1 clk/64
|
||||
* 1 0 0 clk/256
|
||||
* 1 0 1 clk/1024
|
||||
* 1 1 0 External clock source on T1 pin. Clock on falling edge.
|
||||
* 1 1 1 External clock source on T1 pin. Clock on rising edge.
|
||||
*/
|
||||
/* TCCR1B |= (1 << CS12); // 256 prescaler
|
||||
TCNT1 = 34286; // preload timer 65536-16MHz/256/2Hz
|
||||
//TODO: TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
|
||||
|
||||
interrupts(); // enable all interrupts
|
||||
}
|
||||
*/
|
||||
39
arduino/HalMultiSensor/Interrupt.h
Normal file
39
arduino/HalMultiSensor/Interrupt.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef INTERRUPT_H
|
||||
#define INTERRUPT_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef void (*InterruptFunction) ();
|
||||
|
||||
class Interrupt
|
||||
{
|
||||
public:
|
||||
static void wakeUp() { wakeUpNow = true; };
|
||||
static void sleep();
|
||||
static void setupPinInterrupt(int pin);
|
||||
static void setupWatchDogInterrupt(int32_t milliseconds);
|
||||
//static void setupTimerInterrupt(unsigned int milliseconds);
|
||||
|
||||
static void setPinCallback(InterruptFunction callback){ Interrupt::pinCallback = callback;}
|
||||
static void setWatchDogCallback(InterruptFunction callback){ Interrupt::wdtCallback = callback;}
|
||||
|
||||
/* Should not be called externally, used as triggering functions */
|
||||
static void handlePinInterrupt();
|
||||
static void handleWatchDogInterrupt();
|
||||
private:
|
||||
static bool wakeUpNow;
|
||||
|
||||
static InterruptFunction pinCallback;
|
||||
static InterruptFunction wdtCallback;
|
||||
|
||||
static void setupWatchDogInterrupt();
|
||||
|
||||
// Disable constructors and copy operators
|
||||
Interrupt() {};
|
||||
Interrupt(Interrupt const&);
|
||||
void operator=(Interrupt const&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // INTERRUPT_H
|
||||
1
arduino/HalMultiSensor/ProtocolNexa.cpp
Normal file
1
arduino/HalMultiSensor/ProtocolNexa.cpp
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
8
arduino/HalMultiSensor/ProtocolNexa.h
Normal file
8
arduino/HalMultiSensor/ProtocolNexa.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef PROTOCOLNEXA_H
|
||||
#define PROTOCOLNEXA_H
|
||||
|
||||
#include "HalInterfaces.h"
|
||||
|
||||
|
||||
|
||||
#endif // PROTOCOLNEXA_H
|
||||
215
arduino/HalMultiSensor/ProtocolOregon.cpp
Normal file
215
arduino/HalMultiSensor/ProtocolOregon.cpp
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
#include "ProtocolOregon.h"
|
||||
|
||||
#define RF_DELAY 512
|
||||
#define RF_DELAY_LONG RF_DELAY*2
|
||||
#define RF_SEND_HIGH() digitalWrite(txPin, HIGH)
|
||||
#define RF_SEND_LOW() digitalWrite(txPin, LOW)
|
||||
|
||||
|
||||
void ProtocolOregon::setup()
|
||||
{
|
||||
pinMode(txPin, OUTPUT);
|
||||
RF_SEND_LOW();
|
||||
}
|
||||
|
||||
|
||||
void ProtocolOregon::send(const PowerData& data)
|
||||
{
|
||||
send(data.consumption, 0);
|
||||
}
|
||||
|
||||
void ProtocolOregon::send(const TemperatureData& data)
|
||||
{
|
||||
send(data.temperature, data.humidity);
|
||||
}
|
||||
|
||||
void ProtocolOregon::send(const LightData& data)
|
||||
{
|
||||
send(data.lumen, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ProtocolOregon::send(float temperature, short humidity)
|
||||
{
|
||||
byte buffer[9];
|
||||
setType(buffer, 0x1A,0x2D); //temperature/humidity sensor (THGR2228N)
|
||||
setChannel(buffer, 0x20);
|
||||
setId(buffer, address); //set id of the sensor, BB=187
|
||||
setBatteryLevel(buffer, true); // false : low, true : high
|
||||
setTemperature(buffer, temperature); //org setTemperature(OregonMessageBuffer, 55.5);
|
||||
setHumidity(buffer, humidity);
|
||||
calculateAndSetChecksum(buffer);
|
||||
|
||||
// Send the Message over RF
|
||||
rfSend(buffer, sizeof(buffer));
|
||||
// Send a "pause"
|
||||
RF_SEND_LOW();
|
||||
delayMicroseconds(RF_DELAY_LONG * 8);
|
||||
// Send a copy of the first message. The v2.1 protocol send the message two RF_DELAYs
|
||||
rfSend(buffer, sizeof(buffer));
|
||||
RF_SEND_LOW();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the sensor type
|
||||
* \param data Oregon message
|
||||
* \param type Sensor type
|
||||
*/
|
||||
inline void ProtocolOregon::setType(byte data[], byte b1, byte b2)
|
||||
{
|
||||
data[0] = b1;
|
||||
data[1] = b2;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the sensor channel
|
||||
* \param data Oregon message
|
||||
* \param channel Sensor channel (0x10, 0x20, 0x30)
|
||||
*/
|
||||
inline void ProtocolOregon::setChannel(byte data[], byte channel)
|
||||
{
|
||||
data[2] = channel;
|
||||
}
|
||||
|
||||
|
||||
inline void ProtocolOregon::setId(byte data[], byte id)
|
||||
{
|
||||
data[3] = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param level false: low, true: high
|
||||
*/
|
||||
inline void ProtocolOregon::setBatteryLevel(byte data[], bool level)
|
||||
{
|
||||
if (!level) data[4] = 0x0C;
|
||||
else data[4] = 0x00;
|
||||
}
|
||||
|
||||
inline void ProtocolOregon::setTemperature(byte data[], float temp)
|
||||
{
|
||||
// Set temperature sign
|
||||
if (temp < 0)
|
||||
{
|
||||
data[6] = 0x08;
|
||||
temp *= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data[6] = 0x00;
|
||||
}
|
||||
|
||||
// Determine decimal and float part
|
||||
int tempInt = (int)temp;
|
||||
int td = (int)(tempInt / 10);
|
||||
int tf = (int)round((float)((float)tempInt/10 - (float)td) * 10);
|
||||
|
||||
int tempFloat = (int)round((float)(temp - (float)tempInt) * 10);
|
||||
|
||||
// Set temperature decimal part
|
||||
data[5] = (td << 4);
|
||||
data[5] |= tf;
|
||||
|
||||
// Set temperature float part
|
||||
data[4] |= (tempFloat << 4);
|
||||
}
|
||||
|
||||
inline void ProtocolOregon::setHumidity(byte data[], byte hum)
|
||||
{
|
||||
data[7] = (hum/10);
|
||||
data[6] |= (hum - data[7]*10) << 4;
|
||||
}
|
||||
|
||||
inline void ProtocolOregon::calculateAndSetChecksum(byte data[])
|
||||
{
|
||||
int sum = 0;
|
||||
for(byte i = 0; i<8;i++)
|
||||
{
|
||||
sum += (data[i]&0xF0) >> 4;
|
||||
sum += (data[i]&0x0F);
|
||||
}
|
||||
data[8] = ((sum - 0x0A) & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//*********************************************************************************************************
|
||||
|
||||
|
||||
/**
|
||||
* \brief Send logical "0" over RF
|
||||
* \details a zero bit be represented by an off-to-on transition
|
||||
* \ of the RF signal at the middle of a clock period.
|
||||
* \ Remember, the Oregon v2.1 protocol adds an inverted bit first
|
||||
*/
|
||||
inline void ProtocolOregon::sendZero(void)
|
||||
{
|
||||
RF_SEND_HIGH();
|
||||
delayMicroseconds(RF_DELAY);
|
||||
RF_SEND_LOW();
|
||||
delayMicroseconds(RF_DELAY_LONG);
|
||||
RF_SEND_HIGH();
|
||||
delayMicroseconds(RF_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send logical "1" over RF
|
||||
* \details a one bit be represented by an on-to-off transition
|
||||
* \ of the RF signal at the middle of a clock period.
|
||||
* \ Remember, the Oregon v2.1 protocol add an inverted bit first
|
||||
*/
|
||||
inline void ProtocolOregon::sendOne(void)
|
||||
{
|
||||
RF_SEND_LOW();
|
||||
delayMicroseconds(RF_DELAY);
|
||||
RF_SEND_HIGH();
|
||||
delayMicroseconds(RF_DELAY_LONG);
|
||||
RF_SEND_LOW();
|
||||
delayMicroseconds(RF_DELAY);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/******************************************************************/
|
||||
/******************************************************************/
|
||||
|
||||
/**
|
||||
* \brief Send a buffer over RF
|
||||
* \param data Data to send
|
||||
* \param length size of data array
|
||||
*/
|
||||
void ProtocolOregon::sendData(byte data[], byte length)
|
||||
{
|
||||
for (byte i=0; i<length; ++i)
|
||||
{
|
||||
(bitRead(data[i], 0)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 1)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 2)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 3)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 4)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 5)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 6)) ? sendOne() : sendZero();
|
||||
(bitRead(data[i], 7)) ? sendOne() : sendZero();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send an Oregon message
|
||||
* \param data The Oregon message
|
||||
*/
|
||||
void ProtocolOregon::rfSend(byte data[], byte size)
|
||||
{
|
||||
// Send preamble
|
||||
byte preamble[] = { 0xFF,0xFF };
|
||||
sendData(preamble, 2);
|
||||
// Send sync nibble
|
||||
//sendQuarterLSB(0xA); // It is not use in this version since the sync nibble is include in the Oregon message to send.
|
||||
// Send data
|
||||
sendData(data, size);
|
||||
// Send postamble
|
||||
byte postamble[] = { 0x00 };
|
||||
sendData(postamble, 1);
|
||||
}
|
||||
|
||||
37
arduino/HalMultiSensor/ProtocolOregon.h
Normal file
37
arduino/HalMultiSensor/ProtocolOregon.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef PROTOCOLOREGON_H
|
||||
#define PROTOCOLOREGON_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "HalInterfaces.h"
|
||||
|
||||
|
||||
class ProtocolOregon : public ProtocolTemperature, public ProtocolPowerConsumption, public ProtocolLight
|
||||
{
|
||||
public:
|
||||
ProtocolOregon(short pin, unsigned char address) : txPin(pin), address(address){};
|
||||
|
||||
virtual void setup();
|
||||
virtual void send(const TemperatureData& data);
|
||||
virtual void send(const PowerData& data);
|
||||
virtual void send(const LightData& data);
|
||||
|
||||
private:
|
||||
short txPin;
|
||||
unsigned char address;
|
||||
|
||||
void send(float temperature, short humidity);
|
||||
void setType(byte *data, byte b1, byte b2);
|
||||
void setChannel(byte *data, byte channel);
|
||||
void setId(byte *data, byte id);
|
||||
void setBatteryLevel(byte *data, bool level);
|
||||
void setTemperature(byte *data, float temp);
|
||||
void setHumidity(byte* data, byte hum);
|
||||
void calculateAndSetChecksum(byte* data);
|
||||
|
||||
void sendZero(void);
|
||||
void sendOne(void);
|
||||
void sendData(byte *data, byte length);
|
||||
void rfSend(byte *data, byte size);
|
||||
};
|
||||
|
||||
#endif // PROTOCOLOREGON_H
|
||||
93
arduino/HalMultiSensor/SensorBH1750.cpp
Normal file
93
arduino/HalMultiSensor/SensorBH1750.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
|
||||
This is a library for the BH1750FVI Digital Light Sensor
|
||||
breakout board.
|
||||
|
||||
The board uses I2C for communication. 2 pins are required to
|
||||
interface to the device.
|
||||
|
||||
|
||||
based on Christopher Laws, March, 2013 code.
|
||||
|
||||
*/
|
||||
|
||||
#include "SensorBH1750.h"
|
||||
#include <util/delay.h>
|
||||
|
||||
|
||||
#define BH1750_I2CADDR 0x23
|
||||
|
||||
// No active state
|
||||
#define BH1750_POWER_DOWN 0x00
|
||||
|
||||
// Waiting for measurement command
|
||||
#define BH1750_POWER_ON 0x01
|
||||
|
||||
// Reset data register value - not accepted in POWER_DOWN mode
|
||||
#define BH1750_RESET 0x07
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
#define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10
|
||||
|
||||
// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||
#define BH1750_CONTINUOUS_HIGH_RES_MODE_2 0x11
|
||||
|
||||
// Start measurement at 4lx resolution. Measurement time is approx 16ms.
|
||||
#define BH1750_CONTINUOUS_LOW_RES_MODE 0x13
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_HIGH_RES_MODE 0x20
|
||||
|
||||
// Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_HIGH_RES_MODE_2 0x21
|
||||
|
||||
// Start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||
// Device is automatically set to Power Down after measurement.
|
||||
#define BH1750_ONE_TIME_LOW_RES_MODE 0x23
|
||||
|
||||
|
||||
|
||||
void SensorBH1750::setup() {
|
||||
Wire.begin();
|
||||
//configure(BH1750_ONE_TIME_HIGH_RES_MODE);
|
||||
}
|
||||
|
||||
|
||||
void SensorBH1750::configure(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE:
|
||||
case BH1750_CONTINUOUS_HIGH_RES_MODE_2:
|
||||
case BH1750_CONTINUOUS_LOW_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE:
|
||||
case BH1750_ONE_TIME_HIGH_RES_MODE_2:
|
||||
case BH1750_ONE_TIME_LOW_RES_MODE:
|
||||
// apply a valid mode change
|
||||
Wire.beginTransmission(BH1750_I2CADDR);
|
||||
Wire.write(mode);
|
||||
Wire.endTransmission();
|
||||
_delay_ms(10);
|
||||
break;
|
||||
default:
|
||||
// Invalid measurement mode
|
||||
DEBUG("Invalid measurement mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SensorBH1750::read(LightData& data) {
|
||||
configure(BH1750_ONE_TIME_HIGH_RES_MODE);
|
||||
_delay_ms(200); // Wait for measurement
|
||||
|
||||
Wire.beginTransmission(BH1750_I2CADDR);
|
||||
Wire.requestFrom(BH1750_I2CADDR, 2);
|
||||
uint16_t level = Wire.read();
|
||||
level <<= 8;
|
||||
level |= Wire.read();
|
||||
Wire.endTransmission();
|
||||
|
||||
data.lumen = level/1.2; // convert to lux
|
||||
}
|
||||
|
||||
21
arduino/HalMultiSensor/SensorBH1750.h
Normal file
21
arduino/HalMultiSensor/SensorBH1750.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SensorBH1750_H
|
||||
#define SensorBH1750_H
|
||||
|
||||
#include <Wire.h>
|
||||
#include "HalInterfaces.h"
|
||||
|
||||
|
||||
class SensorBH1750 : public SensorLight{
|
||||
public:
|
||||
virtual void setup();
|
||||
virtual void read(LightData& data);
|
||||
|
||||
private:
|
||||
unsigned int pulses;
|
||||
|
||||
void configure(uint8_t mode);
|
||||
|
||||
};
|
||||
|
||||
#endif // SensorBH1750_H
|
||||
|
||||
165
arduino/HalMultiSensor/SensorDHT.cpp
Normal file
165
arduino/HalMultiSensor/SensorDHT.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/* DHT library
|
||||
MIT license
|
||||
written by Adafruit Industries
|
||||
*/
|
||||
// Modified by Ziver Koc
|
||||
//
|
||||
|
||||
#include "SensorDHT.h"
|
||||
|
||||
|
||||
void SensorDHT::setup()
|
||||
{
|
||||
// set up the pins!
|
||||
pinMode(_pin, INPUT_PULLUP);
|
||||
#ifdef __AVR
|
||||
_bit = digitalPinToBitMask(_pin);
|
||||
_port = digitalPinToPort(_pin);
|
||||
#endif
|
||||
_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for
|
||||
// reading pulses from DHT sensor.
|
||||
}
|
||||
|
||||
|
||||
// Expect the signal line to be at the specified level for a period of time and
|
||||
// return a count of loop cycles spent at that level (this cycle count can be
|
||||
// used to compare the relative time of two pulses). If more than a millisecond
|
||||
// ellapses without the level changing then the call fails with a 0 response.
|
||||
// This is adapted from Arduino's pulseInLong function (which is only available
|
||||
// in the very latest IDE versions):
|
||||
// https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
|
||||
uint32_t SensorDHT::expectPulse(bool level) {
|
||||
uint32_t count = 0;
|
||||
// On AVR platforms use direct GPIO port access as it's much faster and better
|
||||
// for catching pulses that are 10's of microseconds in length:
|
||||
#ifdef __AVR
|
||||
uint8_t portState = level ? _bit : 0;
|
||||
while ((*portInputRegister(_port) & _bit) == portState) {
|
||||
if (count++ >= _maxcycles) {
|
||||
return 0; // Exceeded timeout, fail.
|
||||
}
|
||||
}
|
||||
// Otherwise fall back to using digitalRead (this seems to be necessary on ESP8266
|
||||
// right now, perhaps bugs in direct port access functions?).
|
||||
#else
|
||||
while (digitalRead(_pin) == level) {
|
||||
if (count++ >= _maxcycles) {
|
||||
return 0; // Exceeded timeout, fail.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void SensorDHT::read(TemperatureData& retData)
|
||||
{
|
||||
// Reset 40 bits of received data to zero.
|
||||
static uint8_t data[5];
|
||||
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
|
||||
|
||||
// Send start signal. See DHT datasheet for full signal diagram:
|
||||
// http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
|
||||
|
||||
// Go into high impedence state to let pull-up raise data line level and
|
||||
// start the reading process.
|
||||
digitalWrite(_pin, HIGH);
|
||||
delay(250);
|
||||
|
||||
// First set data line low for 20 milliseconds.
|
||||
pinMode(_pin, OUTPUT);
|
||||
digitalWrite(_pin, LOW);
|
||||
delay(20);
|
||||
|
||||
uint32_t cycles[80];
|
||||
{
|
||||
// Turn off interrupts temporarily because the next sections are timing critical
|
||||
// and we don't want any interruptions.
|
||||
noInterrupts();
|
||||
|
||||
// End the start signal by setting data line high for 40 microseconds.
|
||||
digitalWrite(_pin, HIGH);
|
||||
delayMicroseconds(40);
|
||||
|
||||
// Now start reading the data line to get the value from the DHT sensor.
|
||||
pinMode(_pin, INPUT_PULLUP);
|
||||
delayMicroseconds(10); // Delay a bit to let sensor pull data line low.
|
||||
|
||||
// First expect a low signal for ~80 microseconds followed by a high signal
|
||||
// for ~80 microseconds again.
|
||||
if (expectPulse(LOW) == 0) {
|
||||
DEBUG("DHT:Timeout waiting for start signal low pulse.");
|
||||
interrupts();
|
||||
return;
|
||||
}
|
||||
if (expectPulse(HIGH) == 0) {
|
||||
DEBUG("DHT:Timeout waiting for start signal high pulse.");
|
||||
interrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
// Now read the 40 bits sent by the sensor. Each bit is sent as a 50
|
||||
// microsecond low pulse followed by a variable length high pulse. If the
|
||||
// high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
|
||||
// then it's a 1. We measure the cycle count of the initial 50us low pulse
|
||||
// and use that to compare to the cycle count of the high pulse to determine
|
||||
// if the bit is a 0 (high state cycle count < low state cycle count), or a
|
||||
// 1 (high state cycle count > low state cycle count). Note that for speed all
|
||||
// the pulses are read into a array and then examined in a later step.
|
||||
for (int i=0; i<80; i+=2) {
|
||||
cycles[i] = expectPulse(LOW);
|
||||
cycles[i+1] = expectPulse(HIGH);
|
||||
}
|
||||
|
||||
interrupts();
|
||||
} // Timing critical code is now complete.
|
||||
|
||||
// Inspect pulses and determine which ones are 0 (high state cycle count < low
|
||||
// state cycle count), or 1 (high state cycle count > low state cycle count).
|
||||
for (int i=0; i<40; ++i) {
|
||||
uint32_t lowCycles = cycles[2*i];
|
||||
uint32_t highCycles = cycles[2*i+1];
|
||||
if ((lowCycles == 0) || (highCycles == 0)) {
|
||||
DEBUG("DHT:Timeout waiting for pulse.");
|
||||
return;
|
||||
}
|
||||
data[i/8] <<= 1;
|
||||
// Now compare the low and high cycle times to see if the bit is a 0 or 1.
|
||||
if (highCycles > lowCycles) {
|
||||
// High cycles are greater than 50us low cycle count, must be a 1.
|
||||
data[i/8] |= 1;
|
||||
}
|
||||
// Else high cycles are less than (or equal to, a weird case) the 50us low
|
||||
// cycle count so this must be a zero. Nothing needs to be changed in the
|
||||
// stored data.
|
||||
}
|
||||
|
||||
|
||||
// Check we read 40 bits and that the checksum matches.
|
||||
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
|
||||
switch (_type) {
|
||||
case DHT11:
|
||||
retData.temperature = data[2];
|
||||
retData.humidity = data[0];
|
||||
break;
|
||||
case DHT22:
|
||||
case DHT21:
|
||||
retData.temperature = data[2] & 0x7F;
|
||||
retData.temperature *= 256;
|
||||
retData.temperature += data[3];
|
||||
retData.temperature *= 0.1;
|
||||
if (data[2] & 0x80) {
|
||||
retData.temperature *= -1;
|
||||
}
|
||||
retData.humidity = data[0];
|
||||
retData.humidity *= 256;
|
||||
retData.humidity += data[1];
|
||||
retData.humidity *= 0.1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG("DHT:Checksum failure!");
|
||||
}
|
||||
}
|
||||
33
arduino/HalMultiSensor/SensorDHT.h
Normal file
33
arduino/HalMultiSensor/SensorDHT.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef SensorDHT_h
|
||||
#define SensorDHT_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "HalInterfaces.h"
|
||||
|
||||
|
||||
// Define types of sensors.
|
||||
#define DHT11 11
|
||||
#define DHT22 22
|
||||
#define DHT21 21
|
||||
|
||||
|
||||
class SensorDHT : public SensorTemperature
|
||||
{
|
||||
public:
|
||||
SensorDHT(uint8_t type, uint8_t pin) : _type(type), _pin(pin) {};
|
||||
|
||||
virtual void setup();
|
||||
virtual void read(TemperatureData& data);
|
||||
|
||||
private:
|
||||
uint8_t _type, _pin;
|
||||
uint32_t _maxcycles;
|
||||
#ifdef __AVR
|
||||
// Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask
|
||||
// for the digital pin connected to the DHT. Other platforms will use digitalRead.
|
||||
uint8_t _bit, _port;
|
||||
#endif
|
||||
|
||||
uint32_t expectPulse(bool level);
|
||||
};
|
||||
#endif
|
||||
25
arduino/HalMultiSensor/SensorPhotocell.cpp
Normal file
25
arduino/HalMultiSensor/SensorPhotocell.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "SensorPhotocell.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
unsigned int SensorPhotocell::pulse = 0;
|
||||
|
||||
void SensorPhotocell::interruptHandler()
|
||||
{
|
||||
digitalWrite(INDICATOR_PIN, HIGH);
|
||||
DEBUG("PHCELL: INTERRUPT");
|
||||
++pulse;
|
||||
digitalWrite(INDICATOR_PIN, LOW);
|
||||
}
|
||||
|
||||
|
||||
void SensorPhotocell::setup()
|
||||
{
|
||||
Interrupt::setPinCallback(SensorPhotocell::interruptHandler);
|
||||
Interrupt::setupPinInterrupt(PC2); //PC3
|
||||
}
|
||||
|
||||
void SensorPhotocell::read(PowerData& data)
|
||||
{
|
||||
data.consumption = pulse;
|
||||
pulse = 0;
|
||||
}
|
||||
20
arduino/HalMultiSensor/SensorPhotocell.h
Normal file
20
arduino/HalMultiSensor/SensorPhotocell.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef SensorPhotocell_H
|
||||
#define SensorPhotocell_H
|
||||
|
||||
#include "HalInterfaces.h"
|
||||
#include "Interrupt.h"
|
||||
|
||||
|
||||
class SensorPhotocell : public SensorPowerConsumption
|
||||
{
|
||||
public:
|
||||
virtual void setup();
|
||||
virtual void read(PowerData& data);
|
||||
|
||||
private:
|
||||
static unsigned int pulse;
|
||||
|
||||
static void interruptHandler();
|
||||
};
|
||||
|
||||
#endif // SensorPhotocell_H
|
||||
155
arduino/NexaTellstick/NexaTellstick.ino
Normal file
155
arduino/NexaTellstick/NexaTellstick.ino
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#include "NexaSelfLearningReceiver.h"
|
||||
|
||||
#define TX_PIN 10
|
||||
#define RX_PIN 4
|
||||
#define RX_LED 13
|
||||
|
||||
//Radio RX
|
||||
NexaSelfLearningReceiver receiver = NexaSelfLearningReceiver(RX_PIN, RX_LED);
|
||||
short dim = 0;
|
||||
uint64_t receivedSignal = 0;
|
||||
|
||||
//Serial RX
|
||||
byte rxBuffer[79];
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
};
|
||||
|
||||
void loop(){
|
||||
|
||||
//Receive and execute command over serial
|
||||
if(Serial.available() > 0){
|
||||
uint8_t rxDataSize = Serial.readBytesUntil('+', &rxBuffer[0], 79);
|
||||
if(rxDataSize > 0){
|
||||
if(parseRxBuffer(&rxBuffer[0], 0, rxDataSize, false, 3, 0)){
|
||||
//Serial.println(F("DEBUG:PARSE OK"));
|
||||
}else{
|
||||
//Serial.println(F("DEBUG:PARSE ERROR"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Receive signal over air and send it over serial
|
||||
receivedSignal = receiver.receiveSignal(NULL, NULL, NULL, NULL, &dim, 100);
|
||||
if(receivedSignal > 0){
|
||||
Serial.print(F("+Wclass:command;protocol:arctech;model:selflearning;data:0x"));
|
||||
uint8_t hexToSend = (dim == NULL ? 8 : 9);
|
||||
for(int8_t i = hexToSend-1; i >= 0; --i){
|
||||
Serial.print( (byte)((receivedSignal>>(4*i))&0x0F), HEX);
|
||||
}
|
||||
Serial.println(F(";"));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bool parseRxBuffer(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause){
|
||||
if(startIndex > endIndex){
|
||||
return false;
|
||||
}
|
||||
char c = buffer[startIndex];
|
||||
//Serial.print("DEBUG: char:"); Serial.println(c, DEC);
|
||||
switch(c){
|
||||
case 'S':
|
||||
return handleS(buffer, startIndex+1, endIndex, debug, repeat, pause);
|
||||
case 'T':
|
||||
return handleT(buffer, startIndex+1, endIndex, debug, repeat, pause);
|
||||
case 'V':
|
||||
Serial.println(F("+V2"));
|
||||
return parseRxBuffer(buffer, startIndex+1, endIndex, debug, repeat, pause);
|
||||
case 'D':
|
||||
return parseRxBuffer(buffer, startIndex+1, endIndex, !debug, repeat, pause);
|
||||
case 'P':
|
||||
if(endIndex-startIndex+1 < 3){return false;} //at least {'P',[p-value],'+'} must be left in the buffer
|
||||
return parseRxBuffer(buffer, startIndex+2, endIndex, debug, repeat, buffer[startIndex+1]);
|
||||
case 'R':
|
||||
if(endIndex-startIndex+1 < 3){return false;} //at least {'R',[r-value],'+'} must be left in the buffer
|
||||
return parseRxBuffer(buffer, startIndex+2, endIndex, debug, buffer[startIndex+1], pause);
|
||||
case '+':
|
||||
return true;
|
||||
default:
|
||||
//Serial.print("DEBUG: unknown char: '"); Serial.print(c, BIN); Serial.println("'");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
bool handleS(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause){
|
||||
//Parse message received from serial
|
||||
uint8_t S_data[78]; //78 pulses
|
||||
uint8_t pulseCount = 0;
|
||||
for(uint8_t i = startIndex; i <= endIndex; ++i){
|
||||
if(buffer[i] == '+'){
|
||||
break;
|
||||
}else if(i == endIndex){
|
||||
return false;
|
||||
}else{
|
||||
S_data[pulseCount++] = buffer[i];
|
||||
}
|
||||
}
|
||||
//Send message
|
||||
for(uint8_t rep = 0; rep < repeat; ++rep){
|
||||
bool nextPinState = HIGH;
|
||||
for(int i = 0; i < pulseCount; ++i){
|
||||
if(S_data[i] > 0 || i == pulseCount-1){
|
||||
digitalWrite(TX_PIN, nextPinState);
|
||||
delayMicroseconds(S_data[i]*10);
|
||||
}
|
||||
nextPinState = !nextPinState;
|
||||
}
|
||||
delay(pause);
|
||||
}
|
||||
//send confirmation over serial
|
||||
Serial.println(F("+S"));
|
||||
return true;
|
||||
};
|
||||
|
||||
bool handleT(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause){
|
||||
//Parse message received from serial
|
||||
uint8_t T_data[72]; //0-188 pulses
|
||||
if(endIndex - startIndex < 5){
|
||||
//Serial.println("DEBUG: wrong size!");
|
||||
return false;
|
||||
}
|
||||
uint8_t buff_p = startIndex;
|
||||
uint8_t T_times[4] = {buffer[buff_p++], buffer[buff_p++], buffer[buff_p++], buffer[buff_p++]};
|
||||
uint8_t T_long = buffer[buff_p++];
|
||||
uint8_t T_bytes = 0;
|
||||
if( (T_long/4.0) > (float)(T_long/4) ){
|
||||
T_bytes = T_long/4 + 1;
|
||||
}else{
|
||||
T_bytes = T_long/4;
|
||||
}
|
||||
uint8_t j = 0;
|
||||
while(j < T_bytes){
|
||||
if(buffer[buff_p] == '+'){
|
||||
break;
|
||||
}else if(buff_p >= endIndex){
|
||||
return false;
|
||||
}else{
|
||||
T_data[j++] = buffer[buff_p++];
|
||||
}
|
||||
}
|
||||
if( j != T_bytes ){
|
||||
return false;
|
||||
}
|
||||
//Send message
|
||||
for(uint8_t rep = 0; rep < repeat; ++rep){
|
||||
bool nextPinState = HIGH;
|
||||
for(int i = 0; i < T_long; ++i){
|
||||
uint8_t timeIndex = (T_data[i/4]>>(6-(2*(i%4))))&0x03;
|
||||
if(T_times[timeIndex] > 0 || i == T_long-1){
|
||||
digitalWrite(TX_PIN, nextPinState);
|
||||
delayMicroseconds(10*T_times[timeIndex]);
|
||||
}
|
||||
nextPinState = !nextPinState;
|
||||
}
|
||||
digitalWrite(TX_PIN, LOW);
|
||||
if(rep < repeat-1){
|
||||
delay(pause);
|
||||
}
|
||||
}
|
||||
//send confirmation over serial
|
||||
Serial.println(F("+T"));
|
||||
return parseRxBuffer(buffer, buff_p, endIndex, debug, repeat, pause);
|
||||
};
|
||||
|
||||
1
arduino/lib/NexaControl
Submodule
1
arduino/lib/NexaControl
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 5fd5429375b3fffbf0bdd041d493d5c6ff0c156a
|
||||
126
build.gradle
Normal file
126
build.gradle
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'application'
|
||||
}
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2025 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// ------------------------------------
|
||||
// Hal common configuration
|
||||
// ------------------------------------
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'java-library'
|
||||
|
||||
dependencies {
|
||||
//implementation 'se.koc:zutil:1.0.314'
|
||||
implementation 'se.koc:zutil:1.0.0-SNAPSHOT'
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.hamcrest:hamcrest-core:2.2'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs 'src'
|
||||
}
|
||||
// We do not want the resource folder to be included in the jar file
|
||||
//resources {
|
||||
// srcDir 'resource'
|
||||
//}
|
||||
}
|
||||
test {
|
||||
java {
|
||||
srcDirs 'test'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint:deprecation"
|
||||
//options.compilerArgs << "-Xlint:unchecked"
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
// Hal general configuration
|
||||
// ------------------------------------
|
||||
|
||||
dependencies {
|
||||
project.subprojects.each { subProject ->
|
||||
runtimeOnly subProject
|
||||
}
|
||||
}
|
||||
|
||||
distributions {
|
||||
main {
|
||||
contents {
|
||||
// from root project
|
||||
from 'hal.conf.example'
|
||||
from 'logging.properties'
|
||||
from 'run.sh'
|
||||
|
||||
// from subprojects
|
||||
project.subprojects.each { subProject ->
|
||||
into('bin') {
|
||||
from "${subProject.projectDir}/resources/bin"
|
||||
}
|
||||
into('web') {
|
||||
from "${subProject.projectDir}/resources/web"
|
||||
}
|
||||
into('resources') {
|
||||
from ("${subProject.projectDir}/resources") {
|
||||
exclude 'bin'
|
||||
exclude 'web'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distTar.enabled = false
|
||||
distZip.enabled = false
|
||||
assemble.dependsOn(installDist)
|
||||
|
||||
project.gradle.startParameter.taskNames.each { taskName ->
|
||||
if (taskName == 'distZip') {
|
||||
distZip.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass = 'se.hal.HalServer'
|
||||
}
|
||||
|
||||
startScripts.enabled = false
|
||||
91
build.xml
91
build.xml
|
|
@ -1,91 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Zutil" >
|
||||
|
||||
<!-- ________________________ PROPERTIES AND SETTINGS ________________________ -->
|
||||
|
||||
<!--common properties-->
|
||||
<property name="gitRoot" value="." />
|
||||
<property name="srcDir" value="${gitRoot}/src" />
|
||||
<property name="testDir" value="${gitRoot}/test" />
|
||||
<property name="libDir" value="${gitRoot}/lib" />
|
||||
<property name="buildRoot" value="${gitRoot}/build" />
|
||||
<property name="buildDir" value="${buildRoot}/production" />
|
||||
<property name="buildTestDir" value="${buildRoot}/test" />
|
||||
<property name="releaseDir" value="${buildRoot}/release" />
|
||||
<property name="reportsDir" value="${buildRoot}/reports" />
|
||||
|
||||
<!--define standard arduments for javac-->
|
||||
<presetdef name="javac">
|
||||
<javac includeantruntime="false" />
|
||||
</presetdef>
|
||||
|
||||
<!-- ________________________ CLASSPATHS ________________________ -->
|
||||
|
||||
<!--classpath included when building-->
|
||||
<path id="classpath.build">
|
||||
<fileset dir="${libDir}">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
<pathelement location="${buildDir}" />
|
||||
</path>
|
||||
|
||||
<path id="classpath.test">
|
||||
<pathelement location="${buildTestDir}" />
|
||||
<!--include libraries used for building-->
|
||||
<path refid="classpath.build"/>
|
||||
</path>
|
||||
|
||||
<!-- ________________________ EXECUTION TARGETS ________________________ -->
|
||||
|
||||
<target name="test" depends="build-test">
|
||||
<mkdir dir="${reportsDir}" />
|
||||
<junit printsummary="yes" haltonfailure="false" fork="true">
|
||||
<classpath refid="classpath.test" />
|
||||
<formatter type="plain" usefile="false" /> <!-- to screen -->
|
||||
<formatter type="xml" /> <!-- to file -->
|
||||
|
||||
<batchtest todir="${reportsDir}" skipNonTests="true">
|
||||
<fileset dir="${buildTestDir}" includes="**/*Test*.class" />
|
||||
</batchtest>
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
<!-- ________________________ BUILD TARGETS ________________________ -->
|
||||
|
||||
<!--clean all build paths-->
|
||||
<target name="clean">
|
||||
<delete includeemptydirs="true" failonerror="false">
|
||||
<fileset dir="${buildRoot}" includes="**/*"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<!--build product code-->
|
||||
<target name="release" depends="build">
|
||||
<jar destfile="${releaseDir}/Zutil.jar" basedir="${buildDir}" />
|
||||
</target>
|
||||
|
||||
<target name="build">
|
||||
<mkdir dir="${buildDir}" />
|
||||
<javac srcdir="${srcDir}" destdir="${buildDir}" debug="yes" debugLevel="lines,vars,source">
|
||||
<classpath refid="classpath.build" />
|
||||
<include name="**/*.java" />
|
||||
</javac>
|
||||
<copy todir="${buildDir}">
|
||||
<fileset dir="${srcDir}"
|
||||
excludes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build-test" depends="build">
|
||||
<mkdir dir="${buildTestDir}" />
|
||||
<javac srcdir="${testDir}" destdir="${buildTestDir}" debug="yes" debugLevel="lines,vars,source">
|
||||
<classpath refid="classpath.test" />
|
||||
<include name="**/*.java" />
|
||||
</javac>
|
||||
<copy todir="${buildTestDir}">
|
||||
<fileset dir="${testDir}"
|
||||
excludes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
BIN
external/Z-Stick_Gen5_Drivers.zip
vendored
Normal file
BIN
external/Z-Stick_Gen5_Drivers.zip
vendored
Normal file
Binary file not shown.
7
external/tellstick-core/AUTHORS.txt
vendored
Normal file
7
external/tellstick-core/AUTHORS.txt
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
telldus-core has been developed by :
|
||||
|
||||
Micke Prag <micke.prag@telldus.se>
|
||||
Fredrik Jacobsson <fredrik.jacobsson@telldus.se>
|
||||
Stefan Persson <stefan.persson@telldus.se>
|
||||
|
||||
The package is maintained by Micke Prag <micke.prag@telldus.se>
|
||||
502
external/tellstick-core/LICENSE.txt
vendored
Normal file
502
external/tellstick-core/LICENSE.txt
vendored
Normal file
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
267
external/tellstick-core/Protocol.cpp
vendored
Normal file
267
external/tellstick-core/Protocol.cpp
vendored
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/Protocol.h"
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "client/telldus-core.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
#include "service/ProtocolBrateck.h"
|
||||
#include "service/ProtocolComen.h"
|
||||
#include "service/ProtocolEverflourish.h"
|
||||
#include "service/ProtocolFineoffset.h"
|
||||
#include "service/ProtocolFuhaote.h"
|
||||
#include "service/ProtocolGroup.h"
|
||||
#include "service/ProtocolHasta.h"
|
||||
#include "service/ProtocolIkea.h"
|
||||
#include "service/ProtocolMandolyn.h"
|
||||
#include "service/ProtocolNexa.h"
|
||||
#include "service/ProtocolOregon.h"
|
||||
#include "service/ProtocolRisingSun.h"
|
||||
#include "service/ProtocolSartano.h"
|
||||
#include "service/ProtocolScene.h"
|
||||
#include "service/ProtocolSilvanChip.h"
|
||||
#include "service/ProtocolUpm.h"
|
||||
#include "service/ProtocolWaveman.h"
|
||||
#include "service/ProtocolX10.h"
|
||||
#include "service/ProtocolYidong.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
class Protocol::PrivateData {
|
||||
public:
|
||||
ParameterMap parameterList;
|
||||
std::wstring model;
|
||||
};
|
||||
|
||||
Protocol::Protocol() {
|
||||
d = new PrivateData;
|
||||
}
|
||||
|
||||
Protocol::~Protocol(void) {
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::wstring Protocol::model() const {
|
||||
std::wstring strModel = d->model;
|
||||
// Strip anything after : if it is found
|
||||
size_t pos = strModel.find(L":");
|
||||
if (pos != std::wstring::npos) {
|
||||
strModel = strModel.substr(0, pos);
|
||||
}
|
||||
|
||||
return strModel;
|
||||
}
|
||||
|
||||
void Protocol::setModel(const std::wstring &model) {
|
||||
d->model = model;
|
||||
}
|
||||
|
||||
void Protocol::setParameters(const ParameterMap ¶meterList) {
|
||||
d->parameterList = parameterList;
|
||||
}
|
||||
|
||||
std::wstring Protocol::getStringParameter(const std::wstring &name, const std::wstring &defaultValue) const {
|
||||
ParameterMap::const_iterator it = d->parameterList.find(name);
|
||||
if (it == d->parameterList.end()) {
|
||||
return defaultValue;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int Protocol::getIntParameter(const std::wstring &name, int min, int max) const {
|
||||
std::wstring value = getStringParameter(name, L"");
|
||||
if (value == L"") {
|
||||
return min;
|
||||
}
|
||||
std::wstringstream st;
|
||||
st << value;
|
||||
int intValue = 0;
|
||||
st >> intValue;
|
||||
if (intValue < min) {
|
||||
return min;
|
||||
}
|
||||
if (intValue > max) {
|
||||
return max;
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
bool Protocol::checkBit(int data, int bitno) {
|
||||
return ((data >> bitno)&0x01);
|
||||
}
|
||||
|
||||
|
||||
Protocol *Protocol::getProtocolInstance(const std::wstring &protocolname) {
|
||||
if (TelldusCore::comparei(protocolname, L"arctech")) {
|
||||
return new ProtocolNexa();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"brateck")) {
|
||||
return new ProtocolBrateck();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"comen")) {
|
||||
return new ProtocolComen();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"everflourish")) {
|
||||
return new ProtocolEverflourish();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"fuhaote")) {
|
||||
return new ProtocolFuhaote();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"hasta")) {
|
||||
return new ProtocolHasta();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"ikea")) {
|
||||
return new ProtocolIkea();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"risingsun")) {
|
||||
return new ProtocolRisingSun();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"sartano")) {
|
||||
return new ProtocolSartano();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"silvanchip")) {
|
||||
return new ProtocolSilvanChip();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"upm")) {
|
||||
return new ProtocolUpm();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"waveman")) {
|
||||
return new ProtocolWaveman();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"x10")) {
|
||||
return new ProtocolX10();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"yidong")) {
|
||||
return new ProtocolYidong();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"group")) {
|
||||
return new ProtocolGroup();
|
||||
|
||||
} else if (TelldusCore::comparei(protocolname, L"scene")) {
|
||||
return new ProtocolScene();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::list<std::string> Protocol::getParametersForProtocol(const std::wstring &protocolName) {
|
||||
std::list<std::string> parameters;
|
||||
if (TelldusCore::comparei(protocolName, L"arctech")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"brateck")) {
|
||||
parameters.push_back("house");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"comen")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"everflourish")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"fuhaote")) {
|
||||
parameters.push_back("code");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"hasta")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"ikea")) {
|
||||
parameters.push_back("system");
|
||||
parameters.push_back("units");
|
||||
// parameters.push_back("fade");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"risingsun")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"sartano")) {
|
||||
parameters.push_back("code");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"silvanchip")) {
|
||||
parameters.push_back("house");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"upm")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"waveman")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"x10")) {
|
||||
parameters.push_back("house");
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"yidong")) {
|
||||
parameters.push_back("unit");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"group")) {
|
||||
parameters.push_back("devices");
|
||||
|
||||
} else if (TelldusCore::comparei(protocolName, L"scene")) {
|
||||
parameters.push_back("devices");
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
std::list<std::string> Protocol::decodeData(const std::string &fullData) {
|
||||
std::list<std::string> retval;
|
||||
std::string decoded = "";
|
||||
|
||||
ControllerMessage dataMsg(fullData);
|
||||
if ( TelldusCore::comparei(dataMsg.protocol(), L"arctech") ) {
|
||||
decoded = ProtocolNexa::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
decoded = ProtocolWaveman::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
decoded = ProtocolSartano::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if (TelldusCore::comparei(dataMsg.protocol(), L"everflourish") ) {
|
||||
decoded = ProtocolEverflourish::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if (TelldusCore::comparei(dataMsg.protocol(), L"fineoffset") ) {
|
||||
decoded = ProtocolFineoffset::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if (TelldusCore::comparei(dataMsg.protocol(), L"mandolyn") ) {
|
||||
decoded = ProtocolMandolyn::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if (TelldusCore::comparei(dataMsg.protocol(), L"oregon") ) {
|
||||
decoded = ProtocolOregon::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if (TelldusCore::comparei(dataMsg.protocol(), L"x10") ) {
|
||||
decoded = ProtocolX10::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
} else if (TelldusCore::comparei(dataMsg.protocol(), L"hasta") ) {
|
||||
decoded = ProtocolHasta::decodeData(dataMsg);
|
||||
if (decoded != "") {
|
||||
retval.push_back(decoded);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
46
external/tellstick-core/Protocol.h
vendored
Normal file
46
external/tellstick-core/Protocol.h
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOL_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOL_H_
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "client/telldus-core.h"
|
||||
|
||||
typedef std::map<std::wstring, std::wstring> ParameterMap;
|
||||
|
||||
class Controller;
|
||||
|
||||
class Protocol {
|
||||
public:
|
||||
Protocol();
|
||||
virtual ~Protocol(void);
|
||||
|
||||
static Protocol *getProtocolInstance(const std::wstring &protocolname);
|
||||
static std::list<std::string> getParametersForProtocol(const std::wstring &protocolName);
|
||||
static std::list<std::string> decodeData(const std::string &fullData);
|
||||
|
||||
virtual int methods() const = 0;
|
||||
std::wstring model() const;
|
||||
void setModel(const std::wstring &model);
|
||||
void setParameters(const ParameterMap ¶meterList);
|
||||
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller) = 0;
|
||||
|
||||
protected:
|
||||
virtual std::wstring getStringParameter(const std::wstring &name, const std::wstring &defaultValue = L"") const;
|
||||
virtual int getIntParameter(const std::wstring &name, int min, int max) const;
|
||||
|
||||
static bool checkBit(int data, int bit);
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOL_H_
|
||||
53
external/tellstick-core/ProtocolBrateck.cpp
vendored
Normal file
53
external/tellstick-core/ProtocolBrateck.cpp
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolBrateck.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolBrateck::methods() const {
|
||||
return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP;
|
||||
}
|
||||
|
||||
std::string ProtocolBrateck::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
const char S = '!';
|
||||
const char L = 'V';
|
||||
const char B1[] = {L, S, L, S, 0};
|
||||
const char BX[] = {S, L, L, S, 0};
|
||||
const char B0[] = {S, L, S, L, 0};
|
||||
const char BUP[] = {L, S, L, S, S, L, S, L, S, L, S, L, S, L, S, L, S, 0};
|
||||
const char BSTOP[] = {S, L, S, L, L, S, L, S, S, L, S, L, S, L, S, L, S, 0};
|
||||
const char BDOWN[] = {S, L, S, L, S, L, S, L, S, L, S, L, L, S, L, S, S, 0};
|
||||
|
||||
std::string strReturn;
|
||||
std::wstring strHouse = this->getStringParameter(L"house", L"");
|
||||
if (strHouse == L"") {
|
||||
return "";
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < strHouse.length(); ++i ) {
|
||||
if (strHouse[i] == '1') {
|
||||
strReturn.insert(0, B1);
|
||||
} else if (strHouse[i] == '-') {
|
||||
strReturn.insert(0, BX);
|
||||
} else if (strHouse[i] == '0') {
|
||||
strReturn.insert(0, B0);
|
||||
}
|
||||
}
|
||||
|
||||
strReturn.insert(0, "S");
|
||||
if (method == TELLSTICK_UP) {
|
||||
strReturn.append(BUP);
|
||||
} else if (method == TELLSTICK_DOWN) {
|
||||
strReturn.append(BDOWN);
|
||||
} else if (method == TELLSTICK_STOP) {
|
||||
strReturn.append(BSTOP);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
strReturn.append("+");
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
19
external/tellstick-core/ProtocolBrateck.h
vendored
Normal file
19
external/tellstick-core/ProtocolBrateck.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolBrateck : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLBRATECK_H_
|
||||
23
external/tellstick-core/ProtocolComen.cpp
vendored
Normal file
23
external/tellstick-core/ProtocolComen.cpp
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolComen.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolComen::methods() const {
|
||||
return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN);
|
||||
}
|
||||
|
||||
int ProtocolComen::getIntParameter(const std::wstring &name, int min, int max) const {
|
||||
if (name.compare(L"house") == 0) {
|
||||
int intHouse = Protocol::getIntParameter(L"house", 1, 16777215);
|
||||
// The last two bits must be hardcoded
|
||||
intHouse <<= 2;
|
||||
intHouse += 2;
|
||||
return intHouse;
|
||||
}
|
||||
return Protocol::getIntParameter(name, min, max);
|
||||
}
|
||||
21
external/tellstick-core/ProtocolComen.h
vendored
Normal file
21
external/tellstick-core/ProtocolComen.h
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/ProtocolNexa.h"
|
||||
|
||||
class ProtocolComen : public ProtocolNexa {
|
||||
public:
|
||||
virtual int methods() const;
|
||||
|
||||
protected:
|
||||
virtual int getIntParameter(const std::wstring &name, int min, int max) const;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLCOMEN_H_
|
||||
133
external/tellstick-core/ProtocolEverflourish.cpp
vendored
Normal file
133
external/tellstick-core/ProtocolEverflourish.cpp
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolEverflourish.h"
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
int ProtocolEverflourish::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN;
|
||||
}
|
||||
|
||||
std::string ProtocolEverflourish::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
unsigned int deviceCode = this->getIntParameter(L"house", 0, 16383);
|
||||
unsigned int intCode = this->getIntParameter(L"unit", 1, 4)-1;
|
||||
unsigned char action;
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
action = 15;
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
action = 0;
|
||||
} else if (method == TELLSTICK_LEARN) {
|
||||
action = 10;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
const char ssss = 85;
|
||||
const char sssl = 84; // 0
|
||||
const char slss = 69; // 1
|
||||
|
||||
const char bits[2] = {sssl, slss};
|
||||
int i, check;
|
||||
|
||||
std::string strCode;
|
||||
|
||||
deviceCode = (deviceCode << 2) | intCode;
|
||||
|
||||
check = calculateChecksum(deviceCode);
|
||||
|
||||
char preamble[] = {'R', 5, 'T', 114, 60, 1, 1, 105, ssss, ssss, 0};
|
||||
strCode.append(preamble);
|
||||
|
||||
for(i = 15; i >= 0; i--) {
|
||||
strCode.append(1, bits[(deviceCode >> i)&0x01]);
|
||||
}
|
||||
for(i = 3; i >= 0; i--) {
|
||||
strCode.append(1, bits[(check >> i)&0x01]);
|
||||
}
|
||||
for(i = 3; i >= 0; i--) {
|
||||
strCode.append(1, bits[(action >> i)&0x01]);
|
||||
}
|
||||
|
||||
strCode.append(1, ssss);
|
||||
strCode.append(1, '+');
|
||||
|
||||
return strCode;
|
||||
}
|
||||
|
||||
// The calculation used in this function is provided by Frank Stevenson
|
||||
unsigned int ProtocolEverflourish::calculateChecksum(unsigned int x) {
|
||||
unsigned int bits[16] = {
|
||||
0xf, 0xa, 0x7, 0xe,
|
||||
0xf, 0xd, 0x9, 0x1,
|
||||
0x1, 0x2, 0x4, 0x8,
|
||||
0x3, 0x6, 0xc, 0xb
|
||||
};
|
||||
unsigned int bit = 1;
|
||||
unsigned int res = 0x5;
|
||||
int i;
|
||||
unsigned int lo, hi;
|
||||
|
||||
if ((x & 0x3) == 3) {
|
||||
lo = x & 0x00ff;
|
||||
hi = x & 0xff00;
|
||||
lo += 4;
|
||||
if (lo>0x100) {
|
||||
lo = 0x12;
|
||||
}
|
||||
x = lo | hi;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
if (x & bit) {
|
||||
res = res ^ bits[i];
|
||||
}
|
||||
bit = bit << 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string ProtocolEverflourish::decodeData(const ControllerMessage &dataMsg) {
|
||||
uint64_t allData;
|
||||
unsigned int house = 0;
|
||||
unsigned int unit = 0;
|
||||
unsigned int method = 0;
|
||||
|
||||
allData = dataMsg.getInt64Parameter("data");
|
||||
|
||||
house = allData & 0xFFFC00;
|
||||
house >>= 10;
|
||||
|
||||
unit = allData & 0x300;
|
||||
unit >>= 8;
|
||||
unit++; // unit from 1 to 4
|
||||
|
||||
method = allData & 0xF;
|
||||
|
||||
if(house > 16383 || unit < 1 || unit > 4) {
|
||||
// not everflourish
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:everflourish;model:selflearning;house:" << house << ";unit:" << unit << ";method:";
|
||||
if(method == 0) {
|
||||
retString << "turnoff;";
|
||||
} else if(method == 15) {
|
||||
retString << "turnon;";
|
||||
} else if(method == 10) {
|
||||
retString << "learn;";
|
||||
} else {
|
||||
// not everflourish
|
||||
return "";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
24
external/tellstick-core/ProtocolEverflourish.h
vendored
Normal file
24
external/tellstick-core/ProtocolEverflourish.h
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolEverflourish : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
private:
|
||||
static unsigned int calculateChecksum(unsigned int x);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLEVERFLOURISH_H_
|
||||
52
external/tellstick-core/ProtocolFineoffset.cpp
vendored
Normal file
52
external/tellstick-core/ProtocolFineoffset.cpp
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolFineoffset.h"
|
||||
#include <stdlib.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
std::string ProtocolFineoffset::decodeData(const ControllerMessage &dataMsg) {
|
||||
std::string data = dataMsg.getParameter("data");
|
||||
if (data.length() < 8) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Checksum currently not used
|
||||
// uint8_t checksum = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2));
|
||||
data = data.substr(0, data.length()-2);
|
||||
|
||||
uint8_t humidity = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2));
|
||||
data = data.substr(0, data.length()-2);
|
||||
|
||||
uint16_t value = (uint16_t)TelldusCore::hexTo64l(data.substr(data.length()-3));
|
||||
double temperature = (value & 0x7FF)/10.0;
|
||||
|
||||
value >>= 11;
|
||||
if (value & 1) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
data = data.substr(0, data.length()-3);
|
||||
|
||||
uint16_t id = (uint16_t)TelldusCore::hexTo64l(data) & 0xFF;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:fineoffset;id:" << id << ";model:";
|
||||
|
||||
if (humidity <= 100) {
|
||||
retString << "temperaturehumidity;humidity:" << static_cast<int>(humidity) << ";";
|
||||
} else if (humidity == 0xFF) {
|
||||
retString << "temperature;";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
retString << "temp:" << std::fixed << std::setprecision(1) << temperature << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
19
external/tellstick-core/ProtocolFineoffset.h
vendored
Normal file
19
external/tellstick-core/ProtocolFineoffset.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolFineoffset : public Protocol {
|
||||
public:
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLFINEOFFSET_H_
|
||||
60
external/tellstick-core/ProtocolFuhaote.cpp
vendored
Normal file
60
external/tellstick-core/ProtocolFuhaote.cpp
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolFuhaote.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolFuhaote::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
std::string ProtocolFuhaote::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
const char S = 19;
|
||||
const char L = 58;
|
||||
const char B0[] = {S, L, L, S, 0};
|
||||
const char B1[] = {L, S, L, S, 0};
|
||||
const char OFF[] = {S, L, S, L, S, L, L, S, 0};
|
||||
const char ON[] = {S, L, L, S, S, L, S, L, 0};
|
||||
|
||||
std::string strReturn = "S";
|
||||
std::wstring strCode = this->getStringParameter(L"code", L"");
|
||||
if (strCode == L"") {
|
||||
return "";
|
||||
}
|
||||
|
||||
// House code
|
||||
for(size_t i = 0; i < 5; ++i) {
|
||||
if (strCode[i] == '0') {
|
||||
strReturn.append(B0);
|
||||
} else if (strCode[i] == '1') {
|
||||
strReturn.append(B1);
|
||||
}
|
||||
}
|
||||
// Unit code
|
||||
for(size_t i = 5; i < 10; ++i) {
|
||||
if (strCode[i] == '0') {
|
||||
strReturn.append(B0);
|
||||
} else if (strCode[i] == '1') {
|
||||
strReturn.append(1, S);
|
||||
strReturn.append(1, L);
|
||||
strReturn.append(1, S);
|
||||
strReturn.append(1, L);
|
||||
}
|
||||
}
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strReturn.append(ON);
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strReturn.append(OFF);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
strReturn.append(1, S);
|
||||
strReturn.append("+");
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
19
external/tellstick-core/ProtocolFuhaote.h
vendored
Normal file
19
external/tellstick-core/ProtocolFuhaote.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolFuhaote : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLFUHAOTE_H_
|
||||
16
external/tellstick-core/ProtocolGroup.cpp
vendored
Normal file
16
external/tellstick-core/ProtocolGroup.cpp
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolGroup.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolGroup::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_BELL | TELLSTICK_LEARN | TELLSTICK_EXECUTE | TELLSTICK_TOGGLE | TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP;
|
||||
}
|
||||
|
||||
std::string ProtocolGroup::getStringForMethod(int method, unsigned char data, Controller *) {
|
||||
return "";
|
||||
}
|
||||
22
external/tellstick-core/ProtocolGroup.h
vendored
Normal file
22
external/tellstick-core/ProtocolGroup.h
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLGROUP_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLGROUP_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolGroup : public Protocol {
|
||||
public:
|
||||
virtual int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLGROUP_H_
|
||||
|
||||
|
||||
|
||||
201
external/tellstick-core/ProtocolHasta.cpp
vendored
Normal file
201
external/tellstick-core/ProtocolHasta.cpp
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolHasta.h"
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
int ProtocolHasta::methods() const {
|
||||
return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN;
|
||||
}
|
||||
|
||||
std::string ProtocolHasta::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
if (TelldusCore::comparei(model(), L"selflearningv2")) {
|
||||
return getStringForMethodv2(method);
|
||||
}
|
||||
return getStringForMethodv1(method);
|
||||
}
|
||||
|
||||
std::string ProtocolHasta::getStringForMethodv1(int method) {
|
||||
int house = this->getIntParameter(L"house", 1, 65536);
|
||||
int unit = this->getIntParameter(L"unit", 1, 15);
|
||||
std::string strReturn;
|
||||
|
||||
strReturn.append(1, 164);
|
||||
strReturn.append(1, 1);
|
||||
strReturn.append(1, 164);
|
||||
strReturn.append(1, 1);
|
||||
strReturn.append(1, 164);
|
||||
strReturn.append(1, 164);
|
||||
|
||||
strReturn.append(convertByte( (house & 0xFF) ));
|
||||
strReturn.append(convertByte( (house>>8) & 0xFF ));
|
||||
|
||||
int byte = unit&0x0F;
|
||||
|
||||
if (method == TELLSTICK_UP) {
|
||||
byte |= 0x00;
|
||||
|
||||
} else if (method == TELLSTICK_DOWN) {
|
||||
byte |= 0x10;
|
||||
|
||||
} else if (method == TELLSTICK_STOP) {
|
||||
byte |= 0x50;
|
||||
|
||||
} else if (method == TELLSTICK_LEARN) {
|
||||
byte |= 0x40;
|
||||
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
strReturn.append(convertByte(byte));
|
||||
|
||||
strReturn.append(convertByte(0x0));
|
||||
strReturn.append(convertByte(0x0));
|
||||
|
||||
// Remove the last pulse
|
||||
strReturn.erase(strReturn.end()-1, strReturn.end());
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolHasta::convertByte(unsigned char byte) {
|
||||
std::string retval;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
if (byte & 1) {
|
||||
retval.append(1, 33);
|
||||
retval.append(1, 17);
|
||||
} else {
|
||||
retval.append(1, 17);
|
||||
retval.append(1, 33);
|
||||
}
|
||||
byte >>= 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::string ProtocolHasta::getStringForMethodv2(int method) {
|
||||
int house = this->getIntParameter(L"house", 1, 65536);
|
||||
int unit = this->getIntParameter(L"unit", 1, 15);
|
||||
int sum = 0;
|
||||
std::string strReturn;
|
||||
strReturn.append(1, 245);
|
||||
strReturn.append(1, 1);
|
||||
strReturn.append(1, 245);
|
||||
strReturn.append(1, 245);
|
||||
strReturn.append(1, 63);
|
||||
strReturn.append(1, 1);
|
||||
strReturn.append(1, 63);
|
||||
strReturn.append(1, 1);
|
||||
strReturn.append(1, 35);
|
||||
strReturn.append(1, 35);
|
||||
|
||||
strReturn.append(convertBytev2( (house>>8) & 0xFF ));
|
||||
sum = ((house>>8)&0xFF);
|
||||
strReturn.append(convertBytev2( (house & 0xFF) ));
|
||||
sum += (house & 0xFF);
|
||||
|
||||
int byte = unit&0x0F;
|
||||
|
||||
if (method == TELLSTICK_UP) {
|
||||
byte |= 0xC0;
|
||||
|
||||
} else if (method == TELLSTICK_DOWN) {
|
||||
byte |= 0x10;
|
||||
|
||||
} else if (method == TELLSTICK_STOP) {
|
||||
byte |= 0x50;
|
||||
|
||||
} else if (method == TELLSTICK_LEARN) {
|
||||
byte |= 0x40;
|
||||
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
strReturn.append(convertBytev2(byte));
|
||||
sum += byte;
|
||||
|
||||
strReturn.append(convertBytev2(0x01));
|
||||
sum += 0x01;
|
||||
|
||||
int checksum = ((static_cast<int>(sum/256)+1)*256+1) - sum;
|
||||
strReturn.append(convertBytev2(checksum));
|
||||
strReturn.append(1, 63);
|
||||
strReturn.append(1, 35);
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolHasta::convertBytev2(unsigned char byte) {
|
||||
std::string retval;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
if (byte & 1) {
|
||||
retval.append(1, 63);
|
||||
retval.append(1, 35);
|
||||
} else {
|
||||
retval.append(1, 35);
|
||||
retval.append(1, 63);
|
||||
}
|
||||
byte >>= 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::string ProtocolHasta::decodeData(const ControllerMessage& dataMsg) {
|
||||
uint64_t allData = dataMsg.getInt64Parameter("data");
|
||||
|
||||
unsigned int house = 0;
|
||||
unsigned int unit = 0;
|
||||
unsigned int method = 0;
|
||||
std::string model;
|
||||
std::string methodstring;
|
||||
|
||||
allData >>= 8;
|
||||
unit = allData & 0xF;
|
||||
allData >>= 4;
|
||||
method = allData & 0xF;
|
||||
allData >>= 4;
|
||||
if(TelldusCore::comparei(dataMsg.model(), L"selflearning")) {
|
||||
// version1
|
||||
house = allData & 0xFFFF;
|
||||
house = ((house << 8) | (house >> 8)) & 0xFFFF;
|
||||
model = "selflearning";
|
||||
if(method == 0) {
|
||||
methodstring = "up";
|
||||
} else if(method == 1) {
|
||||
methodstring = "down";
|
||||
} else if(method == 5) {
|
||||
methodstring = "stop";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
// version2
|
||||
house = allData & 0xFFFF;
|
||||
|
||||
model = "selflearningv2";
|
||||
if(method == 12) {
|
||||
methodstring = "up";
|
||||
} else if(method == 1 || method == 8) { // is method 8 correct?
|
||||
methodstring = "down";
|
||||
} else if(method == 5) {
|
||||
methodstring = "stop";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if(house < 1 || house > 65535 || unit < 1 || unit > 16) {
|
||||
// not hasta
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:hasta;model:" << model << ";house:" << house << ";unit:" << unit << ";method:" << methodstring << ";";
|
||||
return retString.str();
|
||||
}
|
||||
27
external/tellstick-core/ProtocolHasta.h
vendored
Normal file
27
external/tellstick-core/ProtocolHasta.h
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLHASTA_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLHASTA_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/ControllerMessage.h"
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolHasta : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
protected:
|
||||
static std::string convertByte(unsigned char byte);
|
||||
static std::string convertBytev2(unsigned char byte);
|
||||
std::string getStringForMethodv1(int method);
|
||||
std::string getStringForMethodv2(int method);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLHASTA_H_
|
||||
151
external/tellstick-core/ProtocolIkea.cpp
vendored
Normal file
151
external/tellstick-core/ProtocolIkea.cpp
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolIkea.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
#ifdef _WINDOWS
|
||||
#define strtok_r(s, d, p) strtok_s(s, d, p)
|
||||
#endif
|
||||
|
||||
int ProtocolIkea::methods() const {
|
||||
if (TelldusCore::comparei(model(), L"selflearning-switch")) {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM;
|
||||
}
|
||||
|
||||
std::string ProtocolIkea::getStringForMethod(int method, unsigned char level, Controller *) {
|
||||
const char B1[] = {84, 84, 0};
|
||||
const char B0[] = {170, 0};
|
||||
|
||||
int intSystem = this->getIntParameter(L"system", 1, 16)-1;
|
||||
int intFadeStyle = TelldusCore::comparei(this->getStringParameter(L"fade", L"true"), L"true");
|
||||
std::wstring wstrUnits = this->getStringParameter(L"units", L"");
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
level = 255;
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
level = 0;
|
||||
} else if (method == TELLSTICK_DIM) {
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (wstrUnits == L"") {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string strUnits(TelldusCore::wideToString(wstrUnits));
|
||||
int intUnits = 0; // Start without any units
|
||||
|
||||
char *tempUnits = new char[strUnits.size()+1];
|
||||
#ifdef _WINDOWS
|
||||
strcpy_s(tempUnits, strUnits.size()+1, strUnits.c_str());
|
||||
#else
|
||||
snprintf(tempUnits, strUnits.size()+1, "%s", strUnits.c_str());
|
||||
#endif
|
||||
|
||||
char *saveptr;
|
||||
char *strToken = strtok_r(tempUnits, ",", &saveptr);
|
||||
do {
|
||||
int intUnit = atoi(strToken);
|
||||
if (intUnit == 10) {
|
||||
intUnit = 0;
|
||||
}
|
||||
intUnits = intUnits | ( 1<<(9-intUnit) );
|
||||
} while ( (strToken = strtok_r(NULL, ",", &saveptr)) != NULL );
|
||||
|
||||
delete[] tempUnits;
|
||||
|
||||
std::string strReturn;
|
||||
strReturn.append(1, 'S');
|
||||
strReturn.append(1, 84);
|
||||
strReturn.append(1, 84);
|
||||
strReturn.append(1, 84);
|
||||
strReturn.append(1, 84);
|
||||
strReturn.append(1, 84);
|
||||
strReturn.append(1, 84);
|
||||
strReturn.append(1, 170);
|
||||
|
||||
std::string strChannels = "";
|
||||
int intCode = (intSystem << 10) | intUnits;
|
||||
int checksum1 = 0;
|
||||
int checksum2 = 0;
|
||||
for (int i = 13; i >= 0; --i) {
|
||||
if ((intCode >> i) & 1) {
|
||||
strChannels.append(B1);
|
||||
if (i % 2 == 0)
|
||||
checksum2++;
|
||||
else
|
||||
checksum1++;
|
||||
} else {
|
||||
strChannels.append(B0);
|
||||
}
|
||||
}
|
||||
strReturn.append(strChannels); // System + Units
|
||||
|
||||
strReturn.append(checksum1 %2 == 0 ? B1 : B0); // 1st checksum
|
||||
strReturn.append(checksum2 %2 == 0 ? B1 : B0); // 2nd checksum
|
||||
|
||||
int intLevel = 0;
|
||||
if (level <= 12) {
|
||||
intLevel = 10; // Level 10 is actually off
|
||||
} else if (level <= 37) {
|
||||
intLevel = 1;
|
||||
} else if (level <= 62) {
|
||||
intLevel = 2;
|
||||
} else if (level <= 87) {
|
||||
intLevel = 3;
|
||||
} else if (level <= 112) {
|
||||
intLevel = 4;
|
||||
} else if (level <= 137) {
|
||||
intLevel = 5;
|
||||
} else if (level <= 162) {
|
||||
intLevel = 6;
|
||||
} else if (level <= 187) {
|
||||
intLevel = 7;
|
||||
} else if (level <= 212) {
|
||||
intLevel = 8;
|
||||
} else if (level <= 237) {
|
||||
intLevel = 9;
|
||||
} else {
|
||||
intLevel = 0; // Level 0 is actually full on
|
||||
}
|
||||
|
||||
int intFade = 0;
|
||||
if (intFadeStyle == 1) {
|
||||
intFade = 11 << 4; // Smooth
|
||||
} else {
|
||||
intFade = 1 << 4; // Instant
|
||||
}
|
||||
|
||||
intCode = intLevel | intFade; // Concat level and fade
|
||||
|
||||
checksum1 = 0;
|
||||
checksum2 = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if ((intCode >> i) & 1) {
|
||||
strReturn.append(B1);
|
||||
if (i % 2 == 0)
|
||||
checksum1++;
|
||||
else
|
||||
checksum2++;
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
}
|
||||
}
|
||||
|
||||
strReturn.append(checksum1 %2 == 0 ? B1 : B0); // 1st checksum
|
||||
strReturn.append(checksum2 %2 == 0 ? B1 : B0); // 2nd checksum
|
||||
|
||||
strReturn.append("+");
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
19
external/tellstick-core/ProtocolIkea.h
vendored
Normal file
19
external/tellstick-core/ProtocolIkea.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLIKEA_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLIKEA_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolIkea : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLIKEA_H_
|
||||
46
external/tellstick-core/ProtocolMandolyn.cpp
vendored
Normal file
46
external/tellstick-core/ProtocolMandolyn.cpp
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolMandolyn.h"
|
||||
#include <stdlib.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
std::string ProtocolMandolyn::decodeData(const ControllerMessage &dataMsg) {
|
||||
std::string data = dataMsg.getParameter("data");
|
||||
uint32_t value = (uint32_t)TelldusCore::hexTo64l(data);
|
||||
|
||||
// parity not used
|
||||
// bool parity = value & 0x1;
|
||||
value >>= 1;
|
||||
|
||||
double temp = static_cast<double>(value & 0x7FFF) - static_cast<double>(6400);
|
||||
temp = temp/128.0;
|
||||
value >>= 15;
|
||||
|
||||
uint8_t humidity = (value & 0x7F);
|
||||
value >>= 7;
|
||||
|
||||
// battOk not used
|
||||
// bool battOk = value & 0x1;
|
||||
value >>= 3;
|
||||
|
||||
uint8_t channel = (value & 0x3)+1;
|
||||
value >>= 2;
|
||||
|
||||
uint8_t house = value & 0xF;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:mandolyn;id:"
|
||||
<< house*10+channel
|
||||
<< ";model:temperaturehumidity;"
|
||||
<< "temp:" << std::fixed << std::setprecision(1) << temp
|
||||
<< ";humidity:" << static_cast<int>(humidity) << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
19
external/tellstick-core/ProtocolMandolyn.h
vendored
Normal file
19
external/tellstick-core/ProtocolMandolyn.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLMANDOLYN_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLMANDOLYN_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolMandolyn : public Protocol {
|
||||
public:
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLMANDOLYN_H_
|
||||
279
external/tellstick-core/ProtocolNexa.cpp
vendored
Normal file
279
external/tellstick-core/ProtocolNexa.cpp
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolNexa.h"
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "service/TellStick.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
int ProtocolNexa::lastArctecCodeSwitchWasTurnOff = 0; // TODO(stefan): always removing first turnon now, make more flexible (waveman too)
|
||||
|
||||
int ProtocolNexa::methods() const {
|
||||
if (TelldusCore::comparei(model(), L"codeswitch")) {
|
||||
return (TELLSTICK_TURNON | TELLSTICK_TURNOFF);
|
||||
|
||||
} else if (TelldusCore::comparei(model(), L"selflearning-switch")) {
|
||||
return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN);
|
||||
|
||||
} else if (TelldusCore::comparei(model(), L"selflearning-dimmer")) {
|
||||
return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_LEARN);
|
||||
|
||||
} else if (TelldusCore::comparei(model(), L"bell")) {
|
||||
return TELLSTICK_BELL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getStringForMethod(int method, unsigned char data, Controller *controller) {
|
||||
if (TelldusCore::comparei(model(), L"codeswitch")) {
|
||||
return getStringCodeSwitch(method);
|
||||
} else if (TelldusCore::comparei(model(), L"bell")) {
|
||||
return getStringBell();
|
||||
}
|
||||
if ((method == TELLSTICK_TURNON) && TelldusCore::comparei(model(), L"selflearning-dimmer")) {
|
||||
// Workaround for not letting a dimmer do into "dimming mode"
|
||||
return getStringSelflearning(TELLSTICK_DIM, 255);
|
||||
}
|
||||
if (method == TELLSTICK_LEARN) {
|
||||
std::string str = getStringSelflearning(TELLSTICK_TURNON, data);
|
||||
|
||||
// Check to see if we are an old TellStick (fw <= 2, batch <= 8)
|
||||
TellStick *ts = reinterpret_cast<TellStick *>(controller);
|
||||
if (!ts) {
|
||||
return str;
|
||||
}
|
||||
if (ts->pid() == 0x0c30 && ts->firmwareVersion() <= 2) {
|
||||
// Workaround for the bug in early firmwares
|
||||
// The TellStick have a fixed pause (max) between two packets.
|
||||
// It is only correct between the first and second packet.
|
||||
// It seems faster to send two packes at a time and some
|
||||
// receivers seems picky about this when learning.
|
||||
// We also return the last packet so Device::doAction() doesn't
|
||||
// report TELLSTICK_ERROR_METHOD_NOT_SUPPORTED
|
||||
|
||||
str.insert(0, 1, 2); // Repeat two times
|
||||
str.insert(0, 1, 'R');
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
controller->send(str);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
return getStringSelflearning(method, data);
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getStringCodeSwitch(int method) {
|
||||
std::string strReturn = "S";
|
||||
|
||||
std::wstring house = getStringParameter(L"house", L"A");
|
||||
int intHouse = house[0] - L'A';
|
||||
strReturn.append(getCodeSwitchTuple(intHouse));
|
||||
strReturn.append(getCodeSwitchTuple(getIntParameter(L"unit", 1, 16)-1));
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strReturn.append("$k$k$kk$$kk$$kk$$k+");
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strReturn.append(this->getOffCode());
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getStringBell() {
|
||||
std::string strReturn = "S";
|
||||
|
||||
std::wstring house = getStringParameter(L"house", L"A");
|
||||
int intHouse = house[0] - L'A';
|
||||
strReturn.append(getCodeSwitchTuple(intHouse));
|
||||
strReturn.append("$kk$$kk$$kk$$k$k"); // Unit 7
|
||||
strReturn.append("$kk$$kk$$kk$$kk$$k+"); // Bell
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getStringSelflearning(int method, unsigned char level) {
|
||||
int intHouse = getIntParameter(L"house", 1, 67108863);
|
||||
int intCode = getIntParameter(L"unit", 1, 16)-1;
|
||||
return getStringSelflearningForCode(intHouse, intCode, method, level);
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getStringSelflearningForCode(int intHouse, int intCode, int method, unsigned char level) {
|
||||
const unsigned char START[] = {'T', 127, 255, 24, 1, 0};
|
||||
// const char START[] = {'T',130,255,26,24,0};
|
||||
|
||||
std::string strMessage(reinterpret_cast<const char*>(START));
|
||||
strMessage.append(1, (method == TELLSTICK_DIM ? 147 : 132)); // Number of pulses
|
||||
|
||||
std::string m;
|
||||
for (int i = 25; i >= 0; --i) {
|
||||
m.append( intHouse & 1 << i ? "10" : "01" );
|
||||
}
|
||||
m.append("01"); // Group
|
||||
|
||||
// On/off
|
||||
if (method == TELLSTICK_DIM) {
|
||||
m.append("00");
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
m.append("01");
|
||||
} else if (method == TELLSTICK_TURNON) {
|
||||
m.append("10");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
for (int i = 3; i >= 0; --i) {
|
||||
m.append( intCode & 1 << i ? "10" : "01" );
|
||||
}
|
||||
|
||||
if (method == TELLSTICK_DIM) {
|
||||
unsigned char newLevel = level/16;
|
||||
for (int i = 3; i >= 0; --i) {
|
||||
m.append(newLevel & 1 << i ? "10" : "01");
|
||||
}
|
||||
}
|
||||
|
||||
// The number of data is odd.
|
||||
// Add this to make it even, otherwise the following loop will not work
|
||||
m.append("0");
|
||||
|
||||
unsigned char code = 9; // b1001, startcode
|
||||
for (unsigned int i = 0; i < m.length(); ++i) {
|
||||
code <<= 4;
|
||||
if (m[i] == '1') {
|
||||
code |= 8; // b1000
|
||||
} else {
|
||||
code |= 10; // b1010
|
||||
// code |= 11; //b1011
|
||||
}
|
||||
if (i % 2 == 0) {
|
||||
strMessage.append(1, code);
|
||||
code = 0;
|
||||
}
|
||||
}
|
||||
strMessage.append("+");
|
||||
|
||||
// for( int i = 0; i < strMessage.length(); ++i ) {
|
||||
// printf("%i,", (unsigned char)strMessage[i]);
|
||||
// }
|
||||
// printf("\n");
|
||||
return strMessage;
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::decodeData(const ControllerMessage& dataMsg) {
|
||||
uint64_t allData = dataMsg.getInt64Parameter("data");
|
||||
|
||||
if(TelldusCore::comparei(dataMsg.model(), L"selflearning")) {
|
||||
// selflearning
|
||||
return decodeDataSelfLearning(allData);
|
||||
} else {
|
||||
// codeswitch
|
||||
return decodeDataCodeSwitch(allData);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::decodeDataSelfLearning(uint64_t allData) {
|
||||
unsigned int house = 0;
|
||||
unsigned int unit = 0;
|
||||
unsigned int group = 0;
|
||||
unsigned int method = 0;
|
||||
|
||||
house = allData & 0xFFFFFFC0;
|
||||
house >>= 6;
|
||||
|
||||
group = allData & 0x20;
|
||||
group >>= 5;
|
||||
|
||||
method = allData & 0x10;
|
||||
method >>= 4;
|
||||
|
||||
unit = allData & 0xF;
|
||||
unit++;
|
||||
|
||||
if(house < 1 || house > 67108863 || unit < 1 || unit > 16) {
|
||||
// not arctech selflearning
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:arctech;model:selflearning;house:" << house << ";unit:" << unit << ";group:" << group << ";method:";
|
||||
if(method == 1) {
|
||||
retString << "turnon;";
|
||||
} else if(method == 0) {
|
||||
retString << "turnoff;";
|
||||
} else {
|
||||
// not arctech selflearning
|
||||
return "";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::decodeDataCodeSwitch(uint64_t allData) {
|
||||
unsigned int house = 0;
|
||||
unsigned int unit = 0;
|
||||
unsigned int method = 0;
|
||||
|
||||
method = allData & 0xF00;
|
||||
method >>= 8;
|
||||
|
||||
unit = allData & 0xF0;
|
||||
unit >>= 4;
|
||||
unit++;
|
||||
|
||||
house = allData & 0xF;
|
||||
|
||||
if(house > 16 || unit < 1 || unit > 16) {
|
||||
// not arctech codeswitch
|
||||
return "";
|
||||
}
|
||||
|
||||
house = house + 'A'; // house from A to P
|
||||
|
||||
if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1) {
|
||||
lastArctecCodeSwitchWasTurnOff = 0;
|
||||
return ""; // probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose
|
||||
// one turnon/bell, but it's better than the alternative...
|
||||
}
|
||||
|
||||
if(method == 6) {
|
||||
lastArctecCodeSwitchWasTurnOff = 1;
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:arctech;model:codeswitch;house:" << static_cast<char>(house);
|
||||
|
||||
if(method == 6) {
|
||||
retString << ";unit:" << unit << ";method:turnoff;";
|
||||
} else if(method == 14) {
|
||||
retString << ";unit:" << unit << ";method:turnon;";
|
||||
} else if(method == 15) {
|
||||
retString << ";method:bell;";
|
||||
} else {
|
||||
// not arctech codeswitch
|
||||
return "";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getCodeSwitchTuple(int intCode) {
|
||||
std::string strReturn = "";
|
||||
for( int i = 0; i < 4; ++i ) {
|
||||
if (intCode & 1) { // Convert 1
|
||||
strReturn.append("$kk$");
|
||||
} else { // Convert 0
|
||||
strReturn.append("$k$k");
|
||||
}
|
||||
intCode >>= 1;
|
||||
}
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolNexa::getOffCode() const {
|
||||
return "$k$k$kk$$kk$$k$k$k+";
|
||||
}
|
||||
39
external/tellstick-core/ProtocolNexa.h
vendored
Normal file
39
external/tellstick-core/ProtocolNexa.h
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLNEXA_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLNEXA_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include "service/ControllerMessage.h"
|
||||
#include "service/Device.h"
|
||||
|
||||
class ProtocolNexa : public Protocol {
|
||||
public:
|
||||
virtual int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
protected:
|
||||
std::string getStringSelflearning(int method, unsigned char data);
|
||||
std::string getStringCodeSwitch(int method);
|
||||
std::string getStringBell();
|
||||
virtual std::string getOffCode() const;
|
||||
static std::string getCodeSwitchTuple(int code);
|
||||
static std::string getStringSelflearningForCode(int house, int unit, int method, unsigned char data);
|
||||
|
||||
private:
|
||||
static int lastArctecCodeSwitchWasTurnOff;
|
||||
static std::string decodeDataCodeSwitch(uint64_t allData);
|
||||
static std::string decodeDataSelfLearning(uint64_t allData);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLNEXA_H_
|
||||
347
external/tellstick-core/ProtocolOregon.cpp
vendored
Normal file
347
external/tellstick-core/ProtocolOregon.cpp
vendored
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolOregon.h"
|
||||
#include <stdlib.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
std::string ProtocolOregon::decodeData(const ControllerMessage &dataMsg) {
|
||||
std::string data = dataMsg.getParameter("data");
|
||||
|
||||
std::wstring model = dataMsg.model();
|
||||
if (model.compare(L"0xEA4C") == 0) {
|
||||
return decodeEA4C(data);
|
||||
} else if (model.compare(L"0x1A2D") == 0) {
|
||||
return decode1A2D(data);
|
||||
} else if (model.compare(L"0xF824") == 0) {
|
||||
return decodeF824(data);
|
||||
} else if (model.compare(L"0x1984") == 0 || model.compare(L"0x1994") == 0) {
|
||||
return decode1984(data, model);
|
||||
} else if (model.compare(L"0x2914") == 0) {
|
||||
return decode2914(data);
|
||||
} else if (model.compare(L"0xC844") == 0 || model.compare(L"0xEC40") == 0) {
|
||||
// C844 - pool thermometer
|
||||
return decodeC844(data, model);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ProtocolOregon::decodeEA4C(const std::string &data) {
|
||||
uint64_t value = TelldusCore::hexTo64l(data);
|
||||
|
||||
uint8_t checksum = 0xE + 0xA + 0x4 + 0xC;
|
||||
checksum -= (value & 0xF) * 0x10;
|
||||
checksum -= 0xA;
|
||||
value >>= 8;
|
||||
|
||||
uint8_t checksumw = (value >> 4) & 0xF;
|
||||
bool neg = value & (1 << 3);
|
||||
int hundred = value & 3;
|
||||
checksum += (value & 0xF);
|
||||
value >>= 8;
|
||||
|
||||
uint8_t temp2 = value & 0xF;
|
||||
uint8_t temp1 = (value >> 4) & 0xF;
|
||||
checksum += temp2 + temp1;
|
||||
value >>= 8;
|
||||
|
||||
uint8_t temp3 = (value >> 4) & 0xF;
|
||||
checksum += (value & 0xF) + temp3;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t address = value & 0xFF;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
// channel not used
|
||||
// uint8_t channel = (value >> 4) & 0x7;
|
||||
|
||||
if (checksum != checksumw) {
|
||||
return "";
|
||||
}
|
||||
|
||||
double temperature = ((hundred * 1000) + (temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
if (neg) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:oregon;model:EA4C;id:" << static_cast<int>(address)
|
||||
<< ";temp:" << std::fixed << std::setprecision(1) << temperature << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolOregon::decode1984(const std::string &data, const std::wstring &model) {
|
||||
// wind
|
||||
uint64_t value = TelldusCore::hexTo64l(data);
|
||||
|
||||
uint8_t crcCheck = value & 0xF; // PROBABLY crc
|
||||
value >>= 4;
|
||||
uint8_t messageChecksum1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t messageChecksum2 = value & 0xF;
|
||||
|
||||
value >>= 4;
|
||||
uint8_t avg1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t avg2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t avg3 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t gust1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t gust2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t gust3 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t unknown1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t unknown2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t direction = value & 0xF;
|
||||
|
||||
value >>= 4;
|
||||
uint8_t battery = value & 0xF; // PROBABLY battery
|
||||
value >>= 4;
|
||||
uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
value >>= 8;
|
||||
uint8_t channel = value & 0xF;
|
||||
checksum += unknown1 + unknown2 + avg1 + avg2 + avg3 + gust1 + gust2 + gust3 + direction + battery + channel;
|
||||
|
||||
if (model.compare(L"0x1984") == 0) {
|
||||
checksum += 0x1 + 0x9 + 0x8 + 0x4;
|
||||
} else {
|
||||
checksum += 0x1 + 0x9 + 0x9 + 0x4;
|
||||
}
|
||||
|
||||
if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) {
|
||||
// checksum error
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
double avg = ((avg1 * 100) + (avg2 * 10) + avg3)/10.0;
|
||||
double gust = ((gust1 * 100) + (gust2 * 10) + gust3)/10.0;
|
||||
float directiondegree = 22.5 * direction;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:oregon;model:1984;id:" << static_cast<int>(rollingcode)
|
||||
<< ";winddirection:" << directiondegree
|
||||
<< ";windaverage:" << std::fixed << std::setprecision(1) << avg
|
||||
<< ";windgust:" << std::fixed << std::setprecision(1) << gust << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolOregon::decode1A2D(const std::string &data) {
|
||||
uint64_t value = TelldusCore::hexTo64l(data);
|
||||
// checksum2 not used yet
|
||||
// uint8_t checksum2 = value & 0xFF;
|
||||
value >>= 8;
|
||||
uint8_t checksum1 = value & 0xFF;
|
||||
value >>= 8;
|
||||
|
||||
uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t hum1 = value & 0xF;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t neg = value & (1 << 3);
|
||||
uint8_t hum2 = (value >> 4) & 0xF;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t temp2 = value & 0xF;
|
||||
uint8_t temp1 = (value >> 4) & 0xF;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t temp3 = (value >> 4) & 0xF;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t address = value & 0xFF;
|
||||
value >>= 8;
|
||||
|
||||
checksum += ((value >> 4) & 0xF) + (value & 0xF);
|
||||
// channel not used
|
||||
// uint8_t channel = (value >> 4) & 0x7;
|
||||
|
||||
checksum += 0x1 + 0xA + 0x2 + 0xD - 0xA;
|
||||
|
||||
// TODO(micke): Find out how checksum2 works
|
||||
if (checksum != checksum1) {
|
||||
return "";
|
||||
}
|
||||
|
||||
double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
if (neg) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
int humidity = (hum1 * 10.0) + hum2;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:oregon;model:1A2D;id:" << static_cast<int>(address)
|
||||
<< ";temp:" << std::fixed << std::setprecision(1) << temperature
|
||||
<< ";humidity:" << humidity << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolOregon::decode2914(const std::string &data) {
|
||||
// rain
|
||||
uint64_t value = TelldusCore::hexTo64l(data);
|
||||
|
||||
uint8_t messageChecksum1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t messageChecksum2 = value & 0xF;
|
||||
|
||||
value >>= 4;
|
||||
uint8_t totRain1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t totRain2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t totRain3 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t totRain4 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t totRain5 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t totRain6 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t rainRate1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t rainRate2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t rainRate3 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t rainRate4 = value & 0xF;
|
||||
|
||||
value >>= 4;
|
||||
uint8_t battery = value & 0xF; // PROBABLY battery
|
||||
value >>= 4;
|
||||
uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
value >>= 8;
|
||||
uint8_t channel = value & 0xF;
|
||||
checksum += totRain1 + totRain2 + totRain3 + totRain4 + totRain5 + totRain6 + rainRate1 + rainRate2 + rainRate3 + rainRate4 + battery + channel + 0x2 + 0x9 + 0x1 + 0x4;
|
||||
|
||||
if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) {
|
||||
// checksum error
|
||||
return "";
|
||||
}
|
||||
|
||||
double totRain = ((totRain1 * 100000) + (totRain2 * 10000) + (totRain3 * 1000) + (totRain4 * 100) + (totRain5 * 10) + totRain6)/1000.0*25.4;
|
||||
double rainRate = ((rainRate1 * 1000) + (rainRate2 * 100) + (rainRate3 * 10) + rainRate4)/100.0*25.4;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:oregon;model:2914;id:" << static_cast<int>(rollingcode)
|
||||
<< ";raintotal:" << std::fixed << std::setprecision(1) << totRain
|
||||
<< ";rainrate:" << std::fixed << std::setprecision(1) << rainRate << ";";
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolOregon::decodeF824(const std::string &data) {
|
||||
uint64_t value = TelldusCore::hexTo64l(data);
|
||||
|
||||
uint8_t crcCheck = value & 0xF; // PROBABLY crc
|
||||
value >>= 4;
|
||||
uint8_t messageChecksum1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t messageChecksum2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t unknown = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t hum1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t hum2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t neg = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t temp1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t temp2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t temp3 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t battery = value & 0xF; // PROBABLY battery
|
||||
value >>= 4;
|
||||
uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
value >>= 8;
|
||||
uint8_t channel = value & 0xF;
|
||||
checksum += unknown + hum1 + hum2 + neg + temp1 + temp2 + temp3 + battery + channel + 0xF + 0x8 + 0x2 + 0x4;
|
||||
|
||||
if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) {
|
||||
// checksum error
|
||||
return "";
|
||||
}
|
||||
|
||||
double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
if (neg) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
int humidity = (hum1 * 10.0) + hum2;
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:oregon;model:F824;id:" << static_cast<int>(rollingcode)
|
||||
<< ";temp:" << std::fixed << std::setprecision(1) << temperature
|
||||
<< ";humidity:" << humidity << ";";
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
|
||||
std::string ProtocolOregon::decodeC844(const std::string &data, const std::wstring &model) {
|
||||
uint64_t value = TelldusCore::hexTo64l(data);
|
||||
|
||||
uint8_t messageChecksum1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t messageChecksum2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t neg = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t temp1 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t temp2 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t temp3 = value & 0xF;
|
||||
value >>= 4;
|
||||
uint8_t battery = value & 0xF; // PROBABLY battery
|
||||
value >>= 4;
|
||||
uint8_t rollingcode = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF);
|
||||
value >>= 8;
|
||||
uint8_t channel = value & 0xF;
|
||||
checksum += neg + temp1 + temp2 + temp3 + battery + channel;
|
||||
|
||||
if (model.compare(L"0xC844") == 0) {
|
||||
checksum += 0xC + 0x8 + 0x4 + 0x4;
|
||||
} else {
|
||||
checksum += 0xE + 0xC + 0x4 + 0x0;
|
||||
}
|
||||
|
||||
if (((checksum >> 4) & 0xF) != messageChecksum1 || (checksum & 0xF) != messageChecksum2) {
|
||||
// checksum error
|
||||
return "";
|
||||
}
|
||||
|
||||
double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
if (neg) {
|
||||
temperature = -temperature;
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:sensor;protocol:oregon;model:C844;id:" << static_cast<int>(rollingcode)
|
||||
<< ";temp:" << std::fixed << std::setprecision(1) << temperature << ";";
|
||||
return retString.str();
|
||||
}
|
||||
27
external/tellstick-core/ProtocolOregon.h
vendored
Normal file
27
external/tellstick-core/ProtocolOregon.h
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLOREGON_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLOREGON_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolOregon : public Protocol {
|
||||
public:
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
protected:
|
||||
static std::string decodeEA4C(const std::string &data);
|
||||
static std::string decode1A2D(const std::string &data);
|
||||
static std::string decodeF824(const std::string &data);
|
||||
static std::string decode1984(const std::string &data, const std::wstring &model);
|
||||
static std::string decode2914(const std::string &data);
|
||||
static std::string decodeC844(const std::string &data, const std::wstring &model);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLOREGON_H_
|
||||
115
external/tellstick-core/ProtocolRisingSun.cpp
vendored
Normal file
115
external/tellstick-core/ProtocolRisingSun.cpp
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolRisingSun.h"
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
int ProtocolRisingSun::methods() const {
|
||||
if (TelldusCore::comparei(model(), L"selflearning")) {
|
||||
return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN);
|
||||
}
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
std::string ProtocolRisingSun::getStringForMethod(int method, unsigned char data, Controller *controller) {
|
||||
if (TelldusCore::comparei(model(), L"selflearning")) {
|
||||
return getStringSelflearning(method);
|
||||
}
|
||||
return getStringCodeSwitch(method);
|
||||
}
|
||||
|
||||
std::string ProtocolRisingSun::getStringSelflearning(int method) {
|
||||
int intHouse = this->getIntParameter(L"house", 1, 33554432)-1;
|
||||
int intCode = this->getIntParameter(L"code", 1, 16)-1;
|
||||
|
||||
const char code_on[][7] = {
|
||||
"110110", "001110", "100110", "010110",
|
||||
"111001", "000101", "101001", "011001",
|
||||
"110000", "001000", "100000", "010000",
|
||||
"111100", "000010", "101100", "011100"
|
||||
};
|
||||
const char code_off[][7] = {
|
||||
"111110", "000001", "101110", "011110",
|
||||
"110101", "001101", "100101", "010101",
|
||||
"111000", "000100", "101000", "011000",
|
||||
"110010", "001010", "100010", "010010"
|
||||
};
|
||||
const char l = 120;
|
||||
const char s = 51;
|
||||
|
||||
std::string strCode = "10";
|
||||
int code = intCode;
|
||||
code = (code < 0 ? 0 : code);
|
||||
code = (code > 15 ? 15 : code);
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strCode.append(code_on[code]);
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strCode.append(code_off[code]);
|
||||
} else if (method == TELLSTICK_LEARN) {
|
||||
strCode.append(code_on[code]);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
int house = intHouse;
|
||||
for(int i = 0; i < 25; ++i) {
|
||||
if (house & 1) {
|
||||
strCode.append(1, '1');
|
||||
} else {
|
||||
strCode.append(1, '0');
|
||||
}
|
||||
house >>= 1;
|
||||
}
|
||||
|
||||
std::string strReturn;
|
||||
for(unsigned int i = 0; i < strCode.length(); ++i) {
|
||||
if (strCode[i] == '1') {
|
||||
strReturn.append(1, l);
|
||||
strReturn.append(1, s);
|
||||
} else {
|
||||
strReturn.append(1, s);
|
||||
strReturn.append(1, l);
|
||||
}
|
||||
}
|
||||
|
||||
std::string prefix = "P";
|
||||
prefix.append(1, 5);
|
||||
if (method == TELLSTICK_LEARN) {
|
||||
prefix.append("R");
|
||||
prefix.append( 1, 50 );
|
||||
}
|
||||
prefix.append("S");
|
||||
strReturn.insert(0, prefix);
|
||||
strReturn.append(1, '+');
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolRisingSun::getStringCodeSwitch(int method) {
|
||||
std::string strReturn = "S.e";
|
||||
strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"house", 1, 4)-1));
|
||||
strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"unit", 1, 4)-1));
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strReturn.append("e..ee..ee..ee..e+");
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strReturn.append("e..ee..ee..e.e.e+");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolRisingSun::getCodeSwitchTuple(int intToConvert) {
|
||||
std::string strReturn = "";
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
if (i == intToConvert) {
|
||||
strReturn.append( ".e.e" );
|
||||
} else {
|
||||
strReturn.append( "e..e" );
|
||||
}
|
||||
}
|
||||
return strReturn;
|
||||
}
|
||||
24
external/tellstick-core/ProtocolRisingSun.h
vendored
Normal file
24
external/tellstick-core/ProtocolRisingSun.h
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLRISINGSUN_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLRISINGSUN_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolRisingSun : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
|
||||
protected:
|
||||
std::string getStringSelflearning(int method);
|
||||
std::string getStringCodeSwitch(int method);
|
||||
static std::string getCodeSwitchTuple(int code);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLRISINGSUN_H_
|
||||
108
external/tellstick-core/ProtocolSartano.cpp
vendored
Normal file
108
external/tellstick-core/ProtocolSartano.cpp
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolSartano.h"
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int16 uint16_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
int ProtocolSartano::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
std::string ProtocolSartano::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
std::wstring strCode = this->getStringParameter(L"code", L"");
|
||||
return getStringForCode(strCode, method);
|
||||
}
|
||||
|
||||
std::string ProtocolSartano::getStringForCode(const std::wstring &strCode, int method) {
|
||||
std::string strReturn("S");
|
||||
|
||||
for (size_t i = 0; i < strCode.length(); ++i) {
|
||||
if (strCode[i] == L'1') {
|
||||
strReturn.append("$k$k");
|
||||
} else {
|
||||
strReturn.append("$kk$");
|
||||
}
|
||||
}
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strReturn.append("$k$k$kk$$k+");
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strReturn.append("$kk$$k$k$k+");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolSartano::decodeData(const ControllerMessage &dataMsg) {
|
||||
uint64_t allDataIn;
|
||||
uint16_t allData = 0;
|
||||
unsigned int code = 0;
|
||||
unsigned int method1 = 0;
|
||||
unsigned int method2 = 0;
|
||||
unsigned int method = 0;
|
||||
|
||||
allDataIn = dataMsg.getInt64Parameter("data");
|
||||
|
||||
uint16_t mask = (1<<11);
|
||||
for(int i = 0; i < 12; ++i) {
|
||||
allData >>= 1;
|
||||
if((allDataIn & mask) == 0) {
|
||||
allData |= (1<<11);
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
code = allData & 0xFFC;
|
||||
code >>= 2;
|
||||
|
||||
method1 = allData & 0x2;
|
||||
method1 >>= 1;
|
||||
|
||||
method2 = allData & 0x1;
|
||||
|
||||
if(method1 == 0 && method2 == 1) {
|
||||
method = 0; // off
|
||||
} else if(method1 == 1 && method2 == 0) {
|
||||
method = 1; // on
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(code > 1023) {
|
||||
// not sartano
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:sartano;model:codeswitch;code:";
|
||||
mask = (1<<9);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if((code & mask) != 0) {
|
||||
retString << 1;
|
||||
} else {
|
||||
retString << 0;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
retString << ";method:";
|
||||
|
||||
if(method == 0) {
|
||||
retString << "turnoff;";
|
||||
} else {
|
||||
retString << "turnon;";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
24
external/tellstick-core/ProtocolSartano.h
vendored
Normal file
24
external/tellstick-core/ProtocolSartano.h
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLSARTANO_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLSARTANO_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolSartano : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
protected:
|
||||
std::string getStringForCode(const std::wstring &code, int method);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLSARTANO_H_
|
||||
16
external/tellstick-core/ProtocolScene.cpp
vendored
Normal file
16
external/tellstick-core/ProtocolScene.cpp
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolScene.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolScene::methods() const {
|
||||
return TELLSTICK_EXECUTE;
|
||||
}
|
||||
|
||||
std::string ProtocolScene::getStringForMethod(int method, unsigned char data, Controller *) {
|
||||
return "";
|
||||
}
|
||||
22
external/tellstick-core/ProtocolScene.h
vendored
Normal file
22
external/tellstick-core/ProtocolScene.h
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLSCENE_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLSCENE_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolScene : public Protocol {
|
||||
public:
|
||||
virtual int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLSCENE_H_
|
||||
|
||||
|
||||
|
||||
146
external/tellstick-core/ProtocolSilvanChip.cpp
vendored
Normal file
146
external/tellstick-core/ProtocolSilvanChip.cpp
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolSilvanChip.h"
|
||||
#include <string>
|
||||
#include "common/Strings.h"
|
||||
|
||||
int ProtocolSilvanChip::methods() const {
|
||||
if (TelldusCore::comparei(model(), L"kp100")) {
|
||||
return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN;
|
||||
} else if (TelldusCore::comparei(model(), L"ecosavers")) {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN;
|
||||
} else if (TelldusCore::comparei(model(), L"displaymatic")) {
|
||||
return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string ProtocolSilvanChip::getStringForMethod(int method, unsigned char data, Controller *controller) {
|
||||
if (TelldusCore::comparei(model(), L"kp100")) {
|
||||
std::string preamble;
|
||||
preamble.append(1, 100);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 100);
|
||||
|
||||
const std::string one = "\xFF\x1\x2E\x2E";
|
||||
const std::string zero = "\x2E\xFF\x1\x2E";
|
||||
int button = 0;
|
||||
if (method == TELLSTICK_UP) {
|
||||
button = 2;
|
||||
} else if (method == TELLSTICK_DOWN) {
|
||||
button = 8;
|
||||
} else if (method == TELLSTICK_STOP) {
|
||||
button = 4;
|
||||
} else if (method == TELLSTICK_LEARN) {
|
||||
button = 1;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return this->getString(preamble, one, zero, button);
|
||||
} else if (TelldusCore::comparei(model(), L"displaymatic")) {
|
||||
std::string preamble;
|
||||
preamble.append(1, 0x25);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 0x25);
|
||||
const std::string one = "\x69\25";
|
||||
const std::string zero = "\x25\x69";
|
||||
int button = 0;
|
||||
if (method == TELLSTICK_UP) {
|
||||
button = 1;
|
||||
} else if (method == TELLSTICK_DOWN) {
|
||||
button = 4;
|
||||
} else if (method == TELLSTICK_STOP) {
|
||||
button = 2;
|
||||
}
|
||||
return this->getString(preamble, one, zero, button);
|
||||
} else if (TelldusCore::comparei(model(), L"ecosavers")) {
|
||||
std::string preamble;
|
||||
preamble.append(1, 0x25);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 255);
|
||||
preamble.append(1, 1);
|
||||
preamble.append(1, 0x25);
|
||||
const std::string one = "\x69\25";
|
||||
const std::string zero = "\x25\x69";
|
||||
int intUnit = this->getIntParameter(L"unit", 1, 4);
|
||||
int button = 0;
|
||||
if (intUnit == 1) {
|
||||
button = 7;
|
||||
} else if (intUnit == 2) {
|
||||
button = 3;
|
||||
} else if (intUnit == 3) {
|
||||
button = 5;
|
||||
} else if (intUnit == 4) {
|
||||
button = 6;
|
||||
}
|
||||
|
||||
if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) {
|
||||
button |= 8;
|
||||
}
|
||||
return this->getString(preamble, one, zero, button);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ProtocolSilvanChip::getString(const std::string &preamble, const std::string &one, const std::string &zero, int button) {
|
||||
int intHouse = this->getIntParameter(L"house", 1, 1048575);
|
||||
std::string strReturn = preamble;
|
||||
|
||||
for( int i = 19; i >= 0; --i ) {
|
||||
if (intHouse & (1 << i)) {
|
||||
strReturn.append(one);
|
||||
} else {
|
||||
strReturn.append(zero);
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 3; i >= 0; --i) {
|
||||
if (button & (1 << i)) {
|
||||
strReturn.append(one);
|
||||
} else {
|
||||
strReturn.append(zero);
|
||||
}
|
||||
}
|
||||
|
||||
strReturn.append(zero);
|
||||
return strReturn;
|
||||
}
|
||||
22
external/tellstick-core/ProtocolSilvanChip.h
vendored
Normal file
22
external/tellstick-core/ProtocolSilvanChip.h
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLSILVANCHIP_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLSILVANCHIP_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolSilvanChip : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
|
||||
protected:
|
||||
virtual std::string getString(const std::string &preamble, const std::string &one, const std::string &zero, int button);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLSILVANCHIP_H_
|
||||
78
external/tellstick-core/ProtocolUpm.cpp
vendored
Normal file
78
external/tellstick-core/ProtocolUpm.cpp
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolUpm.h"
|
||||
#include <string>
|
||||
|
||||
int ProtocolUpm::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN;
|
||||
}
|
||||
|
||||
std::string ProtocolUpm::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
const char S = ';';
|
||||
const char L = '~';
|
||||
const char START[] = {S, 0};
|
||||
const char B1[] = {L, S, 0};
|
||||
const char B0[] = {S, L, 0};
|
||||
// const char BON[] = {S,L,L,S,0};
|
||||
// const char BOFF[] = {S,L,S,L,0};
|
||||
|
||||
int intUnit = this->getIntParameter(L"unit", 1, 4)-1;
|
||||
std::string strReturn;
|
||||
|
||||
int code = this->getIntParameter(L"house", 0, 4095);
|
||||
for( size_t i = 0; i < 12; ++i ) {
|
||||
if (code & 1) {
|
||||
strReturn.insert(0, B1);
|
||||
} else {
|
||||
strReturn.insert(0, B0);
|
||||
}
|
||||
code >>= 1;
|
||||
}
|
||||
strReturn.insert(0, START); // Startcode, first
|
||||
|
||||
code = 0;
|
||||
if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) {
|
||||
code += 2;
|
||||
} else if (method != TELLSTICK_TURNOFF) {
|
||||
return "";
|
||||
}
|
||||
code <<= 2;
|
||||
code += intUnit;
|
||||
|
||||
int check1 = 0, check2 = 0;
|
||||
for( size_t i = 0; i < 6; ++i ) {
|
||||
if (code & 1) {
|
||||
if (i % 2 == 0) {
|
||||
check1++;
|
||||
} else {
|
||||
check2++;
|
||||
}
|
||||
}
|
||||
if (code & 1) {
|
||||
strReturn.append(B1);
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
}
|
||||
code >>= 1;
|
||||
}
|
||||
|
||||
if (check1 % 2 == 0) {
|
||||
strReturn.append(B0);
|
||||
} else {
|
||||
strReturn.append(B1);
|
||||
}
|
||||
if (check2 % 2 == 0) {
|
||||
strReturn.append(B0);
|
||||
} else {
|
||||
strReturn.append(B1);
|
||||
}
|
||||
|
||||
strReturn.insert(0, "S");
|
||||
strReturn.append("+");
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
19
external/tellstick-core/ProtocolUpm.h
vendored
Normal file
19
external/tellstick-core/ProtocolUpm.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLUPM_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLUPM_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
|
||||
class ProtocolUpm : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLUPM_H_
|
||||
77
external/tellstick-core/ProtocolWaveman.cpp
vendored
Normal file
77
external/tellstick-core/ProtocolWaveman.cpp
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolWaveman.h"
|
||||
#ifdef _MSC_VER
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
int ProtocolWaveman::lastArctecCodeSwitchWasTurnOff = 0;
|
||||
|
||||
int ProtocolWaveman::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
std::string ProtocolWaveman::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
return getStringCodeSwitch(method);
|
||||
}
|
||||
|
||||
std::string ProtocolWaveman::getOffCode() const {
|
||||
return "$k$k$k$k$k$k$k$k$k+";
|
||||
}
|
||||
|
||||
std::string ProtocolWaveman::decodeData(const ControllerMessage& dataMsg) {
|
||||
uint64_t allData = 0;
|
||||
unsigned int house = 0;
|
||||
unsigned int unit = 0;
|
||||
unsigned int method = 0;
|
||||
|
||||
allData = dataMsg.getInt64Parameter("data");
|
||||
|
||||
method = allData & 0xF00;
|
||||
method >>= 8;
|
||||
|
||||
unit = allData & 0xF0;
|
||||
unit >>= 4;
|
||||
unit++;
|
||||
|
||||
house = allData & 0xF;
|
||||
|
||||
if(house > 16 || unit < 1 || unit > 16) {
|
||||
// not waveman
|
||||
return "";
|
||||
}
|
||||
|
||||
house = house + 'A'; // house from A to P
|
||||
|
||||
if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1) {
|
||||
lastArctecCodeSwitchWasTurnOff = 0;
|
||||
return ""; // probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose
|
||||
// one turnon/bell, but it's better than the alternative...
|
||||
}
|
||||
|
||||
if(method == 6) {
|
||||
lastArctecCodeSwitchWasTurnOff = 1;
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:waveman;model:codeswitch;house:" << static_cast<char>(house);
|
||||
|
||||
if(method == 0) {
|
||||
retString << ";unit:" << unit << ";method:turnoff;";
|
||||
} else if(method == 14) {
|
||||
retString << ";unit:" << unit << ";method:turnon;";
|
||||
} else {
|
||||
// not waveman
|
||||
return "";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
26
external/tellstick-core/ProtocolWaveman.h
vendored
Normal file
26
external/tellstick-core/ProtocolWaveman.h
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLWAVEMAN_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLWAVEMAN_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/ProtocolNexa.h"
|
||||
|
||||
class ProtocolWaveman : public ProtocolNexa {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
|
||||
protected:
|
||||
virtual std::string getOffCode() const;
|
||||
|
||||
private:
|
||||
static int lastArctecCodeSwitchWasTurnOff;
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLWAVEMAN_H_
|
||||
185
external/tellstick-core/ProtocolX10.cpp
vendored
Normal file
185
external/tellstick-core/ProtocolX10.cpp
vendored
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "service/ProtocolX10.h"
|
||||
#ifdef _MSC_VER
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
const unsigned char HOUSES[] = {6, 0xE, 2, 0xA, 1, 9, 5, 0xD, 7, 0xF, 3, 0xB, 0, 8, 4, 0xC};
|
||||
|
||||
int ProtocolX10::methods() const {
|
||||
return TELLSTICK_TURNON | TELLSTICK_TURNOFF;
|
||||
}
|
||||
|
||||
std::string ProtocolX10::getStringForMethod(int method, unsigned char data, Controller *controller) {
|
||||
const unsigned char S = 59, L = 169;
|
||||
const char B0[] = {S, S, 0};
|
||||
const char B1[] = {S, L, 0};
|
||||
const unsigned char START_CODE[] = {'S', 255, 1, 255, 1, 255, 1, 100, 255, 1, 180, 0};
|
||||
const unsigned char STOP_CODE[] = {S, 0};
|
||||
|
||||
std::string strReturn = reinterpret_cast<const char*>(START_CODE);
|
||||
std::string strComplement = "";
|
||||
|
||||
std::wstring strHouse = getStringParameter(L"house", L"A");
|
||||
int intHouse = strHouse[0] - L'A';
|
||||
if (intHouse < 0) {
|
||||
intHouse = 0;
|
||||
} else if (intHouse > 15) {
|
||||
intHouse = 15;
|
||||
}
|
||||
// Translate it
|
||||
intHouse = HOUSES[intHouse];
|
||||
int intCode = getIntParameter(L"unit", 1, 16)-1;
|
||||
|
||||
for( int i = 0; i < 4; ++i ) {
|
||||
if (intHouse & 1) {
|
||||
strReturn.append(B1);
|
||||
strComplement.append(B0);
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
strComplement.append(B1);
|
||||
}
|
||||
intHouse >>= 1;
|
||||
}
|
||||
strReturn.append( B0 );
|
||||
strComplement.append( B1 );
|
||||
|
||||
if (intCode >= 8) {
|
||||
strReturn.append(B1);
|
||||
strComplement.append(B0);
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
strComplement.append(B1);
|
||||
}
|
||||
|
||||
strReturn.append( B0 );
|
||||
strComplement.append( B1 );
|
||||
strReturn.append( B0 );
|
||||
strComplement.append( B1 );
|
||||
|
||||
strReturn.append( strComplement );
|
||||
strComplement = "";
|
||||
|
||||
strReturn.append( B0 );
|
||||
strComplement.append( B1 );
|
||||
|
||||
if (intCode >> 2 & 1) { // Bit 2 of intCode
|
||||
strReturn.append(B1);
|
||||
strComplement.append(B0);
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
strComplement.append(B1);
|
||||
}
|
||||
|
||||
if (method == TELLSTICK_TURNON) {
|
||||
strReturn.append(B0);
|
||||
strComplement.append(B1);
|
||||
} else if (method == TELLSTICK_TURNOFF) {
|
||||
strReturn.append(B1);
|
||||
strComplement.append(B0);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (intCode & 1) { // Bit 0 of intCode
|
||||
strReturn.append(B1);
|
||||
strComplement.append(B0);
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
strComplement.append(B1);
|
||||
}
|
||||
|
||||
if (intCode >> 1 & 1) { // Bit 1 of intCode
|
||||
strReturn.append(B1);
|
||||
strComplement.append(B0);
|
||||
} else {
|
||||
strReturn.append(B0);
|
||||
strComplement.append(B1);
|
||||
}
|
||||
|
||||
for( int i = 0; i < 3; ++i ) {
|
||||
strReturn.append( B0 );
|
||||
strComplement.append( B1 );
|
||||
}
|
||||
|
||||
strReturn.append( strComplement );
|
||||
strReturn.append( reinterpret_cast<const char*>(STOP_CODE) );
|
||||
strReturn.append("+");
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
std::string ProtocolX10::decodeData(const ControllerMessage& dataMsg) {
|
||||
uint64_t intData = 0, currentBit = 31;
|
||||
bool method = 0;
|
||||
|
||||
intData = dataMsg.getInt64Parameter("data");
|
||||
|
||||
int unit = 0;
|
||||
int rawHouse = 0;
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
rawHouse >>= 1;
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
rawHouse |= 0x8;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkBit(intData, currentBit--) != 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
unit |= (1<<3);
|
||||
}
|
||||
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
return "";
|
||||
}
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
currentBit = 14;
|
||||
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
unit |= (1<<2);
|
||||
}
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
method = 1;
|
||||
}
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
unit |= (1<<0);
|
||||
}
|
||||
if (checkBit(intData, currentBit--)) {
|
||||
unit |= (1<<1);
|
||||
}
|
||||
|
||||
int intHouse = 0;
|
||||
for(int i = 0; i < 16; ++i) {
|
||||
if (HOUSES[i] == rawHouse) {
|
||||
intHouse = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream retString;
|
||||
retString << "class:command;protocol:x10;model:codeswitch;";
|
||||
retString << "house:" << static_cast<char>('A' + intHouse);
|
||||
retString << ";unit:" << unit+1;
|
||||
retString << ";method:";
|
||||
if (method == 0) {
|
||||
retString << "turnon;";
|
||||
} else {
|
||||
retString << "turnoff;";
|
||||
}
|
||||
|
||||
return retString.str();
|
||||
}
|
||||
22
external/tellstick-core/ProtocolX10.h
vendored
Normal file
22
external/tellstick-core/ProtocolX10.h
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLX10_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLX10_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/Protocol.h"
|
||||
#include "service/ControllerMessage.h"
|
||||
|
||||
class ProtocolX10 : public Protocol {
|
||||
public:
|
||||
int methods() const;
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
|
||||
static std::string decodeData(const ControllerMessage &dataMsg);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLX10_H_
|
||||
31
external/tellstick-core/ProtocolYidong.cpp
vendored
Normal file
31
external/tellstick-core/ProtocolYidong.cpp
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include <string>
|
||||
#include "service/ProtocolYidong.h"
|
||||
|
||||
std::string ProtocolYidong::getStringForMethod(int method, unsigned char, Controller *) {
|
||||
int intCode = this->getIntParameter(L"unit", 1, 4);
|
||||
std::wstring strCode = L"111";
|
||||
|
||||
switch(intCode) {
|
||||
case 1:
|
||||
strCode.append(L"0010");
|
||||
break;
|
||||
case 2:
|
||||
strCode.append(L"0001");
|
||||
break;
|
||||
case 3:
|
||||
strCode.append(L"0100");
|
||||
break;
|
||||
case 4:
|
||||
strCode.append(L"1000");
|
||||
break;
|
||||
}
|
||||
|
||||
strCode.append(L"110");
|
||||
return getStringForCode(strCode, method);
|
||||
}
|
||||
18
external/tellstick-core/ProtocolYidong.h
vendored
Normal file
18
external/tellstick-core/ProtocolYidong.h
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#ifndef TELLDUS_CORE_SERVICE_PROTOCOLYIDONG_H_
|
||||
#define TELLDUS_CORE_SERVICE_PROTOCOLYIDONG_H_
|
||||
|
||||
#include <string>
|
||||
#include "service/ProtocolSartano.h"
|
||||
|
||||
class ProtocolYidong : public ProtocolSartano {
|
||||
public:
|
||||
virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller);
|
||||
};
|
||||
|
||||
#endif // TELLDUS_CORE_SERVICE_PROTOCOLYIDONG_H_
|
||||
30
external/tellstick-core/README.txt
vendored
Normal file
30
external/tellstick-core/README.txt
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
This is Telldus Core version {version}
|
||||
|
||||
Telldus Core is the driver and tools for controlling a Telldus Technologies
|
||||
TellStick. It does not containing any GUI tools which makes it suitable for
|
||||
server use.
|
||||
|
||||
|
||||
INSTALLING Telldus Core
|
||||
|
||||
On Windows, if you want to install the precompiles binary packages, simply
|
||||
launch the package and follow the instructions in the installation wizard.
|
||||
|
||||
If you have a source package (a .tar.gz file), follow the instruction in the
|
||||
INSTALL file.
|
||||
|
||||
|
||||
CONFIGURATION AND TOOLS
|
||||
|
||||
Once Telldus Core is installed, we suggest that you start by adding the devices
|
||||
you want to control.
|
||||
|
||||
On Windows, this is done by installing TelldusCenter. On Linux it's done by
|
||||
editing the file /etc/tellstick.conf directly, or in TelldusCenter.
|
||||
|
||||
Telldus Core installs the tool tdtool for controlling devices with TellStick.
|
||||
Have a look in the man page for a description how to use it:
|
||||
|
||||
man tdtool
|
||||
|
||||
TellStick is a trademark of Telldus Technologies AB
|
||||
BIN
external/tellstick-driver/SerialDriver_Windows/Static/amd64/ftd2xx.lib
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/Static/amd64/ftd2xx.lib
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/Static/i386/ftd2xx.lib
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/Static/i386/ftd2xx.lib
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftbusui.dll
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftbusui.dll
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftcserco.dll
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftcserco.dll
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftd2xx.lib
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftd2xx.lib
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftd2xx64.dll
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftd2xx64.dll
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftdibus.sys
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftdibus.sys
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftlang.dll
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftlang.dll
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftser2k.sys
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftser2k.sys
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftserui2.dll
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/amd64/ftserui2.dll
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/dpinst-amd64.exe
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/dpinst-amd64.exe
vendored
Normal file
Binary file not shown.
BIN
external/tellstick-driver/SerialDriver_Windows/dpinst-x86.exe
vendored
Normal file
BIN
external/tellstick-driver/SerialDriver_Windows/dpinst-x86.exe
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue