Search Results: "sune"

14 September 2021

Sven Hoexter: PV - Monitoring Envertech Microinverter via

Some time ago I looked briefly at an Envertech data logger for small scale photovoltaic setups. Turned out that PV inverter are kinda unreliable, and you really have to monitor them to notice downtimes and defects. Since my pal shot for a quick win I've cobbled together another Python script to query the portal at, and report back if the generated power is down to 0. The script is currently run on a vserver via cron and reports back via the system MTA. So yeah, you need to have something like that already at hand. Script and Configuration You've to provide your PV systems location with latitude and longitude so the script can calculate (via python3-suntime) the sunrise and sunset times. At the location we deal with we expect to generate some power at least from sunrise + 1h to sunet - 1h. That is tunable via the configuration option toleranceSeconds. Retrieving the stationId is a bit ugly because it's not provided via any API, instead it's rendered serverside into the website. So I just logged in on the portal and picked it up by looking into the page source. API I guess this is some classic in the IoT land, but neither the documentation provided on the portal frontpage as docx, nor the API docs at port 8090 are complete and correct. The few bits I gathered via the Firefox Web Developer Tools are:
  1. Login - POST, sent userName and pwd containing your login name and password. The response JSON is very explicit if your login was not successful and why.
  2. Store the session cookie called ASP.NET_SessionId for use on all subsequent requests.
  3. Retrieve station info - POST, sent ASP.NET_SessionId and stationId with the ID of the station. Returns a JSON with an object named Data. The field Power contains the currently generated power as a float with two digits (e.g. 0.01).
  4. Logout - POST, sent ASP.NET_SessionId.
Some Surprises There were a few surprises, maybe they help others dealing with an Envertech setup.
  1. The portal truncates passwords at 16 chars.
  2. The "Forget Password?" function mails you back the password in plain text (that's how I learned about 1.).
  3. The login API endpoint reporting the exact reason why the login failed is somewhat out of fashion. Though this one is probably not a credential stuffing target because there is no money to make, so don't care.
  4. The data logger reports the data to at port 10013.
  5. There is some checksuming done on the reported data, but the system is not replay safe. So you can sent it any valid data string at a later time and get wrong data recorded.
  6. People at decoded some values but could not figure out the checksuming so far.

17 October 2017

Sune Vuorela: KDE still makes Qt

A couple of years ago, I made a blog post, KDE makes Qt, with data about which percentage of Qt contributions came from people starting in KDE. Basically, how many Qt contributions are made by people who used KDE as a gateway drug into it. I have now updated the graphs with data until the end of September 2017: KDE still makes Qt Many of these changes are made by people not directly as a result of their KDE work, but as a result of their paid work. But this doesn t change the fact that KDE is an important project for attracting contributors to Qt, and a very good place to find experienced Qt developers.

2 October 2017

Lars Wirzenius: Attracting contributors to a new project

How do you attract contributors to a new free software project? I'm in the very early stages of a new personal project. It is irrelevant for this blog post what the new project actually is. Instead, I am thinking about the following question:
Do I want the project to be mainly for myself, and maybe a handful of others, or do I want to try to make it a more generally useful, possibly even a well-known, popular project? In other words, do I want to just solve a specific problem I have or try to solve it for a large group of people?
If it's a personal project, I'm all set. I can just start writing code. (In fact, I have.) If it's the latter, I'll need to attract contributions from others, and how do I do that? I asked that question on Twitter and Mastodon and got several suggestions. This is a summary of those, with some editorialising from me. I don't know if these things are all correct, or that they're enough to grow a successful, popular project. Karl Foger'l seminal book Producing Open Source Software should also be mentioned.

14 July 2016

Sune Vuorela: Leaky lambdas and self referencing shared pointers

After a bit of a debugging session, I ended up looking at some code in a large project
m_foo = std::make_shared<SomeQObject>();
/* plenty of lines and function boundaries left out */ 
(void)connect(m_foo.get(), &SomeQObject::someSignal, [m_foo]()  
  /* */
The connection gets removed when the pointer inside m_foo gets de-allocated by the shared_ptr.
But the connection target is a lambda that has captured a copy of the shared_ptr There is at least a couple of solutions. I guess the lesson learnt is be careful when capturing shared pointers.

10 July 2016

Sune Vuorela: Let Qt models meet std::vector<std::tuple< >>

The problem So. I was stuck with a container of tuples that I wanted to see in a Qt view (QTableView, QtQuick ListView or similar). So how to do that? Another problem: I haven t been doing fun things with templates recently. A solution? After a bit of hacking, it seems like it can just be done like
typedef std::tuple<std::string, QString> Element;
typedef std::vector List;
List list =   std::make_tuple("first", "second"), 
              std::make_tuple("third", "fourth")  ;
std::unique_ptr<TableModel> magic = createTableModel(list);
QTableView view;
and tada:
QTableView Of course, we are also QtQuick friendly
std::unique_ptr<ListModel>List>> magic = createListModel(list);
// expose magic->model() to your quickview
and a delegate containing the following
    text: role0
    text: role1
can give:
ListView But enough about creation. Whattabout manipulation? Luckily we got you covered. Insert two extra rows at position 1?
auto lines =   std::make_tuple("extra", "extra"),
               std::make_tuple("extra2","extra2")  ;
magic->insertRows(1,lines.begin(), lines.end());
Append a row?
Remove 2 rows at position 3?
Replace the underlying list?
List newList;
// fill list
Read-only looping over the elements?
for(const Element& e : magic->list())
The Qt model of course also accepts setData calls. Future? If anyone is interested I will polish the code a bit and publish it. If that s the case, how should I name this thing? And I did get around doing fun things with templates again.

21 June 2016

Reproducible builds folks: Reproducible builds: week 60 in Stretch cycle

What happened in the Reproducible Builds effort between June 12th and June 18th 2016: Media coverage GSoC and Outreachy updates Weekly reports by our participants: Toolchain fixes With this upload of texlive-bin we decided to stop keeping our patched fork of as most of the patches for SOURCE_DATE_EPOCH support had been integrated upstream already, and the last one (making FORCE_SOURCE_DATE default to 1) had been refused. So, we are now going to let the archive be rebuilt against unstable's texlive-bin and see how many packages will become unreproducible with this change; once enough data will be collected we will ponder whether FORCE_SOURCE_DATE should be exported by helper tools (such as debhelper) or manually exported by every package that needs it. (For those wondering: we still recommend to follow SOURCE_DATE_EPOCH always and don't recommend other projects to implement FORCE_SOURCE_DATE ) With the drop of texlive-bin we now have only three modified packages in our experimental repository. Reproducible work in other projects Packages fixed The following 12 packages have become reproducible due to changes in their build dependencies: django-floppyforms flask-restful hy jets3t kombu llvm-toolchain-3.8 moap python-bottle python-debtcollector python-django-debug-toolbar python-osprofiler stevedore The following packages have become reproducible after being fixed: Some uploads have fixed some reproducibility issues, but not all of them: Uploads with reproducibility fixes that currently fail to build: Patches submitted that have not made their way to the archive yet: Package reviews 36 reviews have been added, 12 have been updated and 31 have been removed in this week. 17 FTBFS bugs have been reported by Chris Lamb, Santiago Vila and Dominic Hargreaves. diffoscope development Satyam worked on argument completion (#826711) for diffoscope. strip-nondeterminism development Mattia Rizzolo uploaded strip-nondeterminism 0.019-1~bpo8+1 to jessie-backports. reprotest development Ceridwen filed an Intent To Package (ITP) bug for reprotest as #827293. Misc. This week's edition was written by Mattia Rizzolo, Reiner Herrmann, Ed Maste and Holger Levsen and reviewed by a bunch of Reproducible builds folks on IRC.

18 June 2016

Sune Vuorela: R is for Randa

This week I have been gathered with 38 KDE people in Randa, Switzerland. Randa is a place in a valley in the middle of the Alps close to various peaks like Matterhorn. It has been a week of intense hacking, bugfixing, brainstorming and a bit of enjoying the nature. R is for Reproducible builds I spent the first couple of days trying to get the Qt Documentation generation tool to reproducible generate documentation. Some of the fixes were of the usual put data in an randomized datastructure, then iterate over it and create output , where the fix is similar well known: Sort the datastructure first. Others were a bit more severe bugs that lead to the documentation to shuffle around the obsolete bit, and the inheritance chains. Most of these fixes have been reviewed and submitted to the Qt 5.6 branch, one is still pending review, but that hopefully gets fixed soon. Then most of Qt (except things containing copies of (parts) of webkit and derivatives) should be reproducible. R is for Roaming around in the mountains Sleeping, hacking and dining in the same building sometimes leads to a enormous desire for fresh air. Luckily in the middle of the alps, it is readily available, and at least once a day many people went for a walk. To say hi to a sheep. Or to just go uphill until tired and then going back down. Or just finding a circle around. For this area, OpenStreetMap seems to have better maps than Google. We also went on a nice group trip to Zermatt and surroundings, sponsored by our friends in Edeltech. R is for Releasing One of the tasks I set myself for was to get my barcode generation library (prison. you know. being behind bars.) ready for release. A bit of api cleanup, including some future proofing, was done, and all users adapted. Hopefully it will be released as part of the next KDE Frameworks release. R is for Reviewing code When signing up for the sprint, one has to declare a couple of tasks to work on. One of the things I put myself up to was reviewing David Faure s code changes. First, he is very productive, and second, he often gets into creating patches in code areas where many other contributors are scared to look. So someone has to do it, and code never scared me. R is for Running I planned on going running along the river monday, wednesday and friday. Fortunately that happened, but due to Switzerland having a bit more ups and downs than flat Denmark, it didn t go that fast. R is for Random bugfixing When in the hacking mood surrounded by great developers, it is very easy to just fix minor bugs when you encounter them. There is likely someone around who knows the code in question. Or you are just in the mood to actually fix it, rather than living with a missing clock applet or a corner case crash. R is for Rubber ducking I am a brilliant person sized rubber duck. And I did get the opportunity to show off my skills a couple of times, as well as using some of the other people for that. R is for Raising money These sprints in Randa is only possible because of all the nice donations from people and companies around the world. The fundraiser is still running, and can be found at

12 June 2016

Sune Vuorela: Randa day 0

Sitting on Lake Zurich and reflecting over things was a great way to get started. After spending a bit of time in a train, I climbed part of a mountain together with Adriaan up to the snow where I could throw a snowball at him. We also designed a couple of new frameworks on our climbing trip. Maybe they will be presented later.

16 February 2016

Sune Vuorela: So close, but so far away

strcpy_s(dest, strlen(src),src);

2 February 2016

Sune Vuorela: Compilers and error messages

So. I typo ed up some template code the other day. And once again I learned the importance of using several c++ compilers. Here is a very reduced version of my code:
#include <utility>
template <typename T> auto foo(const T& t) -> decltype(x.first)

return t.first;

int main()

return 0;
And let s start with the compiler I was testing with first. MSVC (2013 and 2015)
main.cpp(8): error C2672: foo : no matching overloaded function found
main.cpp(8): error C2893: Failed to specialize function template unknown-type foo(const T &)
It is not completely clear from that error message what s going on, so let s try some other compilers: GCC (4.9-5.3)
2 : error: x was not declared in this scope
template <typename T> auto foo(const T& t) -> decltype(x.first)
That s pretty clear. More compilers: Clang (3.3-3.7)
2 : error: use of undeclared identifier x
template <typename T> auto foo(const T& t) -> decltype(x.first)
ICC (13)
example.cpp(2): error: identifier x is undefined
template <typename T> auto foo(const T& t) -> decltype(x.first)
(Yes. I mistyped the variable name used for decltype. Replacing the x with t makes it build). Thanks to and for testing with various compilers.

5 October 2015

Sune Vuorela: KDE at Qt World Summit

So. KDE has landed at Qt World Summit. kdeboothqtws2015 You can come and visit our booth and KDE 19 years of Qt Experience.

4 September 2015

Sune Vuorela: I accidentally the Debian menu

So quite some time ago, I filed this. After some going back and forth, it lead to this. And finally we have a conclusion. It took only two years, but now we are there. Let s continue make Debian rock.

20 August 2015

Sune Vuorela: Debconf 2015 7

The other day, the main talk was Lets encrypt , today it was Let s reproduce

Sune Vuorela: Debconf 2015 6

There is more people with blue hair at Debconf than at an average Akademy. KDE we need to do better :)

19 August 2015

Sune Vuorela: Debconf 2015 5

Watching people figuring out how to use a Danish cheese slicer is kind interesting. But by using enough force most people succeeding in getting a lump of cheese.

18 August 2015

Sune Vuorela: Debconf 2015 4

I refuse to be bound by software I cannot negotiate with enrico

16 August 2015

Sune Vuorela: Debconf 2015 3

It is still an open question what the Debian Project Leader wears under their kilt.

15 August 2015

Sune Vuorela: Debconf 2015 2

It is amazing at debconf when your Application Manager is rocking the dance floor!

Sune Vuorela: Debconf 2015 1

When greeted by Clint with one single word: kamel s , one has arrived to Debconf.

15 May 2015

Sune Vuorela: Getting a Q_INVOKABLE C++ function reevaluated by QML engine

Unfortunately, with all the normal magic of QML property bindings, getting a property updated in a setup that involves return values from functions isn t really doable, like this:

text: qtobject.calculatedValue()

I m told there is a low priority feature request for a way of signalling that a function now returns a different value and all properties using it should be reevaluated. I have so far discovered two different workarounds for that that I will be presenting here. Using an extra property Appending an extra property to trigger the reevaluation of the function is one way of doing it.

text: qtobject.calculatedValue() + qtobject.emptyNotifierThing

with the following on the C++ side:

Q_PROPERTY(QString emptyNotifierThing READ emptyString NOTIFY valueChanged)
QString emptyString() const
return QString();

This is a bit more code to write and to remember to use, but it does get the job done. Intermediate layer
Another way is to inject an intermediate layer, an extra object, that has the function. It can even be simplified by having a pointer to itself.

text: qtobject.dataAccess.calculatedValue()

with the following on the C++ side:

Q_PROPERTY(QObject* dataAccess READ dataAccess NOTIFY valueChanged)
QObject* dataAccess()
return this;

It seems a bit simpler for the reader on the QML side, but also gets the job done. I am not sure which way is the best one, but the intermediate layer has a nicer feeling to it when more complicated types are involved.