Hi,
I will try it out, patch by patch, but first i would like to have every thing working before i proceed.
i have tried write code for events (telldus 2.1.1) but it do not work in C++/Python or mono.
Should it work in telldus 2.1.1, i have added logging outputs in "EventUpdateManager.h" line 85 and 97 to on the service side if something is happening and ill get those outputs.
Python callbacks that i have snatched (Tried both raw and regular), it just output "Waiting for events..."
Code: Select all
from ctypes import c_int, c_ubyte, c_void_p, POINTER, string_at #imports allowing the use of our library
from threading import Timer
import time
import platform
#platform specific imports:
if (platform.system() == 'Windows'):
#Windows
from ctypes import windll, WINFUNCTYPE
lib = windll.LoadLibrary('TelldusCore.dll') #import our library
else:
#Linux
from ctypes import cdll, CFUNCTYPE
lib = cdll.LoadLibrary('libtelldus-core.so.2') #import our library
timers = {} #timerlist
def turnOn():
print "turning on"
lib.tdTurnOn(1)
def turnOff():
print "turning off"
lib.tdTurnOff(1)
#function to be called when a device event occurs
def callbackfunction(deviceId, method, value, callbackId, context):
global timers
print "callback!"
if (deviceId == 1):
# is turning on deviceId 1 here, so just return if events for that device are picked up
return
t = 0
print "Received event for device %d" % (deviceId,)
if (deviceId in timers):
# a timer already exists for this device, it might be running so interrupt it
# Many devices (for example motion detectors) resends their messages many times to ensure that they
# are received correctly. In this example, we don't want to run the turnOn/turnOff methods every time, instead we
# start a timer, and run the method when the timer is finished. For every incoming event on this device, the timer
# is restarted.
t = timers[deviceId]
t.cancel()
if (method == 1):
#on
t = Timer(0.5, turnOn) #start timer with 0.5 second delay (adjust the delay to suit your needs), then turn on
else:
#off
t = Timer(0.5, turnOff) #start timer with 0.5 second delay (adjust the delay to suit your needs), then turn off
t.start()
timers[deviceId] = t #put timer in list, to allow later cancellation
#function to be called when device event occurs, even for unregistered devices
def rawcallbackfunction(data, controllerId, callbackId, context):
print string_at(data)
if (platform.system() == 'Windows'):
CMPFUNC = WINFUNCTYPE(c_void_p, c_int, c_int, POINTER(c_ubyte), c_int, c_void_p) #first is return type
CMPFUNCRAW = WINFUNCTYPE(c_void_p, POINTER(c_ubyte), c_int, c_int, c_void_p)
else:
CMPFUNC = CFUNCTYPE(c_void_p, c_int, c_int, POINTER(c_ubyte), c_int, c_void_p)
CMPFUNCRAW = CFUNCTYPE(c_void_p, POINTER(c_ubyte), c_int, c_int, c_void_p)
cmp_func = CMPFUNC(callbackfunction)
cmp_funcraw = CMPFUNCRAW(rawcallbackfunction)
lib.tdInit()
lib.tdRegisterDeviceEvent(cmp_func, 0)
#lib.tdRegisterRawDeviceEvent(cmp_funcraw, 0) #uncomment this, and comment out tdRegisterDeviceEvent, to see data for not registered devices
print "Waiting for events..."
while(1):
time.sleep(0.5) #don't exit
The C++ code, just output "Starting..." and never "Event from device "
Code: Select all
#include <unistd.h>
#include <stdio.h>
#include <telldus-core.h>
#include <iostream>
class Events {
public:
Events();
~Events();
void deviceEvent(int deviceId, int method, const char *data);
static void deviceEventCallback(int deviceId, int method, const char *data, int callbackId, void *context);
private:
int callbackId;
};
Events::Events() {
callbackId = tdRegisterDeviceEvent( reinterpret_cast<TDDeviceEvent>(&Events::deviceEventCallback), this );
}
Events::~Events() {
tdUnregisterCallback(callbackId);
}
void Events::deviceEvent(int deviceId, int method, const char *data) {
printf("Event from device %i\n", deviceId);
}
void Events::deviceEventCallback(int deviceId, int method, const char *data, int callbackId, void *context) {
Events *e = reinterpret_cast<Events *>(context);
if (e) {
/** Please note!
* We are here in another thread than the main. Some measures to syncronize
* this must be taken!
**/
e->deviceEvent(deviceId, method, data);
}
}
int main(void) {
tdInit();
Events ev;
printf("Starting... \n");
//Our own simple eventloop
while(1) {
sleep(100);
}
printf("Closing... \n");
tdClose();
return 0;
}
Mono by using the TelldusNETWrapper
Code: Select all
public class TestProgram
{
int deviceId;
int id1;
int id2;
TelldusNETWrapper wrapper = new TelldusNETWrapper();
TelldusNETWrapper.EventCallbackFunction evt = new TelldusNETWrapper.EventCallbackFunction(TestProgram.EventCallbackFunctionImpl);
TelldusNETWrapper.RawListeningCallbackFunction evt2 = new TelldusNETWrapper.RawListeningCallbackFunction(TestProgram.RawListeningCallbackFunctionImpl);
public int SUPPORTED_METHODS = TelldusNETWrapper.TELLSTICK_TURNON | TelldusNETWrapper.TELLSTICK_TURNOFF | TelldusNETWrapper.TELLSTICK_DIM;
public void Start()
{
id1 = wrapper.tdRegisterDeviceEvent(evt, null);
Console.WriteLine(id1);
id2 = wrapper.tdRegisterRawDeviceEvent(evt2, null);
loadDevice();
}
public void Stop()
{
wrapper.unregisterCallback(id1);
wrapper.unregisterCallback(id2);
TelldusNETWrapper.tdClose();
}
private void loadDevice()
{
int numberOfDevices = TelldusNETWrapper.tdGetNumberOfDevices(); //get number of devices, to make sure that devices exists
if (numberOfDevices > 0)
{
deviceId = TelldusNETWrapper.tdGetDeviceId(0); //just pick the first one, get the id of that device, and use it
//UpdateStatus(deviceId);
}
else if (numberOfDevices < 0)
{
Console.WriteLine(TelldusNETWrapper.tdGetErrorString(numberOfDevices)); //get a human readable error message for this error code
}
else
{
Console.WriteLine("No devices configured");
}
//TelldusNETWrapper.tdClose(); //release resources in the Telldus libraries
}
public static int EventCallbackFunctionImpl(int deviceId, int method, string data, int callbackId, Object obj)
{
Console.WriteLine("EventCallbackFunction");
Console.WriteLine(
String.Format(
"Device Id: {0}/nMethod: {1}/nData: {2}/nCallbackId: {3}/nObject: {4}",
deviceId,
method,
data,
obj == null? "Is null": "Is set"));
return 1;
}
public static int RawListeningCallbackFunctionImpl(string data, int controllerId, int callbackId, Object obj)
{
Console.WriteLine("RawListeningCallbackFunction");
Console.WriteLine(
String.Format(
"Controller Id: {0}/nCallbackId: {1}/nData: {2}/nObject: {3}",
controllerId,
callbackId,
data,
obj == null ? "Is null" : "Is set"));
return 1;
}
private void UpdateStatus(int deviceId)
{
Console.WriteLine(TelldusNETWrapper.tdGetName(deviceId) + TelldusNETWrapper.tdGetModel(deviceId));
int status = TelldusNETWrapper.tdLastSentCommand(deviceId, SUPPORTED_METHODS);
string value = TelldusNETWrapper.tdLastSentValue(deviceId);
//TelldusNETWrapper.tdClose();
SetStatus(status, value);
}
private void SetStatus(int status, string value)
{
if (status == 1)
{
Console.WriteLine("Lights ON");
}
else if (status == 2)
{
Console.WriteLine("Lights OFF");
}
else
{
Console.WriteLine(String.Concat("Dim: ", value));
}
}
public void LightsOn()
{
TelldusNETWrapper.tdTurnOn(deviceId); //turn on the device
//TelldusNETWrapper.tdClose(); //release resources in the Telldus libraries
//UpdateStatus(deviceId);
}
public void LightsOff()
{
TelldusNETWrapper.tdTurnOff(deviceId); //turn on the device
//TelldusNETWrapper.tdClose(); //release resources in the Telldus libraries
//UpdateStatus(deviceId);
}
public void LightsDim(int value)
{
TelldusNETWrapper.tdDim(deviceId,Convert.ToChar(value)); //turn on the device
//TelldusNETWrapper.tdClose(); //release resources in the Telldus libraries
//UpdateStatus(deviceId);
}
}
class Program
{
static void Main(string[] args)
{
try
{
var p = new TestProgram();
p.Start();
string command = "";
while(command != "q")
{
Console.WriteLine("\nType");
Console.WriteLine("1: Lights On");
Console.WriteLine("2: Lights Off");
Console.WriteLine("3 120: Dim to 120");
command = Console.ReadLine();
if(command == "1")
{
p.LightsOn();
}
else if(command == "2")
{
p.LightsOff();
} else
{
string[] s = command.Split(' ');
if(s.Length == 2 && s[0] == "3")
{
p.LightsDim(Convert.ToInt32(s[1]));
}
}
}
p.Stop();
}
catch (Exception exc)
{
//error handling if DLL is missing or wrong format (e.g. compiled for different platform)
if (exc is System.DllNotFoundException || exc is System.BadImageFormatException)
{
Console.WriteLine("DLL not found (libtelldus-core.so and TelldusNETWrapper.dll are needed)");
}
else
{
Console.WriteLine(exc.Message);
Console.ReadLine();
throw exc;
}
}
Console.WriteLine("Program terminated, press enter");
Console.ReadLine();
}
}
Thanks for listening and coming with suggestions!