<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Tolga Gezginiş]]></title><description><![CDATA[The language of technology]]></description><link>https://tolga.gezginis.com/</link><image><url>https://tolga.gezginis.com/favicon.png</url><title>Tolga Gezginiş</title><link>https://tolga.gezginis.com/</link></image><generator>Ghost 6.44</generator><lastBuildDate>Wed, 10 Jun 2026 16:27:07 GMT</lastBuildDate><atom:link href="https://tolga.gezginis.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Teaching RAG to Say 'I Don't Know']]></title><description><![CDATA[How to decide when a RAG system should stay quiet instead of hallucinating, using confidence scoring, Reciprocal Rank Fusion, and a rejection gate that never calls the LLM, built on pgvector.]]></description><link>https://tolga.gezginis.com/teaching-rag-to-say-i-dont-know/</link><guid isPermaLink="false">6a272e1b39b7b000011849c8</guid><category><![CDATA[rag]]></category><category><![CDATA[llm]]></category><category><![CDATA[postgresql]]></category><category><![CDATA[pgvector]]></category><category><![CDATA[python]]></category><category><![CDATA[ai]]></category><dc:creator><![CDATA[Tolga Gezginiş]]></dc:creator><pubDate>Mon, 08 Jun 2026 21:14:38 GMT</pubDate><media:content url="https://cdn.synaps.media/tgezginis/content/images/2026/06/photo-1553852892-60d02bad79e9.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn.synaps.media/tgezginis/content/images/2026/06/photo-1553852892-60d02bad79e9.jpeg" alt="Teaching RAG to Say &apos;I Don&apos;t Know&apos;"><p>The quality of a RAG system isn&apos;t defined by the moments it answers correctly. It&apos;s defined by whether it can recognize the moment it shouldn&apos;t answer at all and stay quiet. Most RAG implementations lack this second ability: ask anything, and they hand you something. This post walks through a retrieval layer that bakes &quot;how much can we trust this answer&quot; into the pipeline itself, and when needed says &quot;I don&apos;t have information on this&quot; without ever calling the LLM.</p><p>The examples come from a self-hosted RAG platform running in production; the language is Python and the database is PostgreSQL + pgvector.</p><h2 id="the-problem-high-similarity-wrong-answer">The problem: high similarity, wrong answer</h2><p>The classic RAG flow is simple:</p><pre><code class="language-python"># Naive RAG: always produces an answer
async def naive_answer(db, query: str) -&gt; str:
    embedding = await embed(query)
    chunks = await vector_search(db, embedding, top_k=5)  # always returns 5
    context = &quot;\n\n&quot;.join(c.content for c in chunks)
    return await llm.chat(
        system=f&quot;Answer using the following context:\n{context}&quot;,
        user=query,
    )
</code></pre><p>Embed the query, pull the nearest k chunks, stuff them into the prompt, ask the LLM. This flow has a silent flaw.&#xA0;<code>vector_search</code>&#xA0;always returns &quot;the nearest k results,&quot; but it never asks &quot;is anything actually close enough?&quot; Even when the knowledge base contains nothing about the topic, the nearest k chunks still come back and land in the prompt. Notice that&#xA0;<code>naive_answer</code>&#xA0;can never say &quot;I don&apos;t know&quot; under any condition; its return type doesn&apos;t even make that possible.</p><p>The conceptual mistake here is treating cosine similarity as a quality signal. Similarity is a ranking signal: is result A more relevant than result B? It answers that well. But &quot;is result A relevant enough to answer this question?&quot; is a different question, and similarity alone doesn&apos;t answer it. The &quot;best&quot; chunk at 0.65 cosine distance can still be entirely irrelevant in absolute terms.</p><p>The result is RAG&apos;s most dangerous mode: the model builds extremely confident sentences on top of weak context. The user never sees the source, only a fluent and wrong answer.</p><p>The fix is not to delegate &quot;confidence&quot; to the prompt (saying&#xA0;<code>answer only based on the context</code>). That instruction helps, but it&apos;s a weak line of defense; it relies on the model complying. Far more robust is to measure confidence in the retrieval layer and never go to the LLM when it&apos;s low.</p><h2 id="a-two-tier-threshold">A two-tier threshold</h2><p>A single threshold doesn&apos;t solve this, because we&apos;re making two distinct decisions:</p><ol><li>Is this chunk worth putting into the context? (noise cleanup)</li><li>Should we even attempt an answer with the context we have? (the answer decision)</li></ol><p>Different jobs, different thresholds:</p><pre><code class="language-python"># Minimum confidence for a chunk to enter the context (filters low-quality matches)
MIN_CHUNK_CONFIDENCE = 25.0
# If average confidence is below this, skip the LLM and reject directly
MIN_CONFIDENCE_GATE = 40.0
</code></pre><p>First we convert cosine distance into a 0-100 chunk score:</p><pre><code class="language-python">def _distance_to_confidence(distance: float, max_dist: float = 0.65) -&gt; float:
    if distance &lt;= 0:
        return 100.0
    if distance &gt;= max_dist:
        return 0.0
    return round(max(0, (1 - distance) * 100), 1)
</code></pre><p>A linear transform; not a sophisticated calibration, and deliberately so.&#xA0;<code>max_dist</code>&#xA0;is a ceiling: anything beyond that distance counts as zero and is already dropped during retrieval. The goal here isn&apos;t to produce a true probability, but a consistent scale that&apos;s comparable against thresholds. On that scale, 25 (&quot;don&apos;t put it in the context&quot;) and 40 (&quot;don&apos;t answer at all&quot;) become meaningful boundaries.</p><h2 id="hybrid-retrieval-vector-bm25-fused-with-rrf">Hybrid retrieval: vector + BM25, fused with RRF</h2><p>Vector search captures meaning but is weak on exact matches: a product code, a proper name, an SKU doesn&apos;t resemble something semantically &quot;close,&quot; it appears verbatim where it appears. BM25 keyword search is the opposite: strong on exact matches, weak on meaning. Using both is natural, but there&apos;s a problem: their scores aren&apos;t comparable. A cosine distance and a PostgreSQL&#xA0;<code>ts_rank</code>&#xA0;are not on the same scale and can&apos;t be summed.</p><p>Each search produces its own ranked list. The vector side, via pgvector and cosine distance:</p><pre><code class="language-python">distance_expr = Chunk.embedding.cosine_distance(query_vector)
stmt = (
    select(Chunk, distance_expr.label(&quot;distance&quot;))
    .where(Chunk.embed_id == embed_id)
    .where(Chunk.chunk_type == &quot;child&quot;)
    .order_by(distance_expr)        # smaller distance = more relevant
    .limit(top_k)
)
</code></pre><p>The keyword side, via PostgreSQL full-text search over a prefix-matching tsquery:</p><pre><code class="language-python"># &quot;return policy&quot; -&gt; &quot;return:* &amp; policy:*&quot;  (prefix also matches &quot;returns&quot;, &quot;policies&quot;)
ts_query = func.to_tsquery(&quot;simple&quot;, func.unaccent(prefix_expr))
rank_expr = func.ts_rank(Chunk.search_vector, ts_query)
</code></pre><p><code>distance</code>&#xA0;(near 0 = good) and&#xA0;<code>ts_rank</code>&#xA0;(large = good) point neither in the same direction nor on the same scale. The fix is to fuse ranks, not scores: Reciprocal Rank Fusion.</p><pre><code class="language-python">def _reciprocal_rank_fusion(
    vector_results: list[tuple[str, float]],
    keyword_results: list[tuple[str, float]],
    k: int = 60,
) -&gt; list[str]:
    scores: dict[str, float] = {}
    for rank, (chunk_id, _) in enumerate(vector_results):
        scores[chunk_id] = scores.get(chunk_id, 0) + 1.0 / (k + rank + 1)
    for rank, (chunk_id, _) in enumerate(keyword_results):
        scores[chunk_id] = scores.get(chunk_id, 0) + 1.0 / (k + rank + 1)
    return sorted(scores.keys(), key=lambda x: scores[x], reverse=True)
</code></pre><p>The elegance of RRF is that it ignores the raw score value entirely. It uses only the rank: a chunk near the top of both lists gets a high total, one that appears in only a single list gets less. A concrete example (k=60):</p><pre><code class="language-text">Vector order:   [A, B, C]      Keyword order:  [C, A, D]

A: 1/(60+0+1) + 1/(60+1+1) = 0.01639 + 0.01613 = 0.03252
C: 1/(60+2+1) + 1/(60+0+1) = 0.01587 + 0.01639 = 0.03226
B: 1/(60+1+1)              = 0.01613
D: 1/(60+2+1)              = 0.01587

Fused order: [A, C, B, D]
</code></pre><p>Even though neither A nor C tops a single list, they rise to the top because they appear in both. The constant&#xA0;<code>k=60</code>&#xA0;(from the original RRF paper) softens the influence of the leading ranks; as k grows, the gaps between ranks shrink. This approach is scale-independent and resistant to outlier scores, which makes it the most practical way to combine two heterogeneous search systems.</p><p>After the fused ranking we filter out low-quality chunks, with one exception:</p><pre><code class="language-python"># Hand-written Q&amp;A always ranks first, exempt from the minimum confidence filter
training_chunks = [c for c in chunks if c.chunk_metadata.get(&quot;source&quot;) == &quot;training_data&quot;]
doc_chunks = [c for c in chunks if c.chunk_metadata.get(&quot;source&quot;) != &quot;training_data&quot;]

# Drop document chunks below the threshold
doc_chunks = [c for c in doc_chunks if score_map.get(c.id, 0) &gt;= MIN_CHUNK_CONFIDENCE]
</code></pre><p>Curated (hand-prepared) answers are exempt from this filter, and from the rejection gate we&apos;ll see next. The reasoning: if someone wrote the correct answer to this question by hand, the system&apos;s statistical confidence calculation shouldn&apos;t override that human decision.</p><h2 id="the-rejection-gate-never-calling-the-llm">The rejection gate: never calling the LLM</h2><p>This is the real decision. If average confidence is below the threshold, we don&apos;t build a prompt and go to the LLM; we reject directly:</p><pre><code class="language-python">avg_confidence = _calc_final_confidence(chunks)
has_training_data = any(c.chunk_metadata.get(&quot;source&quot;) == &quot;training_data&quot; for c in chunks)

# If confidence is too low, skip the LLM. Never reject when training data matches.
if not has_training_data and avg_confidence is not None and avg_confidence &lt; MIN_CONFIDENCE_GATE:
    yield f&quot;{json.dumps(meta, ensure_ascii=False)}\n&quot;
    yield &quot;[REJECTION]&quot;
    yield await _get_rejection_message(embed, lang)
    return
</code></pre><p>This has three concrete benefits:</p><ul><li><strong>Zero hallucination risk.</strong>&#xA0;Weak context never reaches the model, so the model can&apos;t build on it.</li><li><strong>Token savings.</strong>&#xA0;No chat completion call is made for a query that will be rejected. At high volume this is a serious cost line.</li><li><strong>Faster response.</strong>&#xA0;Rejection skips the slowest step (LLM generation), so it returns instantly.</li></ul><p>Since the stream is SSE, we mark the rejection with a&#xA0;<code>[REJECTION]</code>&#xA0;sentinel; when the frontend sees it, it renders the response as a &quot;no information&quot; state instead of a normal answer. From the client&apos;s side, a rejected query looks like this:</p><pre><code class="language-text">{&quot;sources&quot;: [], &quot;response_time_ms&quot;: 48, &quot;avg_confidence&quot;: 22.0}
[REJECTION]
I don&apos;t have enough information about this topic in my knowledge base.
</code></pre><p>Note&#xA0;<code>response_time_ms: 48</code>: because the LLM was never called, the response returned in under 50 ms. For comparison, the first token of an accepted query usually takes 800-2000 ms. The rejection message itself is chosen by query language: first a fixed fallback dictionary, then LLM translation if needed.</p><pre><code class="language-python">_FALLBACK_REJECTION = {
    &quot;tr&quot;: &quot;Bu konuda bilgi taban&#x131;mda yeterli bilgi bulunmamaktad&#x131;r.&quot;,
    &quot;en&quot;: &quot;I don&apos;t have enough information about this topic in my knowledge base.&quot;,
    &quot;de&quot;: &quot;Zu diesem Thema habe ich nicht gen&#xFC;gend Informationen in meiner Wissensdatenbank.&quot;,
}
</code></pre><h2 id="final-confidence-is-not-the-retrieval-score">Final confidence is not the retrieval score</h2><p>The confidence score we show to the user and to analytics is not the raw cosine score. This is a deliberate separation: the raw retrieval score is an internal metric, while the confidence shown to the user is a UX decision. Telling a user &quot;42% confidence&quot; is misleading, because that number isn&apos;t confidence in the sense they understand.</p><pre><code class="language-python">def _calc_final_confidence(chunks, is_rejected=False):
    scores = [getattr(c, &quot;_confidence&quot;, None) for c in chunks]
    scores = [s for s in scores if s is not None]
    if not scores:
        return round(10.0 if not is_rejected else 5.0, 1)
    best_score = max(scores)
    if is_rejected:
        # Chunks found but couldn&apos;t answer -&gt; 20-50 range
        return round(20 + (best_score / 100) * 30, 1)
    # Chunks found and answer given -&gt; 70-100 range
    normalized = min(1.0, max(0.0, (best_score - 20) / 60))
    return round(70 + normalized * 30, 1)
</code></pre><p>The score first lands in a tier based on the outcome: answer given (70-100), chunks found but rejected (20-50), no chunks at all (5-10). The raw score of the best chunk only fine-tunes within that tier. This way the user interprets the number correctly: 80 really is &quot;good,&quot; 35 really is &quot;questionable.&quot;</p><h2 id="how-to-tune-these-numbers">How to tune these numbers</h2><p><code>25</code>,&#xA0;<code>40</code>,&#xA0;<code>0.65</code>,&#xA0;<code>k=60</code>&#xA0;are not universal truths; they&apos;re values that settled in for our domain. The practical way to calibrate them for your own system:</p><ol><li>Log&#xA0;<code>avg_confidence</code>&#xA0;on real queries.</li><li>Hand-label correct and incorrect answers, and plot the confidence histogram of each group.</li><li>Put the gate where the two distributions intersect.</li></ol><p>In practice, a simple sweep over the logged data shows the real cost of the threshold:</p><pre><code class="language-python"># Evaluate candidate gate values over labeled historical queries
def evaluate_gate(samples, gate):
    # samples: [(avg_confidence, was_correct), ...]
    rejected = [s for s in samples if s[0] &lt; gate]
    answered = [s for s in samples if s[0] &gt;= gate]
    false_rejects = sum(1 for c, ok in rejected if ok)      # rejected, but could have answered correctly
    hallucinations = sum(1 for c, ok in answered if not ok)  # answered, but wrong
    return false_rejects, hallucinations

for gate in (30, 35, 40, 45, 50):
    fr, hl = evaluate_gate(samples, gate)
    print(f&quot;gate={gate}: missed={fr}, hallucinations={hl}&quot;)
</code></pre><p>The two columns in the output are exactly the trade-off you want to manage: as&#xA0;<code>gate</code>&#xA0;rises, hallucinations drop and missed (needlessly rejected) queries climb. The domain&apos;s tolerance for error sets this balance. A medical or legal assistant should reject aggressively; a general FAQ bot can be more generous.</p><h2 id="closing">Closing</h2><p>The path to better confidence in RAG is usually sought in &quot;better embeddings,&quot; &quot;a bigger model,&quot; &quot;a smarter prompt.&quot; Yet the highest-leverage intervention is often simpler: teach the system to stay quiet. Instead of leaving confidence to the LLM&apos;s inner world, put a deterministic gate in the retrieval layer; that gate is cheap, testable, and predictable.</p><p>A system that can say &quot;I can&apos;t answer this&quot; earns more trust than one that answers everything. Because once a user gets a wrong-but-confident answer, they lose trust in the correct answers too.</p>]]></content:encoded></item><item><title><![CDATA[CTO Olmak: Ekip, Zorluklar ve Gerçekler]]></title><description><![CDATA[<p>CTO rol&#xFC; d&#x131;&#x15F;ar&#x131;dan genellikle cazip g&#xF6;r&#xFC;n&#xFC;r. Karar veren, y&#xF6;nlendiren, teknolojiyi &#x15F;ekillendiren ki&#x15F;i&#x2026; Ama i&#x15F;in i&#xE7;inde olunca fark ediyorsun ki bu koltuk asl&#x131;nda s&#xFC;rekli de&</p>]]></description><link>https://tolga.gezginis.com/cto-olmak-ekip-zorluklar-ve-gercekler/</link><guid isPermaLink="false">68ed316916f49f0001298196</guid><category><![CDATA[cto]]></category><category><![CDATA[development]]></category><category><![CDATA[management]]></category><dc:creator><![CDATA[Tolga Gezginiş]]></dc:creator><pubDate>Mon, 13 Oct 2025 17:20:24 GMT</pubDate><media:content url="https://cdn.synaps.media/tgezginis/content/images/2025/10/photo-1495427513693-3f40da04b3fd.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn.synaps.media/tgezginis/content/images/2025/10/photo-1495427513693-3f40da04b3fd.jpeg" alt="CTO Olmak: Ekip, Zorluklar ve Ger&#xE7;ekler"><p>CTO rol&#xFC; d&#x131;&#x15F;ar&#x131;dan genellikle cazip g&#xF6;r&#xFC;n&#xFC;r. Karar veren, y&#xF6;nlendiren, teknolojiyi &#x15F;ekillendiren ki&#x15F;i&#x2026; Ama i&#x15F;in i&#xE7;inde olunca fark ediyorsun ki bu koltuk asl&#x131;nda s&#xFC;rekli de&#x11F;i&#x15F;en bir denge oyunu. Teknik bilgi tek ba&#x15F;&#x131;na yetmiyor; liderlik, sab&#x131;r, ileti&#x15F;im ve bazen de duygusal dayan&#x131;kl&#x131;l&#x131;k gerekiyor.</p><p>Ekip y&#xF6;netimi bu i&#x15F;in en karma&#x15F;&#x131;k taraf&#x131;. Teknik problemler genelde &#xE7;&#xF6;z&#xFC;lebilir; log tutars&#x131;n, debug yapars&#x131;n, sistemi aya&#x11F;a kald&#x131;r&#x131;rs&#x131;n. Ama insanlarla &#xE7;al&#x131;&#x15F;mak farkl&#x131;. Herkesin motivasyonu, ileti&#x15F;im bi&#xE7;imi, &#xF6;nceli&#x11F;i birbirinden farkl&#x131;. Bu &#xE7;e&#x15F;itlilik bir yandan inan&#x131;lmaz bir g&#xFC;&#xE7;, ama do&#x11F;ru y&#xF6;netilmedi&#x11F;inde t&#xFC;m ekibe yay&#x131;lan bir probleme d&#xF6;n&#xFC;&#x15F;&#xFC;yor.</p><p>Benim i&#xE7;in d&#xF6;n&#xFC;m noktas&#x131;, ileti&#x15F;imi &#x201C;problemi &#xE7;&#xF6;zmek&#x201D; i&#xE7;in de&#x11F;il &#x201C;anlamaya &#xE7;al&#x131;&#x15F;mak&#x201D; i&#xE7;in kullanmam gerekti&#x11F;ini fark etti&#x11F;im and&#x131;. Eskiden biriyle fikir ayr&#x131;l&#x131;&#x11F;&#x131; ya&#x15F;ad&#x131;&#x11F;&#x131;mda hemen &#xE7;&#xF6;z&#xFC;m &#xFC;retmeye odaklan&#x131;rd&#x131;m. Oysa &#xE7;o&#x11F;u zaman insanlar &#xE7;&#xF6;z&#xFC;m de&#x11F;il, duyulmak istiyor. Dinlemeyi &#xF6;&#x11F;rendik&#xE7;e, anla&#x15F;&#x131;lmaman&#x131;n ne kadar y&#x131;prat&#x131;c&#x131; oldu&#x11F;unu da fark ettim.</p><p>Bir CTO olarak bazen &#x201C;her &#x15F;eyi bilmem&#x201D; beklentisiyle kar&#x15F;&#x131;la&#x15F;&#x131;yorum. Ekibin g&#xF6;z&#xFC;nde, y&#xF6;neticilerin g&#xF6;z&#xFC;nde, hatta kendi i&#xE7; sesimde bile&#x2026; Oysa &#xE7;o&#x11F;u zaman bilmiyorum. Bilmemeyi kabul etmek, &#xF6;&#x11F;renmeye a&#xE7;&#x131;k kalmak, &#x201C;bunu birlikte &#xE7;&#xF6;zelim&#x201D; diyebilmek en b&#xFC;y&#xFC;k rahatlama oldu. Bu tav&#x131;r, ekipte g&#xFC;ven yarat&#x131;yor. &#xC7;&#xFC;nk&#xFC; kimse kusursuz bir liderin alt&#x131;nda kendini rahat hissetmez; ama insani bir liderin alt&#x131;nda b&#xFC;y&#xFC;mek ister.</p><h3 id="kriz-anlar%C4%B1nda-sorumluluk-almak-ve-stresi-y%C3%B6netmek"><strong>Kriz Anlar&#x131;nda Sorumluluk Almak ve Stresi Y&#xF6;netmek</strong></h3><p>Bu yolculukta unutamad&#x131;&#x11F;&#x131;m anlardan biri, kritik bir servisin saatlerce cloud provider kaynakl&#x131; bir donan&#x131;m problemi y&#xFC;z&#xFC;nden devre d&#x131;&#x15F;&#x131; kald&#x131;&#x11F;&#x131; g&#xFC;nd&#xFC;. Bir yandan m&#xFC;&#x15F;terilerden mesajlar ya&#x11F;&#x131;yor, di&#x11F;er yandan ekip panik i&#xE7;inde &#xE7;&#xF6;z&#xFC;m ar&#x131;yordu. Ak&#x131;ll&#x131; saatim s&#xFC;rekli y&#xFC;ksek nab&#x131;z bildirimi g&#xF6;nderiyordu. Eminim t&#xFC;m ekip arkada&#x15F;lar&#x131;m da ayn&#x131; stresi ya&#x15F;&#x131;yordu.</p><p>Herkesin g&#xF6;z&#xFC; bir karar bekliyordu. &#x201C;Yeni sunucuya ge&#xE7;i&#x15F;i ba&#x15F;latal&#x131;m m&#x131;? Yoksa sorunun d&#xFC;zelmesini bekleyelim mi?&#x201D; sorular&#x131; aras&#x131;nda saniyeler uzuyordu. &#x130;&#xE7;imden f&#x131;rt&#x131;nalar kopsa da sakin kalmam gerekti&#x11F;ini biliyordum. Zor bir kararla yeni sunucuya ge&#xE7;i&#x15F; yapt&#x131;k. &#x130;&#x15F;e yarad&#x131;, ama as&#x131;l mesele teknik &#xE7;&#xF6;z&#xFC;m de&#x11F;il o anki duru&#x15F;tu. Gerginlik yerini odaklanmaya b&#x131;rakm&#x131;&#x15F;t&#x131;. Sonra d&#xFC;&#x15F;&#xFC;nd&#xFC;m: liderlik bazen do&#x11F;ru karar&#x131; bulmak de&#x11F;il, zor anda karar almay&#x131; ve o karar&#x131;n sorumlulu&#x11F;unu &#xFC;stlenmeyi bilmektir.</p><p>CTO olduktan sonra stresin bedensel etkilerini de daha net hissetmeye ba&#x15F;lad&#x131;m. Y&#x131;llard&#x131;r kontrol alt&#x131;nda tuttu&#x11F;um sedef hastal&#x131;&#x11F;&#x131;m, &#xF6;zellikle yo&#x11F;un d&#xF6;nemlerde yeniden alevlendi. O d&#xF6;nemde doktorum, &#x201C;stres seni i&#xE7;eriden yak&#x131;yor&#x201D; demi&#x15F;ti. Ger&#xE7;ekten de hakl&#x131;yd&#x131;.</p><p>Kimi sabahlar uykusuzlukla, kimi ak&#x15F;amlar-geceler bitmeyen i&#x15F;lerle bo&#x11F;u&#x15F;urken fark ettim ki liderlik sadece insan ve teknoloji y&#xF6;netmek de&#x11F;il, kendi stresini de y&#xF6;netebilmek. Bunun kolay bir re&#xE7;etesi yok. Bazen i&#x15F;e birka&#xE7; dakika ara verip y&#xFC;r&#xFC;y&#xFC;&#x15F; yapmak, bazen sessizce bir kahve i&#xE7;mek bile sistemi s&#x131;f&#x131;rlayabiliyor. En az&#x131;ndan ben kendimde bu k&#xFC;&#xE7;&#xFC;k rutinleri oturtmaya &#xE7;al&#x131;&#x15F;&#x131;yorum. &#xC7;&#xFC;nk&#xFC; stresin birikti&#x11F;i yerde, ak&#x131;l da sezgi de k&#xF6;relmeye ba&#x15F;l&#x131;yor.</p><h3 id="hatalarla-b%C3%BCy%C3%BCmek-ve-%C3%B6%C4%9Frenmeye-devam-etmek"><strong>Hatalarla B&#xFC;y&#xFC;mek ve &#xD6;&#x11F;renmeye Devam Etmek</strong></h3><p>Teknik bor&#xE7;, bizim gibi &#xFC;r&#xFC;n odakl&#x131; ekiplerde s&#xFC;rekli g&#xF6;lgede duran bir konu. Her yeni &#xF6;zelli&#x11F;in arkas&#x131;nda bir miktar bor&#xE7; birikiyor. Eskiden bunu bir utan&#xE7; kayna&#x11F;&#x131; gibi g&#xF6;r&#xFC;rd&#xFC;m, &#x15F;imdi daha ger&#xE7;ek&#xE7;i bak&#x131;yorum: bor&#xE7; ka&#xE7;&#x131;n&#x131;lmaz, mesele onu fark edip kontrol alt&#x131;nda tutabilmek. &#x201C;B&#xFC;y&#xFC;me mi, stabilite mi?&#x201D; sorusunun cevab&#x131; hi&#xE7;bir zaman net olmuyor.</p><p>Y&#x131;llar i&#xE7;inde &#x15F;unu &#xF6;&#x11F;rendim: ekiplerin performans&#x131; bilgiyle de&#x11F;il, g&#xFC;venle &#xF6;l&#xE7;&#xFC;l&#xFC;yor. &#x130;nsanlar hata yapmaktan korkmad&#x131;&#x11F;&#x131;nda yarat&#x131;c&#x131;l&#x131;k ortaya &#xE7;&#x131;k&#x131;yor. Bunu sa&#x11F;lamak i&#xE7;in zaman zaman geriye &#xE7;ekilip &#x201C;neden bu kadar bask&#x131; hissediliyor?&#x201D; diye sormam gerekti. &#xC7;o&#x11F;u zaman cevab&#x131; d&#x131;&#x15F;ar&#x131;da de&#x11F;il, kendi davran&#x131;&#x15F;lar&#x131;mda buldum. Aceleyle att&#x131;&#x11F;&#x131;m bir yorum, toplant&#x131;da s&#xF6;yledi&#x11F;im bir kelime, bir fikri h&#x131;zla kapatmam&#x2026; K&#xFC;&#xE7;&#xFC;k detaylar, ekipte b&#xFC;y&#xFC;k yank&#x131;lar yaratabiliyor.</p><p>Bug&#xFC;n geriye d&#xF6;n&#xFC;p bakt&#x131;&#x11F;&#x131;mda, en &#xE7;ok b&#xFC;y&#xFC;d&#xFC;&#x11F;&#xFC;m anlar hatas&#x131;z d&#xF6;nemler de&#x11F;il, t&#xF6;kezledi&#x11F;im zamanlar oldu. Bir projede yanl&#x131;&#x15F; ki&#x15F;iye g&#xFC;venmek, yanl&#x131;&#x15F; &#xF6;ncelik se&#xE7;mek ya da bir &#xE7;at&#x131;&#x15F;ma an&#x131;nda sessiz kalmak&#x2026; Bunlar&#x131;n her biri beni y&#xF6;neticilikten &#xE7;ok insan olarak olgunla&#x15F;t&#x131;rd&#x131;.</p><p>CTO olmak bazen bir maraton, bazen satran&#xE7;, bazen de sadece f&#x131;rt&#x131;nay&#x131; atlatmak. Ama her durumda tek bir &#x15F;ey sabit kal&#x131;yor: bu yolculukta &#x201C;bilmiyorum&#x201D; diyebilmek ve &#xF6;&#x11F;renmeye &#xE7;al&#x131;&#x15F;mak &#xE7;ok de&#x11F;erli. &#xC7;&#xFC;nk&#xFC; liderlik, her &#x15F;eyi bilmek de&#x11F;il; &#xF6;&#x11F;renmeyi hi&#xE7; b&#x131;rakmamakt&#x131;r.</p>]]></content:encoded></item><item><title><![CDATA[Home Assistant + Tesla: Smarter Living]]></title><description><![CDATA[Discover how to supercharge your life with Home Assistant and Tesla automations. From smart garage control to battery alerts, unlock the full potential of your connected home and car.]]></description><link>https://tolga.gezginis.com/home-assistant-tesla-smarter-living/</link><guid isPermaLink="false">68bc7f05a80d820001aa0755</guid><category><![CDATA[tesla]]></category><category><![CDATA[home assistant]]></category><category><![CDATA[smart home]]></category><category><![CDATA[automation]]></category><dc:creator><![CDATA[Tolga Gezginiş]]></dc:creator><pubDate>Sat, 06 Sep 2025 19:04:40 GMT</pubDate><media:content url="https://cdn.synaps.media/tgezginis/content/images/2025/09/priscilla-du-preez-ZKRHDRbgYzA-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/priscilla-du-preez-ZKRHDRbgYzA-unsplash.jpg" alt="Home Assistant + Tesla: Smarter Living"><p>Hello, tech enthusiasts!</p><p>As a smart home user, I experience every day how automation simplifies our lives. Especially when you combine a flexible and powerful platform like <a href="https://www.home-assistant.io/?ref=tolga.gezginis.com" rel="noreferrer"><strong>Home Assistant</strong></a> with a technological marvel like a <strong>Tesla</strong>, the possibilities that emerge are truly fascinating. In this blog post, I&apos;ll share some automations I&apos;ve created by integrating Tesla with Home Assistant and ideas on how you can enhance this process.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-21.43.41.png" class="kg-image" alt="Home Assistant + Tesla: Smarter Living" loading="lazy" width="2000" height="1516" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-21.43.41.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-21.43.41.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-21.43.41.png 1600w, https://cdn.synaps.media/tgezginis/content/images/size/w2400/2025/09/Screenshot-2025-09-06-at-21.43.41.png 2400w" sizes="(min-width: 1200px) 1200px"></figure><p>As you can see in the image, I&apos;ve integrated all my Tesla&apos;s data into my Home Assistant via Tesla Fleet integration. This allows me to monitor a wealth of information in real-time, from battery level to whether the doors are open, and even the car&apos;s speed, all from a single screen. But the real fun begins when you start creating automations that simplify your life using this data.</p><figure class="kg-card kg-image-card"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-21.44.47.png" class="kg-image" alt="Home Assistant + Tesla: Smarter Living" loading="lazy" width="1684" height="570" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-21.44.47.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-21.44.47.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-21.44.47.png 1600w, https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-21.44.47.png 1684w" sizes="(min-width: 720px) 720px"></figure><h3 id="tesla-fleet-setup-and-configuration">Tesla Fleet Setup and Configuration</h3><p>The <strong>Tesla Fleet</strong> integration in Home Assistant allows you to connect to your Tesla vehicles and access a wealth of data and control functionalities. To set it up, you&apos;ll typically need to:</p><ol><li><strong>Add the Integration:</strong> Navigate to <strong>Settings &gt; Devices &amp; Services &gt; Add Integration</strong> in your Home Assistant instance.</li><li><strong>Authenticate:</strong> You&apos;ll be prompted to log in with your Tesla account credentials. This process securely authenticates your access to your vehicle data.</li><li><strong>Select Vehicles:</strong> After successful authentication, you can select which of your Tesla vehicles you want to integrate with Home Assistant.</li><li><strong>Configure Entities:</strong> Once added, Home Assistant will create various <strong>entities</strong> for your vehicle, representing different aspects like battery level, charging status, location, doors, climate control, and more. These entities can then be used in dashboards, automations, and scripts.</li></ol><p>This integration is the backbone for many advanced Tesla automations, providing the necessary data points to create intelligent routines.</p><h2 id="automation-suggestions">Automation Suggestions</h2><h3 id="1-arrival-automation-let-your-garage-door-open-automatically">1. Arrival Automation: Let Your Garage Door Open Automatically</h3><p>This automation ensures your garage door opens automatically as you approach home. Using just location data isn&apos;t enough, because you wouldn&apos;t want the door opening every time you get close. That&apos;s why I created a smarter scenario:</p><ul><li><strong>Triggers:</strong><ul><li>When my car gets within 20 meters of home.</li><li>Or when my car has been in the &quot;home&quot; zone for 5 seconds.</li></ul></li><li><strong>Conditions:</strong><ul><li>The driver is present in the seat (<code>binary_sensor.tesla_is_user_present</code>). This prevents the garage door from opening without me.</li><li>The car is in motion (<code>sensor.tesla_speed</code> is greater than 0).</li><li>The garage door is not already open.</li></ul></li><li><strong>Actions:</strong><ul><li>First, I turn on the garage lights.</li><li>Then, I&apos;ve added an AI-powered control mechanism. By analyzing the image from the garage camera, I check if there are any vehicles in the garage other than the ATV. This way, I prevent the door from opening and potentially hitting other vehicles inside.</li><li>If the AI&apos;s response is &quot;No,&quot; I disarm the garage alarm and open the garage door.</li><li>If the response is &quot;Yes,&quot; I receive a notification on my phone stating, &quot;The garage door was not opened because another vehicle is in the garage.&quot;</li><li>Finally, after 5 minutes, I turn off the garage lights.</li></ul></li></ul><p>Thanks to this complex yet secure and user-friendly automation, I can drive directly into the garage without touching anything upon arrival.</p><hr><h3 id="2-reverse-gear-automation-effortless-exit-from-the-garage">2. Reverse Gear Automation: Effortless Exit from the Garage</h3><p>This automation ensures the garage door opens automatically when you&apos;re backing out of the garage.</p><ul><li><strong>Trigger:</strong><ul><li>When the Tesla&apos;s gear has been in &quot;R&quot; (Reverse) for 3 seconds.</li></ul></li><li><strong>Conditions:</strong><ul><li>My location is within the &quot;home&quot; zone.</li><li>The driver is in the car.</li><li>The car&apos;s heading is oriented towards the garage door (<code>sensor.tesla_heading</code> is between 85 and 100 degrees).</li><li>The garage door is not already open.</li></ul></li><li><strong>Action:</strong><ul><li>When all conditions are met, the garage door automatically opens.</li></ul></li></ul><p>This automation provides significant convenience when exiting the garage and greatly simplifies the maneuvering process.</p><hr><h3 id="3-battery-level-alert-never-forget-to-charge">3. Battery Level Alert: Never Forget to Charge</h3><p>Battery level is critical for electric vehicles. This simple automation notifies me when my car&apos;s charge level drops below a certain threshold:</p><ul><li><strong>Trigger:</strong><ul><li>When the Tesla&apos;s battery level (<code>sensor.tesla_battery_level</code>) drops below 21%.</li></ul></li><li><strong>Action:</strong><ul><li>A notification is sent to my phone with the title &quot;Tesla Model Y Charge Below 20%&quot; and the message, &quot;Tesla Model Y&apos;s charge has dropped below 20%. Please charge as soon as possible!&quot;</li></ul></li></ul><p>This way, the risk of forgetting to charge is eliminated, and I don&apos;t experience the stress of running out of power.</p><h3 id="what-else-can-be-done">What Else Can Be Done?</h3><p>With the flexibility offered by Home Assistant and the richness of Tesla data, you can create many more automations by pushing your imagination. Here are a few ideas:</p><ul><li><strong>Tracking your Tesla when it travels a wide area:</strong> You can set up notifications for when it leaves a specific geographic area (<code>geo_fence</code>). For example, if your child takes the car and moves outside a designated zone, you&apos;ll be notified instantly.</li><li><strong>Closing windows based on weather:</strong> Using rain sensor data, you can ensure that windows close automatically if they are detected to be open. You don&apos;t even have to be home!</li><li><strong>Automatic locking of doors and trunk:</strong> When you park the car and leave home, you can set up an automation to ensure the doors and trunk are locked.</li><li><strong>Notification when charge limit is reached:</strong> You can set up a notification for when the charge limit is reached (<code>sensor.tesla_charge_limit</code>), allowing you to take action to stop charging.</li></ul><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-21.46.42.png" class="kg-image" alt="Home Assistant + Tesla: Smarter Living" loading="lazy" width="2000" height="381" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-21.46.42.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-21.46.42.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-21.46.42.png 1600w, https://cdn.synaps.media/tgezginis/content/images/size/w2400/2025/09/Screenshot-2025-09-06-at-21.46.42.png 2400w" sizes="(min-width: 1200px) 1200px"><figcaption><span style="white-space: pre-wrap;">You can monitor the charging currents for the past month</span></figcaption></figure><p>You too can create automations that simplify your life with Home Assistant and Tesla integration, taking your smart home experience to the next level. Do you have any other ideas on this topic? Don&apos;t forget to share them in the comments!</p>]]></content:encoded></item><item><title><![CDATA[Explore Your Tesla's Data with Teslamate]]></title><description><![CDATA[Unlock your Tesla's full potential with Teslamate! Learn how to easily set up this powerful open-source data logger using Docker. Get detailed insights into your drives, charging, and battery health.]]></description><link>https://tolga.gezginis.com/explore-your-teslas-data-with-teslamate/</link><guid isPermaLink="false">68bc4801a80d820001aa06c1</guid><category><![CDATA[tesla]]></category><category><![CDATA[docker]]></category><category><![CDATA[teslamate]]></category><category><![CDATA[electric vehicle]]></category><category><![CDATA[tech guide]]></category><category><![CDATA[grafana]]></category><dc:creator><![CDATA[Tolga Gezginiş]]></dc:creator><pubDate>Mon, 01 Sep 2025 15:14:00 GMT</pubDate><media:content url="https://cdn.synaps.media/tgezginis/content/images/2025/09/photo-1641659376402-3d2f48a91ed7.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/photo-1641659376402-3d2f48a91ed7.jpeg" alt="Explore Your Tesla&apos;s Data with Teslamate"><p>Tesla cars have revolutionized the automotive world with their technology and driving experience. However, beyond the standard features your car offers, it&apos;s natural to want to understand your driving habits, charging efficiency, and vehicle performance in greater depth. This is precisely where <a href="https://github.com/teslamate-org/teslamate?ref=tolga.gezginis.com" rel="noreferrer"><strong>Teslamate</strong></a> comes in. Teslamate is a powerful, open-source project that allows you to locally store your Tesla&apos;s data and provides you with comprehensive analyses.</p><p>In this post, we&apos;ll explore what Teslamate is, why you should use it, and most importantly, how to <strong>easily set it up with </strong><a href="https://www.docker.com/?ref=tolga.gezginis.com" rel="noreferrer"><strong>Docker</strong></a>, step by step.</p><hr><h3 id="what-is-teslamate-and-why-use-it">What is Teslamate and Why Use It?</h3><p>Teslamate retrieves data from your vehicle via Tesla&apos;s API (location, speed, battery status, charging information, driving statistics, etc.) and securely stores it on your own local server. This means:</p><ul><li><strong>Your Privacy is Protected:</strong> Your data is stored in an environment you control.</li><li><strong>Detailed Analytics:</strong> You can visualize your driving patterns, energy consumption, charging costs, and past trips through graphs and maps.</li><li><strong>Performance Tracking:</strong> Gain valuable insights into your car&apos;s battery health and charging efficiency.</li></ul><figure class="kg-card kg-image-card kg-width-wide"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/diagram-export-9-6-2025-6_11_06-PM-1.jpg" class="kg-image" alt="Explore Your Tesla&apos;s Data with Teslamate" loading="lazy" width="1122" height="263" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/diagram-export-9-6-2025-6_11_06-PM-1.jpg 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/diagram-export-9-6-2025-6_11_06-PM-1.jpg 1000w, https://cdn.synaps.media/tgezginis/content/images/2025/09/diagram-export-9-6-2025-6_11_06-PM-1.jpg 1122w"></figure><h3 id="setting-up-teslamate-with-docker-a-step-by-step-guide">Setting Up Teslamate with Docker: A Step-by-Step Guide</h3><p>The most practical way to install Teslamate is by using <strong>Docker</strong>. Docker allows you to run applications in their own isolated environments, simplifying complex setup processes.</p><p><strong>Prerequisites:</strong></p><p>Before you begin, make sure you have the following:</p><ul><li><strong>Docker:</strong> (If you are new to Docker, see Installing Docker and Docker Compose).</li><li><strong>A Machine that&apos;s always on:</strong> This can be a computer, a Raspberry Pi, a mini PC, or a VPS running in the cloud. It needs to be operational 24/7 so Teslamate can continually fetch data.</li><li><strong>Sufficient RAM:</strong> At least 1 GB of RAM is required for a successful installation, but we recommend having at least 2 GB for optimal operation.</li><li><strong>External Internet Access:</strong> To communicate with tesla.com and retrieve data.</li></ul><p><strong>Setup Steps:</strong></p><ol><li><strong>Download the Teslamate Docker Compose File</strong></li></ol><p>Typically, Teslamate&apos;s GitHub repository contains a ready-to-use docker-compose.yml file. You can start by downloading this file.Bash</p><pre><code class="language-shell">curl -L https://raw.githubusercontent.com/teslamate-io/teslamate/master/docker-compose.yml -o docker-compose.yml
</code></pre><ol start="2"><li><strong>Database Configuration (Optional but Recommended)</strong></li></ol><p>Teslamate uses a PostgreSQL database to store data. The docker-compose.yml file includes settings for the database. For security and data persistence, you can customize the database information as well (e.g., POSTGRES_PASSWORD).</p><pre><code class="language-yaml"># Relevant section from docker-compose.yml (example)
environment:
  - TESLA_EMAIL=your_email@example.com
  - TESLA_PASSWORD=your_password
  # ... other settings
</code></pre><ol start="3"><li><strong>Start Teslamate</strong></li></ol><p>After saving the file, open your command prompt in the directory where the docker-compose.yml file is located and run the following command:Bash</p><pre><code>docker compose up -d
</code></pre><p>This command will start Teslamate and its dependent services (like the database) in the background.</p><p><strong>Once Teslamate starts:</strong></p><ul><li>Open the web interface&#xA0;<a href="http://localhost:4000/?ref=tolga.gezginis.com" rel="noopener noreferrer">http://your-ip-address:4000</a></li><li>Sign in with your Tesla Account</li></ul><p><strong>Accessing the Dashboards:</strong></p><ol start="5"><ol><li><strong>Teslamate Dashboard:</strong> Once all services are running, you can access the core Teslamate interface, which shows direct data feeds and basic analytics, by navigating to <a href="http://your-ip-address:4000/?ref=tolga.gezginis.com">http://your-ip-address:4000</a> in your browser.</li><li><strong>Grafana Dashboards:</strong> For more advanced and customizable metrics visualization, Grafana is used. Access the Grafana dashboards by navigating to <a href="http://your-ip-address:3000/?ref=tolga.gezginis.com" rel="noreferrer">http://your-ip-address:3000</a> in your browser. The initial login credentials are often <code>admin/admin</code>, but you&apos;ll be prompted to change these for security. You&apos;ll find pre-configured dashboards here that leverage the data collected by Teslamate.</li></ol></ol><h3 id="what-can-you-do-with-teslamate">What Can You Do with Teslamate?</h3><p>After setup, you&apos;ll get to know your car better with the features Teslamate offers:</p><ul><li><strong>Teslamate Interface (Port 4000):</strong> Quick overview of recent trips, charging status, and direct data logs.</li></ul><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-17.53.44.png" class="kg-image" alt="Explore Your Tesla&apos;s Data with Teslamate" loading="lazy" width="2000" height="773" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-17.53.44.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-17.53.44.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-17.53.44.png 1600w, https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-17.53.44.png 2024w" sizes="(min-width: 1200px) 1200px"><figcaption><span style="white-space: pre-wrap;">Teslamate Dashboard</span></figcaption></figure><ul><li><strong>Grafana Dashboards (Port 3000):</strong><ul><li><strong>Trip History:</strong> Detailed mapping and analysis of all your drives.</li><li><strong>Charging Analysis:</strong> In-depth reports on charging times, costs, and charger performance.</li><li><strong>Energy Consumption:</strong> Average Wh/km values and consumption differences by driving mode.</li><li><strong>Battery Health:</strong> Comprehensive tracking of your battery&apos;s status and degradation over time.</li></ul></li></ul><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-17.54.30.png" class="kg-image" alt="Explore Your Tesla&apos;s Data with Teslamate" loading="lazy" width="2000" height="1063" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-17.54.30.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-17.54.30.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-17.54.30.png 1600w, https://cdn.synaps.media/tgezginis/content/images/size/w2400/2025/09/Screenshot-2025-09-06-at-17.54.30.png 2400w" sizes="(min-width: 1200px) 1200px"><figcaption><span style="white-space: pre-wrap;">Overview</span></figcaption></figure><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-17.55.22.png" class="kg-image" alt="Explore Your Tesla&apos;s Data with Teslamate" loading="lazy" width="2000" height="1015" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-17.55.22.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-17.55.22.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-17.55.22.png 1600w, https://cdn.synaps.media/tgezginis/content/images/size/w2400/2025/09/Screenshot-2025-09-06-at-17.55.22.png 2400w" sizes="(min-width: 1200px) 1200px"><figcaption><span style="white-space: pre-wrap;">Drive Stats</span></figcaption></figure><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/Screenshot-2025-09-06-at-17.56.10.png" class="kg-image" alt="Explore Your Tesla&apos;s Data with Teslamate" loading="lazy" width="2000" height="696" srcset="https://cdn.synaps.media/tgezginis/content/images/size/w600/2025/09/Screenshot-2025-09-06-at-17.56.10.png 600w, https://cdn.synaps.media/tgezginis/content/images/size/w1000/2025/09/Screenshot-2025-09-06-at-17.56.10.png 1000w, https://cdn.synaps.media/tgezginis/content/images/size/w1600/2025/09/Screenshot-2025-09-06-at-17.56.10.png 1600w, https://cdn.synaps.media/tgezginis/content/images/size/w2400/2025/09/Screenshot-2025-09-06-at-17.56.10.png 2400w" sizes="(min-width: 1200px) 1200px"><figcaption><span style="white-space: pre-wrap;">Trip Statics</span></figcaption></figure><h3 id="conclusion">Conclusion</h3><p>Teslamate, paired with Grafana for advanced visualization, is a fantastic tool for Tesla owners, enabling them to use their vehicles more consciously through data. Thanks to Docker, its installation is greatly simplified. With Teslamate and Grafana, you can fully unlock your car&apos;s potential and gain deep insights into its performance.</p><p>With these initial steps, you&apos;ve taken control of your car&apos;s data and set up powerful tools for analysis. In our upcoming posts, we&apos;ll delve deeper into optimizing your Grafana dashboards and exploring advanced Teslamate features.</p><p><strong>Have you tried setting up Teslamate and Grafana? Don&apos;t forget to share your experiences and any questions in the comments below!</strong></p>]]></content:encoded></item><item><title><![CDATA[Creating a Ruby on Rails Development Environment with Docker]]></title><description><![CDATA[Set up your Ruby on Rails development environment with Docker! This comprehensive guide covers integrating PostgreSQL and Redis and simplifying your project pull from GitHub while ensuring data security with Docker concepts.]]></description><link>https://tolga.gezginis.com/creating-a-ruby-on-rails-development-environment-with-docker/</link><guid isPermaLink="false">68bc3967a80d820001aa069c</guid><category><![CDATA[development]]></category><category><![CDATA[ruby]]></category><category><![CDATA[ruby on rails]]></category><category><![CDATA[docker]]></category><dc:creator><![CDATA[Tolga Gezginiş]]></dc:creator><pubDate>Wed, 23 Aug 2023 07:00:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1605745341112-85968b19335b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGRvY2tlcnxlbnwwfHx8fDE3NTcxNjc3NjZ8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<hr><img src="https://images.unsplash.com/photo-1605745341112-85968b19335b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGRvY2tlcnxlbnwwfHx8fDE3NTcxNjc3NjZ8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="Creating a Ruby on Rails Development Environment with Docker"><p>Docker is a helpful tool for making software development easier. In this guide, we&apos;ll show you how to set up a development environment for Ruby on Rails using Docker. We&apos;ll also make sure your data stays secure, even if you stop or remove containers. We&apos;ll be working with PostgreSQL and Redis databases, and we&apos;ll assume you&apos;re getting a project from GitHub.</p><h2 id="installing-docker">Installing Docker</h2><p>Start by installing Docker on your computer. Docker Desktop is easy to use and works on both Windows and macOS. Get it from the <a href="https://www.docker.com/?ref=tolga.gezginis.com">official Docker website</a>. I personally recommend <a href="https://orbstack.dev/?ref=tolga.gezginis.com">OrbStack</a> over Docker Desktop. (MacOS only yet)</p><h2 id="docker-compose">Docker Compose</h2><p>Docker Compose is a handy tool for managing applications with multiple parts. It lets you describe everything in one file. Here&apos;s a simpler <code>docker-compose.yml</code> for setting up Ruby on Rails with PostgreSQL and Redis, and making sure your data stays safe:</p><pre><code class="language-yaml">version: &apos;3&apos;
services:
  web:
    image: ruby:latest
    ports:
      - &quot;3000:3000&quot;
    volumes:
      - ./app:/app
    depends_on:
      - db
      - redis
  db:
    image: postgres:latest
    environment:
      POSTGRES_DB: myapp_development
      POSTGRES_USER: myapp_user
      POSTGRES_PASSWORD: myapp_password
    volumes:
      - pg_data:/var/lib/postgresql/data
  redis:
    image: redis:latest
    volumes:
      - redis_data:/data
volumes:
  pg_data:
  redis_data:
</code></pre><p>In this simpler setup, we&apos;ve introduced volumes (<code>pg_data</code> for PostgreSQL and <code>redis_data</code> for Redis) to make sure your data stays safe.</p><pre><code class="language-bash">git clone https://github.com/yourusername/your-rails-project.git
</code></pre><p>Next, navigate to your project directory:</p><pre><code class="language-bash">cd your-rails-project

</code></pre><h2 id="creating-a-ruby-on-rails-application">Creating a Ruby on Rails Application:</h2><p>Now, let&apos;s consider you are pulling an existing Ruby on Rails project from GitHub. Clone the project into your desired directory.</p><h2 id="configuring-postgresql-and-redis">Configuring PostgreSQL and Redis</h2><p>In your Rails project, you&apos;ll need to configure your <code>database.yml</code> and any other environment-specific configuration files to work with the Docker containers for PostgreSQL and Redis. Ensure you have the correct host, username, password, and database name settings.</p><h2 id="dockerizing-your-ruby-on-rails-application">Dockerizing Your Ruby on Rails Application:</h2><p>For your Rails application to work seamlessly with Docker, you&apos;ll need to create a <code>Dockerfile</code> in the root of your project. This file defines how your Ruby application should be built within a Docker container.</p><p>Here&apos;s a basic <code>Dockerfile</code> for a Ruby on Rails project:</p><pre><code class="language-dockerfile"># Use an official Ruby runtime as a parent image
FROM ruby:latest

# Set the working directory in the container
WORKDIR /app

# Copy the Gemfile and Gemfile.lock into the container
COPY Gemfile Gemfile.lock ./

# Install any needed gems mentioned in your Gemfile
RUN bundle install

# Copy the rest of your application code into the container
COPY . .

# Expose port 3000 to the outside world
EXPOSE 3000

# Start your Rails application
CMD [&quot;rails&quot;, &quot;server&quot;, &quot;-b&quot;, &quot;0.0.0.0&quot;]
</code></pre><h2 id="starting-the-environment">Starting the Environment</h2><p>With your environment set up, it&apos;s time to start it:</p><pre><code class="language-bash">docker-compose up
</code></pre><p>Docker will keep your PostgreSQL and Redis data safe outside the containers, even if you stop or remove them.</p><h2 id="developing-your-application">Developing Your Application</h2><p>You can start working on your Ruby on Rails project as usual. Docker will handle data safety for your PostgreSQL and Redis databases.</p><h2 id="shutting-down-the-environment">Shutting Down the Environment</h2><p>When you&apos;re done, you can shut down the environment:</p><pre><code class="language-bash">docker-compose down
</code></pre><h2 id="conclusion">Conclusion</h2><p>By using Docker volumes in your development environment, you&apos;ve made sure that your PostgreSQL and Redis data stays secure, even if you stop or remove containers. Docker volumes are an important part of working with containers, making sure your data is always available and protected.</p>]]></content:encoded></item><item><title><![CDATA[Communication in Remote Work: Synchronous and Asynchronous]]></title><description><![CDATA[Enhance your remote team's communication by understanding and implementing effective synchronous and asynchronous techniques. Get practical advice on meetings, project clarity, and employee satisfaction.]]></description><link>https://tolga.gezginis.com/communication-in-remote-work-synchronous-and-asynchronous/</link><guid isPermaLink="false">68bc383ba80d820001aa0687</guid><category><![CDATA[development]]></category><category><![CDATA[remote]]></category><dc:creator><![CDATA[Tolga Gezginiş]]></dc:creator><pubDate>Thu, 18 Nov 2021 13:00:00 GMT</pubDate><media:content url="https://cdn.synaps.media/tgezginis/content/images/2025/09/remote-work-1.jpg" medium="image"/><content:encoded><![CDATA[<hr><img src="https://cdn.synaps.media/tgezginis/content/images/2025/09/remote-work-1.jpg" alt="Communication in Remote Work: Synchronous and Asynchronous"><p>With the pandemic, many software teams have transitioned to remote work, either full-time or in a hybrid model. In this article, I will focus on team communication in remote work, rather than dwelling on the pros and cons of this transition.</p><p>Remote work has led to a transformation in how teams organize and communicate, compared to the traditional office model:</p><ul><li>Face-to-face meetings have been replaced by online meetings.</li><li>Communication tools like Slack, Zoom, and Google Meet have become essential.</li><li>Documentation has gained importance in tracking work progress.</li></ul><h2 id="synchronous-communication">Synchronous Communication</h2><p>Synchronous communication is when communication happens in real-time, and immediate responses are expected from all participants. It resembles the question-answer interaction that occurs in face-to-face communication.</p><p>Examples of synchronous communication methods used in software teams include:</p><ul><li><strong>Daily Stand-Up Meetings:</strong> Short but effective meetings where teams discuss current progress, questions, or obstacles.</li><li><strong>Project Planning Meetings:</strong> Meetings where the team discusses the project&apos;s future and plans tasks accordingly, with everyone participating.</li><li><strong>Retrospective Meetings:</strong> Meetings where progress is evaluated, and the team discusses what went right or wrong in tasks or methods.</li><li><strong>Pair Programming:</strong> Collaborative work on a project or task by team members.</li><li><strong>Onboarding Meetings for New Team Members:</strong> Ensuring a smooth integration process for new team members.</li><li><strong>Evaluation Meetings:</strong> Meetings to assess performance.</li><li><strong>One-on-One Meetings:</strong> Individual meetings.</li><li><strong>Meetings for Sharing Important Company Updates:</strong> Meetings where significant company developments are shared.</li></ul><h3 id="increasing-efficiency-in-synchronous-communication">Increasing Efficiency in Synchronous Communication</h3><p><strong>Plan Meetings in Advance:</strong><br>Planning meetings a few days in advance, after checking your team members&apos; availability, allows them to make time for it. This fosters respect among team members.</p><p><strong>Define Meeting Objectives:</strong><br>A crucial aspect of an efficient meeting is conveying its purpose and the problem to be discussed beforehand. This helps participants prepare and keeps the meeting focused.</p><p><strong>Limit Meeting Duration:</strong><br>Meetings can easily go off-topic. To prevent this, set a time limit for meetings and communicate it to participants.</p><p><strong>Indicate Availability and Show Respect:</strong><br>Synchronous communication, by nature, can disrupt the other party. To avoid this, keep your availability status up to date and show respect for others&apos; schedules. It also helps determine if your message is genuinely urgent.</p><p><strong>Enhance Your Working Environment:</strong><br>Since the quality of internet infrastructure may not always meet expectations in remote work, take measures to avoid connection issues during team meetings. Address problems like audio quality and malfunctioning microphones.</p><h2 id="asynchronous-communication">Asynchronous Communication</h2><p>Although synchronous communication may seem essential for quickly resolving urgent issues, asynchronous communication is preferred for healthy project management and employee satisfaction.</p><p>In asynchronous communication, unlike synchronous communication, real-time responses are not expected. People are given time to respond when it suits them, ensuring that no unnecessary pressure is placed on them.</p><p>Examples of asynchronous communication methods used in software teams include:</p><ul><li>Non-urgent questions that don&apos;t require immediate attention.</li><li>Pull Requests</li><li>Code Reviews and Edits</li><li>Introducing New Team Members.</li><li>Sharing Major Company or Project Updates.</li></ul><h3 id="increasing-efficiency-in-asynchronous-communication">Increasing Efficiency in Asynchronous Communication</h3><p><strong>Be Clear in Your Expectations:</strong><br>Since asynchronous communication isn&apos;t instant, clarity in your message is essential. Use clear language and provide additional information or documents if necessary.</p><p><strong>Practice Patience When Waiting for Responses:</strong><br>Asynchronous communication requires patience when awaiting responses. It&apos;s crucial not to rush others and to wait for them to respond at their convenience.</p><p><strong>Document Everything:</strong><br>Don&apos;t hesitate to document planned or ongoing tasks, even if they seem trivial. These documents serve as guides for your team and future colleagues.</p><h2 id="summary">Summary</h2><p>In situations where everything seems urgent, nothing is truly urgent. It&apos;s essential to question what&apos;s genuinely urgent and what isn&apos;t. Sending a private message to someone and then saying, &quot;It&apos;s not urgent; can you look at it when you have time?&quot; is counterproductive. Instead, for non-urgent matters, consider using asynchronous communication by posting in a shared group. Making this a team-wide culture contributes to a more efficient and focused team.</p><p>Best regards.</p>]]></content:encoded></item></channel></rss>