Compare commits
No commits in common. "master" and "BUILD-18" have entirely different histories.
912 changed files with 35299 additions and 128834 deletions
17
.classpath
Normal file
17
.classpath
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?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
5
.gitattributes
vendored
|
|
@ -1,5 +0,0 @@
|
|||
# Github language stats file
|
||||
external/* linguist-vendored
|
||||
lib/* linguist-vendored
|
||||
*.css linguist-vendored
|
||||
*.js linguist-vendored
|
||||
16
.gitignore
vendored
Normal file → Executable file
16
.gitignore
vendored
Normal file → Executable file
|
|
@ -1,14 +1,2 @@
|
|||
# Configuration and dependencies
|
||||
/hal.conf
|
||||
/hal.db*
|
||||
/lib/zutil-*
|
||||
/recordings/
|
||||
|
||||
# Runtime files
|
||||
/screenlog.0*
|
||||
/OZW_Log.txt
|
||||
|
||||
# Build and Ide files
|
||||
build
|
||||
.gradle
|
||||
.idea
|
||||
Zutil.jar
|
||||
/build/
|
||||
|
|
|
|||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "arduino/lib/NexaControl"]
|
||||
path = arduino/lib/NexaControl
|
||||
url = https://github.com/dcollin/NexaControl.git
|
||||
31
.project
Normal file
31
.project
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?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
35
Jenkinsfile
vendored
|
|
@ -1,35 +0,0 @@
|
|||
// 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) 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.
|
||||
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.
|
||||
104
README.md
104
README.md
|
|
@ -1,104 +0,0 @@
|
|||
# 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
Executable file
35
Zutil.iml
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
<?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>
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef ARCHTECH_H
|
||||
#define ARCHTECH_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP);
|
||||
|
||||
#endif //ARCHTECH_H
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#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;
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
#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();
|
||||
};
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
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");
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,234 +0,0 @@
|
|||
#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
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#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 +0,0 @@
|
|||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef PROTOCOLNEXA_H
|
||||
#define PROTOCOLNEXA_H
|
||||
|
||||
#include "HalInterfaces.h"
|
||||
|
||||
|
||||
|
||||
#endif // PROTOCOLNEXA_H
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#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
|
||||
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
/* 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!");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
#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 +0,0 @@
|
|||
Subproject commit 5fd5429375b3fffbf0bdd041d493d5c6ff0c156a
|
||||
126
build.gradle
126
build.gradle
|
|
@ -1,126 +0,0 @@
|
|||
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
Executable file
91
build.xml
Executable file
|
|
@ -0,0 +1,91 @@
|
|||
<?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
BIN
external/Z-Stick_Gen5_Drivers.zip
vendored
Binary file not shown.
7
external/tellstick-core/AUTHORS.txt
vendored
7
external/tellstick-core/AUTHORS.txt
vendored
|
|
@ -1,7 +0,0 @@
|
|||
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
502
external/tellstick-core/LICENSE.txt
vendored
|
|
@ -1,502 +0,0 @@
|
|||
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
267
external/tellstick-core/Protocol.cpp
vendored
|
|
@ -1,267 +0,0 @@
|
|||
//
|
||||
// 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
46
external/tellstick-core/Protocol.h
vendored
|
|
@ -1,46 +0,0 @@
|
|||
//
|
||||
// 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
53
external/tellstick-core/ProtocolBrateck.cpp
vendored
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// 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
19
external/tellstick-core/ProtocolBrateck.h
vendored
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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
23
external/tellstick-core/ProtocolComen.cpp
vendored
|
|
@ -1,23 +0,0 @@
|
|||
//
|
||||
// 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
21
external/tellstick-core/ProtocolComen.h
vendored
|
|
@ -1,21 +0,0 @@
|
|||
//
|
||||
// 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
133
external/tellstick-core/ProtocolEverflourish.cpp
vendored
|
|
@ -1,133 +0,0 @@
|
|||
//
|
||||
// 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
24
external/tellstick-core/ProtocolEverflourish.h
vendored
|
|
@ -1,24 +0,0 @@
|
|||
//
|
||||
// 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
52
external/tellstick-core/ProtocolFineoffset.cpp
vendored
|
|
@ -1,52 +0,0 @@
|
|||
//
|
||||
// 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
19
external/tellstick-core/ProtocolFineoffset.h
vendored
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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
60
external/tellstick-core/ProtocolFuhaote.cpp
vendored
|
|
@ -1,60 +0,0 @@
|
|||
//
|
||||
// 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
19
external/tellstick-core/ProtocolFuhaote.h
vendored
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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
16
external/tellstick-core/ProtocolGroup.cpp
vendored
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// 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
22
external/tellstick-core/ProtocolGroup.h
vendored
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// 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
201
external/tellstick-core/ProtocolHasta.cpp
vendored
|
|
@ -1,201 +0,0 @@
|
|||
//
|
||||
// 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
27
external/tellstick-core/ProtocolHasta.h
vendored
|
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// 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
151
external/tellstick-core/ProtocolIkea.cpp
vendored
|
|
@ -1,151 +0,0 @@
|
|||
//
|
||||
// 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
19
external/tellstick-core/ProtocolIkea.h
vendored
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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
46
external/tellstick-core/ProtocolMandolyn.cpp
vendored
|
|
@ -1,46 +0,0 @@
|
|||
//
|
||||
// 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
19
external/tellstick-core/ProtocolMandolyn.h
vendored
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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
279
external/tellstick-core/ProtocolNexa.cpp
vendored
|
|
@ -1,279 +0,0 @@
|
|||
//
|
||||
// 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
39
external/tellstick-core/ProtocolNexa.h
vendored
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// 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
347
external/tellstick-core/ProtocolOregon.cpp
vendored
|
|
@ -1,347 +0,0 @@
|
|||
//
|
||||
// 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
27
external/tellstick-core/ProtocolOregon.h
vendored
|
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// 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
115
external/tellstick-core/ProtocolRisingSun.cpp
vendored
|
|
@ -1,115 +0,0 @@
|
|||
//
|
||||
// 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
24
external/tellstick-core/ProtocolRisingSun.h
vendored
|
|
@ -1,24 +0,0 @@
|
|||
//
|
||||
// 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
108
external/tellstick-core/ProtocolSartano.cpp
vendored
|
|
@ -1,108 +0,0 @@
|
|||
//
|
||||
// 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
24
external/tellstick-core/ProtocolSartano.h
vendored
|
|
@ -1,24 +0,0 @@
|
|||
//
|
||||
// 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
16
external/tellstick-core/ProtocolScene.cpp
vendored
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// 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
22
external/tellstick-core/ProtocolScene.h
vendored
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// 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
146
external/tellstick-core/ProtocolSilvanChip.cpp
vendored
|
|
@ -1,146 +0,0 @@
|
|||
//
|
||||
// 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
22
external/tellstick-core/ProtocolSilvanChip.h
vendored
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// 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
78
external/tellstick-core/ProtocolUpm.cpp
vendored
|
|
@ -1,78 +0,0 @@
|
|||
//
|
||||
// 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
19
external/tellstick-core/ProtocolUpm.h
vendored
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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
77
external/tellstick-core/ProtocolWaveman.cpp
vendored
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// 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
26
external/tellstick-core/ProtocolWaveman.h
vendored
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// 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
185
external/tellstick-core/ProtocolX10.cpp
vendored
|
|
@ -1,185 +0,0 @@
|
|||
//
|
||||
// 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
22
external/tellstick-core/ProtocolX10.h
vendored
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// 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
31
external/tellstick-core/ProtocolYidong.cpp
vendored
|
|
@ -1,31 +0,0 @@
|
|||
//
|
||||
// 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
18
external/tellstick-core/ProtocolYidong.h
vendored
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// 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
30
external/tellstick-core/README.txt
vendored
|
|
@ -1,30 +0,0 @@
|
|||
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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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