Skip to content

Commit 6ed2394

Browse files
committed
Merge branch 'staging/3.9' into release/3.9
2 parents 473fb78 + d7d5ec6 commit 6ed2394

File tree

5 files changed

+3271
-451
lines changed

5 files changed

+3271
-451
lines changed

_layouts/pricing.html

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
setCloudServerDefault();
4545
window.addEventListener('popstate', onPopPricingState);
4646
onPopPricingState();
47+
setTimeout(()=> popCopyButton(), 200);
4748
});
4849
}
4950

@@ -57,25 +58,35 @@
5758
}
5859

5960
function onPopPricingState() {
60-
var params = Qs.parse(window.location.search, { ignoreQueryPrefix: true });
61-
var sectionId = params['section'] || params['active'];
61+
const params = Qs.parse(window.location.search, { ignoreQueryPrefix: true });
62+
let sectionId = params['section'] || params['active'];
6263
if (!sectionId) {
6364
sectionId = '{{page.defaultActivePricingSection}}';
6465
}
6566
setActivePricingSection(sectionId);
66-
var productId = params['product'];
67+
const productId = params['product'];
6768
if (productId) {
6869
setActiveProductSection(productId);
6970
}
70-
var solutionId = params['solution'];
71+
let solutionId = params['solution'];
7172
if (solutionId) {
7273
setActiveSolutionSection(solutionId);
7374
}
75+
let faqSection = params['faqSection'];
76+
if (faqSection) {
77+
switchFaqSection(faqSection);
78+
const questionEl = document.querySelector(`div[data-item-id="${window.location.hash.replace('#', '')}"]`);
79+
if (Array.from(questionEl.parentNode.children).indexOf(questionEl) > 6) {
80+
loadMoreFaq(questionEl.parentNode.children[6]);
81+
}
82+
checkIfOpenedRetryClear(`div[data-item-id="${window.location.hash.replace('#', '')}"]`);
83+
}
7484
}
7585

7686
function activatePricingSection(sectionId) {
7787
updateQueryParam({section: sectionId, product: null, solution: null});
7888
setActivePricingSection(sectionId);
89+
switchFaqContainer(sectionId);
7990
}
8091

8192
function activateProductSection(productId) {
@@ -95,7 +106,7 @@
95106
setActiveSolutionSection(solutionId);
96107
}
97108

98-
function updateQueryParam(setParams) {
109+
function updateQueryParam(setParams, clear = false) {
99110
var params = Qs.parse(window.location.search, { ignoreQueryPrefix: true });
100111
for (var paramName of Object.keys(setParams)) {
101112
var paramValue = setParams[paramName];
@@ -105,8 +116,11 @@
105116
params[paramName] = undefined;
106117
}
107118
}
119+
if (clear) {
120+
delete params.faqSection;
121+
}
108122
var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + Qs.stringify(params);
109-
if (window.location.hash) {
123+
if (window.location.hash && !clear) {
110124
newurl += window.location.hash;
111125
}
112126
window.history.pushState({ path: newurl }, '', newurl);
@@ -131,6 +145,8 @@
131145
var solutionId = getDefaultSolutionIdBySectionId(sectionId);
132146
if (solutionId) {
133147
setActiveSolutionSection(solutionId);
148+
} else {
149+
switchFaqContainer('thingsboard-ce');
134150
}
135151
}
136152

@@ -148,6 +164,7 @@
148164
var solutionId = getDefaultSolutionIdBySectionId(sectionId);
149165
setActiveSolutionSection(solutionId);
150166
reportPriceOpen(sectionId);
167+
switchFaqContainer(sectionId);
151168
}
152169
}
153170

@@ -169,6 +186,7 @@
169186
var headerId = $solutionButtonElement.attr("data-description-toggle");
170187
$('.pricing-div .pricing-section'+id).addClass("active");
171188
$('.pricing-content-header .pricing-content-description'+headerId).addClass("active");
189+
switchFaqContainer(sectionId);
172190
}
173191
}
174192

@@ -247,6 +265,119 @@
247265
"event_category": solutionId
248266
});
249267
}
268+
269+
let currentFaqContainer = 'thingsboard-cloud';
270+
let sectionSwitched = false;
271+
272+
function switchFaqContainer(containerId) {
273+
if (changeFaqHeader(containerId)) {
274+
currentFaqContainer = containerId;
275+
document.querySelectorAll('#FAQ section').forEach(el => el.classList.remove('active'));
276+
document.getElementById(`faq-${containerId}`).classList.add('active');
277+
}
278+
}
279+
280+
function changeFaqHeader(id) {
281+
let correspondingHeader;
282+
switch (id) {
283+
case 'thingsboard-ce':
284+
correspondingHeader = 'ThingsBoard Community Edition FAQs';
285+
break;
286+
case 'thingsboard-cloud':
287+
correspondingHeader = 'ThingsBoard Cloud FAQs';
288+
break;
289+
case 'pe-pay-as-you-go':
290+
correspondingHeader = 'ThingsBoard Professional Edition: Self-managed Subscriptions FAQs';
291+
break;
292+
case 'pe-perpetual':
293+
correspondingHeader = 'ThingsBoard Professional Edition: Self-managed Perpetual FAQs';
294+
break;
295+
case 'trendz-pay-as-you-go':
296+
correspondingHeader = 'Trendz Analytics: Self-managed Subscriptions FAQs';
297+
break;
298+
case 'trendz-perpetual':
299+
correspondingHeader = 'Trendz Analytics: Self-managed Perpetual FAQs';
300+
break;
301+
case 'trendz-cloud':
302+
correspondingHeader = 'Trendz Analytics Cloud FAQs';
303+
break;
304+
case 'edge-community':
305+
correspondingHeader = 'Edge Community FAQs';
306+
break;
307+
case 'edge-pay-as-you-go':
308+
correspondingHeader = 'Edge Subscriptions FAQs';
309+
break;
310+
case 'edge-perpetual':
311+
correspondingHeader = 'Edge Perpetual FAQs';
312+
break;
313+
}
314+
if (correspondingHeader) {
315+
document.getElementById('faq-header').innerText = correspondingHeader;
316+
}
317+
return correspondingHeader;
318+
}
319+
320+
function switchFaqSection(sectionId, el) {
321+
if (el?.classList.contains('active')) return
322+
document.querySelectorAll(`#faq-${currentFaqContainer} .faq-section-option`).forEach(el => el.classList.remove('active'));
323+
document.querySelectorAll(`#faq-${currentFaqContainer} .pi-accordion`).forEach(el => el.classList.remove('active'));
324+
document.getElementById(`faq-${currentFaqContainer}-${sectionId}`).classList.add('active');
325+
el ? el.classList.add('active') : document.querySelector(`#faq-${currentFaqContainer} #${sectionId}`).classList.add('active');
326+
sectionSwitched = true;
327+
}
328+
329+
function loadMoreFaq(el) {
330+
while(el) {
331+
el.classList.toggle('hidden');
332+
el = el.nextElementSibling;
333+
}
334+
}
335+
336+
function copyQuestionLink(event, questionId, button) {
337+
event.stopPropagation();
338+
const params = Qs.parse(window.location.search, { ignoreQueryPrefix: true });
339+
params['faqSection'] = document.querySelector(`#faq-${currentFaqContainer} .faq-section-option.active`).id;
340+
const questionUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + Qs.stringify(params) + '#' + questionId;
341+
const $temp = $("<input>");
342+
$("body").append($temp);
343+
window.getSelection().removeAllRanges();
344+
$temp.val(questionUrl).select();
345+
document.execCommand("copy");
346+
$temp.remove();
347+
button.classList.toggle('copied');
348+
const tooltipEl = button.firstElementChild;
349+
tooltipEl.innerHTML = "Copied";
350+
setTimeout(() => {
351+
tooltipEl.innerHTML = 'Copy question link';
352+
button.classList.toggle('copied');
353+
}, 1500);
354+
}
355+
356+
function popCopyButton() {
357+
if (document.querySelector('.item').querySelector('.title')) {
358+
document.querySelectorAll('.item').forEach(el => {
359+
const clipButton = $(`
360+
<button class="clipboard-btn" onmousedown="this.style.backgroundColor='#e8f1ff'"
361+
onmouseup="this.style.removeProperty('background-color')"
362+
onclick="copyQuestionLink(event, '${el.getAttribute('data-item-id')}', this)">
363+
<span class="tooltiptext">Copy question link</span>
364+
</button>`);
365+
$(el).find('.title').append(clipButton);
366+
});
367+
} else {
368+
setTimeout(() => popCopyButton(), 100);
369+
}
370+
}
371+
372+
function checkIfOpenedRetryClear(questionId) {
373+
const question = document.querySelector(questionId);
374+
if (question.classList.contains('on')){
375+
updateQueryParam({}, true);
376+
} else {
377+
setTimeout(() => checkIfOpenedRetryClear(questionId), 100)
378+
}
379+
}
380+
250381
</script>
251382

252383
{% include cookie-consent.html %}

docs/user-guide/install/pe/aws-marketplace.md

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ Make sure you review the usage instructions. It is always a good idea to copy th
4242

4343
You can optionally change your EC2 Instance Type, VPC and Subnet. This step is usually for advanced AWS EC2 users.
4444

45+
{% capture vm-min-req %}
46+
ThingsBoard requires EC2 instance with at least **4GB of RAM**; consider [adjusting the memory parameters](/docs/user-guide/install/pe/ubuntu/#step-6-optional-memory-update-for-slow-machines-4gb-of-ram) to ensure stability.
47+
For optimal performance, we recommend an instance with at least **8GB of RAM** and **2 vCPUs**.
48+
{% endcapture %}
49+
{% include templates/info-banner.md content=vm-min-req %}
50+
4551
#### Step 3.3. Configure Security Group Settings
4652

4753
Make sure you create new Security Group based on seller settings.
@@ -111,7 +117,7 @@ Please use the official guides:
111117
* [Connecting to Your Linux Instance from Windows Using PuTTY](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) - for Windows users;
112118
* [Connecting to Your Linux Instance Using SSH](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) - For Linux/Mac users.
113119

114-
Note: You will need to use instance Public DNS name (see [Step 3.7](/docs/user-guide/install/pe/aws/#step-37-obtain-your-public-ip-and-ec2-instance-id)) and the key file (see [Step 3.4](/docs/user-guide/install/pe/aws/#step-34-configure-key-pair-settings))
120+
Note: You will need to use instance Public DNS name (see [Step 3.7](/docs/user-guide/install/pe/aws-marketplace/#step-37-obtain-your-public-ip-and-ec2-instance-id)) and the key file (see [Step 3.4](/docs/user-guide/install/pe/aws-marketplace/#step-34-configure-key-pair-settings))
115121

116122
#### Step 5.2. Put License Secret to thingsboard configuration file
117123

@@ -165,14 +171,21 @@ Use this login to connect as system Administrator
165171

166172
167173

168-
Default password for System Administrator is Instance ID (see [Step 3.7](/docs/user-guide/install/pe/aws/#step-37-obtain-your-public-ip-and-ec2-instance-id)). In this example:
174+
Default password for System Administrator is Instance ID (see [Step 3.7](/docs/user-guide/install/pe/aws-marketplace/#step-37-obtain-your-public-ip-and-ec2-instance-id)). In this example:
169175

170176
- **i-032b8bbf297987458**
171177

172178
Now you can proceed to the next steps.
173179

174180
### Post-installation steps
175181

182+
{% capture elastic-ip-note %}
183+
By default, AWS Marketplace instances **do not assign a static public IP**. This means that the **public IP may change upon instance restart**.
184+
To ensure a persistent public IP, you must **assign an Elastic IP** to your EC2 instance. You can follow the steps in the [AWS documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-eips.html).
185+
{% endcapture %}
186+
187+
{% include templates/info-banner.md content=elastic-ip-note %}
188+
176189
**Configure HAProxy to enable HTTPS**
177190

178191
* Step 1. Assign valid domain name system (DNS) record to your instance external IP address.
@@ -202,16 +215,16 @@ Customer may still use <a href="https://thingsboard.cloud" target="blank">Things
202215
<li>AWS EC2 instance price - we believe <a href="https://www.ec2instances.info/">ec2instances.info</a> is a convenient resource to compare prices.</li>
203216
<li>Additional EC2 costs for network traffic, disk space and other optional services (Cloud Watch or similar)</li>
204217
</ul>
205-
<p>Example A: The price for ThingsBoard PE instance with Maker subscription plan based on t2.micro with 20 GB disk will cost approximately $20.5 per month:</p>
218+
<p>Example A: The price for ThingsBoard PE instance with Maker subscription plan based on t3.medium with 20 GB disk will cost approximately $42.4 per month:</p>
206219
<ul>
207220
<li>$10.00 for monthly ThingsBoard PE Maker subscription fee</li>
208-
<li>$8.468 for 1 month of t2.micro usage</li>
221+
<li>$30.368 for 1 month of t3.medium usage</li>
209222
<li>$2.0 for 20 GB of EBS volume per month</li>
210223
</ul>
211-
<p>Example B: The price for ThingsBoard PE instance with Prototype subscription plan based on t2.medium with 100 GB disk will cost approximately $142.872 per month:</p>
224+
<p>Example B: The price for ThingsBoard PE instance with Prototype subscription plan based on m5.large with 100 GB disk will cost approximately $179 per month:</p>
212225
<ul>
213226
<li>$99.00 for monthly ThingsBoard PE Prototype subscription fee</li>
214-
<li>$33.872 for 1 month of t2.medium usage</li>
227+
<li>$70.08 for 1 month of m5.large usage</li>
215228
<li>$10.0 for 100 GB of EBS volume per month</li>
216229
</ul>
217230
<p>All prices are in USD.</p>
@@ -231,7 +244,7 @@ See <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html">off
231244

232245
**How to enable HTTPS?**
233246

234-
See <a href="/docs/user-guide/install/pe/aws/#post-installation-steps">Post-installation steps</a>
247+
See <a href="/docs/user-guide/install/pe/aws-marketplace/#post-installation-steps">Post-installation steps</a>
235248
<br><br>
236249

237250
**How do I configure my TB PE instance?**
@@ -243,27 +256,54 @@ See <a href="/docs/user-guide/install/config/">official documentation page</a> f
243256
**How do I get software updates for my TB PE instance?**
244257

245258
You will receive an email notification about new software versions once it becomes available.
246-
This email notification will contain a link to <a href="/docs/user-guide/install/aws-marketplace-pe-upgrade/">official documentation page</a> with the upgrade instructions.
259+
This email notification will contain a link to <a href="/docs/user-guide/install/pe/upgrade-instructions/">official documentation page</a> with the upgrade instructions.
247260
<br><br>
248261

249262
**How do I backup my database?**
250-
Depending on your instance type and configuration, ThingsBoard may store data in SQL or NoSQL databases.
251-
ThingsBoard may also store data using hybrid database mode.
252-
Please review <a href="/docs/reference/#sql-vs-nosql-vs-hybrid-database-approach">architecture docs</a> for more info on available database types.
253-
Once you figure out the database type(s) you are using in your instance, you can review official <a href="https://www.postgresql.org/docs/9.1/backup.html">PostgreSQL</a>
254-
or <a href="https://docs.datastax.com/en/cassandra/3.0/cassandra/operations/opsBackupRestore.html">Cassandra</a> documentation.
255-
There is also planty of docs and tools in the web how you can backup and restore your DB.
263+
264+
You can follow <a href="/docs/user-guide/install/pe/upgrade-instructions/#prepare-for-upgrading-thingsboard-centos-ubuntu">backup instructions</a> avgit sailable with upgrade instructions.
265+
266+
For additional guidance, you can also refer to the official <a href="https://www.postgresql.org/docs/16/backup.html">PostgreSQL backup documentation</a>.
267+
256268
<br><br>
257269

258270
**How do I upgrade my instance type?**
259271

260-
See official License Server <a href="/products/license-server/">documentation page</a> for more details.
272+
To upgrade your EC2 instance type, follow these steps:
273+
274+
1. Stop the ThingsBoard Service
275+
276+
Before changing the instance type, stop the ThingsBoard service to ensure a clean shutdown:
277+
278+
```bash
279+
sudo service thingsboard stop
280+
```
281+
{: .copy-code}
282+
283+
2. Stop the EC2 Instance
284+
285+
Go to the AWS EC2 Console, select your instance, and stop it:
286+
287+
- Navigate to EC2 Dashboard
288+
- Select the instance you want to upgrade
289+
- Click Instance state → Stop instance
290+
291+
3. Change the Instance Type
292+
293+
Once the instance is stopped, update its type:
294+
295+
- In the EC2 Console, go to Actions → Instance settings → Change instance type
296+
- Select the desired instance type
297+
- Click Change
298+
299+
4. Start the Instance
300+
261301
<br><br>
262302

263303
**Where is my ThingsBoard instance logs?**
264304

265305
ThingsBoard logs are stored in the <i>/var/log/thingsboard</i> folder.
266-
See <a href="/docs/user-guide/install/config/#logging">configuration page</a> to find out how to configure logging levels.
306+
For more details on managing logs and configuring log levels, refer to the <a href="/docs/pe/user-guide/troubleshooting/#logs">Troubleshooting Guide</a>
267307
<br><br>
268308

269309
**How do I get professional support?**

0 commit comments

Comments
 (0)