Smartstyring av varme

Smartstyring av varmepumpe og panelovn.

Varmepumpe er "dum", altså uten noen form for annen styring enn fjernkontroll.
Satt opp en Broadlink RM4C Mini Universal Remote, og tok opp de funksjonene jeg ønsket (av/på, temp og viftehastighet)

Opprettet egen styring i NR som gir meg muligheten til å se nåværende moduser i HA, samt slå av/på, endre temp og viftehastighet.

Varmepumpa er en Mitsubishi Kirigamine 6,6

For styring av panelovn (800W) brukes smartplugg fra Proshop.

 

Bruker PowerSaver og noden "Lowest Price" for å finne de 12 billigste timene i døgnet, og setter Globalcontext til true

Hvis Nordpool-prisen er lavere enn estimert strømstøttepris denne mnd, settes GlobalContext til true.

Jo nærmere slutten av måneden en kommer, jo sikrere er prisen. Derfor:
Dag 1-10 må Nordpool-prisen være 2 kr under estimert strømstøttepris for å sette GlobalContext til true.
Dag 11-20 må Nordpool-prisen være 1 kr under estimert strømstøttepris for å sette GlobalContext til true.
Dag 21-25 må Nordpool-prisen være 0,5 kr under estimert strømstøttepris for å sette GlobalContext til true.
Dag 26-31 må Nordpool-prisen være 0,2 kr under estimert strømstøttepris for å sette GlobalContext til true.
Dette må muligens justeres da strømprisene er veldig ustabile.

Mitt hus er hønngammelt, og selvom det bl.a. er etterisolert, så er 1.etg veldig kald. Spesielt når det blåser.
For å kunne få en stabil styring av oppvarming, bruker jeg snitt-temperaturen fra 3 rom (2 rom i 1. etg, og 1 rom i 2. etg).
Først regnes snittet ut pr rom, der jeg tar snittet av de siste 30 verdiene (1 time)
Disse snittene brukes igjen for å regne ut snittet for hele huset.
Disse snittverdiene settes i en Globalcontext som enten "stigende", "stabil", eller "synkende" basert på kriterier fra forrige verdi.

Lenke til JSON-kode hos Pastebin her!

I tillegg kjøres en tempsjekk 1 gang pr time (rett for hel) som ser om temp i noen av rommene er for lav eller høy.
true eller false dyttes til en GlobalContext
Hvis det fyres i vedovnen, settes en egen GlobalContext med true eller false

For å kunne styre varmepumpen, måtte jeg opprette egne script for hver enkelt knapp på fjernkontrollen,
Power: av og på
Temp: 16-31
Vifte: 1-4 og auto

All styring av pumpa går igjennom disse hjelperne foran hvert script, slik at riktig output settes.

Lenke til JSON-kode hos Pastebin her!

For å få det litt ryddigere, satte jeg opp alle modusene under hverandre, med "LinkOut"-node til ønsket "LinkIn"-node

Hoved-smartstyringen baserer seg på
1. om modus er Auto eller Manuell (må være Auto)
2. om Nordpool-prisen er lav (må være false)
3. om Nordpool-prisen er lavere enn estimert strømstøttepris (må være false)
4. om det er for kaldt i ett av rommene (må være false)
5. om det fyres i vedovnen (må være false)

Før temp og pumpehastighet justeres, sjekkes  det først snitt-temperaturen i huset. Så sjekkes det hvor på skalaen temperaturen ligger, og deretter justeres evt temp og viftehastighet.

Hvis Nordpool-prisen er innenfor PowerSavers betingelser, sjekkes det om snitt-temp i huset er under 22. Hvis ja, så økes temp og viftehastighet utifra hvor kaldt/varmt det er i huset

Hvis estimert strømstøttepris er true, så sjekkes det om snitt-temp i huset er under 23. Hvis ja, så økes temp og viftehastighet utifra hvor kaldt/varmt det er i huset.
Denne har som formål og varme opp huset skikkelig inntil prisen stiger igjen.

Lenke til JSON-kode hos Pastebin her!

 

Kortet som vises i HA.
1. rad: Status, temp SP, vifte, Skru av/på, velg manuell eller auto-modus
2. rad: velg ønsket temp SP
3. rad: velg ønsket viftehastighet

Jeg startet med Home Assistant våren 2022, og Node Red noe etter det, så jeg er forholdsvis nybegynner.
Sikkert flere, og bedre, måter å løse dette på. Men dette funker for meg 🙂

Drivstoffpriser

Henter inn priser på drivstoff fra ønskede stasjoner.
Stasjonsnavn finnes  i appen Drivstoffpriser (Android og Apple)

Koden under importeres inn i Node Red og justeres etter eget behov

Helgrille pattegris

  • Beregn 5-6 timer på en 25kg gris
  • Når 2 timer igjen til spising bør temp være 50 grader

 

Marinade

  • 3 l solsikkeolje
  • 4 knuste hvitløksfedd
  • Chilli
  • Salt
  • Pepper
  • Paprikakrydder
  • Grillkrydder
  • Appelsinjuice
  • Timian
  • 0,5 l mørkt øl

Faktura Larsen med modifisert forfalsdato

I Faktura Larsen, som er gratis fakturaprogram, er det en teit skrivefeil som kommer på alle fakturaer. Ordet Forfallsdato er skrevet med èn l, slik at det står Forfalsdato.

Her kan du laste ned både siste versjon av Faktura Larsen, og en patch for å rette på denne skrivefeilen

Faktura Larsen (1145 nedlastinger)

Faktura Larsen patch (954 nedlastinger)

Bekreft via meldingsboks

Meldingsboks med Ja eller Nei. Ja kjører skript, Nei skriver til logg

function Bekreft() {
 // Display a dialog box with a message and "Yes" and "No" buttons. The user can also close the dialog by clicking the close button in its title bar.
 var ui = SpreadsheetApp.getUi();
 var response = ui.alert('Melding', 
ui.ButtonSet.YES_NO);

 // Process the user's response.
 if (response == ui.Button.YES) {
    KjørSkript();
 } else {
   Logger.log('Valgte nei');
 }
}

Dynamiske datavalideringslister

Bruke 2 stk datavalideringslister i Google Sheets, der liste nr 2 velges ut ifra hva som blir valgt i liste nr 1

function onEdit(e) {

        //SpreadsheetApp.getActive()

        var sh = e.source.getActiveSheet(),
        allValues, list,
        
        /* easy to change' variables */
        
        sheet = 'NavnPåArk',
        sheetWithLists = 'NavnPåArkMedLister',
        rangeWithLists = 'C1:G10', //Område med lister, der første rad er overskriftene (liste 1)        
        colValidation = 2, //1=A, 2=B... Kolonnen med første liste
        secondValidationOffset = 1; //forskyvningskolonner mot høyre til neste kolonne med lste
    
    /*check conditions*/
    if (sh.getName() !== sheet || e.range.columnStart !== colValidation || e.range.rowStart < 2 || typeof e.value == 'object') return;
    
    /*get all values from the sheet with the lists (cached after the first run)*/
    allValues = getFromCache_(sheetWithLists, rangeWithLists)
    
    /*get the correct list(column) and remove the header*/
    list = allValues.map(function (v, i) {
        return v[allValues[0].indexOf(e.value)]
    }).splice(1);
    
    /*set the validation in offset column*/
    e.range.offset(0, secondValidationOffset)
        .setDataValidation(SpreadsheetApp.newDataValidation()
            .requireValueInList(list)
            .build());
}

function getFromCache_(sheetName, range) {

    var key = 'DE_' + sheetName,
        c = CacheService.getPublicCache(),
        d,
        t = c.get(key);
    if (t) {
        d = JSON.parse(t);
    } else {
        d = SpreadsheetApp.getActiveSpreadsheet()
            .getSheetByName(sheetName)
            .getDataRange()
            .getValues();
        c.put(key, JSON.stringify(d));
    }
    return d;
}

Gå til neste ledige rad etter åpning

Etter åpning av en Google Sheets-arbeidsbok, så settes aktiv celle i neste ledige rad i et valgt ark

function onOpen() {
    var sheet = SpreadsheetApp.getActive()
        .getSheetByName('NavnPåArk'),
        lr;
    var val = sheet.getRange('C:C') // Kolonne for sjekk etter neste ledig
        .getValues();
    for (var i = 0, vLen = val.length; i < vLen; i++) {
        if (!val[i][0] && i > 2) {
            lr = i + 1;
            break;
        }
    }
    sheet.setActiveRange(sheet.getRange('C' + lr)) //Ønsket kolonne for celle skal bli aktiv
}

Spotify – 1 song repeat

  1. Start opp Spotify
  2. Finn sangen du ønsker og spille
  3. Legg til sangen i en ny, tom spilleliste
  4. Start avspilling og klikk på Repeat
  5. Start opp vedlagt programsnutt
  6. Etter 32 spilte sekunder, starter sangen på nytt. Loopes 10000 ganger
  7. For og avslutte programmet, høyreklikk på ikon nede til høyre ved klokka, og velg Avslutt

Last ned: Spotify - 1 song repeat (340 nedlastinger)

Programmet er laget med AutoHotKey.

Kode


Loop, 10000 ; Antall loop
{
Sleep, 33000
WinActivate, ahk_exe Spotify.exe
CoordMode, Mouse, Screen
x := (A_ScreenWidth / 2)
y := (A_ScreenHeight / 2)
mousemove, x, y
Sleep, 500
MouseClick, right,
Send ^{Right}
}

Oppdatert: 21.06.18