Skip to content

Commit

Permalink
linux support
Browse files Browse the repository at this point in the history
  • Loading branch information
bertmelis authored Nov 28, 2023
1 parent b6187e8 commit 4b40049
Show file tree
Hide file tree
Showing 21 changed files with 531 additions and 180 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/build_platformio.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,30 @@ jobs:
run: pio pkg install --global --library plerup/EspSoftwareSerial
- name: Build PlatformIO examples
run: pio ci --lib="." --board=lolin32
env:
PLATFORMIO_CI_SRC: ${{ matrix.example }}

build-for-linux:
runs-on: ubuntu-latest
strategy:
matrix:
example: [
examples/linux/main.cpp
]
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
~/.cache/pip
~/.platformio/.cache
key: ${{ runner.os }}-pio
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install PlatformIO Core
run: pip install --upgrade platformio
- name: Build PlatformIO examples
run: pio ci --lib="." --project-conf="./examples/linux/platformio.ini"
env:
PLATFORMIO_CI_SRC: ${{ matrix.example }}
106 changes: 106 additions & 0 deletions examples/linux/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include <signal.h>
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono> // is already included by VitoWiFi
#include <VitoWiFi.h>

VitoWiFi::VitoWiFi<VitoWiFi::VS2> vitoWiFi("/dev/ttyUSB0");

bool exitProgram = false;
bool readValues = false;
uint8_t datapointIndex = 0;

VitoWiFi::Datapoint datapoints[] = {
VitoWiFi::Datapoint("outsidetemp", 0x5525, 2, VitoWiFi::div10),
VitoWiFi::Datapoint("boilertemp", 0x0810, 2, VitoWiFi::div10),
VitoWiFi::Datapoint("pump", 0x2906, 1, VitoWiFi::noconv)
};

void signalHandler(int signum) {
std::cout << "Caught signal " << signum << std::endl;
exitProgram = true;
}

void onResponse(const VitoWiFi::PacketVS2& response, const VitoWiFi::Datapoint& request) {
// raw data can be accessed through the 'response' argument
std::cout << "Raw data received: " << std::endl;
const uint8_t* data = response.data();
for (uint8_t i = 0; i < response.dataLength(); ++i) {
std::cout << std::hex << (int)data[i] << " ";
}
std::cout << std::endl;

// the raw data can be decoded using the datapoint. Be sure to use the correct type
std::cout << request.name() <<": ";
if (request.converter() == VitoWiFi::div10) {
float value = request.decode(response);
std::cout << std::setprecision(2) << value << std::endl;
} else if (request.converter() == VitoWiFi::noconv) {
bool value = request.decode(response);
if (value) {
std::cout << "ON" << std::endl;
} else {
std::cout << "OFF" << std::endl;
}
// alternatively, we can just cast response.data()[0] to bool
}
}

void onError(VitoWiFi::OptolinkResult error, const VitoWiFi::Datapoint& request) {
printf("Datapoint \"%s\" error: ", request.name());
if (error == VitoWiFi::OptolinkResult::TIMEOUT) {
std::cout << "timeout" << std::endl;
} else if (error == VitoWiFi::OptolinkResult::LENGTH) {
std::cout << "length" << std::endl;
} else if (error == VitoWiFi::OptolinkResult::NACK) {
std::cout << "nack" << std::endl;
} else if (error == VitoWiFi::OptolinkResult::CRC) {
std::cout << "crc" << std::endl;
} else if (error == VitoWiFi::OptolinkResult::ERROR) {
std::cout << "error" << std::endl;
}
}

void setup() {
sleep(2);
std::cout << "Setting up vitoWiFi" << std::endl;

vitoWiFi.onResponse(onResponse);
vitoWiFi.onError(onError);
vitoWiFi.begin();

std::cout << "Setup finished" << std::endl;
}

void loop() {
static uint32_t lastMillis = 0;
if (millis() - lastMillis > 60000UL) { // read all values every 60 seconds
lastMillis = millis();
readValues = true;
datapointIndex = 0;
}

if (readValues) {
if (vitoWiFi.read(datapoints[datapointIndex])) {
++datapointIndex;
}
if (datapointIndex == 3) {
readValues = false;
}
}

vitoWiFi.loop();
}


int main() {
setup();
while(1) {
loop();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (exitProgram) break;
}
vitoWiFi.end();
return EXIT_SUCCESS;
}
12 changes: 12 additions & 0 deletions examples/linux/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[common]
build_flags =
-std=c++11
-Wall
-Wextra
-Werror

[env:native]
platform = native
build_flags =
${common.build_flags}
build_type = debug
18 changes: 2 additions & 16 deletions examples/simple-read-VS1/simple-read-VS1.ino
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
/*
This example defines three datapoints.
The first two are TEMPL type datapoints and have their own callback.
When no specific callback is attached to a datapoint, it uses the global callback.
Note the difference in return value between the callbacks:
for tempCallback uses value.getFloat() as TEMPL datapoints return a float.
globalCallback uses value.getString(char*,size_t). This method is independent of the returned type.
*/

#include <Arduino.h>

#include <VitoWiFi.h>

#ifdef ESP8266
#if defined(ARDUINO_ARCH_ESP8266)
// optolink on full UART, logging output on secondary
#define SERIAL1 Serial
#define SERIAL2 Serial1
#define SERIALBAUDRATE 74880
#endif

#ifdef ESP32
#elif defined(ARDUINO_ARCH_ESP32)
// optolink on UART2, logging output on UART1 (connected to USB)
#define SERIAL1 Serial1
#define SERIAL2 Serial
Expand Down
18 changes: 2 additions & 16 deletions examples/simple-read-VS2/simple-read-VS2.ino
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
/*
This example defines three datapoints.
The first two are TEMPL type datapoints and have their own callback.
When no specific callback is attached to a datapoint, it uses the global callback.
Note the difference in return value between the callbacks:
for tempCallback uses value.getFloat() as TEMPL datapoints return a float.
globalCallback uses value.getString(char*,size_t). This method is independent of the returned type.
*/

#include <Arduino.h>

#include <VitoWiFi.h>

#ifdef ESP8266
#if defined(ARDUINO_ARCH_ESP8266)
// optolink on full UART, logging output on secondary
#define SERIAL1 Serial
#define SERIAL2 Serial1
#define SERIALBAUDRATE 74880
#endif

#ifdef ESP32
#elif defined(ARDUINO_ARCH_ESP32)
// optolink on UART2, logging output on UART1 (connected to USB)
#define SERIAL1 Serial1
#define SERIAL2 Serial
Expand Down
18 changes: 2 additions & 16 deletions examples/simple-write-VS1/simple-write-VS1.ino
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
/*
This example defines three datapoints.
The first two are TEMPL type datapoints and have their own callback.
When no specific callback is attached to a datapoint, it uses the global callback.
Note the difference in return value between the callbacks:
for tempCallback uses value.getFloat() as TEMPL datapoints return a float.
globalCallback uses value.getString(char*,size_t). This method is independent of the returned type.
*/

#include <Arduino.h>

#include <VitoWiFi.h>

#ifdef ESP8266
#if defined(ARDUINO_ARCH_ESP8266)
// optolink on full UART, logging output on secondary
#define SERIAL1 Serial
#define SERIAL2 Serial1
#define SERIALBAUDRATE 74880
#endif

#ifdef ESP32
#elif defined(ARDUINO_ARCH_ESP32)
// optolink on UART2, logging output on UART1 (connected to USB)
#define SERIAL1 Serial1
#define SERIAL2 Serial
Expand Down
18 changes: 2 additions & 16 deletions examples/simple-write-VS2/simple-write-VS2.ino
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
/*
This example defines three datapoints.
The first two are TEMPL type datapoints and have their own callback.
When no specific callback is attached to a datapoint, it uses the global callback.
Note the difference in return value between the callbacks:
for tempCallback uses value.getFloat() as TEMPL datapoints return a float.
globalCallback uses value.getString(char*,size_t). This method is independent of the returned type.
*/

#include <Arduino.h>

#include <VitoWiFi.h>

#ifdef ESP8266
#if defined(ARDUINO_ARCH_ESP8266)
// optolink on full UART, logging output on secondary
#define SERIAL1 Serial
#define SERIAL2 Serial1
#define SERIALBAUDRATE 74880
#endif

#ifdef ESP32
#elif defined(ARDUINO_ARCH_ESP32)
// optolink on UART2, logging output on UART1 (connected to USB)
#define SERIAL1 Serial1
#define SERIAL2 Serial
Expand Down
70 changes: 37 additions & 33 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
{
"name": "VitoWiFi",
"version": "3.0.0",
"keywords": "iot, home, automation, Arduino, esp8266, esp32, Viessmann, serial, optolink",
"description": "Communicate with Viessmann boilers using the optolink for ESP8266 and ESP32",
"homepage": "https://github.com/bertmelis/VitoWiFi",
"license": "MIT",
"authors": {
"name": "Bert Melis",
"url": "https://github.com/bertmelis",
"maintainer": true
},
"repository": {
"type": "git",
"url": "https://github.com/bertmelis/VitoWiFi.git",
"branch": "master"
},
"frameworks": "arduino",
"platforms": [
"espressif8266",
"espressif32"
],
"dependencies": [
{
"owner": "plerup",
"name": "EspSoftwareSerial",
"version": ">=1.2.2",
"platforms": [
"espressif8266",
"espressif32"
]
}
]
}
"name": "VitoWiFi",
"version": "3.0.0",
"keywords": "iot, home, automation, Arduino, esp8266, esp32, Viessmann, serial, optolink",
"description": "Communicate with Viessmann boilers using the optolink for ESP8266 and ESP32",
"homepage": "https://github.com/bertmelis/VitoWiFi",
"license": "MIT",
"authors": {
"name": "Bert Melis",
"url": "https://github.com/bertmelis",
"maintainer": true
},
"repository": {
"type": "git",
"url": "https://github.com/bertmelis/VitoWiFi.git",
"branch": "master"
},
"frameworks": [
"arduino",
"*"
],
"platforms": [
"espressif8266",
"espressif32",
"native"
],
"dependencies": [
{
"owner": "plerup",
"name": "EspSoftwareSerial",
"version": ">=1.2.2",
"platforms": [
"espressif8266",
"espressif32"
]
}
]
}
2 changes: 1 addition & 1 deletion src/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ the LICENSE file.

#if defined(__linux__)
#include <chrono> // NOLINT [build/c++11]
#define millis() std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count()
#define millis() std::chrono::duration_cast<std::chrono::duration<std::uint32_t>>(std::chrono::steady_clock::now().time_since_epoch()).count()
#endif

#define vw_abort() abort()
Loading

0 comments on commit 4b40049

Please sign in to comment.