GithubHelp home page GithubHelp logo

tamtamhero / fw-fanctrl Goto Github PK

View Code? Open in Web Editor NEW
169.0 8.0 31.0 448 KB

A simple systemd service to better control Framework Laptop's fan(s)

License: BSD 3-Clause "New" or "Revised" License

Python 56.90% Shell 43.10%

fw-fanctrl's Introduction

fw-fanctrl

This is a simple Python service for Linux that drives Framework Laptop's fan(s) speed according to a configurable speed/temp curve. Its default configuration targets very silent fan operation, but it's easy to configure it for a different comfort/performance trade-off. Its possible to specify two separate fan curves depending on whether the Laptop is charging/discharging. Under the hood, it uses ectool to change parameters in Framework's embedded controller (EC).

It is compatible with all kinds of 13" and 16" models, both AMD/Intel CPUs, with or without a discrete GPU.

If the service is paused or stopped, the fans will revert to their default behaviour.

Install

Dependencies

To communicate with the embedded controller the ectool is required. You can either let the script download it from the gitlab repository artifacts, or disable its installation (--no-ectool) and install your own.

You also need to disable secure boot of your device for ectool to work (more details about why here)

Then run:

sudo ./install.sh

This bash script will to create and activate a service that runs this repo's main script, fanctrl.py. It will copy fanctrl.py (to an executable file fw-fanctrl), download the ectool to [dest-dir(/)]/bin and create a config file in [dest-dir(/)][sysconf-dir(/etc)]/fw-fanctrl/config.json

this script also includes options to:

  • specify an installation destination directory (--dest-dir <installation destination directory (defaults to /)>).
  • specify an installation prefix directory (--prefix-dir <installation prefix directory (defaults to /usr)>).
  • specify a default configuration directory (--sysconf-dir <system configuration destination directory (defaults to /etc)>).
  • disable ectool installation and service activation (--no-ectool)
  • disable post-install process (--no-post-install)
  • disable pre-uninstall process (--no-pre-uninstall)

Update

To install an update, you can pull the latest commit on the main branch of this repository, and run the install script again.

Uninstall

sudo ./install.sh --remove

Configuration

There is a single config.json file located at [dest-dir(/)][sysconf-dir(/etc)]/fw-fanctrl/config.json.

(You will need to reload the configuration with)

fw-fanctrl --reload

It contains different strategies, ranked from the most silent to the noisiest. It is possible to specify two different strategies for charging/discharging allowing for different optimization goals. On discharging one could have fan curve optimized for low fan speeds in order to save power while accepting a bit more heat. On charging one could have a fan curve that focuses on keeping the CPU from throttling and the system cool, at the expense of fan noise. You can add new strategies, and if you think you have one that deserves to be shared, feel free to make a PR to this repo :)

Strategies can be configured with the following parameters:

  • SpeedCurve:

    This is the curve points for f(temperature) = fan speed

    fw-fanctrl measures the CPU temperature, compute a moving average of it, and then find an appropriate fan speed value by interpolation on the curve.

  • FanSpeedUpdateFrequency:

    Time interval between every update to the fan's speed. fw-fanctrl measures temperature every second and add it to its moving average, but the actual update to fan speed is controlled using this configuration. This is for comfort, otherwise the speed is changed too often and it is noticeable and annoying, especially at low speed. For a more reactive fan, you can lower this setting. Defaults to 5 seconds.

  • MovingAverageInterval:

    Number of seconds on which the moving average of temperature is computed. Increase it, and the fan speed will change more gradually. Lower it, and it will gain in reactivity. Defaults to 20 seconds.

Charging/Discharging strategies

The strategy active by default is the one specified in the defaultStrategy entry. Optionally a separate strategy only active during discharge can be defined, using the strategyOnDischarging entry. By default no extra strategy for discharging is provided, the default strategy is active during all times.

Commands

Option Context Description
<strategy> run & configure the name of the strategy to use
--run run run the service
--config run specify the configuration path
--no-log run disable state logging
--query, -q configure print the current strategy name
--list-strategies configure print the available strategies
--reload, -r configure reload the configuration file
--pause configure temporarily disable the service and reset the fans to their default behaviour
--resume configure resume the service
--hardware-controller, --hc run select the hardware controller. choices: ectool
--socket-controller, --sc run & configure select the socket controller. choices: unix

fw-fanctrl's People

Contributors

centurio-macro avatar deflateawning avatar emrebicer avatar gidobossftw5731 avatar gronkdalonka avatar leopoldhub avatar maximilize avatar naklama avatar ngraham20 avatar originalme avatar tamtamhero avatar wesitos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fw-fanctrl's Issues

Issues with suspend-then-hibernate due to script in /usr/lib/systemd/system-sleep/

If I use suspend-then-hibernate, e.g. "systemctl suspend-then-hibernate" I observe that it takes up to 90 seconds to successfully suspend, and 90 seconds again to wake up.

If I use suspend e.g. "systemctl suspend" or hybrid-sleep e.g. "systemctl hybrid-sleep", the laptop suspends and wakes in just a couple of seconds.

If I remove /usr/lib/systemd/system-sleep/fw-fanctrl-suspend, the issue goes away. I have no idea why, as running the command "runuser -l myuser -c "fw-fanctrl sleep" returns instantly.

Command argument refactoring proposition

Hi @TamtamHero ,

I would like to refactor the existing command line arguments, complete them with missing essential ones and would appreciate your feedback.

Here are the current arguments (including those in PR #29):

contexts:

  • direct : can be used in a command that will run the background service
  • indirect : can be used in a command that will communicate with the background service
option group context description
<strategy> run & configure direct & indirect the name of the strategy to use
--run run direct run the service
--config run direct specify the configuration path
--no-log run direct disable state logging
--list-strategies configure indirect print the available strategies
--query, -q configure indirect print the current strategy name
--reload, -r configure indirect reload the configuration file
--pause configure indirect temporarily disable the service
--resume configure indirect resume the service

And here are the new ones:

| option | group | context | description |
|---------------------------------------------------------------|-----------------|----------|------------------------------------------|
| --run (?<strategy>) | run | direct | run the service |
| --config | run | direct | specify the configuration path |
| --silent | run | direct | disable state logging |
| --use <strategy> | | indirect | run the service |
| --actual-strategy,-a | | indirect | print the current strategy name |
| --strategy-detail,-d (?<strategy>) | | indirect | list a strategy configuration |
| --list-strategies,--ls,-l | | indirect | print the available strategies |
| --reload-config,--reload, -r | | indirect | reload the configuration file |
| --add-strategy,-A <strategy-name> | add | indirect | add a new strategy to the config |
| --configure-strategy,-C <strategy-name> | configure | indirect | configure a strategy |
| --update-frequency,--uf,-u <update-freq> | add & configure | indirect | set the strategy update frequency |
| --moving-average-interval,--mai,-m <moving-average-interval> | add & configure | indirect | set the strategy moving average interval |
| --curve-point,--cp,-c <temp>:<fan-duty> | add & configure | indirect | set a point in the curve |
| --delete-strategy,-D <strategy-name> | | indirect | delete a strategy |
| --pause | | indirect | temporarily disable the service |
| --resume | | indirect | resume the service |

Edit: After much thoughts, I think we should use subcommands when possible, as they are more intuitive.

run : direct : run the service. (use reset to reset to the default strategy)

argument description
strategy name of the strategy to use e.g: "lazy". (use print strategies to list available strategies). (optional)
--config, -c config file path. (default: /etc/fw-fanctrl/config.json)
--silent, -s disable printing speed/temp status to stdout

reload : indirect : reload configuration

reset : indirect : reset the current strategy to the default one

set-default : indirect : set the default strategy

argument description
strategy name of the strategy to use e.g: "lazy". (use print strategies to list available strategies)
--discharge, --d is the default for discharging strategy

remove-default : indirect : remove the default strategy

argument description
--discharge, --d is the default for discharging strategy

add : indirect : add a new strategy

argument description
strategy name of the strategy to use e.g: "lazy". (use print strategies to list available strategies)
curve_point... a point in the temperature curve in the format: temp:speed
--update-frequency, --uf, -u time interval between every temperature update. (min: 1. default: 5)
--average-interval, --ai, -a number of seconds on which the moving average of temperature is computed. (min: 0. default: 20)

configure : indirect : configure an existing strategy

argument description
strategy name of the strategy to use e.g: "lazy". (use print strategies to list available strategies)
curve_point... a point in the temperature curve in the format: temp:speed. (optional)
--update-frequency, --uf, -u time interval between every temperature update. (min: 1. default: 5)
--average-interval, --ai, -a number of seconds on which the moving average of temperature is computed. (min: 0. default: 20)

delete : direct : delete an existing strategy

argument description
strategy name of the strategy to use e.g: "lazy". (use print strategies to list available strategies)

pause : direct : pause the service

resume : resume : pause the service

print : direct : print desired information

argument (OR) description
current-strategy print the current strategy
strategy-details strategy print the details of the specified strategy
strategies list the available strategies

The aim is to make them more intuitive and organised, and to achieve this many of them will have to be renamed/removed and users will have to change the way they use the actual commands.

What are your thoughts on this?
Should we go for it or add a deprecation warning for now?

Reading the temperature from the wrong sensor

The fw-fanctrl tool was working ok but after some intensive compilation recently I detect that is reading the temperature from the wrong sensor, provoking that the fan never goes to 100% on max load, making the CPU throttle and the chasis unconformable to the touch...

OS: Manjaro
Kernel: 6.9.0-1-MANJARO
Host: Laptop 13 (AMD Ryzen 7040Series) (A7)

lm-sensors output:

❯ sensors
ucsi_source_psy_USBC000:002-isa-0000
Adapter: ISA adapter
in0:           5.00 V  (min =  +5.00 V, max =  +5.00 V)
curr1:         0.00 A  (max =  +1.50 A)

iwlwifi_1-virtual-0
Adapter: Virtual device
temp1:        +34.0°C  

ucsi_source_psy_USBC000:004-isa-0000
Adapter: ISA adapter
in0:          20.00 V  (min =  +5.00 V, max = +38.80 V)
curr1:         5.00 A  (max =  +3.56 A)

amdgpu-pci-c100
Adapter: PCI adapter
vddgfx:      838.00 mV 
vddnb:       765.00 mV 
edge:         +87.0°C  
PPT:          28.22 W  (avg =  28.01 W)

BAT1-acpi-0
Adapter: ACPI interface
in0:          17.70 V  
curr1:         0.00 A  

ucsi_source_psy_USBC000:003-isa-0000
Adapter: ISA adapter
in0:           0.00 V  (min =  +0.00 V, max =  +0.00 V)
curr1:       680.00 mA (max =  +0.00 A)

ucsi_source_psy_USBC000:001-isa-0000
Adapter: ISA adapter
in0:           0.00 V  (min =  +0.00 V, max =  +0.00 V)
curr1:         0.00 A  (max =  +0.00 A)

k10temp-pci-00c3
Adapter: PCI adapter
Tctl:         +88.1°C  

nvme-pci-0200
Adapter: PCI adapter
Composite:    +39.9°C  (low  = -273.1°C, high = +89.8°C)
                       (crit = +94.8°C)
Sensor 1:     +39.9°C  (low  = -273.1°C, high = +65261.8°C)
Sensor 2:     +35.9°C  (low  = -273.1°C, high = +65261.8°C)

acpitz-acpi-0
Adapter: ACPI interface
temp1:        +50.8°C  
temp2:        +55.8°C  
temp3:        +45.8°C  
temp4:        +87.8°C

fw-fanctrl output for the same temp:

speed: 19% temp: 47.8°C movingAverage: 46.3°C
speed: 19% temp: 47.8°C movingAverage: 46.4°C
speed: 19% temp: 47.8°C movingAverage: 46.5°C
speed: 19% temp: 47.8°C movingAverage: 46.57°C
speed: 19% temp: 47.8°C movingAverage: 46.63°C
speed: 19% temp: 47.8°C movingAverage: 46.7°C
speed: 19% temp: 48.8°C movingAverage: 46.8°C
speed: 19% temp: 47.8°C movingAverage: 46.87°C
speed: 19% temp: 47.8°C movingAverage: 46.93°C
speed: 20% temp: 48.8°C movingAverage: 47.03°C
speed: 20% temp: 48.8°C movingAverage: 47.13°C
speed: 20% temp: 48.8°C movingAverage: 47.23°C
speed: 20% temp: 48.8°C movingAverage: 47.33°C
speed: 20% temp: 48.8°C movingAverage: 47.43°C
speed: 20% temp: 48.8°C movingAverage: 47.53°C
speed: 20% temp: 48.8°C movingAverage: 47.63°C
speed: 20% temp: 48.8°C movingAverage: 47.73°C
speed: 20% temp: 48.8°C movingAverage: 47.8°C
speed: 20% temp: 48.8°C movingAverage: 47.87°C
speed: 20% temp: 48.8°C movingAverage: 47.93°C
speed: 20% temp: 48.8°C movingAverage: 48.0°C
speed: 20% temp: 48.8°C movingAverage: 48.07°C
speed: 20% temp: 48.8°C movingAverage: 48.13°C
speed: 20% temp: 49.8°C movingAverage: 48.2°C
speed: 21% temp: 49.8°C movingAverage: 48.3°C
speed: 21% temp: 49.8°C movingAverage: 48.4°C
speed: 21% temp: 49.8°C movingAverage: 48.5°C
speed: 21% temp: 49.8°C movingAverage: 48.6°C
speed: 21% temp: 49.8°C movingAverage: 48.7°C
speed: 21% temp: 49.8°C movingAverage: 48.77°C
speed: 21% temp: 49.8°C movingAverage: 48.83°C
speed: 21% temp: 49.8°C movingAverage: 48.9°C
speed: 21% temp: 49.8°C movingAverage: 48.97°C
speed: 21% temp: 49.8°C movingAverage: 49.03°C

Please let me know if I can help with extra info. Thanks!

[BUG] Crash - `EC returned error result code 1`

Describe the bug
fw-fanctrl often crashes, with the seemingly relevant error being EC returned error result code 1 (full report below). This usually happens after somewhere between a few seconds and 10 minutes I think (these are simply guesses based on my own time perception). It sounds like this might not be an error with fw-fanctrl to me, based on the fact it's saying "EC returned error...", but I imagine the error handling could certainly be more graceful (e.g. the UTF-8 decode error shown in the full report, which I interpret as not being the root cause of the crash).

To Reproduce
I'm not entirely sure; clearly this is something unique to my setup, or it would be happening to everyone. But however you reproduce EC returning an error code 1 must be how.

Error message

$ sudo fw-fanctrl --run
speed: 15%, temp: 31°C, movingAverageTemp: 31.0°C, effectureTemp: 31.0°C
speed: 15%, temp: 31°C, movingAverageTemp: 31.0°C, effectureTemp: 31.0°C
speed: 15%, temp: 30°C, movingAverageTemp: 30.7°C, effectureTemp: 30°C
EC returned error result code 1
EC response has invalid checksum
EC returned too much data
Traceback (most recent call last):
  File "/usr/bin/fw-fanctrl", line 329, in <module>
    main()
  File "/usr/bin/fw-fanctrl", line 306, in main
    fan.run(debug=not args.no_log)
  File "/usr/bin/fw-fanctrl", line 252, in run
    self.printState()
  File "/usr/bin/fw-fanctrl", line 234, in printState
    currentTemperture = self.getActualTemperature()
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/bin/fw-fanctrl", line 189, in getActualTemperature
    rawOut = subprocess.run(bashCommand, stdout=subprocess.PIPE, shell=True, text=True).stdout
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 550, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 1196, in communicate
    stdout = self.stdout.read()
             ^^^^^^^^^^^^^^^^^^
  File "<frozen codecs>", line 322, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfd in position 143: invalid start byte

Environment (please complete the following information):

Cannot open lockfile error

Fedora 37 on 12th Gen Framework laptop.

Running fw-fanctrl --config ~/.config/fw-fanctrl/config.json results in the following output:

Cannot open lockfile /run/lock/cros_ec_lockCould not acquire GEC lock.
speed: 15% temp: 42.5°C movingAverage: 42.5°C
speed: 15% temp: 42.0°C movingAverage: 42.48°C
speed: 15% temp: 40.666666666666664°C movingAverage: 42.42°C
Cannot open lockfile /run/lock/cros_ec_lockCould not acquire GEC lock.
speed: 15% temp: 41.166666666666664°C movingAverage: 42.38°C
speed: 15% temp: 40.916666666666664°C movingAverage: 42.33°C
speed: 15% temp: 40.333333333333336°C movingAverage: 42.25°C
speed: 15% temp: 41.75°C movingAverage: 42.23°C
speed: 15% temp: 40.416666666666664°C movingAverage: 42.16°C
Cannot open lockfile /run/lock/cros_ec_lockCould not acquire GEC lock.
speed: 15% temp: 40.833333333333336°C movingAverage: 42.1°C

Running the same command as root (via sudo) does not have an issue with the lockfile (which is owned by root).

Should this utility only be run as root? If so, should the configuration file be installed on a per-user basis?

install.sh attempts to stop service during packaging

Describe the bug
The installation script attempts to assume control over the systemd services it installs by trying to stop them if they are running. This is fine for systems directly calling the install script, though it introduces issues during AUR package build. It is a better idea to have this happen in post-install, and for the AUR package this does not make sense anyways until the actual package installation runs (where pacman's hooks manage the systemd services).

To Reproduce
Steps to reproduce the behavior:

  1. Build the package with a previous version of fw-fanctrl already installed and actively running
  2. Wait for the packaging process to call install script.

Expected behavior
It should copy the files and create the package successfully without touching any host services.

Error message

==> Starting package()...
creating '/home/icedream/Documents/Source/Git/aur.archlinux.org/fw-fanctrl-git/pkg/fw-fanctrl-git/usr/lib/systemd/system'
creating services
stopping [fw-fanctrl]
Failed to stop fw-fanctrl.service: Access denied
See system logs and 'systemctl status fw-fanctrl.service' for details.

This also pops up a graphical request to allow access to the host systemd.

Environment (please complete the following information):

  • OS: Arch
  • Version: commit fb4c933
  • Installation method: AUR/makepkg

Can't get value of subfeature curr1_input: Can't read

Fedora 36 kernel 6.2.12., framework gen 12th.
Just notice that despite the service was in running state it was not working - CPU got 100 C and start throttling.
Here is journalctl:

kwi 27 08:56:57 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.
kwi 27 08:56:57 framework systemd[1]: fw-fanctrl.service: Consumed 37min 54.503s CPU time.
kwi 27 08:56:57 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 27 08:56:57 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 27 08:56:57 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 26 09:12:51 framework python3[15106]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 26 08:44:58 framework python3[10200]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 26 08:16:29 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.

Before the time I can notice that the service consume a lot of CPU and also have different errors (which probably is why the FW was so quite) :

-- Boot 644552e41ada4807a69228efd7b6c557 --
kwi 26 08:14:28 framework systemd[1]: fw-fanctrl.service: Consumed 6.343s CPU time.
kwi 26 08:14:28 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 26 08:14:28 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 26 08:14:28 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 25 21:33:42 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.
-- Boot 6cf6a57ede98488c8200bad27bfb9ddb --
kwi 25 20:40:55 framework systemd[1]: fw-fanctrl.service: Consumed 43min 33.261s CPU time.
kwi 25 20:40:55 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 25 20:40:55 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 25 20:40:55 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 24 11:29:44 framework python3[523387]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 24 11:08:51 framework python3[519305]: EC result 1 (INVALID_COMMAND)
kwi 24 11:08:51 framework python3[519305]: EC result 7 (INVALID_CHECKSUM)
kwi 24 11:08:51 framework python3[519305]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 24 10:28:12 framework python3[511159]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 24 10:28:12 framework python3[511159]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 24 10:28:12 framework python3[511159]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 20 17:20:16 framework python3[356320]: EC result 7 (INVALID_CHECKSUM)
kwi 20 17:20:16 framework python3[356320]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 20 16:28:47 framework python3[344826]: EC result 7 (INVALID_CHECKSUM)
kwi 20 09:53:07 framework python3[256432]: ERROR: Can't get value of subfeature temp1_input: Can't read
kwi 20 09:53:06 framework python3[256410]: ERROR: Can't get value of subfeature temp1_input: Can't read
kwi 20 09:53:05 framework python3[256404]: ERROR: Can't get value of subfeature temp1_input: Can't read
kwi 20 09:53:04 framework python3[256397]: ERROR: Can't get value of subfeature temp1_input: Can't read
kwi 19 21:08:00 framework python3[243779]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 19 15:09:25 framework python3[185589]: EC result 7 (INVALID_CHECKSUM)
kwi 18 09:21:10 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.
-- Boot 79d24f8d0cbe49b4bc49b311bc4f5179 --
kwi 18 09:18:12 framework systemd[1]: fw-fanctrl.service: Consumed 31min 11.310s CPU time.
kwi 18 09:18:12 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 18 09:18:12 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 18 09:18:12 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 17 15:55:44 framework python3[211165]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 17 11:41:54 framework python3[160535]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 17 11:37:52 framework python3[159695]: EC returned error result code 7
kwi 17 10:59:32 framework python3[151728]: EC returned error result code 7
kwi 17 10:59:32 framework python3[151728]: EC returned error result code 7
kwi 17 10:42:06 framework python3[148010]: EC returned error result code 7
kwi 17 10:42:06 framework python3[148010]: EC returned error result code 7
kwi 17 10:42:06 framework python3[148010]: EC returned error result code 7
kwi 14 15:38:27 framework python3[86713]: EC result 1 (INVALID_COMMAND)
kwi 14 15:38:27 framework python3[86713]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 14 15:38:27 framework python3[86713]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 14 13:15:24 framework python3[53632]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 14 13:15:24 framework python3[53632]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 14 12:27:58 framework python3[44461]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 14 11:39:03 framework python3[33655]: EC result 7 (INVALID_CHECKSUM)
kwi 14 11:39:03 framework python3[33655]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 14 11:39:03 framework python3[33655]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 14 11:12:12 framework python3[26977]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 14 11:12:12 framework python3[26977]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 14 10:48:08 framework python3[21264]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 14 09:24:52 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.
-- Boot 41a8abc55a1f43c1a2f6c4b36ff6a9ea --
kwi 14 09:21:30 framework systemd[1]: fw-fanctrl.service: Consumed 1h 15min 31.659s CPU time.
kwi 14 09:21:30 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 14 09:21:30 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 14 09:21:30 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 13 16:56:15 framework python3[557993]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 13 15:38:44 framework python3[539256]: EC result 1 (INVALID_COMMAND)
kwi 13 15:38:44 framework python3[539256]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 13 15:38:44 framework python3[539256]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 13 15:33:57 framework python3[538037]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 13 15:22:00 framework python3[535332]: Couldn't find EC
kwi 13 15:22:00 framework python3[535332]: Unable to establish host communication
kwi 13 15:22:00 framework python3[535332]: Cannot find I2C adapter
kwi 13 15:22:00 framework python3[535332]: Missing Chromium EC memory map.
kwi 13 13:41:54 framework python3[512914]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 13 13:20:43 framework python3[508422]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 13 13:20:43 framework python3[508422]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 13 13:09:56 framework python3[506285]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 13 13:09:56 framework python3[506285]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 13 12:34:42 framework python3[498462]: EC result 1 (INVALID_COMMAND)
kwi 13 12:34:42 framework python3[498462]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 13 12:34:42 framework python3[498462]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 13 11:47:57 framework python3[488192]: EC result 1 (INVALID_COMMAND)
kwi 13 11:47:57 framework python3[488192]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 13 11:08:33 framework python3[479337]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 12 17:49:56 framework python3[394215]: EC result 1 (INVALID_COMMAND)
kwi 12 17:49:56 framework python3[394215]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 12 14:29:58 framework python3[348437]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 12 14:17:51 framework python3[345813]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 12 14:17:51 framework python3[345813]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 11 16:38:44 framework python3[238503]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 11 16:04:35 framework python3[230894]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 11 16:03:33 framework python3[230712]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 11 09:48:56 framework python3[144844]: EC result 7 (INVALID_CHECKSUM)
kwi 11 09:48:56 framework python3[144844]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 11 09:07:27 framework python3[133445]: EC result 7 (INVALID_CHECKSUM)
kwi 07 10:24:49 framework python3[21897]: EC result 7 (INVALID_CHECKSUM)
kwi 07 09:53:29 framework python3[15828]: ERROR: Can't get value of subfeature curr1_input: Can't read
kwi 07 09:43:50 framework python3[13112]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 07 09:43:50 framework python3[13112]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 07 09:43:50 framework python3[13112]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 07 03:37:37 framework python3[1565]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 07 03:37:34 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.
-- Boot e72b7f5318814a8c908d915cda740caf --
kwi 07 03:36:33 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 07 03:36:33 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 07 03:36:33 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 07 03:36:28 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.
-- Boot ca589b949ee14a91a61cb84427d76079 --
kwi 07 03:35:31 framework systemd[1]: fw-fanctrl.service: Consumed 14min 25.623s CPU time.
kwi 07 03:35:31 framework systemd[1]: Stopped fw-fanctrl.service - FrameWork Fan Controller.
kwi 07 03:35:31 framework systemd[1]: fw-fanctrl.service: Deactivated successfully.
kwi 07 03:35:31 framework systemd[1]: Stopping fw-fanctrl.service - FrameWork Fan Controller...
kwi 06 21:37:08 framework python3[240507]: EC result 7 (INVALID_CHECKSUM)
kwi 06 21:16:46 framework python3[237256]: EC result 7 (INVALID_CHECKSUM)
kwi 06 18:46:31 framework python3[219301]: EC result 7 (INVALID_CHECKSUM)
kwi 06 18:23:03 framework python3[215196]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 06 18:23:03 framework python3[215196]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 06 18:23:03 framework python3[215196]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 06 18:10:56 framework python3[213402]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 06 18:03:31 framework python3[212246]: EC result 7 (INVALID_CHECKSUM)
kwi 06 17:50:01 framework python3[209570]: EC result 7 (INVALID_CHECKSUM)
kwi 06 17:39:56 framework python3[208019]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 06 15:43:33 framework python3[187609]: EC result 7 (INVALID_CHECKSUM)
kwi 06 08:50:07 framework python3[115943]: EC result 7 (INVALID_CHECKSUM)
kwi 05 20:57:36 framework python3[114441]: EC result 7 (INVALID_CHECKSUM)
kwi 05 20:57:36 framework python3[114441]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 05 18:36:31 framework python3[94646]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 05 18:16:23 framework python3[91727]: EC result 7 (INVALID_CHECKSUM)
kwi 05 17:53:04 framework python3[88044]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
kwi 05 16:29:18 framework python3[73106]: ERROR: Can't get value of subfeature temp1_input: I/O error
kwi 05 16:28:34 framework python3[72990]: ERROR: Can't get value of subfeature temp1_input: I/O error
kwi 05 16:08:41 framework python3[69710]: ERROR: Can't get value of subfeature temp1_input: I/O error
kwi 05 15:43:41 framework python3[65511]: ERROR: Can't get value of subfeature temp1_input: I/O error
kwi 05 15:43:33 framework python3[65500]: ERROR: Can't get value of subfeature temp1_input: I/O error
kwi 05 14:37:19 framework python3[54951]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknown>)
kwi 05 11:04:24 framework python3[19757]: EC result 7 (INVALID_CHECKSUM)
kwi 05 09:34:47 framework systemd[1]: Started fw-fanctrl.service - FrameWork Fan Controller.

Fans keep working after suspend

I cloned the repository on my Arch Linux system and ran the install script. It works as intended however the fans will keep working after suspend (sleep), Is there a way to make fans stop and start them on resume?

FileNotFoundError: [Errno 2] No such file or directory on latest commit

Just updated the AUR package after last commits. Now it's not running. Tried to reinstall the package, no luck

$ fw-fanctrl
Traceback (most recent call last):
File "/usr/bin/fw-fanctrl", line 320, in
main()
File "/usr/bin/fw-fanctrl", line 301, in main
client_socket.connect(COMMANDS_SOCKET_FILE_PATH)
FileNotFoundError: [Errno 2] No such file or directory

[BUG] What's going on here? Laptop showed 0 battery power and then shutoff

Describe the bug

The error message below happened. Right before the timestamps of the logs, the computer showed 0% battery and then shutdown due to critically-low battery.

DeflateAwning@host ~> sudo systemctl status fw-fanctrl.service
[sudo] password for DeflateAwning:                          
● fw-fanctrl.service - Framework Fan Controller
     Loaded: loaded (/lib/systemd/system/fw-fanctrl.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2024-06-30 14:27:12 PDT; 12min ago
   Main PID: 2166 (python3)
      Tasks: 2 (limit: 76620)
     Memory: 6.8M
        CPU: 21.528s
     CGroup: /system.slice/fw-fanctrl.service
             └─2166 /usr/bin/python3 /usr/bin/fw-fanctrl --run --config /etc/fw-fanctrl/config.json --no-log

Jun 30 14:29:04 host python3[4114]: Unable to establish host communication
Jun 30 14:29:04 host python3[4114]: Couldn't find EC
Jun 30 14:31:13 host python3[4799]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknow>
Jun 30 14:32:54 host python3[7435]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknow>
Jun 30 14:35:19 host python3[8437]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
Jun 30 14:36:44 host python3[8940]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
Jun 30 14:36:44 host python3[8940]: EC result 7 (INVALID_CHECKSUM)
Jun 30 14:37:06 host python3[9072]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)
Jun 30 14:37:43 host python3[9250]: ioctl -1, errno 90 (Message too long), EC result 255 (<unknow>
Jun 30 14:38:41 host python3[9598]: ioctl -1, errno 74 (Bad message), EC result 255 (<unknown>)

Environment (please complete the following information):

  • OS: Linux Mint
  • Version: Latest?
  • Configuration file: default
  • Installation method: installer script

Additional context
Crashes in a tool which controls system temperature are very bad.

In my opinion, this tool should be marked as Unstable in the README, based on this experience.

[BUG] --list-strategies provides no output

When running fw-fanctrl --list-strategies, no output is provided. This behavior is consistent, provides no error message, and persists after reinstalling. I have confirmed that the configuration file exists in the default location.

Environment

  • OS: EndeavourOS (Arch Based)
  • Version: r46.d4b45c6-1
  • Installation method: fw-fanctrl-git AUR package

No binary embedding

Hi, as stated here by @dariov1988 , we should not embed binaries into the project, but rather fetch them from the official source.

The build artifacts for ectool can be found here.

This is an open question:
Do you have any recommendations on how we should fetch, extract and install the artifacts for this project?

Unable to establish host communication

When I start the service, I see this in the logs:

5:39 PM Couldn't find EC                                        python3
5:39 PM Unable to establish host communication                  python3
5:39 PM Cannot find I2C adapter                                 python3
5:39 PM Missing Chromium EC memory map.                         python3
5:39 PM Started fw-fanctrl.service - FrameWork Fan Controller.  systemd

It then continues to repeat this ad infinitum

Here's my config file from ~/.config/fw-fanctrl:
config.json

Occasionally pins CPU to 100%

Framework 13th gen, seems like sometimes after it suspends/hibernates or runs for a few days something goes haywire and it goes up to 100% cpu usage (as reported by top, so only one thread.) Restarting the service solves this. Next time it happens I'll try to collect some logs.

Error running after fresh install (config not found)

Fedora 37 on 12th Gen Framework laptop.

Running fw-fanctrl with no arguments after a fresh install:

$ fw-fanctrl
Traceback (most recent call last):
  File "/usr/local/bin/fw-fanctrl", line 226, in <module>
    main()
  File "/usr/local/bin/fw-fanctrl", line 221, in main
    fan = FanController(configPath=args.config, strategy=args.strategy)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/bin/fw-fanctrl", line 37, in __init__
    with open(configPath, "r") as fp:
         ^^^^^^^^^^^^^^^^^^^^^
IsADirectoryError: [Errno 21] Is a directory: '.'

So far as I can determine, this is because it is assuming that the config path is the current directory (.), but the configuration file has been installed to /home/[user]/.config/fw-fanctrl. Issuing fw-fanctrl --config ~/.config/fw-fanctrl/config.json causes the program to run.

It is not clear from the README or from the help output that a path to a config file is required, and it seems sensible to assume that the config file might be looked for in the location where it was installed to by the installation script. It might even make sense for this to operate at a system level (since the installation script expects to be run as root, and installs a system service), so having a default configuration under the standard Unix /etc path may be a useful step.

ectool and windows support

Hi,

In the PR #29 , we replaced Most of the Linux dependencies (replacing the file paths with ectool) except for the sockets.

It should now be possible to adapt the script for windows users.

The ectool can be built for win x64 by reproducing the goal in the .gitlab-ci.yml file (after installing VisualStudio Community 2022 with the C++ and ClangCL package (the installation path may vary slightly))
I have successfully built it in a VM, however since I do not have a native windows installation, I could not fully test if the ectool can properly interacts with the computer hardware.

If you have one, could you please test it on your end, and if everything is ok add the exe to the repo bin folder so I can start the adaptation?

[BUG] [packaging/AUR] Sleep hook causes 90-second hang on startup / resume from sleep

Describe the bug
Sleep hook causes a hang when coming out of suspend. Also reported at systemd/systemd#33020 and https://bbs.archlinux.org/viewtopic.php?pid=2177336#p2177336.

To Reproduce

  1. Install the package
  2. Reboot
  3. Observe a delay of exactly 90 seconds coming out of sleep.

Expected behavior
The system should resume from sleep instantly.

Screenshots
If applicable, add screenshots to help explain your problem.

Error message

Jun 10 22:40:56 <REDACTED> runuser[56917]: pam_unix(runuser-l:session): session opened for user root(uid=0) by root(uid=0)
Jun 10 22:41:26 <REDACTED> runuser[56812]: pam_systemd(runuser-l:session): Failed to create session: Connection timed out
Jun 10 22:41:26 <REDACTED> runuser[56812]: pam_unix(runuser-l:session): session closed for user root

Environment (please complete the following information):

  • OS: Arch
  • Version commit c9397ab
  • Configuration file NA
  • Installation method yay -S fw-fanctrl-git

Additional context
Removing the sleep hook solves the problem.

[Feature] Support for Framework 16

Hi :-),

i just go my Framework 16 in the mail and did setup Manjaro on it. Because of too little fan rpm my whole laptop is (at least for my feeling) quite to warm.

I found your AUR package, but sadly it does not work because your script uses lm_sensors to determine the temperatures. Would you be capable of adding a mode where the temperatures are determined with the ectool? A AUR package for the framrwork-patched version is already available.

Greetings
hasechris

fanctrl.py for windows [FEATURE]

i run install bat on windows 11 and did installation successfully

however when i run fw-fanctrl --reload command in cmd

i get error

  File "C:\Windows\System32\fanctrl.py", line 329, in <module>
    main()
  File "C:\Windows\System32\fanctrl.py", line 308, in main
    client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                                  ^^^^^^^^^^^^^^
AttributeError: module 'socket' has no attribute 'AF_UNIX'

i updated fanctrl.py end to something like this

SOCKETS_FOLDER_PATH = "/run/fw-fanctrl"
COMMANDS_SOCKET_FILE_PATH = ( '127.0.0.1', 12345) # Example IP address and port number

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    client_socket.connect(COMMANDS_SOCKET_FILE_PATH)
    client_socket.sendall(' '.join(sys.argv[1:]).encode())
    received_data = b""
    while True:
        data_chunk = client_socket.recv(1024)
        if not data_chunk:
            break
        received_data += data_chunk
    # Receive data from the server
    data = received_data.decode()
    print(data)
    if data.startswith("Error:"):
        exit(1)
finally:
    if client_socket:
        client_socket.close()

so what should be COMMANDS_SOCKET_FILE_PATH for windows ??

[Question] about the ec tool project and the right version to use

Hi there,

As stated in this project README, fw-fanctrl

uses fw-ectool to change parameters in FrameWork's embedded controller (EC).

the link refers to the DHowett/fw-ectool project, which is a fork of the Framework team's FrameworkComputer/EmbeddedController project.

The main concern here is that the DHowett/fw-ectool project is a whopping 10098 commits behind the official project.

I imagine that there are reasons for using DHowett/fw-ectool instead of FrameworkComputer/EmbeddedController, but I cannot seem to find any information or documentation about it either in DHowett/fw-ectool or in this project and would appreciate a bit of context about this choice.

Thank you and have a great day.

[Feature] Support for AMD Framework 13

Hello,

I have the new FW AMD 13 inch laptop and I checked out the changes made to support AMD here, but it looks like my output for lm_sensors is missing acpitz-acpi-0 that is required for fw-fanctrl.

Here is my sensors -j output:

{
   "mt7921_phy0-pci-0100":{
      "Adapter": "PCI adapter",
      "temp1":{
         "temp1_input": 48.000
      }
   },
   "ucsi_source_psy_USBC000:004-isa-0000":{
      "Adapter": "ISA adapter",
      "in0":{
         "in0_input": 0.000,
         "in0_min": 0.000,
         "in0_max": 0.000
      },
      "curr1":{
         "curr1_input": 0.000,
         "curr1_max": 0.000
      }
   },
   "ucsi_source_psy_USBC000:002-isa-0000":{
      "Adapter": "ISA adapter",
      "in0":{
         "in0_input": 5.000,
         "in0_min": 5.000,
         "in0_max": 5.000
      },
      "curr1":{
         "curr1_input": 0.000,
         "curr1_max": 1.500
      }
   },
   "nvme-pci-0200":{
      "Adapter": "PCI adapter",
      "Composite":{
         "temp1_input": 39.850,
         "temp1_max": 84.850,
         "temp1_min": -0.150,
         "temp1_crit": 94.850,
         "temp1_alarm": 0.000
      },
      "Sensor 1":{
         "temp2_input": 39.850,
         "temp2_max": 65261.850,
         "temp2_min": -273.150
      },
      "Sensor 2":{
         "temp3_input": 41.850,
         "temp3_max": 65261.850,
         "temp3_min": -273.150
      },
      "Sensor 8":{
         "temp9_input": 39.850,
         "temp9_max": 65261.850,
         "temp9_min": -273.150
      }
   },
   "amdgpu-pci-c100":{
      "Adapter": "PCI adapter",
      "vddgfx":{
         "in0_input": 1.284
      },
      "vddnb":{
         "in1_input": 0.806
      },
      "edge":{
         "temp1_input": 45.000
      },
      "PPT":{
         "power1_average": 8.236,
         "power1_input": 23.184
      }
   },
   "k10temp-pci-00c3":{
      "Adapter": "PCI adapter",
      "Tctl":{
         "temp1_input": 47.750
      }
   },
   "ucsi_source_psy_USBC000:003-isa-0000":{
      "Adapter": "ISA adapter",
      "in0":{
         "in0_input": 5.000,
         "in0_min": 5.000,
         "in0_max": 5.000
      },
      "curr1":{
         "curr1_input": 0.000,
         "curr1_max": 1.500
      }
   },
   "ucsi_source_psy_USBC000:001-isa-0000":{
      "Adapter": "ISA adapter",
      "in0":{
         "in0_input": 0.000,
         "in0_min": 0.000,
         "in0_max": 0.000
      },
      "curr1":{
         "curr1_input": 0.410,
         "curr1_max": 0.000
      }
   },
   "BAT1-acpi-0":{
      "Adapter": "ACPI interface",
      "in0":{
         "in0_input": 16.221
      },
      "curr1":{
         "curr1_input": 0.000
      }
   }
}

In fanctrl.py, i tried using k10temp-pci-00c3 instead of acpitz-acpi-0 and it seems to work somewhat. It seems like both the 16 inch and 13 inch AMD laptops both contain k10temp-pci-00c3, would it be possible to add support for this?

Thanks.

Edit:
It does look like k10temp should be the correct sensor reading to use for current Ryzen AMD processors.

https://docs.kernel.org/hwmon/k10temp.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.