mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 02:04:36 +01:00
added misc helper scripts
This commit is contained in:
15
miscellaneous/calendar content type/README.md
Normal file
15
miscellaneous/calendar content type/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Google Calendar
|
||||
|
||||
To use the 'clandar' content type, you need a helper script, using Google Apps Script. To use Google Apps Script to get all events for the next day and return them via JSON in a web app, you can follow these steps:
|
||||
|
||||
* Create a new Google Apps Script project by going to [https://script.google.com](https://script.google.com) and clicking on "New project".
|
||||
* Paste the content of the calendar.js file into the editor
|
||||
This App Script calls the `getEventsForNextDay()` function to get the events in JSON format, creates a text output with the JSON content, sets the MIME type to JSON, and returns the output.
|
||||
|
||||
* Deploy the web app by clicking on "Deploy > New Deployment" in the script editor
|
||||
* Choose "Web app" as the deployment type
|
||||
* Set 'run as' to 'me', and the access to "Anyone, even anonymous"
|
||||
* click on "Deploy"
|
||||
* Make sure to take note of the web app URL generated by Google.
|
||||
* Test the web app by visiting the web app URL in a web browser. You should see the events for the next day in JSON format.
|
||||
|
||||
38
miscellaneous/calendar content type/calendar.js
Normal file
38
miscellaneous/calendar content type/calendar.js
Normal file
@@ -0,0 +1,38 @@
|
||||
function getEventsForNextDay(days) {
|
||||
var start = new Date();
|
||||
start.setHours(0, 0, 0, 0);
|
||||
var end = new Date();
|
||||
if (days == undefined) days = 1;
|
||||
end.setDate(end.getDate() + parseInt(days, 10));
|
||||
var calendars = CalendarApp.getAllCalendars();
|
||||
var events = [];
|
||||
for (var i = 0; i < calendars.length; i++) {
|
||||
var calendar = calendars[i];
|
||||
var eventsInCalendar = calendar.getEvents(start, end);
|
||||
for (var j = 0; j < eventsInCalendar.length; j++) {
|
||||
var event = eventsInCalendar[j];
|
||||
events.push({
|
||||
calendar: i,
|
||||
title: event.getTitle(),
|
||||
start: Math.floor(event.getStartTime().getTime() / 1000),
|
||||
end: Math.floor(event.getEndTime().getTime() / 1000),
|
||||
isallday: event.isAllDayEvent()
|
||||
});
|
||||
}
|
||||
}
|
||||
events.sort(function(a, b) {
|
||||
return a.start - b.start;
|
||||
});
|
||||
return JSON.stringify(events);
|
||||
}
|
||||
|
||||
function doGet(e) {
|
||||
if(!e) {
|
||||
e = {parameter: {days: 1}};
|
||||
}
|
||||
const params = e.parameter;
|
||||
var content = getEventsForNextDay(params.days);
|
||||
var output = ContentService.createTextOutput(content);
|
||||
output.setMimeType(ContentService.MimeType.JSON);
|
||||
return output;
|
||||
}
|
||||
3
miscellaneous/dayahead content type/README.md
Normal file
3
miscellaneous/dayahead content type/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Day Ahead Energy Prices
|
||||
|
||||
Note: this script is for reference and documentation only. You don't need to deploy it yourself to use the Day Ahead content in OpenEpaperLink, as it makes use of a common install.
|
||||
189
miscellaneous/dayahead content type/get_dayahead.js
Normal file
189
miscellaneous/dayahead content type/get_dayahead.js
Normal file
@@ -0,0 +1,189 @@
|
||||
function doGet(e) {
|
||||
|
||||
var logger = Logger.log;
|
||||
var country = e?.parameter?.country || 'NL';
|
||||
var cache = CacheService.getScriptCache();
|
||||
|
||||
var cachedData = cache.get("output" + country);
|
||||
if (false && cachedData != null) {
|
||||
logger('from cache');
|
||||
return ContentService.createTextOutput(cachedData)
|
||||
.setMimeType(ContentService.MimeType.JSON);
|
||||
}
|
||||
|
||||
var factor = 1;
|
||||
if (country.startsWith('NO')) {
|
||||
// https://github.com/bkper/exchange-app
|
||||
factor = cache.get("currencyNOK");
|
||||
if (factor == null) {
|
||||
// factor = ExchangeApp.convert(1, 'EUR', 'NOK');
|
||||
factor = 11.4;
|
||||
cache.put("currencyNOK", factor, 3600 * 24);
|
||||
}
|
||||
}
|
||||
|
||||
if (country.startsWith('DK')) {
|
||||
// https://github.com/bkper/exchange-app
|
||||
factor = cache.get("currencyDKK");
|
||||
if (factor == null) {
|
||||
// factor = ExchangeApp.convert(1, 'EUR', 'DKK');
|
||||
factor = 7.45;
|
||||
cache.put("currencyDKK", factor, 3600 * 24);
|
||||
}
|
||||
}
|
||||
|
||||
if (country.startsWith('SE')) {
|
||||
// https://github.com/bkper/exchange-app
|
||||
factor = cache.get("currencySEK");
|
||||
if (factor == null) {
|
||||
// factor = ExchangeApp.convert(1, 'EUR', 'SEK');
|
||||
factor = 11.25;
|
||||
cache.put("currencySEK", factor, 3600 * 24);
|
||||
}
|
||||
}
|
||||
|
||||
var domain = lookupValue(country);
|
||||
logger(country + ': ' + domain + ' currency: ' + factor);
|
||||
|
||||
var xmlUrl = 'https://web-api.tp.entsoe.eu/api?documentType=A44&out_Domain=' + domain + '&in_Domain=' + domain + '&periodStart=' + getFormattedMidnightUTC(-1) + '&periodEnd=' + getFormattedMidnightUTC(2) + '&securityToken=*********';
|
||||
var cachedXml = cache.get(xmlUrl);
|
||||
|
||||
if (cachedXml) {
|
||||
logger('Using cached XML content.');
|
||||
var xmlContent = cachedXml;
|
||||
} else {
|
||||
logger('Fetching XML content from ' + xmlUrl);
|
||||
var response = UrlFetchApp.fetch(xmlUrl);
|
||||
var xmlContent = response.getContentText();
|
||||
cache.put(xmlUrl, xmlContent, 3600);
|
||||
}
|
||||
|
||||
xmlContent = xmlContent.replace(/xmlns(:[a-z0-9]+)?=["'][^"']*["']/g, '');
|
||||
xmlContent = xmlContent.replace(/<([a-z0-9]+):/g, '<').replace(/<\/([a-z0-9]+):/g, '</');
|
||||
|
||||
var document = XmlService.parse(xmlContent);
|
||||
var root = document.getRootElement();
|
||||
|
||||
var timeSeriesList = getDescendantsByTagName(root, 'TimeSeries');
|
||||
|
||||
if (timeSeriesList.length > 0) {
|
||||
var jsonData = [];
|
||||
|
||||
|
||||
for (var j = 0; j < timeSeriesList.length; j++) {
|
||||
var timeSeries = timeSeriesList[j];
|
||||
|
||||
var period = timeSeries.getChild('Period');
|
||||
|
||||
if (period) {
|
||||
var startTime = period.getChild('timeInterval').getChildText('start');
|
||||
logger(startTime);
|
||||
var points = period.getChildren('Point');
|
||||
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var position = points[i].getChildText('position');
|
||||
var priceAmount = points[i].getChildText('price.amount') * factor;
|
||||
|
||||
// Convert ISO date to epoch time (in seconds)
|
||||
var epochTime = new Date(startTime).getTime() / 1000 + (position - 1) * 3600;
|
||||
|
||||
jsonData.push({
|
||||
time: epochTime,
|
||||
price: parseFloat(priceAmount)
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
logger('Error: No <Period> element found in TimeSeries ' + (j + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonData.length > 36) {
|
||||
jsonData.splice(0, jsonData.length - 36);
|
||||
}
|
||||
|
||||
cache.put("output" + country, JSON.stringify(jsonData), 3600);
|
||||
logger('All Data: ' + JSON.stringify(jsonData));
|
||||
|
||||
return ContentService.createTextOutput(JSON.stringify(jsonData))
|
||||
.setMimeType(ContentService.MimeType.JSON);
|
||||
} else {
|
||||
logger('Error: No <TimeSeries> elements found in Publication_MarketDocument');
|
||||
return ContentService.createTextOutput('Error: No <TimeSeries> elements found in Publication_MarketDocument');
|
||||
}
|
||||
}
|
||||
|
||||
function getDescendantsByTagName(element, tagName) {
|
||||
var matchingElements = [];
|
||||
|
||||
function findDescendants(currentElement) {
|
||||
var children = currentElement.getChildren();
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (child.getName() === tagName) {
|
||||
matchingElements.push(child);
|
||||
}
|
||||
findDescendants(child);
|
||||
}
|
||||
}
|
||||
|
||||
findDescendants(element);
|
||||
return matchingElements;
|
||||
}
|
||||
|
||||
function getFormattedMidnightUTC(offsetDays) {
|
||||
var now = new Date(); // current date and time
|
||||
var localMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + offsetDays, 0, 0, 0, 0);
|
||||
|
||||
var utcMidnight = new Date(localMidnight.getTime());
|
||||
|
||||
var year = utcMidnight.getUTCFullYear();
|
||||
var month = ('0' + (utcMidnight.getUTCMonth() + 1)).slice(-2); // Months are zero-based
|
||||
var day = ('0' + utcMidnight.getUTCDate()).slice(-2);
|
||||
var hours = ('0' + utcMidnight.getUTCHours()).slice(-2);
|
||||
var minutes = ('0' + utcMidnight.getUTCMinutes()).slice(-2);
|
||||
|
||||
var formattedTime = year + month + day + hours + minutes;
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
// https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html#_areas
|
||||
|
||||
function lookupValue(country) {
|
||||
var countryValues = {
|
||||
'AT': '10YAT-APG------L',
|
||||
'BE': '10YBE----------2',
|
||||
'CH': '10YCH-SWISSGRIDZ',
|
||||
'CZ': '10YCZ-CEPS-----N',
|
||||
'DE': '10Y1001A1001A82H',
|
||||
'DK1': '10YDK-1--------W',
|
||||
'DK2': '10YDK-2--------M',
|
||||
'EE': '10Y1001A1001A39I',
|
||||
'ES': '10YES-REE------0',
|
||||
'FI': '10YFI-1--------U',
|
||||
'FR': '10YFR-RTE------C',
|
||||
'LT': '10YLT-1001A0008Q',
|
||||
'LU': '10Y1001A1001A82H',
|
||||
'LV': '10YLV-1001A00074',
|
||||
'NL': '10YNL----------L',
|
||||
'NO1': '10YNO-1--------2',
|
||||
'NO2': '10YNO-2--------T',
|
||||
'NO3': '10YNO-3--------J',
|
||||
'NO4': '10YNO-4--------9',
|
||||
'NO5': '10Y1001A1001A48H',
|
||||
'PL': '10YPL-AREA-----S',
|
||||
'RO': '10YRO-TEL------P',
|
||||
'SE1': '10Y1001A1001A44P',
|
||||
'SE2': '10Y1001A1001A45N',
|
||||
'SE3': '10Y1001A1001A46L',
|
||||
'SE4': '10Y1001A1001A47J',
|
||||
'SI': '10YSI-ELES-----O',
|
||||
'SK': '10YSK-SEPS-----K'
|
||||
};
|
||||
var value = countryValues[country] || '10YNL----------L';
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1
miscellaneous/render_bitmapfonts/Data/readme.txt
Normal file
1
miscellaneous/render_bitmapfonts/Data/readme.txt
Normal file
@@ -0,0 +1 @@
|
||||
Place the source truetype fonts in this folder
|
||||
15
miscellaneous/render_bitmapfonts/README.md
Normal file
15
miscellaneous/render_bitmapfonts/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
### Convert your own fonts to .vlw format
|
||||
|
||||
Use Processing (https://processing.org/) along with the script in this folder, to convert Truetype fonts to .vlw bitmap fonts.
|
||||
You have to select a subset of the characters to convert, by providing the unicode ranges, or by providing a list of characters.
|
||||
|
||||
### Truetype font sources
|
||||
|
||||
We cannot upload the source Truetype files, but these fonts are currently used:
|
||||
|
||||
- twcondensed.ttf Tw Cen MT Condensed by Microsoft
|
||||
- bahnschrift.ttf Bahnschrift by Microsoft
|
||||
- calibrib.ttf Calibri Bold by Microsoft
|
||||
- REFSAN.ttf MS Reference Sans Serif
|
||||
- BellCentennialStd-Address.ttf Bell Centennial Std Address by Adobe
|
||||
|
||||
129
miscellaneous/render_bitmapfonts/render_bitmapfonts.pde
Normal file
129
miscellaneous/render_bitmapfonts/render_bitmapfonts.pde
Normal file
@@ -0,0 +1,129 @@
|
||||
import java.awt.Desktop;
|
||||
|
||||
int curY = 0;
|
||||
PFont myFont;
|
||||
PrintWriter logOutput;
|
||||
|
||||
void setup() {
|
||||
|
||||
size(1200, 1000);
|
||||
|
||||
boolean smooth = true;
|
||||
boolean crisp = false;
|
||||
curY = 0;
|
||||
|
||||
int[] unicodeBlocks = {
|
||||
0x0021, 0x007E, //Basic Latin, 128, 128, Latin (52 characters), Common (76 characters)
|
||||
0x0080, 0x00FF, //Latin-1 Supplement, 128, 128, Latin (64 characters), Common (64 characters)
|
||||
0x0100, 0x017F, //Latin Extended-A, 128, 128, Latin
|
||||
0x0180, 0x024F, //Latin Extended-B, 208, 208, Latin
|
||||
//0x0250, 0x02AF, //IPA Extensions, 96, 96, Latin
|
||||
//0x02B0, 0x02FF, //Spacing Modifier Letters, 80, 80, Bopomofo (2 characters), Latin (14 characters), Common (64 characters)
|
||||
//0x0030, 0x0039, //Example custom range (numbers 0-9)
|
||||
//0x0041, 0x005A, //Example custom range (Upper case A-Z)
|
||||
//0x0061, 0x007A, //Example custom range (Lower case a-z)
|
||||
//0xF000, 0xF0FF, //weather font
|
||||
};
|
||||
|
||||
int blockCount = unicodeBlocks.length;
|
||||
int firstUnicode = 0;
|
||||
int lastUnicode = 0;
|
||||
char[] charset;
|
||||
int index = 0, count = 0;
|
||||
|
||||
for (int i = 0; i < blockCount; i+=2) {
|
||||
firstUnicode = unicodeBlocks[i];
|
||||
lastUnicode = unicodeBlocks[i+1];
|
||||
if (lastUnicode < firstUnicode) {
|
||||
delay(100);
|
||||
System.err.println("ERROR: Bad Unicode range secified, last < first!");
|
||||
System.err.print("first in range = 0x" + hex(firstUnicode, 4));
|
||||
System.err.println(", last in range = 0x" + hex(lastUnicode, 4));
|
||||
while (true);
|
||||
}
|
||||
count += (lastUnicode - firstUnicode + 1);
|
||||
}
|
||||
|
||||
charset = new char[count];
|
||||
for (int i = 0; i < blockCount; i+=2) {
|
||||
firstUnicode = unicodeBlocks[i];
|
||||
lastUnicode = unicodeBlocks[i+1];
|
||||
for (int code = firstUnicode; code <= lastUnicode; code++) {
|
||||
charset[index] = Character.toChars(code)[0];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
String str = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~°ÄÅÆÖØÚÜßáäåæéíöøúüýąČěľłńŘřŚŠź";
|
||||
char[] charsetbasic = str.toCharArray();
|
||||
str = "ACDEFHIJLMNOPRSTUVWZiortzÁØÚČŚŠ0123456789-";
|
||||
char[] charsetdaynames = str.toCharArray();
|
||||
str = "0123456789.°-";
|
||||
char[] charsetnumbers = str.toCharArray();
|
||||
|
||||
createAndSaveFont("twcondensed", ".ttf", charsetdaynames, 20, crisp);
|
||||
|
||||
createAndSaveFont("bahnschrift", ".ttf", charsetbasic, 20, crisp);
|
||||
createAndSaveFont("bahnschrift", ".ttf", charsetbasic, 30, crisp);
|
||||
createAndSaveFont("bahnschrift", ".ttf", charsetnumbers, 70, crisp);
|
||||
|
||||
createAndSaveFont("calibrib", ".ttf", charsetbasic, 30, crisp);
|
||||
|
||||
createAndSaveFont("calibrib", ".ttf", charset, 16, crisp);
|
||||
createAndSaveFont("REFSAN", ".ttf", charset, 12, crisp);
|
||||
createAndSaveFont("BellCentennialStd-Address", ".ttf", charset, 10, crisp);
|
||||
|
||||
try {
|
||||
String path = sketchPath();
|
||||
Desktop.getDesktop().open(new File(path+"/FontFiles"));
|
||||
}
|
||||
catch(IOException e) {
|
||||
println("Failed to create the file");
|
||||
}
|
||||
}
|
||||
|
||||
void createAndSaveFont(String fontName, String fontType, char charset[], int fontSize, boolean smooth) {
|
||||
|
||||
int displayFontSize = fontSize;
|
||||
myFont = createFont(fontName+fontType, displayFontSize, smooth, charset);
|
||||
fill(0, 0, 0);
|
||||
textFont(myFont);
|
||||
int gapx = displayFontSize*10/8;
|
||||
int gapy = displayFontSize*10/8;
|
||||
int index = 0;
|
||||
fill(0);
|
||||
textSize(displayFontSize);
|
||||
curY += gapy;
|
||||
for (int y = curY; y < height-gapy; y += gapy) {
|
||||
int x = 10;
|
||||
curY = y;
|
||||
while (x < width) {
|
||||
|
||||
int unicode = charset[index];
|
||||
float cwidth = textWidth((char)unicode) + 2;
|
||||
if ( (x + cwidth) > (width - gapx) ) break;
|
||||
|
||||
text(new String(Character.toChars(unicode)), x, y);
|
||||
|
||||
x += cwidth;
|
||||
index++;
|
||||
if (index >= charset.length) break;
|
||||
}
|
||||
if (index >= charset.length) break;
|
||||
}
|
||||
|
||||
PFont font;
|
||||
font = createFont(fontName + fontType, fontSize, smooth, charset);
|
||||
println("Created font " + fontName + str(fontSize) + ".vlw");
|
||||
try {
|
||||
print("Saving to sketch FontFiles folder... ");
|
||||
OutputStream output = createOutput("FontFiles/" + fontName + str(fontSize) + ".vlw");
|
||||
font.save(output);
|
||||
output.close();
|
||||
println("OK!");
|
||||
delay(100);
|
||||
}
|
||||
catch (IOException e) {
|
||||
println("Doh! Failed to create the file");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user